Skip to content

Commit 5fb5e16

Browse files
Add real block write for AudioRequestBuffer (#2712)
Optimize AudioRequestBuffer writing when large blocks are available (i.e. I2S writes of full MP3 or AAC frames in BackgroundAudio). Update I2S to use the new call. Reduces 1152 calls to arb::write() to a single call/return and optimized memcpy in that case.
1 parent 45c0b3a commit 5fb5e16

File tree

3 files changed

+34
-14
lines changed

3 files changed

+34
-14
lines changed

libraries/AudioBufferManager/src/AudioBufferManager.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,38 @@ bool AudioBufferManager::write(uint32_t v, bool sync) {
188188
return true;
189189
}
190190

191+
size_t AudioBufferManager::write(const uint32_t *v, size_t words, bool sync) {
192+
size_t written = 0;
193+
194+
if (!_running || !_isOutput) {
195+
return 0;
196+
}
197+
while (words) {
198+
AudioBuffer ** volatile p = (AudioBuffer ** volatile)&_empty;
199+
if (!*p) {
200+
if (!sync) {
201+
return written;
202+
} else {
203+
while (!*p) {
204+
/* noop busy wait */
205+
}
206+
}
207+
208+
}
209+
size_t availToWriteThisBuff = _wordsPerBuffer - _userOff;
210+
size_t toWrite = std::min(availToWriteThisBuff, words);
211+
memcpy(&((*p)->buff[_userOff]), v, toWrite * sizeof(uint32_t));
212+
written += toWrite;
213+
_userOff += toWrite;
214+
words -= toWrite;
215+
if (_userOff == _wordsPerBuffer) {
216+
_addToList(&_filled, _takeFromList(p));
217+
_userOff = 0;
218+
}
219+
}
220+
return written;
221+
}
222+
191223
bool AudioBufferManager::read(uint32_t *v, bool sync) {
192224
if (!_running || _isOutput) {
193225
return false;

libraries/AudioBufferManager/src/AudioBufferManager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class AudioBufferManager {
3434
bool begin(int dreq, volatile void *pioFIFOAddr);
3535

3636
bool write(uint32_t v, bool sync = true);
37+
size_t write(const uint32_t *v, size_t words, bool sync = true);
3738
bool read(uint32_t *v, bool sync = true);
3839
void flush();
3940

libraries/I2S/src/I2S.cpp

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -500,20 +500,7 @@ size_t I2S::write(const uint8_t *buffer, size_t size) {
500500
if (size & 0x3 || !_running || !_isOutput) {
501501
return 0;
502502
}
503-
504-
size_t writtenSize = 0;
505-
uint32_t *p = (uint32_t *)buffer;
506-
while (size) {
507-
if (!_arb->write(*p, false)) {
508-
// Blocked, stop write here
509-
return writtenSize;
510-
} else {
511-
p++;
512-
size -= 4;
513-
writtenSize += 4;
514-
}
515-
}
516-
return writtenSize;
503+
return _arb->write((const uint32_t *)buffer, size / sizeof(uint32_t), false);
517504
}
518505

519506
int I2S::availableForWrite() {

0 commit comments

Comments
 (0)