mirror of
https://github.com/xdsopl/robot36.git
synced 2025-12-06 07:12:07 +01:00
do the processing in the base band
This commit is contained in:
parent
8beb5ccdc5
commit
b8441694a6
27
app/src/main/java/xdsopl/robot36/ComplexDelay.java
Normal file
27
app/src/main/java/xdsopl/robot36/ComplexDelay.java
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
Complex digital delay line
|
||||||
|
|
||||||
|
Copyright 2024 Ahmet Inan <xdsopl@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
package xdsopl.robot36;
|
||||||
|
|
||||||
|
public class ComplexDelay {
|
||||||
|
public final int length;
|
||||||
|
private final Delay real;
|
||||||
|
private final Delay imag;
|
||||||
|
private final Complex temp;
|
||||||
|
|
||||||
|
ComplexDelay(int length) {
|
||||||
|
this.length = length;
|
||||||
|
this.real = new Delay(length);
|
||||||
|
this.imag = new Delay(length);
|
||||||
|
this.temp = new Complex();
|
||||||
|
}
|
||||||
|
|
||||||
|
Complex push(Complex input) {
|
||||||
|
temp.real = real.push(input.real);
|
||||||
|
temp.imag = imag.push(input.imag);
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -37,11 +37,14 @@ public class MainActivity extends AppCompatActivity {
|
||||||
private float[] recordBuffer;
|
private float[] recordBuffer;
|
||||||
private AudioRecord audioRecord;
|
private AudioRecord audioRecord;
|
||||||
private TextView status;
|
private TextView status;
|
||||||
private Delay powerDelay;
|
private ComplexDelay powerDelay;
|
||||||
private SimpleMovingAverage powerAvg;
|
private SimpleMovingAverage powerAvg;
|
||||||
private ComplexMovingAverage syncAvg;
|
private ComplexMovingAverage syncAvg;
|
||||||
private Phasor osc_1200;
|
private ComplexMovingAverage baseBandLowPass;
|
||||||
private Complex sad;
|
private Phasor syncPulseOscillator;
|
||||||
|
private Phasor baseBandOscillator;
|
||||||
|
private Complex baseBand;
|
||||||
|
private Complex syncPulse;
|
||||||
private int tint;
|
private int tint;
|
||||||
private int curLine;
|
private int curLine;
|
||||||
|
|
||||||
|
|
@ -63,8 +66,9 @@ public class MainActivity extends AppCompatActivity {
|
||||||
|
|
||||||
private void processSamples() {
|
private void processSamples() {
|
||||||
for (float v : recordBuffer) {
|
for (float v : recordBuffer) {
|
||||||
sad = syncAvg.avg(sad.set(powerDelay.push(v)).mul(osc_1200.rotate()));
|
baseBand = baseBandLowPass.avg(baseBand.set(v).mul(baseBandOscillator.rotate()));
|
||||||
float level = sad.norm() / powerAvg.avg(v * v);
|
syncPulse = syncAvg.avg(powerDelay.push(baseBand).mul(syncPulseOscillator.rotate()));
|
||||||
|
float level = syncPulse.norm() / powerAvg.avg(baseBand.norm());
|
||||||
int x = Math.min((int) (scopeWidth * level), scopeWidth);
|
int x = Math.min((int) (scopeWidth * level), scopeWidth);
|
||||||
for (int i = 0; i < x; ++i)
|
for (int i = 0; i < x; ++i)
|
||||||
scopePixels[scopeWidth * curLine + i] = tint;
|
scopePixels[scopeWidth * curLine + i] = tint;
|
||||||
|
|
@ -82,12 +86,21 @@ public class MainActivity extends AppCompatActivity {
|
||||||
double powerWindowSeconds = 0.5;
|
double powerWindowSeconds = 0.5;
|
||||||
int powerWindowSamples = (int) Math.round(powerWindowSeconds * sampleRate) | 1;
|
int powerWindowSamples = (int) Math.round(powerWindowSeconds * sampleRate) | 1;
|
||||||
powerAvg = new SimpleMovingAverage(powerWindowSamples);
|
powerAvg = new SimpleMovingAverage(powerWindowSamples);
|
||||||
powerDelay = new Delay((powerWindowSamples - 1) / 2);
|
powerDelay = new ComplexDelay((powerWindowSamples - 1) / 2);
|
||||||
double syncPulseSeconds = 0.009;
|
double syncPulseSeconds = 0.009;
|
||||||
int syncPulseSamples = (int) Math.round(syncPulseSeconds * sampleRate);
|
int syncPulseSamples = (int) Math.round(syncPulseSeconds * sampleRate);
|
||||||
syncAvg = new ComplexMovingAverage(syncPulseSamples);
|
syncAvg = new ComplexMovingAverage(syncPulseSamples);
|
||||||
osc_1200 = new Phasor(-1200, sampleRate);
|
float lowestFrequency = 1100;
|
||||||
sad = new Complex();
|
float highestFrequency = 2300;
|
||||||
|
float cutoffFrequency = (highestFrequency - lowestFrequency) / 2;
|
||||||
|
int lowPassSamples = (int) Math.round(0.443 * sampleRate / cutoffFrequency) | 1;
|
||||||
|
baseBandLowPass = new ComplexMovingAverage(lowPassSamples);
|
||||||
|
float centerFrequency = (lowestFrequency + highestFrequency) / 2;
|
||||||
|
baseBandOscillator = new Phasor(-centerFrequency, sampleRate);
|
||||||
|
float syncPulseFrequency = 1200;
|
||||||
|
syncPulseOscillator = new Phasor(-(syncPulseFrequency - centerFrequency), sampleRate);
|
||||||
|
baseBand = new Complex();
|
||||||
|
syncPulse = new Complex();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initAudioRecord() {
|
private void initAudioRecord() {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue