12 #define MINIAUDIO_IMPLEMENTATION
13 #include "miniaudio.h"
15 #define MA_BUFFER_COUNT 20
16 #define MA_START_COUNT MA_BUFFER_COUNT-2
38 bool is_input =
false;
39 bool is_output =
true;
61 info.is_output =
false;
64 info.is_input =
false;
65 info.is_output =
true;
69 info.is_output =
true;
72 info.is_input =
false;
73 info.is_output =
false;
97 bool begin()
override {
99 MiniAudioConfig info = config;
100 if (info.is_output && !info.is_input)
101 config_ma = ma_device_config_init(ma_device_type_playback);
102 else if (!info.is_output && info.is_input)
103 config_ma = ma_device_config_init(ma_device_type_capture);
104 else if (info.is_output && info.is_input)
105 config_ma = ma_device_config_init(ma_device_type_duplex);
106 else if (!info.is_output && !info.is_input)
107 config_ma = ma_device_config_init(ma_device_type_loopback);
110 config_ma.playback.channels = info.channels;
111 config_ma.sampleRate = info.sample_rate;
112 config_ma.dataCallback = data_callback;
113 switch (info.bits_per_sample) {
115 config_ma.playback.format = ma_format_s16;
118 config_ma.playback.format = ma_format_s24;
121 config_ma.playback.format = ma_format_s32;
124 LOGE(
"Invalid format");
127 config_ma.pUserData =
this;
129 if (ma_device_init(NULL, &config_ma, &device_ma) != MA_SUCCESS) {
135 ma_device_start(&device_ma);
141 void end()
override {
145 ma_device_uninit(&device_ma);
147 delete (p_buffer_in);
148 p_buffer_in =
nullptr;
149 delete (p_buffer_out);
150 p_buffer_out =
nullptr;
153 int availableForWrite()
override {
return p_buffer_out==
nullptr? 0 : p_buffer_out->
availableForWrite(); }
155 size_t write(
const uint8_t *data,
size_t len)
override {
156 if (p_buffer_out==
nullptr)
return 0;
157 LOGD(
"write: %zu", len);
159 size_t result = p_buffer_out->
writeArray(data, len);
160 if (!is_playing && p_buffer_out->bufferCountFilled()>=MA_START_COUNT) {
167 int available()
override {
return p_buffer_in==
nullptr ? 0 : p_buffer_in->
available(); }
169 size_t readBytes(uint8_t *data,
size_t len)
override {
170 if (p_buffer_in==
nullptr)
return 0;
171 LOGD(
"write: %zu", len);
173 return p_buffer_in->
readArray(data, len);
177 MiniAudioConfig config;
178 ma_device_config config_ma;
180 bool is_playing =
false;
181 bool is_active =
false;
182 bool is_buffers_setup =
false;
183 NBuffer<uint8_t> *p_buffer_out =
nullptr;
184 NBuffer<uint8_t> *p_buffer_in =
nullptr;
192 void setupBuffers(
int size) {
193 if (is_buffers_setup)
return;
194 if (p_buffer_out ==
nullptr && config.is_output)
195 p_buffer_out =
new NBuffer<uint8_t>(size, MA_BUFFER_COUNT);
196 if (p_buffer_in==
nullptr && config.is_input)
197 p_buffer_in =
new NBuffer<uint8_t>(size, MA_BUFFER_COUNT);
198 is_buffers_setup =
true;
201 static void data_callback(ma_device *pDevice,
void *pOutput,
202 const void *pInput, ma_uint32 frameCount) {
203 MiniAudioStream *
self = (MiniAudioStream *)pDevice->pUserData;
204 AudioInfo cfg = self->audioInfo();
206 int bytes = frameCount * cfg.channels * cfg.bits_per_sample / 8;
207 self->setupBuffers(bytes);
211 self->p_buffer_in->writeArray((uint8_t *)pInput, bytes);
215 memset(pOutput, 0, bytes);
216 if (self->is_playing ) {
218 self->p_buffer_out->readArray((uint8_t *)pOutput, bytes);
219 std::this_thread::yield();
RxTxMode
The Microcontroller is the Audio Source (TX_MODE) or Audio Sink (RX_MODE). RXTX_MODE is Source and Si...
Definition: AudioTypes.h:26