-
Notifications
You must be signed in to change notification settings - Fork 818
/
Copy pathAudioJack.java
122 lines (107 loc) · 4.32 KB
/
AudioJack.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package io.pslab.others;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.util.Log;
import java.util.Random;
/**
* Created by viveksb007 on 11/7/17.
*/
public class AudioJack {
/* TODO : Output value in buffer would be between -2^16 and 2^16, need to map it too or show its FFT */
private static final String TAG = "AudioJack";
public static final int SAMPLING_RATE = 44100;
private static final int RECORDING_CHANNEL = AudioFormat.CHANNEL_IN_MONO;
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
private AudioRecord audioRecord = null;
private AudioTrack audioTrack = null;
private int minRecorderBufferSize;
private int minTrackBufferSize;
private String io;
private Random random;
public boolean configurationStatus;
/*
* Context to obtain AudioManager Instance and string io to classify if requested input or output.
* */
public AudioJack(String io) {
this.io = io;
random = new Random();
configurationStatus = configure();
}
private boolean configure() {
if ("input".equals(io)) {
/* Initialize audioRecord */
minRecorderBufferSize = AudioRecord.getMinBufferSize(SAMPLING_RATE, RECORDING_CHANNEL, RECORDER_AUDIO_ENCODING);
if (minRecorderBufferSize == AudioRecord.ERROR || minRecorderBufferSize == AudioRecord.ERROR_BAD_VALUE) {
minRecorderBufferSize = SAMPLING_RATE * 2;
}
audioRecord = new AudioRecord(
MediaRecorder.AudioSource.MIC,
SAMPLING_RATE,
RECORDING_CHANNEL,
RECORDER_AUDIO_ENCODING,
minRecorderBufferSize);
if (audioRecord.getState() != AudioRecord.STATE_INITIALIZED) {
Log.e(TAG, "Audio Record can't be initialized");
return false;
}
audioRecord.startRecording();
} else {
/* Initialize audioTrack */
minTrackBufferSize = AudioTrack.getMinBufferSize(SAMPLING_RATE, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
if (minTrackBufferSize == AudioTrack.ERROR || minTrackBufferSize == AudioTrack.ERROR_BAD_VALUE) {
minTrackBufferSize = SAMPLING_RATE * 2;
}
// Using STREAM_MUSIC. So to change amplitude stream music needs to be changed
audioTrack = new AudioTrack(
AudioManager.STREAM_MUSIC,
SAMPLING_RATE,
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT,
minTrackBufferSize,
AudioTrack.MODE_STREAM);
if (audioTrack.getState() != AudioTrack.STATE_INITIALIZED) {
Log.e(TAG, "AudioTrack can't be initialized");
return false;
}
audioTrack.play();
}
return true;
}
public short[] read() {
/* return captured audio buffer */
short[] audioBuffer = new short[minRecorderBufferSize / 2];
audioRecord.read(audioBuffer, 0, audioBuffer.length);
return audioBuffer;
}
public void write(short[] buffer) {
/* write buffer to audioTrack */
audioTrack.write(buffer, 0, buffer.length);
}
/*
* Would generate a buffer based on frequency value which would be played by AudioTrack to generate wave
* */
public short[] createBuffer(int frequency) {
// generating a random buffer for now
short[] buffer = new short[minTrackBufferSize];
for (int i = 0; i < minTrackBufferSize; i++) {
buffer[i] = (short) (random.nextInt(32767) + (-32768));
}
return buffer;
}
public void release() {
Log.v(TAG, "AudioJack object released");
if (audioRecord != null) {
if (audioRecord.getState() == AudioRecord.RECORDSTATE_RECORDING)
audioRecord.stop();
audioRecord.release();
}
if (audioTrack != null) {
if (audioTrack.getState() == AudioTrack.PLAYSTATE_PLAYING)
audioTrack.stop();
audioTrack.release();
}
}
}