mirror of
https://github.com/xdsopl/robot36.git
synced 2025-12-06 07:12:07 +01:00
show frequency plot
This commit is contained in:
parent
1733dd9aad
commit
774bcf9f18
|
|
@ -32,6 +32,7 @@ import androidx.core.view.ViewCompat;
|
||||||
import androidx.core.view.WindowInsetsCompat;
|
import androidx.core.view.WindowInsetsCompat;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity {
|
public class MainActivity extends AppCompatActivity {
|
||||||
|
|
@ -39,6 +40,9 @@ public class MainActivity extends AppCompatActivity {
|
||||||
private Bitmap scopeBitmap;
|
private Bitmap scopeBitmap;
|
||||||
private PixelBuffer scopeBuffer;
|
private PixelBuffer scopeBuffer;
|
||||||
private ImageView scopeView;
|
private ImageView scopeView;
|
||||||
|
private Bitmap freqPlotBitmap;
|
||||||
|
private PixelBuffer freqPlotBuffer;
|
||||||
|
private ImageView freqPlotView;
|
||||||
private float[] recordBuffer;
|
private float[] recordBuffer;
|
||||||
private AudioRecord audioRecord;
|
private AudioRecord audioRecord;
|
||||||
private Decoder decoder;
|
private Decoder decoder;
|
||||||
|
|
@ -65,16 +69,39 @@ public class MainActivity extends AppCompatActivity {
|
||||||
public void onPeriodicNotification(AudioRecord audioRecord) {
|
public void onPeriodicNotification(AudioRecord audioRecord) {
|
||||||
audioRecord.read(recordBuffer, 0, recordBuffer.length, AudioRecord.READ_BLOCKING);
|
audioRecord.read(recordBuffer, 0, recordBuffer.length, AudioRecord.READ_BLOCKING);
|
||||||
if (decoder.process(recordBuffer, recordChannel)) {
|
if (decoder.process(recordBuffer, recordChannel)) {
|
||||||
|
processScope();
|
||||||
|
processFreqPlot();
|
||||||
|
setStatus(decoder.lastMode.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private void processFreqPlot() {
|
||||||
|
int width = freqPlotBitmap.getWidth();
|
||||||
|
int height = freqPlotBitmap.getHeight();
|
||||||
|
int stride = freqPlotBuffer.width;
|
||||||
|
int line = stride * freqPlotBuffer.line;
|
||||||
|
int channels = recordChannel > 0 ? 2 : 1;
|
||||||
|
Arrays.fill(freqPlotBuffer.pixels, line, line + stride, 0);
|
||||||
|
for (int i = 0; i < recordBuffer.length / channels; ++i) {
|
||||||
|
int x = Math.min(Math.max(Math.round((recordBuffer[i] + 3) * stride / 6), 0), stride - 1);
|
||||||
|
freqPlotBuffer.pixels[line + x] = tint;
|
||||||
|
}
|
||||||
|
System.arraycopy(freqPlotBuffer.pixels, line, freqPlotBuffer.pixels, line + stride * (freqPlotBuffer.height / 2), stride);
|
||||||
|
freqPlotBuffer.line = (freqPlotBuffer.line + 1) % (freqPlotBuffer.height / 2);
|
||||||
|
int offset = stride * (freqPlotBuffer.line + freqPlotBuffer.height / 2 - height);
|
||||||
|
freqPlotBitmap.setPixels(freqPlotBuffer.pixels, offset, stride, 0, 0, width, height);
|
||||||
|
freqPlotView.invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processScope() {
|
||||||
int width = scopeBitmap.getWidth();
|
int width = scopeBitmap.getWidth();
|
||||||
int height = scopeBitmap.getHeight();
|
int height = scopeBitmap.getHeight();
|
||||||
int stride = scopeBuffer.width;
|
int stride = scopeBuffer.width;
|
||||||
int offset = stride * (scopeBuffer.line + scopeBuffer.height / 2 - height);
|
int offset = stride * (scopeBuffer.line + scopeBuffer.height / 2 - height);
|
||||||
scopeBitmap.setPixels(scopeBuffer.pixels, offset, stride, 0, 0, width, height);
|
scopeBitmap.setPixels(scopeBuffer.pixels, offset, stride, 0, 0, width, height);
|
||||||
scopeView.invalidate();
|
scopeView.invalidate();
|
||||||
setStatus(decoder.lastMode.getName());
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private void initAudioRecord() {
|
private void initAudioRecord() {
|
||||||
boolean rateChanged = true;
|
boolean rateChanged = true;
|
||||||
|
|
@ -280,6 +307,10 @@ public class MainActivity extends AppCompatActivity {
|
||||||
scopeView = findViewById(R.id.scope);
|
scopeView = findViewById(R.id.scope);
|
||||||
scopeBuffer = new PixelBuffer(640, 2 * 1280);
|
scopeBuffer = new PixelBuffer(640, 2 * 1280);
|
||||||
createScope(getResources().getConfiguration());
|
createScope(getResources().getConfiguration());
|
||||||
|
freqPlotView = findViewById(R.id.freq_plot);
|
||||||
|
freqPlotBuffer = new PixelBuffer(640, 2 * 640);
|
||||||
|
freqPlotBitmap = Bitmap.createBitmap(freqPlotBuffer.width, freqPlotBuffer.height / 2, Bitmap.Config.ARGB_8888);
|
||||||
|
freqPlotView.setImageBitmap(freqPlotBitmap);
|
||||||
List<String> permissions = new ArrayList<>();
|
List<String> permissions = new ArrayList<>();
|
||||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
|
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
|
||||||
permissions.add(Manifest.permission.RECORD_AUDIO);
|
permissions.add(Manifest.permission.RECORD_AUDIO);
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,9 @@
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/main"
|
android:id="@+id/main"
|
||||||
android:keepScreenOn="true"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:keepScreenOn="true"
|
||||||
tools:context=".MainActivity">
|
tools:context=".MainActivity">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
|
|
@ -14,9 +14,17 @@
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:contentDescription="@string/scope_description"
|
android:contentDescription="@string/scope_description"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toStartOf="@+id/freq_plot"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/freq_plot"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:contentDescription="@string/freq_plot_description"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/scope"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
@ -24,7 +24,8 @@
|
||||||
<string name="audio_setup_failed">Audio setup failed</string>
|
<string name="audio_setup_failed">Audio setup failed</string>
|
||||||
<string name="audio_permission_denied">Audio permission denied</string>
|
<string name="audio_permission_denied">Audio permission denied</string>
|
||||||
<string name="audio_recording_error">Audio recording error</string>
|
<string name="audio_recording_error">Audio recording error</string>
|
||||||
<string name="scope_description">Visualization of audio signal</string>
|
<string name="scope_description">Decoded SSTV picture</string>
|
||||||
|
<string name="freq_plot_description">Frequency plot</string>
|
||||||
<string name="night_mode">Night Mode</string>
|
<string name="night_mode">Night Mode</string>
|
||||||
<string name="enable">Enable</string>
|
<string name="enable">Enable</string>
|
||||||
<string name="disable">Disable</string>
|
<string name="disable">Disable</string>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue