Skip to content

Commit c512384

Browse files
committed
Add audio buffer sample unit test
1 parent dc9abaf commit c512384

File tree

2 files changed

+123
-0
lines changed

2 files changed

+123
-0
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package com.codename1.media;
2+
3+
import com.codename1.capture.Capture;
4+
import com.codename1.io.File;
5+
import com.codename1.io.FileSystemStorage;
6+
import com.codename1.io.Util;
7+
import com.codename1.junit.FormTest;
8+
import com.codename1.junit.UITestBase;
9+
10+
import static org.junit.jupiter.api.Assertions.*;
11+
12+
class AudioBufferSampleTest extends UITestBase {
13+
14+
@FormTest
15+
void captureAudioRedirectsFramesToBufferAndPersistsWav() throws Exception {
16+
FileSystemStorage fs = FileSystemStorage.getInstance();
17+
implementation.clearFileSystem();
18+
implementation.clearAudioCaptureFrames();
19+
String recordingsDir = fs.getAppHomePath() + "recordings/";
20+
fs.mkdir(recordingsDir);
21+
22+
String bufferPath = "tmpBuffer.pcm";
23+
int wavSampleRate = 16000;
24+
AudioBuffer audioBuffer = MediaManager.getAudioBuffer(bufferPath, true, 8);
25+
final float[] captured = new float[audioBuffer.getMaxSize()];
26+
final int[] callbackCount = new int[1];
27+
final int[] lastSampleRate = new int[1];
28+
final int[] lastSize = new int[1];
29+
30+
WAVWriter writer = new WAVWriter(new File("tmpBuffer.wav"), wavSampleRate, 1, 16);
31+
try {
32+
audioBuffer.addCallback(new AudioBuffer.AudioBufferCallback() {
33+
public void frameReceived(AudioBuffer buffer) {
34+
if (buffer.getSampleRate() > wavSampleRate) {
35+
buffer.downSample(wavSampleRate);
36+
}
37+
buffer.copyTo(captured);
38+
lastSampleRate[0] = buffer.getSampleRate();
39+
lastSize[0] = buffer.getSize();
40+
callbackCount[0]++;
41+
try {
42+
writer.write(captured, 0, buffer.getSize());
43+
} catch (Exception e) {
44+
throw new RuntimeException(e);
45+
}
46+
}
47+
});
48+
49+
MediaRecorderBuilder options = new MediaRecorderBuilder()
50+
.audioChannels(1)
51+
.redirectToAudioBuffer(true)
52+
.path(bufferPath);
53+
54+
implementation.addAudioCaptureFrame(32000, 1, new float[]{1f, 0.5f, -0.5f, -1f});
55+
56+
Capture.captureAudio(options);
57+
58+
writer.close();
59+
60+
String copyPath = recordingsDir + "sample.wav";
61+
Util.copy(fs.openInputStream(new File("tmpBuffer.wav").getAbsolutePath()), fs.openOutputStream(copyPath));
62+
63+
assertEquals(1, callbackCount[0]);
64+
assertEquals(wavSampleRate, lastSampleRate[0]);
65+
assertTrue(lastSize[0] > 0);
66+
assertSame(options, implementation.getLastMediaRecorderBuilder());
67+
assertTrue(fs.exists(copyPath));
68+
assertTrue(fs.getFileLength(copyPath) > 44);
69+
} finally {
70+
MediaManager.releaseAudioBuffer(bufferPath);
71+
try {
72+
writer.close();
73+
} catch (Exception ignored) {
74+
}
75+
implementation.clearFileSystem();
76+
}
77+
}
78+
}
79+

maven/core-unittests/src/test/java/com/codename1/testing/TestCodenameOneImplementation.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
import com.codename1.payment.Purchase;
1414
import com.codename1.l10n.L10NManager;
1515
import com.codename1.location.LocationManager;
16+
import com.codename1.media.AudioBuffer;
1617
import com.codename1.media.Media;
18+
import com.codename1.media.MediaManager;
1719
import com.codename1.media.MediaRecorderBuilder;
1820
import com.codename1.messaging.Message;
1921
import com.codename1.notifications.LocalNotification;
@@ -174,6 +176,7 @@ public class TestCodenameOneImplementation extends CodenameOneImplementation {
174176
private String nextCaptureAudioPath = "file://test-audio.wav";
175177
private MediaRecorderBuilder lastMediaRecorderBuilder;
176178
private VideoCaptureConstraints lastVideoConstraints;
179+
private final List<AudioCaptureFrame> audioCaptureFrames = new ArrayList<AudioCaptureFrame>();
177180

178181

179182
public TestCodenameOneImplementation() {
@@ -3408,6 +3411,15 @@ public void captureAudio(MediaRecorderBuilder recordingOptions, ActionListener r
34083411
recordingOptions = new MediaRecorderBuilder();
34093412
}
34103413
lastMediaRecorderBuilder = recordingOptions;
3414+
if (recordingOptions.isRedirectToAudioBuffer()) {
3415+
AudioBuffer buffer = MediaManager.getAudioBuffer(recordingOptions.getPath());
3416+
if (buffer != null) {
3417+
for (AudioCaptureFrame frame : audioCaptureFrames) {
3418+
buffer.copyFrom(frame.getSampleRate(), frame.getNumChannels(), frame.getSamples());
3419+
}
3420+
}
3421+
audioCaptureFrames.clear();
3422+
}
34113423
response.actionPerformed(new ActionEvent(nextCaptureAudioPath));
34123424
}
34133425

@@ -3438,10 +3450,42 @@ public MediaRecorderBuilder getLastMediaRecorderBuilder() {
34383450
return lastMediaRecorderBuilder;
34393451
}
34403452

3453+
public void addAudioCaptureFrame(int sampleRate, int numChannels, float[] samples) {
3454+
audioCaptureFrames.add(new AudioCaptureFrame(sampleRate, numChannels, samples));
3455+
}
3456+
3457+
public void clearAudioCaptureFrames() {
3458+
audioCaptureFrames.clear();
3459+
}
3460+
34413461
public VideoCaptureConstraints getLastVideoConstraints() {
34423462
return lastVideoConstraints;
34433463
}
34443464

3465+
private static final class AudioCaptureFrame {
3466+
private final int sampleRate;
3467+
private final int numChannels;
3468+
private final float[] samples;
3469+
3470+
private AudioCaptureFrame(int sampleRate, int numChannels, float[] samples) {
3471+
this.sampleRate = sampleRate;
3472+
this.numChannels = numChannels;
3473+
this.samples = Arrays.copyOf(samples, samples.length);
3474+
}
3475+
3476+
private int getSampleRate() {
3477+
return sampleRate;
3478+
}
3479+
3480+
private int getNumChannels() {
3481+
return numChannels;
3482+
}
3483+
3484+
private float[] getSamples() {
3485+
return Arrays.copyOf(samples, samples.length);
3486+
}
3487+
}
3488+
34453489
public static final class TestFile {
34463490
final boolean directory;
34473491
final byte[] content;

0 commit comments

Comments
 (0)