mirror of
https://github.com/xdsopl/robot36.git
synced 2026-01-03 06:59:59 +01:00
added simple VU Meter
This commit is contained in:
parent
98a9ee7f1f
commit
ada2422531
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
78
app/src/main/java/xdsopl/robot36/VUMeterView.java
Normal file
78
app/src/main/java/xdsopl/robot36/VUMeterView.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -25,5 +25,6 @@ uchar4 *saved_buffer;
|
|||
int *saved_width;
|
||||
int *saved_height;
|
||||
int *current_mode;
|
||||
int *volume;
|
||||
|
||||
#endif
|
||||
Loading…
Reference in a new issue