Skip to content

Commit

Permalink
added optional intermediate buffer to SaiHandle to allow full use of …
Browse files Browse the repository at this point in the history
…cpu in audio callback at low block sizes
  • Loading branch information
jeffplaisance committed Nov 22, 2024
1 parent bd13385 commit ce3a13a
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 7 deletions.
5 changes: 5 additions & 0 deletions src/daisy_seed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,11 @@ float DaisySeed::AudioCallbackRate() const
return callback_rate_;
}

void DaisySeed::SetIntermediateBuffers(int32_t* buffer_sai1, int32_t* buffer_sai2)
{
audio_handle.SetIntermediateBuffers(buffer_sai1, buffer_sai2);
}

void DaisySeed::SetLed(bool state)
{
led.Write(state);
Expand Down
2 changes: 2 additions & 0 deletions src/daisy_seed.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ class DaisySeed
/** Returns the rate in Hz that the Audio callback is called */
float AudioCallbackRate() const;

void SetIntermediateBuffers(int32_t* buffer_sai1, int32_t* buffer_sai2 = nullptr);

/** Returns the SAI Handle for the Daisy Seed
* This can be useful when adding a secondary codec,
* the result of this function can be passed to the audio reinit
Expand Down
11 changes: 11 additions & 0 deletions src/hid/audio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ class AudioHandle::Impl
: AudioHandle::Result::ERR;
}

void SetIntermediateBuffers(int32_t* buffer_sai1, int32_t* buffer_sai2)
{
sai1_.SetIntermediateBuffer(buffer_sai1);
sai2_.SetIntermediateBuffer(buffer_sai2);
}

float GetSampleRate() { return sai1_.GetSampleRate(); }

AudioHandle::Result SetPostGain(float val)
Expand Down Expand Up @@ -520,6 +526,11 @@ AudioHandle::Result AudioHandle::SetBlockSize(size_t size)
return pimpl_->SetBlockSize(size);
}

void AudioHandle::SetIntermediateBuffers(int32_t* buffer_sai1, int32_t* buffer_sai2)
{
pimpl_->SetIntermediateBuffers(buffer_sai1, buffer_sai2);
}

float AudioHandle::GetSampleRate()
{
return pimpl_->GetSampleRate();
Expand Down
2 changes: 2 additions & 0 deletions src/hid/audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ class AudioHandle
*/
Result SetBlockSize(size_t size);

void SetIntermediateBuffers(int32_t* buffer_sai1, int32_t* buffer_sai2 = nullptr);

/** Sets the amount of gain adjustment to perform before and after callback.
** useful if the hardware has additional headroom, and the nominal value shouldn't be 1.0
**
Expand Down
60 changes: 53 additions & 7 deletions src/per/sai.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "per/sai.h"
#include "daisy_core.h"
#include <cstring>

namespace daisy
{
Expand Down Expand Up @@ -39,8 +40,15 @@ class SaiHandle::Impl
/** Offset stored for weird inter-SAI stuff.*/
size_t dma_offset;

// Optional buffer for audio callback output
int32_t* buff_intermediate_ = nullptr;

void SetIntermediateBuffer(int32_t* buffer) { buff_intermediate_ = buffer; }

/** Callback that dispatches user callback from Cplt and HalfCplt DMA Callbacks */
void InternalCallback(size_t offset);
void InternalCallbackRx(size_t offset);

void InternalCallbackTx(size_t offset);

/** Pin Initiazlization */
void InitPins();
Expand Down Expand Up @@ -283,15 +291,25 @@ void SaiHandle::Impl::DeInitDma(PeripheralBlock block)
}
}

void SaiHandle::Impl::InternalCallback(size_t offset)
void SaiHandle::Impl::InternalCallbackRx(size_t offset)
{
int32_t *in, *out;
in = buff_rx_ + offset;
out = buff_tx_ + offset;
out = (buff_intermediate_ ? buff_intermediate_ : buff_tx_ + offset);
if(callback_)
callback_(in, out, buff_size_ / 2);
}

void SaiHandle::Impl::InternalCallbackTx(size_t offset)
{
if (!buff_intermediate_) {
return;
}
int32_t* in = buff_intermediate_;
int32_t* out = buff_tx_ + offset;
std::memcpy(out, in, buff_size_ / 2 * sizeof(*out));
}

SaiHandle::Result
SaiHandle::Impl::StartDmaTransfer(int32_t* buffer_rx,
int32_t* buffer_tx,
Expand Down Expand Up @@ -503,12 +521,12 @@ extern "C" void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef* hsai)
if(hsai->Instance == SAI1_Block_A || hsai->Instance == SAI1_Block_B)
{
sai_handles[0].dma_offset = 0;
sai_handles[0].InternalCallback(0);
sai_handles[0].InternalCallbackRx(0);
}
else if(hsai->Instance == SAI2_Block_A || hsai->Instance == SAI2_Block_B)
{
sai_handles[1].dma_offset = 0;
sai_handles[1].InternalCallback(0);
sai_handles[1].InternalCallbackRx(0);
}
}

Expand All @@ -517,12 +535,36 @@ extern "C" void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef* hsai)
if(hsai->Instance == SAI1_Block_A || hsai->Instance == SAI1_Block_B)
{
sai_handles[0].dma_offset = sai_handles[0].buff_size_ / 2;
sai_handles[0].InternalCallback(sai_handles[0].dma_offset);
sai_handles[0].InternalCallbackRx(sai_handles[0].dma_offset);
}
else if(hsai->Instance == SAI2_Block_A || hsai->Instance == SAI2_Block_B)
{
sai_handles[1].dma_offset = sai_handles[1].buff_size_ / 2;
sai_handles[1].InternalCallback(sai_handles[1].dma_offset);
sai_handles[1].InternalCallbackRx(sai_handles[1].dma_offset);
}
}

extern "C" void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef* hsai)
{
if(hsai->Instance == SAI1_Block_A || hsai->Instance == SAI1_Block_B)
{
sai_handles[0].InternalCallbackTx(0);
}
else if(hsai->Instance == SAI2_Block_A || hsai->Instance == SAI2_Block_B)
{
sai_handles[1].InternalCallbackTx(0);
}
}

extern "C" void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef* hsai)
{
if(hsai->Instance == SAI1_Block_A || hsai->Instance == SAI1_Block_B)
{
sai_handles[0].InternalCallbackTx(sai_handles[0].buff_size_ / 2);
}
else if(hsai->Instance == SAI2_Block_A || hsai->Instance == SAI2_Block_B)
{
sai_handles[1].InternalCallbackTx(sai_handles[1].buff_size_ / 2);
}
}

Expand Down Expand Up @@ -579,5 +621,9 @@ size_t SaiHandle::GetOffset() const
return pimpl_->dma_offset;
}

void SaiHandle::SetIntermediateBuffer(int32_t* buffer) {
pimpl_->SetIntermediateBuffer(buffer);
}


} // namespace daisy
2 changes: 2 additions & 0 deletions src/per/sai.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ class SaiHandle
/** Returns the current offset within the SAI buffer, will be either 0 or size/2 */
size_t GetOffset() const;

void SetIntermediateBuffer(int32_t* buffer);

inline bool IsInitialized() const
{
return pimpl_ == nullptr ? false : true;
Expand Down

0 comments on commit ce3a13a

Please sign in to comment.