1 #include "Common/Log.h"
2
3 #include "android/jni/AndroidAudio.h"
4 #include "android/jni/OpenSLContext.h"
5
6 std::string g_error;
7 std::mutex g_errorMutex;
8
AudioContext(AndroidAudioCallback cb,int _FramesPerBuffer,int _SampleRate)9 AudioContext::AudioContext(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleRate)
10 : audioCallback(cb), framesPerBuffer(_FramesPerBuffer), sampleRate(_SampleRate) {
11 if (framesPerBuffer == 0)
12 framesPerBuffer = 256;
13 if (framesPerBuffer < 32)
14 framesPerBuffer = 32;
15 if (framesPerBuffer > 4096)
16 framesPerBuffer = 4096;
17
18 sampleRate = _SampleRate;
19 g_error = "";
20 }
21
SetErrorString(const std::string & error)22 void AudioContext::SetErrorString(const std::string &error) {
23 std::unique_lock<std::mutex> lock(g_errorMutex);
24 g_error = error;
25 }
26
27 struct AndroidAudioState {
28 AudioContext *ctx = nullptr;
29 AndroidAudioCallback callback = nullptr;
30 // output
31 int frames_per_buffer = 0;
32 int sample_rate = 0;
33 // input
34 int input_enable = 0;
35 int input_sample_rate = 0;
36 };
37
AndroidAudio_Init(AndroidAudioCallback callback,int optimalFramesPerBuffer,int optimalSampleRate)38 AndroidAudioState *AndroidAudio_Init(AndroidAudioCallback callback, int optimalFramesPerBuffer, int optimalSampleRate) {
39 AndroidAudioState *state = new AndroidAudioState();
40 state->callback = callback;
41 state->frames_per_buffer = optimalFramesPerBuffer ? optimalFramesPerBuffer : 256;
42 state->sample_rate = optimalSampleRate ? optimalSampleRate : 44100;
43 return state;
44 }
45
AndroidAudio_Recording_SetSampleRate(AndroidAudioState * state,int sampleRate)46 bool AndroidAudio_Recording_SetSampleRate(AndroidAudioState *state, int sampleRate) {
47 if (!state) {
48 ERROR_LOG(AUDIO, "AndroidAudioState not initialized, cannot set recording sample rate");
49 return false;
50 }
51 state->input_sample_rate = sampleRate;
52 INFO_LOG(AUDIO, "AndroidAudio_Recording_SetSampleRate=%d", sampleRate);
53 return true;
54 }
55
AndroidAudio_Recording_Start(AndroidAudioState * state)56 bool AndroidAudio_Recording_Start(AndroidAudioState *state) {
57 if (!state) {
58 ERROR_LOG(AUDIO, "AndroidAudioState not initialized, cannot start recording!");
59 return false;
60 }
61 state->input_enable = 1;
62 if (!state->ctx) {
63 ERROR_LOG(AUDIO, "OpenSLContext not initialized, cannot start recording!");
64 return false;
65 }
66 state->ctx->AudioRecord_Start(state->input_sample_rate);
67 INFO_LOG(AUDIO, "AndroidAudio_Recording_Start");
68 return true;
69 }
70
AndroidAudio_Recording_Stop(AndroidAudioState * state)71 bool AndroidAudio_Recording_Stop(AndroidAudioState *state) {
72 if (!state) {
73 ERROR_LOG(AUDIO, "AndroidAudioState not initialized, cannot stop recording!");
74 return false;
75 }
76 if (!state->ctx) {
77 ERROR_LOG(AUDIO, "OpenSLContext not initialized, cannot stop recording!");
78 return false;
79 }
80 state->input_enable = 0;
81 state->input_sample_rate = 0;
82 state->ctx->AudioRecord_Stop();
83 INFO_LOG(AUDIO, "AndroidAudio_Recording_Stop");
84 return true;
85 }
86
AndroidAudio_Recording_State(AndroidAudioState * state)87 bool AndroidAudio_Recording_State(AndroidAudioState *state) {
88 if (!state) {
89 return false;
90 }
91 return state->input_enable;
92 }
93
AndroidAudio_Resume(AndroidAudioState * state)94 bool AndroidAudio_Resume(AndroidAudioState *state) {
95 if (!state) {
96 ERROR_LOG(AUDIO, "Audio was shutdown, cannot resume!");
97 return false;
98 }
99 if (!state->ctx) {
100 INFO_LOG(AUDIO, "Calling OpenSLWrap_Init_T...");
101 state->ctx = new OpenSLContext(state->callback, state->frames_per_buffer, state->sample_rate);
102 INFO_LOG(AUDIO, "Returned from OpenSLWrap_Init_T");
103 bool init_retval = state->ctx->Init();
104 if (!init_retval) {
105 delete state->ctx;
106 state->ctx = nullptr;
107 }
108 if (state->input_enable) {
109 state->ctx->AudioRecord_Start(state->input_sample_rate);
110 }
111 return init_retval;
112 }
113 return false;
114 }
115
AndroidAudio_Pause(AndroidAudioState * state)116 bool AndroidAudio_Pause(AndroidAudioState *state) {
117 if (!state) {
118 ERROR_LOG(AUDIO, "Audio was shutdown, cannot pause!");
119 return false;
120 }
121 if (state->ctx) {
122 INFO_LOG(AUDIO, "Calling OpenSLWrap_Shutdown_T...");
123 delete state->ctx;
124 state->ctx = nullptr;
125 INFO_LOG(AUDIO, "Returned from OpenSLWrap_Shutdown_T ...");
126 return true;
127 }
128 return false;
129 }
130
AndroidAudio_Shutdown(AndroidAudioState * state)131 bool AndroidAudio_Shutdown(AndroidAudioState *state) {
132 if (!state) {
133 ERROR_LOG(AUDIO, "Audio already shutdown!");
134 return false;
135 }
136 if (state->ctx) {
137 ERROR_LOG(AUDIO, "Should not shut down when playing! Something is wrong!");
138 return false;
139 }
140 delete state;
141 INFO_LOG(AUDIO, "OpenSLWrap completely unloaded.");
142 return true;
143 }
144
AndroidAudio_GetErrorString(AndroidAudioState * state)145 const std::string AndroidAudio_GetErrorString(AndroidAudioState *state) {
146 if (!state) {
147 return "No state";
148 }
149 std::unique_lock<std::mutex> lock(g_errorMutex);
150 return g_error;
151 }
152