diff --git a/libraries/AudioBufferManager/src/AudioBufferManager.cpp b/libraries/AudioBufferManager/src/AudioBufferManager.cpp index d082aa493..a2a93b3a3 100644 --- a/libraries/AudioBufferManager/src/AudioBufferManager.cpp +++ b/libraries/AudioBufferManager/src/AudioBufferManager.cpp @@ -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; diff --git a/libraries/AudioBufferManager/src/AudioBufferManager.h b/libraries/AudioBufferManager/src/AudioBufferManager.h index a98c42704..3326cac58 100644 --- a/libraries/AudioBufferManager/src/AudioBufferManager.h +++ b/libraries/AudioBufferManager/src/AudioBufferManager.h @@ -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(); diff --git a/libraries/I2S/src/I2S.cpp b/libraries/I2S/src/I2S.cpp index b3e71659a..ca7374af7 100644 --- a/libraries/I2S/src/I2S.cpp +++ b/libraries/I2S/src/I2S.cpp @@ -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() {