added simple VU Meter

This commit is contained in:
Ahmet Inan 2015-01-14 18:30:00 +01:00
parent 98a9ee7f1f
commit ada2422531
7 changed files with 120 additions and 9 deletions

View file

@ -30,6 +30,7 @@ public class Decoder {
private final MainActivity activity;
private final ImageView image;
private final SpectrumView spectrum;
private final VUMeterView meter;
private final AudioRecord audio;
private final int audioSource = MediaRecorder.AudioSource.MIC;
private final int channelConfig = AudioFormat.CHANNEL_IN_MONO;
@ -42,6 +43,7 @@ public class Decoder {
private final int[] savedBuffer;
private final int[] savedWidth;
private final int[] savedHeight;
private final int[] volume;
private final RenderScript rs;
private final Allocation rsDecoderAudioBuffer;
@ -52,6 +54,7 @@ public class Decoder {
private final Allocation rsDecoderSavedBuffer;
private final Allocation rsDecoderSavedWidth;
private final Allocation rsDecoderSavedHeight;
private final Allocation rsDecoderVolume;
private final ScriptC_decoder rsDecoder;
private final int mode_raw = 0;
@ -73,7 +76,10 @@ public class Decoder {
return;
if (drawImage) {
image.drawCanvas();
spectrum.drawCanvas();
if(enableAnalyzer) {
spectrum.drawCanvas();
meter.drawCanvas();
}
}
}
decode();
@ -81,9 +87,10 @@ public class Decoder {
}
};
public Decoder(MainActivity activity, SpectrumView spectrum, ImageView image) {
public Decoder(MainActivity activity, SpectrumView spectrum, ImageView image, VUMeterView meter) {
this.image = image;
this.spectrum = spectrum;
this.meter = meter;
this.activity = activity;
pixelBuffer = new int[image.bitmap.getWidth() * image.bitmap.getHeight()];
spectrumBuffer = new int[spectrum.bitmap.getWidth() * spectrum.bitmap.getHeight()];
@ -103,6 +110,7 @@ public class Decoder {
currentMode = new int[1];
savedWidth = new int[1];
savedHeight = new int[1];
volume = new int[1];
savedBuffer = new int[pixelBuffer.length];
rs = RenderScript.create(activity.getApplicationContext());
@ -113,6 +121,7 @@ public class Decoder {
rsDecoderCurrentMode = Allocation.createSized(rs, Element.I32(rs), 1, Allocation.USAGE_SHARED | Allocation.USAGE_SCRIPT);
rsDecoderSavedWidth = Allocation.createSized(rs, Element.I32(rs), 1, Allocation.USAGE_SHARED | Allocation.USAGE_SCRIPT);
rsDecoderSavedHeight = Allocation.createSized(rs, Element.I32(rs), 1, Allocation.USAGE_SHARED | Allocation.USAGE_SCRIPT);
rsDecoderVolume = Allocation.createSized(rs, Element.I32(rs), 1, Allocation.USAGE_SHARED | Allocation.USAGE_SCRIPT);
rsDecoderSavedBuffer = Allocation.createSized(rs, Element.I32(rs), savedBuffer.length, Allocation.USAGE_SHARED | Allocation.USAGE_SCRIPT);
rsDecoder = new ScriptC_decoder(rs);
rsDecoder.bind_audio_buffer(rsDecoderAudioBuffer);
@ -122,6 +131,7 @@ public class Decoder {
rsDecoder.bind_current_mode(rsDecoderCurrentMode);
rsDecoder.bind_saved_width(rsDecoderSavedWidth);
rsDecoder.bind_saved_height(rsDecoderSavedHeight);
rsDecoder.bind_volume(rsDecoderVolume);
rsDecoder.bind_saved_buffer(rsDecoderSavedBuffer);
rsDecoder.invoke_initialize(sampleRate, valueBufferLength,
image.bitmap.getWidth(), image.bitmap.getHeight(),
@ -238,6 +248,9 @@ public class Decoder {
rsDecoderCurrentMode.copyTo(currentMode);
switch_mode(currentMode[0]);
rsDecoderVolume.copyTo(volume);
meter.volume = volume[0] / 1023.0f;
rsDecoderSavedHeight.copyTo(savedHeight);
if (savedHeight[0] > 0) {
rsDecoderSavedWidth.copyTo(savedWidth);

View file

@ -125,7 +125,8 @@ public class MainActivity extends Activity {
changeLayoutOrientation(getResources().getConfiguration());
decoder = new Decoder(this,
(SpectrumView)findViewById(R.id.spectrum),
(ImageView)findViewById(R.id.image)
(ImageView)findViewById(R.id.image),
(VUMeterView)findViewById(R.id.meter)
);
manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
showNotification();
@ -165,9 +166,9 @@ public class MainActivity extends Activity {
private void changeLayoutOrientation(Configuration config) {
boolean horizontal = config.orientation == Configuration.ORIENTATION_LANDSCAPE;
View spectrum = findViewById(R.id.spectrum);
spectrum.setVisibility(enableAnalyzer ? View.VISIBLE : View.GONE);
spectrum.setLayoutParams(
View spectrum_meter = findViewById(R.id.spectrum_meter);
spectrum_meter.setVisibility(enableAnalyzer ? View.VISIBLE : View.GONE);
spectrum_meter.setLayoutParams(
new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT, horizontal ? 1.0f : 10.0f));

View file

@ -0,0 +1,78 @@
/*
Copyright 2015 Ahmet Inan <xdsopl@googlemail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package xdsopl.robot36;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class VUMeterView extends SurfaceView implements SurfaceHolder.Callback {
private int canvasWidth = -1, canvasHeight = -1;
private boolean cantTouchThis = true;
private final SurfaceHolder holder;
private final Paint paint;
public float volume = 0.0f;
public VUMeterView(Context context, AttributeSet attrs) {
super(context, attrs);
holder = getHolder();
holder.addCallback(this);
paint = new Paint();
paint.setColor(Color.GREEN);
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
synchronized (holder) {
canvasWidth = width;
canvasHeight = height;
}
drawCanvas();
}
public void surfaceCreated(SurfaceHolder holder) {
synchronized (holder) {
cantTouchThis = false;
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
synchronized (holder) {
cantTouchThis = true;
}
}
void drawCanvas() {
synchronized (holder) {
if (cantTouchThis)
return;
Canvas canvas = null;
try {
canvas = holder.lockCanvas(null);
canvas.drawColor(Color.BLACK);
canvas.drawRect(0, canvasHeight - volume * canvasHeight, canvasWidth, canvasHeight, paint);
} finally {
if (canvas != null)
holder.unlockCanvasAndPost(canvas);
}
}
}
}

View file

@ -19,11 +19,27 @@
android:layout_weight="1"
android:contentDescription="@string/decoder_view" />
<xdsopl.robot36.SpectrumView
android:id="@+id/spectrum"
<LinearLayout
android:id="@+id/spectrum_meter"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="10"
android:contentDescription="@string/spectrum_view" />
android:weightSum="10">
<xdsopl.robot36.SpectrumView
android:id="@+id/spectrum"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:contentDescription="@string/spectrum_view" />
<xdsopl.robot36.VUMeterView
android:id="@+id/meter"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="9"
android:contentDescription="@string/meter_view" />
</LinearLayout>
</LinearLayout>

View file

@ -20,5 +20,6 @@
<string name="action_toggle_scaling">Toggle Scaling</string>
<string name="decoder_view">Decoder View</string>
<string name="spectrum_view">Spectrum View</string>
<string name="meter_view">VU Meter View</string>
</resources>

View file

@ -214,6 +214,7 @@ void decode(int samples) {
int amp = audio_buffer[sample];
float avg_rms = filter(&avg_amplitude, amp * amp);
float avg_amp = sqrt(2.0f * avg_rms);
*volume = clamp(avg_amp / 32.0f, 0.0f, 1023.0f);
if (avg_amp < 16.0f)
continue;
float norm_amp = amp / avg_amp;

View file

@ -25,5 +25,6 @@ uchar4 *saved_buffer;
int *saved_width;
int *saved_height;
int *current_mode;
int *volume;
#endif