Skip to content

Commit

Permalink
Merge pull request #2 from Picovoice/demo-vu-meter
Browse files Browse the repository at this point in the history
Add VU meter to demo
  • Loading branch information
ErisMik committed Jul 17, 2023
2 parents b3d14b1 + 86a4282 commit 061b090
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.ToggleButton;
Expand All @@ -34,7 +33,17 @@
public class MainActivity extends AppCompatActivity {

private final VoiceProcessorFrameListener frameListener = frame -> {
Log.i("VoiceProcessor", String.format("Frame of size %d received!", frame.length));
double sum = 0.0;
for (short sample : frame) {
sum += Math.pow(sample, 2);
}
final double rms = Math.sqrt(sum / (double) frame.length) / (double) Short.MAX_VALUE;
final double dbfs = 20.0 * Math.log10(rms);

runOnUiThread(() -> {
final VuMeterView vuMeterView = findViewById(R.id.vuMeterView);
vuMeterView.setVolumeLevel(dbfs);
});
};
private final VoiceProcessorErrorListener errorListener = this::onAppError;
private VoiceProcessor vp;
Expand All @@ -57,7 +66,6 @@ private void requestRecordPermission() {
}

private void start() {

try {
vp.start(512, 16000);
} catch (VoiceProcessorArgumentException e) {
Expand All @@ -79,7 +87,7 @@ private void onAppError(Exception e) {
errorText.setText(e.getMessage());
errorText.setVisibility(View.VISIBLE);

ToggleButton recordButton = findViewById(R.id.record_button);
ToggleButton recordButton = findViewById(R.id.recordButton);
recordButton.setBackground(ContextCompat.getDrawable(
getApplicationContext(),
R.drawable.button_disabled));
Expand All @@ -102,7 +110,7 @@ public void onRequestPermissionsResult(
}

public void onRecordClick(View view) {
ToggleButton recordButton = findViewById(R.id.record_button);
ToggleButton recordButton = findViewById(R.id.recordButton);
if (recordButton.isChecked()) {
if (vp.hasRecordAudioPermission(this)) {
start();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package ai.picovoice.android.voiceprocessorexample;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;

import java.util.LinkedList;
import java.util.Queue;

public class VuMeterView extends View {

private static final int MAX_VOLUME = 100;
private static final int MIN_VOLUME = 0;
private static final double DBFS_OFFSET = 60.0;
private static final int VOLUME_SMOOTHING_SIZE = 5;

private final Queue<Double> volumeSmoothingQueue = new LinkedList<>();

private Paint backgroundPaint;
private Paint meterPaint;
private Rect meterRect;

public VuMeterView(Context context) {
super(context);
initialize();
}

public VuMeterView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize();
}

private void initialize() {
backgroundPaint = new Paint();
backgroundPaint.setColor(Color.GRAY);

meterPaint = new Paint();
meterPaint.setColor(Color.parseColor("#377dff"));

meterRect = new Rect();
}

public void setVolumeLevel(double dbfsValue) {
double adjustedVal = dbfsValue + DBFS_OFFSET;
adjustedVal = (Math.max(MIN_VOLUME, adjustedVal) / DBFS_OFFSET);
adjustedVal = Math.min(1.0, adjustedVal) * MAX_VOLUME;

if (volumeSmoothingQueue.size() >= VOLUME_SMOOTHING_SIZE) {
volumeSmoothingQueue.poll();
}
volumeSmoothingQueue.offer(adjustedVal);
invalidate();
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

int width = getWidth();
int height = getHeight();

canvas.drawRect(0, 0, width, height, backgroundPaint);

double smoothedValue = 0.0;
for (double val : volumeSmoothingQueue) {
smoothedValue += val;
}
smoothedValue = smoothedValue / volumeSmoothingQueue.size();

int meterWidth = (int) (width * smoothedValue / MAX_VOLUME);
meterRect.set(0, 0, meterWidth, height);
canvas.drawRect(meterRect, meterPaint);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,31 @@
android:layout_height="match_parent"
tools:context="ai.picovoice.android.voiceprocessorexample.MainActivity">

<ToggleButton
android:id="@+id/record_button"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_gravity="center"
android:background="@drawable/button_background"
android:onClick="onRecordClick"
android:textColor="@android:color/white"
android:textOff="@string/start"
android:textOn="@string/stop"
android:textSize="24sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical">

<ai.picovoice.android.voiceprocessorexample.VuMeterView
android:id="@+id/vuMeterView"
android:layout_width="match_parent"
android:layout_height="50sp"
android:layout_margin="20sp" />

<ToggleButton
android:id="@+id/recordButton"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_gravity="center"
android:background="@drawable/button_background"
android:onClick="onRecordClick"
android:textColor="@android:color/white"
android:textOff="@string/start"
android:textOn="@string/stop"
android:textSize="24sp"
android:textStyle="bold" />
</LinearLayout>

<TextView
android:id="@+id/errorMessage"
Expand Down
1 change: 1 addition & 0 deletions resources/.lint/spell-check/dict.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ convmv
coolterm
cortexm
cstring
dbfs
dkgray
dlfcn
dlopen
Expand Down

0 comments on commit 061b090

Please sign in to comment.