Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hrydgard
GitHub Repository: hrydgard/ppsspp
Path: blob/master/android/jni/AndroidAudio.cpp
3185 views
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
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
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
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
46
bool AndroidAudio_Recording_SetSampleRate(AndroidAudioState *state, int sampleRate) {
47
if (!state) {
48
ERROR_LOG(Log::Audio, "AndroidAudioState not initialized, cannot set recording sample rate");
49
return false;
50
}
51
state->input_sample_rate = sampleRate;
52
INFO_LOG(Log::Audio, "AndroidAudio_Recording_SetSampleRate=%d", sampleRate);
53
return true;
54
}
55
56
bool AndroidAudio_Recording_Start(AndroidAudioState *state) {
57
if (!state) {
58
ERROR_LOG(Log::Audio, "AndroidAudioState not initialized, cannot start recording!");
59
return false;
60
}
61
state->input_enable = 1;
62
if (!state->ctx) {
63
ERROR_LOG(Log::Audio, "OpenSLContext not initialized, cannot start recording!");
64
return false;
65
}
66
state->ctx->AudioRecord_Start(state->input_sample_rate);
67
INFO_LOG(Log::Audio, "AndroidAudio_Recording_Start");
68
return true;
69
}
70
71
bool AndroidAudio_Recording_Stop(AndroidAudioState *state) {
72
if (!state) {
73
ERROR_LOG(Log::Audio, "AndroidAudioState not initialized, cannot stop recording!");
74
return false;
75
}
76
if (!state->ctx) {
77
ERROR_LOG(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(Log::Audio, "AndroidAudio_Recording_Stop");
84
return true;
85
}
86
87
bool AndroidAudio_Recording_State(AndroidAudioState *state) {
88
if (!state) {
89
return false;
90
}
91
return state->input_enable;
92
}
93
94
bool AndroidAudio_Resume(AndroidAudioState *state) {
95
if (!state) {
96
ERROR_LOG(Log::Audio, "Audio was shutdown, cannot resume!");
97
return false;
98
}
99
if (!state->ctx) {
100
INFO_LOG(Log::Audio, "Calling OpenSLWrap_Init_T...");
101
state->ctx = new OpenSLContext(state->callback, state->frames_per_buffer, state->sample_rate);
102
INFO_LOG(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
} else if (state->input_enable) {
108
state->ctx->AudioRecord_Start(state->input_sample_rate);
109
}
110
return init_retval;
111
}
112
return false;
113
}
114
115
bool AndroidAudio_Pause(AndroidAudioState *state) {
116
if (!state) {
117
ERROR_LOG(Log::Audio, "Audio was shutdown, cannot pause!");
118
return false;
119
}
120
if (state->ctx) {
121
INFO_LOG(Log::Audio, "Calling OpenSLWrap_Shutdown_T...");
122
delete state->ctx;
123
state->ctx = nullptr;
124
INFO_LOG(Log::Audio, "Returned from OpenSLWrap_Shutdown_T ...");
125
return true;
126
}
127
return false;
128
}
129
130
bool AndroidAudio_Shutdown(AndroidAudioState *state) {
131
if (!state) {
132
ERROR_LOG(Log::Audio, "Audio already shutdown!");
133
return false;
134
}
135
if (state->ctx) {
136
ERROR_LOG(Log::Audio, "Should not shut down when playing! Something is wrong!");
137
return false;
138
}
139
delete state;
140
INFO_LOG(Log::Audio, "OpenSLWrap completely unloaded.");
141
return true;
142
}
143
144
const std::string AndroidAudio_GetErrorString(AndroidAudioState *state) {
145
if (!state) {
146
return "No state";
147
}
148
std::unique_lock<std::mutex> lock(g_errorMutex);
149
return g_error;
150
}
151
152