diff --git a/app/src/main/java/xdsopl/robot36/MainActivity.java b/app/src/main/java/xdsopl/robot36/MainActivity.java index ac6698d..f8b88dc 100644 --- a/app/src/main/java/xdsopl/robot36/MainActivity.java +++ b/app/src/main/java/xdsopl/robot36/MainActivity.java @@ -37,6 +37,7 @@ public class MainActivity extends AppCompatActivity { private float[] recordBuffer; private AudioRecord audioRecord; private TextView status; + private SimpleMovingAverage powerAvg; private int tint; private int curLine; @@ -58,7 +59,7 @@ public class MainActivity extends AppCompatActivity { private void processSamples() { for (float v : recordBuffer) { - int x = Math.min((int) (scopeWidth * v * v), scopeWidth); + int x = Math.min((int) (scopeWidth * powerAvg.avg(v * v)), scopeWidth); for (int i = 0; i < x; ++i) scopePixels[scopeWidth * curLine + i] = tint; for (int i = x; i < scopeWidth; ++i) @@ -71,6 +72,11 @@ public class MainActivity extends AppCompatActivity { scopeView.invalidate(); } + private void initTools(int sampleRate) { + double powerWindowSeconds = 0.5; + powerAvg = new SimpleMovingAverage((int) Math.round(powerWindowSeconds * sampleRate)); + } + private void initAudioRecord() { int audioSource = MediaRecorder.AudioSource.UNPROCESSED; int channelConfig = AudioFormat.CHANNEL_IN_MONO; @@ -87,6 +93,7 @@ public class MainActivity extends AppCompatActivity { if (audioRecord.getState() == AudioRecord.STATE_INITIALIZED) { audioRecord.setRecordPositionUpdateListener(recordListener); audioRecord.setPositionNotificationPeriod(recordBuffer.length); + initTools(sampleRate); startListening(); } else { setStatus(R.string.audio_init_failed); diff --git a/app/src/main/java/xdsopl/robot36/SimpleMovingAverage.java b/app/src/main/java/xdsopl/robot36/SimpleMovingAverage.java new file mode 100644 index 0000000..9a24c87 --- /dev/null +++ b/app/src/main/java/xdsopl/robot36/SimpleMovingAverage.java @@ -0,0 +1,21 @@ +/* +Simple Moving Average + +Copyright 2024 Ahmet Inan +*/ + +package xdsopl.robot36; + +public class SimpleMovingAverage extends SimpleMovingSum { + public SimpleMovingAverage(int length) { + super(length); + } + + public float avg() { + return sum() / length; + } + + public float avg(float input) { + return sum(input) / length; + } +} diff --git a/app/src/main/java/xdsopl/robot36/SimpleMovingSum.java b/app/src/main/java/xdsopl/robot36/SimpleMovingSum.java new file mode 100644 index 0000000..437f8ec --- /dev/null +++ b/app/src/main/java/xdsopl/robot36/SimpleMovingSum.java @@ -0,0 +1,37 @@ +/* +Simple Moving Sum + +Copyright 2024 Ahmet Inan +*/ + +package xdsopl.robot36; + +public class SimpleMovingSum { + private final float[] tree; + private int leaf; + public final int length; + + public SimpleMovingSum(int length) { + this.length = length; + this.tree = new float[2 * length]; + this.leaf = length; + } + + public void add(float input) { + tree[leaf] = input; + for (int child = leaf, parent = leaf / 2; parent > 0; child = parent, parent /= 2) + tree[parent] = tree[child] + tree[child ^ 1]; + if (++leaf >= tree.length) + leaf = length; + } + + public float sum() { + return tree[1]; + } + + public float sum(float input) { + add(input); + return sum(); + } +} +