Skip to content

Commit

Permalink
Add real block write for AudioRequestBuffer (#2712)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
earlephilhower authored Dec 21, 2024
1 parent 45c0b3a commit 5fb5e16
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 14 deletions.
32 changes: 32 additions & 0 deletions libraries/AudioBufferManager/src/AudioBufferManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,38 @@ bool AudioBufferManager::write(uint32_t v, bool sync) {
return true;
}

size_t AudioBufferManager::write(const uint32_t *v, size_t words, bool sync) {
size_t written = 0;

if (!_running || !_isOutput) {
return 0;
}
while (words) {
AudioBuffer ** volatile p = (AudioBuffer ** volatile)&_empty;
if (!*p) {
if (!sync) {
return written;
} else {
while (!*p) {
/* noop busy wait */
}
}

}
size_t availToWriteThisBuff = _wordsPerBuffer - _userOff;
size_t toWrite = std::min(availToWriteThisBuff, words);
memcpy(&((*p)->buff[_userOff]), v, toWrite * sizeof(uint32_t));
written += toWrite;
_userOff += toWrite;
words -= toWrite;
if (_userOff == _wordsPerBuffer) {
_addToList(&_filled, _takeFromList(p));
_userOff = 0;
}
}
return written;
}

bool AudioBufferManager::read(uint32_t *v, bool sync) {
if (!_running || _isOutput) {
return false;
Expand Down
1 change: 1 addition & 0 deletions libraries/AudioBufferManager/src/AudioBufferManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class AudioBufferManager {
bool begin(int dreq, volatile void *pioFIFOAddr);

bool write(uint32_t v, bool sync = true);
size_t write(const uint32_t *v, size_t words, bool sync = true);
bool read(uint32_t *v, bool sync = true);
void flush();

Expand Down
15 changes: 1 addition & 14 deletions libraries/I2S/src/I2S.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,20 +500,7 @@ size_t I2S::write(const uint8_t *buffer, size_t size) {
if (size & 0x3 || !_running || !_isOutput) {
return 0;
}

size_t writtenSize = 0;
uint32_t *p = (uint32_t *)buffer;
while (size) {
if (!_arb->write(*p, false)) {
// Blocked, stop write here
return writtenSize;
} else {
p++;
size -= 4;
writtenSize += 4;
}
}
return writtenSize;
return _arb->write((const uint32_t *)buffer, size / sizeof(uint32_t), false);
}

int I2S::availableForWrite() {
Expand Down

0 comments on commit 5fb5e16

Please sign in to comment.