2 #include "AudioConfig.h"
3 #include "AudioTools/CoreAudio/AudioTimer/AudioTimer.h"
4 #include "AudioTools/CoreAudio/AudioTypes.h"
5 #include "AudioTools/CoreAudio/Buffers.h"
6 #include "AudioTools/CoreAudio/AudioLogger.h"
7 #include "AudioTools/CoreAudio/BaseConverter.h"
8 #include "AudioTools/CoreAudio/AudioEffects/SoundGenerator.h"
9 #include "AudioTools/CoreAudio/BaseStream.h"
10 #include "AudioTools/CoreAudio/AudioOutput.h"
29 p_stream->setTimeout(clientTimeout);
32 virtual bool begin(){
return true;}
35 virtual size_t readBytes(uint8_t *data,
size_t len) {
38 return p_stream->readBytes(data, len);
41 int read() {
return p_stream->read(); }
43 int peek() {
return p_stream->peek(); }
45 int available() {
return p_stream->available(); }
47 virtual size_t write(uint8_t c) {
return p_stream->write(c); }
49 virtual size_t write(
const uint8_t *data,
size_t len) {
50 return p_stream->write(data, len);
53 virtual int availableForWrite() {
return p_stream->availableForWrite(); }
55 virtual void flush() { p_stream->flush(); }
59 int32_t clientTimeout = URL_CLIENT_TIMEOUT;
88 LOGD(
"MemoryStream: %d", buffer_size);
89 this->buffer_size = buffer_size;
90 this->memory_type = memoryType;
97 LOGD(
"MemoryStream: %d", buffer_size);
98 setValue(buffer, buffer_size, memoryType);
110 setValue(source.buffer, source.buffer_size, source.memory_type);
112 source.setValue(
nullptr, 0, source.memory_type);
117 if (memoryCanChange() && buffer!=
nullptr) free(buffer);
127 operator bool()
override {
return available() > 0; }
138 write_pos = memoryCanChange() ? 0 : buffer_size;
139 if (this->buffer==
nullptr && memoryCanChange()){
147 virtual size_t write(uint8_t
byte)
override {
148 if (!is_active)
return 0;
149 if (memory_type == FLASH_RAM)
return 0;
150 if (buffer==
nullptr)
return 0;
152 if (write_pos < buffer_size) {
154 buffer[write_pos] = byte;
160 virtual size_t write(
const uint8_t *data,
size_t len)
override {
161 if (!is_active)
return 0;
162 if (memory_type == FLASH_RAM)
return 0;
164 for (
size_t j = 0; j < len; j++) {
165 if (!write(data[j])) {
173 virtual int available()
override {
174 if (!is_active)
return 0;
175 if (buffer==
nullptr)
return 0;
176 int result = write_pos - read_pos;
177 if (result<=0 && is_loop){
179 read_pos = rewind_pos;
180 result = write_pos - read_pos;
182 if (rewind!=
nullptr) rewind();
184 return is_loop ? DEFAULT_BUFFER_SIZE : result;
187 virtual int availableForWrite()
override {
188 if (!is_active)
return 0;
189 if (memory_type == FLASH_RAM)
return 0;
190 return buffer_size - write_pos;
193 virtual int read()
override {
201 virtual size_t readBytes(uint8_t *data,
size_t len)
override {
202 if (!is_active)
return 0;
204 while (count < len) {
213 virtual int peek()
override {
214 if (!is_active)
return -1;
216 if (available() > 0) {
217 result = buffer[read_pos];
222 virtual void flush()
override {}
224 virtual void end()
override {
230 virtual void clear(
bool reset =
false) {
231 if (memoryCanChange()){
234 if (buffer==
nullptr){
239 memset(buffer, 0, buffer_size);
243 LOGW(
"data is read only");
251 if (buffer!=
nullptr && buffer_size > 12){
252 if (memcmp(
"WAVE", buffer+8, 4)==0){
259 virtual void setLoop(
bool loop,
int rewindPos){
261 rewind_pos = rewindPos;
266 if (!memoryCanChange())
return false;
270 #if defined(ESP32) && defined(ARDUINO)
272 buffer = (buffer==
nullptr) ? (uint8_t*)ps_calloc(size,1) : (uint8_t*)ps_realloc(buffer, size);
276 buffer = (buffer==
nullptr) ? (uint8_t*)calloc(size,1) : (uint8_t*)realloc(buffer, size);
279 return buffer !=
nullptr;
282 virtual uint8_t* data(){
293 this->buffer_size = buffer_size;
295 this->write_pos = buffer_size;
296 this->buffer = (uint8_t *)buffer;
297 this->memory_type = memoryType;
305 uint8_t *buffer =
nullptr;
307 bool is_loop =
false;
308 void (*rewind)() =
nullptr;
309 bool is_active =
false;
311 bool memoryCanChange() {
312 return memory_type!=FLASH_RAM;
316 if (
this == &source)
return;
317 if (source.memory_type == FLASH_RAM){
318 setValue(source.buffer, source.buffer_size, source.memory_type);
320 setValue(
nullptr, source.buffer_size, source.memory_type);
322 memcpy(buffer, source.buffer, buffer_size);
338 virtual int available()
override {
340 return buffer.available();
343 virtual int availableForWrite()
override {
344 return buffer.availableForWrite();
347 virtual void flush()
override {}
348 virtual int peek()
override {
return buffer.peek(); }
349 virtual int read()
override {
return buffer.read(); }
351 virtual size_t readBytes(uint8_t *data,
size_t len)
override {
352 return buffer.readArray(data, len);
355 virtual size_t write(
const uint8_t *data,
size_t len)
override {
357 return buffer.writeArray(data, len);
360 virtual size_t write(uint8_t c)
override {
return buffer.write(c); }
362 void resize(
int size) { buffer.resize(size); }
364 size_t size() {
return buffer.size(); }
392 this->generator_ptr = &generator;
395 AudioInfo defaultConfig() {
return this->generator_ptr->defaultConfig(); }
407 if (generator_ptr==
nullptr){
408 LOGE(
"%s",source_not_defined_error);
411 generator_ptr->begin();
412 notifyAudioChange(generator_ptr->audioInfo());
420 if (generator_ptr==
nullptr){
421 LOGE(
"%s",source_not_defined_error);
424 generator_ptr->begin(cfg);
425 notifyAudioChange(generator_ptr->audioInfo());
433 generator_ptr->end();
438 return generator_ptr->audioInfo();
442 virtual int available()
override {
return active ? DEFAULT_BUFFER_SIZE*2 : 0; }
446 if (!active)
return 0;
447 LOGD(
"GeneratedSoundStream::readBytes: %u", (
unsigned int)len);
448 return generator_ptr->readBytes(data, len);
451 bool isActive() {
return active && generator_ptr->isActive();}
453 operator bool() {
return isActive(); }
455 void flush()
override {}
459 SoundGenerator<T> *generator_ptr;
460 const char* source_not_defined_error =
"Source not defined";
476 buffer.resize(buffer_size);
482 buffer.resize(buffer_size);
488 buffer.resize(buffer_size);
494 void setStream(
Print &out){
504 if (buffer.isFull()) {
507 return buffer.write(c);
511 size_t write(
const uint8_t *data,
size_t len)
override {
512 LOGD(
"%s: %zu", LOG_METHOD, len);
514 for (
int j=0;j<len;j++){
515 result +=
write(data[j]);
523 if (buffer.available() > 0) {
524 writeExt(buffer.address(), buffer.available());
531 if (buffer.isEmpty()) {
534 return buffer.read();
539 if (buffer.isEmpty()) {
542 return buffer.peek();
547 if (buffer.isEmpty()) {
548 return readExt(data, len);
551 return buffer.readArray(data, len);
557 if (buffer.isEmpty()) {
560 return buffer.available();
568 Print* p_out =
nullptr;
573 size_t result = readExt(buffer.
address(), buffer.size());
577 virtual size_t writeExt(
const uint8_t *data,
size_t len) {
578 return p_out ==
nullptr ? 0 : p_out->write(data, len);
580 virtual size_t readExt(uint8_t *data,
size_t len) {
581 return p_in ==
nullptr ? 0 : p_in->readBytes(data, len);
601 setConverter(converter);
605 setConverter(converter);
610 setConverter(converter);
629 virtual int availableForWrite() {
return p_out->availableForWrite(); }
631 virtual size_t write(
const uint8_t *data,
size_t len) {
632 size_t result = p_converter->convert((uint8_t *)data, len);
634 size_t result_written = p_out->write(data, result);
635 return len * result_written / result;
640 size_t readBytes(uint8_t *data,
size_t len)
override {
641 if (p_stream==
nullptr)
return 0;
642 size_t result = p_stream->readBytes(data, len);
643 return p_converter->convert(data, result);
648 if (p_stream==
nullptr)
return 0;
649 return p_stream->available();
653 Stream *p_stream =
nullptr;
654 Print *p_out =
nullptr;
669 this->max_count = count;
678 this->max_count = count;
686 this->max_count = count;
706 return measure(p_stream->readBytes(data, len));
709 int available()
override {
710 return p_stream->available();
714 virtual size_t write(
const uint8_t *data,
size_t len)
override {
715 return measure(p_print->write(data, len));
720 return p_print->availableForWrite();
725 return bytes_per_second;
734 AudioStream::info = info;
739 return AudioStream::begin();
742 bool begin(AudioInfo info){
747 void setFrameSize(
int size){
760 Print *p_print=
nullptr;
763 int bytes_per_second = 0;
766 Print *p_logout=
nullptr;
767 bool report_bytes =
false;
769 size_t measure(
size_t len) {
774 uint32_t end_time =
millis();
775 int time_diff = end_time - start_time;
777 bytes_per_second = total_bytes / time_diff * 1000;
781 start_time = end_time;
789 if (report_bytes || frame_size==0){
790 snprintf(msg, 70,
"==> Bytes per second: %d", bytes_per_second);
792 snprintf(msg, 70,
"==> Samples per second: %d", bytes_per_second/frame_size);
794 if (p_logout!=
nullptr){
795 p_logout->println(msg);
810 size_t total_size = 0;
833 p_info_from = &stream;
837 return progress_info;
854 void setPrint(Print &print){
858 bool begin()
override {
859 if (p_info_from!=
nullptr){
862 return AudioStream::begin();
872 progress_info = info;
880 progress_info.total_size = len;
885 return progress_info.total_size;
890 return total_processed;
895 return total_processed / byteRate();
900 return progress_info.total_size;
910 if (progress_info.total_size==0)
return 0;
911 return 100.0 * total_processed / progress_info.total_size;
916 if (p_stream==
nullptr)
return 0;
917 return measure(p_stream->readBytes(data, len));
920 int available()
override {
921 if (p_stream==
nullptr)
return 0;
922 return p_stream->available();
926 virtual size_t write(
const uint8_t *data,
size_t len)
override {
927 if (p_print==
nullptr)
return 0;
928 return measure(p_print->write(data, len));
933 if (p_print==
nullptr)
return 0;
934 return p_print->availableForWrite();
940 Print *p_print=
nullptr;
942 size_t total_processed = 0;
944 size_t measure(
size_t len) {
945 total_processed += len;
951 int byte_rate = info.sample_rate * info.bits_per_sample * info.channels / 8;
953 LOGE(
"Audio Info not defined");
972 int correction_us = 0;
1003 bool begin(ThrottleConfig cfg) {
1010 bool begin(AudioInfo info) {
1011 LOGI(
"begin sample_rate: %d, channels: %d, bits: %d", (
int)info.sample_rate, (
int) info.channels, (
int)info.bits_per_sample);
1013 this->cfg.copyFrom(info);
1018 frame_size = cfg.bits_per_sample / 8 * cfg.channels;
1025 start_time = micros();
1029 int availableForWrite() {
1031 return p_out->availableForWrite();
1033 return DEFAULT_BUFFER_SIZE;
1036 size_t write(
const uint8_t* data,
size_t len){
1037 size_t result = p_out->write(data, len);
1043 if (p_in==
nullptr)
return 0;
1044 return p_in->available();
1047 size_t readBytes(uint8_t* data,
size_t len)
override{
1048 if (p_in==
nullptr) {
1052 size_t result = p_in->readBytes(data, len);
1058 void delayBytes(
size_t bytes) { delayFrames(bytes / frame_size); }
1061 void delayFrames(
size_t frames) {
1062 sum_frames += frames;
1063 uint64_t durationUsEff = micros() - start_time;
1064 uint64_t durationUsToBe = getDelayUs(sum_frames);
1065 int64_t waitUs = durationUsToBe - durationUsEff + cfg.correction_us;
1066 LOGD(
"wait us: %ld",
static_cast<long>(waitUs));
1068 int64_t waitMs = waitUs / 1000;
1069 if (waitMs > 0) delay(waitMs);
1070 delayMicroseconds(waitUs - (waitMs * 1000));
1072 LOGD(
"negative delay!")
1076 inline int64_t getDelayUs(uint64_t frames){
1077 return (frames * 1000000) / cfg.sample_rate;
1080 inline int64_t getDelayMs(uint64_t frames){
1081 return getDelayUs(frames) / 1000;
1084 inline int64_t getDelaySec(uint64_t frames){
1085 return getDelayUs(frames) / 1000000l;
1089 uint32_t start_time = 0;
1090 uint32_t sum_frames = 0;
1093 Print *p_out =
nullptr;
1094 Stream *p_in =
nullptr;
1106 template<
typename T>
1113 streams.push_back(&in);
1114 weights.push_back(weight);
1115 total_weights += weight;
1120 if (channel<
size()){
1121 streams[channel] = ∈
1123 LOGE(
"Invalid channel %d - max is %d", channel,
size()-1);
1130 LOGI(
"frame_size: %d",frame_size);
1131 return frame_size>0;
1136 if (channel<
size()){
1137 weights[channel] = weight;
1139 for (
int j=0;j<weights.size();j++){
1140 total += weights[j];
1142 total_weights = total;
1144 LOGE(
"Invalid channel %d - max is %d", channel,
size()-1);
1152 result_vect.clear();
1153 current_vect.clear();
1154 total_weights = 0.0;
1159 return streams.size();
1164 if (total_weights==0 || frame_size==0 || len==0) {
1165 LOGW(
"readBytes: %d",(
int)len);
1169 if (limit_available_data){
1177 result_len = len * frame_size / frame_size;
1187 limit_available_data = flag;
1192 retry_count = retry;
1197 Vector<int> weights{0};
1198 int total_weights = 0;
1200 bool limit_available_data =
false;
1201 int retry_count = 5;
1202 Vector<int> result_vect;
1203 Vector<T> current_vect;
1207 int samples = byteCount /
sizeof(T);
1208 result_vect.resize(samples);
1209 current_vect.resize(samples);
1210 int stream_count =
size();
1212 int samples_eff_max = 0;
1213 for (
int j=0;j<stream_count;j++){
1215 int samples_eff =
readSamples(streams[j],current_vect.data(), samples, retry_count);
1216 if (samples_eff > samples_eff_max)
1217 samples_eff_max = samples_eff;
1219 float factor = total_weights == 0.0f ? 0.0f :
static_cast<float>(weights[j]) / total_weights;
1224 for (
int j=0;j<samples;j++){
1225 p_data[j] = result_vect[j];
1227 return samples_eff_max *
sizeof(T);
1232 int result = DEFAULT_BUFFER_SIZE;
1233 for (
int j=0;j<
size();j++){
1234 result = min(result, streams[j]->available());
1239 void resultAdd(
float fact){
1240 for (
int j=0;j<current_vect.size();j++){
1241 current_vect[j]*=fact;
1242 result_vect[j] += current_vect[j];
1247 memset(result_vect.data(), 0,
sizeof(
int)*result_vect.size());
1261 template<
typename T>
1278 LOGW(
"channels corrected to %d",
size());
1284 virtual bool begin() {
1287 return AudioStream::begin();
1292 LOGD(
"readBytes: %d",(
int)len);
1293 T *p_data = (T*) data;
1295 int sample_count = result_len /
sizeof(T);
1296 int size_value =
size();
1298 for (
int j=0;j<sample_count; j++){
1299 for (
int i=0; i<size_value; i++){
1300 p_data[result_idx++] = weights[i] * readSample<T>(streams[i]);
1303 return result_idx*
sizeof(T);
1308 streams.push_back(&in);
1309 weights.push_back(weight);
1314 if (channel<
size()){
1315 weights[channel] = weight;
1317 LOGE(
"Invalid channel %d - max is %d", channel,
size()-1);
1329 return streams.size();
1334 int result = streams[0]->available();
1335 for (
int j=1;j<
size();j++){
1336 int tmp = streams[j]->available();
1346 Vector<float> weights{10};
1365 setUpdateCallback(cb_update);
1371 setUpdateCallback(cb_update);
1374 CallbackStream(
size_t (*cb_read)(uint8_t* data,
size_t len),
size_t (*cb_write)(
const uint8_t* data,
size_t len)) {
1375 setWriteCallback(cb_write);
1376 setReadCallback(cb_read);
1379 void setWriteCallback(
size_t (*cb_write)(
const uint8_t* data,
size_t len)){
1380 this->cb_write = cb_write;
1383 void setReadCallback(
size_t (*cb_read)(uint8_t* data,
size_t len)){
1384 this->cb_read = cb_read;
1387 void setUpdateCallback(
size_t (*cb_update)(uint8_t* data,
size_t len)){
1388 this->cb_update = cb_update;
1392 void setAvailableCallback(
int (*cb)()){
1393 this->cb_available = cb;
1396 virtual bool begin(AudioInfo info) {
1400 virtual bool begin()
override {
1405 void end()
override { active =
false;}
1407 int available()
override {
1408 int result = AudioStream::available();
1410 if (available_bytes>=0)
1411 return available_bytes;
1413 if (cb_available==
nullptr)
1416 int tmp_available = cb_available();
1417 if (tmp_available < 0)
1420 return tmp_available;
1423 size_t readBytes(uint8_t* data,
size_t len)
override {
1424 if (!active)
return 0;
1427 return cb_read(data, len);
1432 result = p_stream->readBytes(data , len);
1435 result = cb_update(data, result);
1440 size_t write(
const uint8_t* data,
size_t len)
override {
1441 if (!active)
return 0;
1444 return cb_write(data, len);
1448 size_t result = len;
1450 result = cb_update((uint8_t*)data, len);
1452 return p_out->write(data, result);
1482 available_bytes = val;
1489 size_t (*cb_write)(
const uint8_t* data,
size_t len) =
nullptr;
1490 size_t (*cb_read)(uint8_t* data,
size_t len) =
nullptr;
1491 size_t (*cb_update)(uint8_t* data,
size_t len) =
nullptr;
1492 int (*cb_available)() =
nullptr;
1493 Stream *p_stream =
nullptr;
1494 Print *p_out =
nullptr;
1495 int available_bytes = -1;
1506 template<
typename T,
class TF>
1514 this->channels = channels;
1522 this->channels = channels;
1539 if (p_converter !=
nullptr && info.
channels!=channels){
1540 LOGE(
"Inconsistent number of channels");
1546 bool begin()
override {
1548 LOGE(
"channels must not be 0");
1551 if (p_converter==
nullptr){
1552 p_converter =
new ConverterNChannels<T,TF>(channels);
1554 return AudioStream::begin();
1557 virtual size_t write(
const uint8_t *data,
size_t len)
override {
1558 if (p_converter==
nullptr)
return 0;
1559 size_t result = p_converter->convert((uint8_t *)data, len);
1560 return p_print->write(data, result);
1563 size_t readBytes(uint8_t *data,
size_t len)
override {
1564 if (p_converter==
nullptr)
return 0;
1565 if (p_stream==
nullptr)
return 0;
1566 size_t result = p_stream->readBytes(data, len);
1567 result = p_converter->convert(data, result);
1571 virtual int available()
override {
1572 if (p_stream==
nullptr)
return 0;
1573 return p_stream->available();
1576 virtual int availableForWrite()
override {
1577 return p_print->availableForWrite();
1583 if (p_converter!=
nullptr){
1584 p_converter->
setFilter(channel, filter);
1586 LOGE(
"p_converter is null");
1598 Stream *p_stream =
nullptr;
1599 Print *p_print =
nullptr;
1635 bool begin()
override {
1647 size_t write(
const uint8_t *data,
size_t len) {
1648 updateVolumes(data, len);
1649 size_t result = len;
1650 if (p_out!=
nullptr){
1651 result = p_out->write(data, len);
1656 size_t readBytes(uint8_t *data,
size_t len){
1657 if (p_stream==
nullptr)
return 0;
1658 size_t result = p_stream->readBytes(data, len);
1659 updateVolumes((
const uint8_t*)data, len);
1670 if (volumes.size() == 0) {
1671 LOGE(
"begin not called!");
1674 if (channel >= volumes.size()) {
1675 LOGE(
"invalid channel %d", channel);
1678 return volumes[channel];
1712 for (
int j = 0; j < info.
channels; j++) {
1726 float f_volume_tmp = 0;
1729 Vector<float> volumes_tmp{0};
1730 Print* p_out =
nullptr;
1731 Stream* p_stream =
nullptr;
1733 void updateVolumes(
const uint8_t *data,
size_t len){
1737 updateVolumesT<int16_t>(data, len);
1740 updateVolumesT<int24_t>(data, len);
1743 updateVolumesT<int32_t>(data, len);
1751 template <
typename T>
void updateVolumesT(
const uint8_t *buffer,
size_t size) {
1752 T *bufferT = (T *)buffer;
1753 int samplesCount = size /
sizeof(T);
1754 for (
int j = 0; j < samplesCount; j++) {
1755 float tmp = abs(
static_cast<float>(bufferT[j]));
1756 updateVolume(tmp, j);
1761 void updateVolume(
float tmp,
int j) {
1762 if (tmp > f_volume_tmp) {
1765 if (volumes_tmp.size() > 0 && info.
channels > 0) {
1767 if (tmp > volumes_tmp[ch]) {
1768 volumes_tmp[ch] = tmp;
1774 f_volume = f_volume_tmp;
1775 for (
int j = 0; j < info.
channels; j++) {
1776 volumes[j] = volumes_tmp[j];
1782 using VolumePrint = VolumeMeter;
1783 using VolumeOutput = VolumeMeter;
1793 uint16_t buffer_size = DEFAULT_BUFFER_SIZE;
1794 bool use_timer =
true;
1796 TimerFunction timer_function = DirectTimerCallback;
1797 bool adapt_sample_rate =
false;
1798 uint16_t (*callback)(uint8_t *data, uint16_t len) =
nullptr;
1802 static void timerCallback(
void *obj);
1813 friend void timerCallback(
void *obj);
1820 if (timer !=
nullptr)
delete timer;
1821 if (buffer !=
nullptr)
delete buffer;
1822 if (frame !=
nullptr)
delete[] frame;
1836 bool do_restart = active;
1837 if (do_restart)
end();
1841 if (do_restart)
begin(cfg);
1850 LOGD(
"%s: %s", LOG_METHOD,
1851 config.rx_tx_mode == RX_MODE ?
"RX_MODE" :
"TX_MODE");
1853 this->frameCallback = config.callback;
1854 if (cfg.use_timer) {
1855 frameSize = cfg.bits_per_sample * cfg.channels / 8;
1856 frame =
new uint8_t[frameSize];
1859 timer->setTimerFunction(cfg.timer_function);
1860 if (cfg.timer_id>=0){
1861 timer->setTimer(cfg.timer_id);
1864 LOGI(
"sample_rate: %u -> time: %u milliseconds", (
unsigned int)cfg.sample_rate, (
unsigned int)time);
1865 timer->setCallbackParameter(
this);
1866 timer->begin(timerCallback, time, TimeUnit::US);
1869 notifyAudioChange(cfg);
1876 if (this->frameCallback !=
nullptr) {
1877 if (cfg.use_timer) {
1878 timer->begin(timerCallback, time, TimeUnit::US);
1888 if (cfg.use_timer) {
1899 bool active =
false;
1900 uint16_t (*frameCallback)(uint8_t *data, uint16_t len);
1904 uint8_t *frame =
nullptr;
1905 uint16_t frameSize = 0;
1907 unsigned long lastTimestamp = 0u;
1908 uint32_t currentRateValue = 0;
1909 uint32_t printCount = 0;
1912 virtual size_t writeExt(
const uint8_t *data,
size_t len)
override {
1913 if (!active)
return 0;
1916 if (!cfg.use_timer) {
1917 result = frameCallback((uint8_t *)data, len);
1919 result = buffer->
writeArray((uint8_t *)data, len);
1926 virtual size_t readExt(uint8_t *data,
size_t len)
override {
1927 if (!active)
return 0;
1931 if (!cfg.use_timer) {
1932 result = frameCallback(data, len);
1942 unsigned long ms =
millis();
1943 if (lastTimestamp > 0u) {
1944 uint32_t diff = ms - lastTimestamp;
1946 uint16_t rate = 1 * 1000 / diff;
1948 if (currentRateValue == 0) {
1949 currentRateValue = rate;
1951 currentRateValue = (currentRateValue + rate) / 2;
1960 LOGI(
"effective sample rate: %u", (
unsigned int)currentRateValue);
1961 if (cfg.adapt_sample_rate &&
1962 abs((
int)currentRateValue - (
int)cfg.
sample_rate) > 200) {
1964 notifyAudioChange(cfg);
1970 void IRAM_ATTR timerCallback(
void *obj) {
1971 TimerCallbackAudioStream *src = (TimerCallbackAudioStream *)obj;
1972 if (src !=
nullptr) {
1975 if (src->cfg.rx_tx_mode == RX_MODE) {
1977 uint16_t available_bytes = src->frameCallback(src->frame, src->frameSize);
1978 uint16_t buffer_available = src->buffer->availableForWrite();
1979 if (buffer_available < available_bytes) {
1981 uint16_t to_clear = available_bytes - buffer_available;
1982 uint8_t tmp[to_clear];
1983 src->buffer->readArray(tmp, to_clear);
1985 if (src->buffer->writeArray(src->frame, available_bytes) !=
1991 if (src->buffer !=
nullptr && src->frame !=
nullptr &&
1992 src->frameSize > 0) {
1993 uint16_t available_bytes =
1994 src->buffer->readArray(src->frame, src->frameSize);
1995 if (available_bytes !=
1996 src->frameCallback(src->frame, available_bytes)) {
1997 LOGE(
"data underflow");
2001 src->measureSampleRate();
MemoryType
Memory types.
Definition: AudioTypes.h:35
RxTxMode
The Microcontroller is the Audio Source (TX_MODE) or Audio Sink (RX_MODE). RXTX_MODE is Source and Si...
Definition: AudioTypes.h:28