samd: When possible, use one DMA channel for stereo AudioOut

.. the documentation doesn't make this clear, but in practice it works
to write both of the DATABUF registers at the same time.  This should
also reduce the amount of wear and tear DMA puts on the system, as the
number of transfers is cut in half.  (the number of bytes transferred
remains the same, though)

In principle, this could cover all stereo cases if audio_dma_convert_signed
also learned to 16-bit extend and swap values.  However, this is the
case that matters for stereo mp3 playback on PyGamer.

Testing performed: Listened to some tracks with good stereo separation.
This commit is contained in:
Jeff Epler 2020-01-26 15:36:12 -06:00
parent c2fd30364e
commit cb6193bbc7

View File

@ -397,15 +397,22 @@ void common_hal_audioio_audioout_play(audioio_audioout_obj_t* self,
if (self->right_channel == &pin_PA02) {
right_channel_reg = (uint32_t) &DAC->DATABUF[0].reg;
}
result = audio_dma_setup_playback(&self->left_dma, sample, loop, true, 0,
false /* output unsigned */,
left_channel_reg,
left_channel_trigger);
if (right_channel_reg != 0 && result == AUDIO_DMA_OK) {
result = audio_dma_setup_playback(&self->right_dma, sample, loop, true, 1,
if(right_channel_reg == left_channel_reg + 2 && audiosample_bits_per_sample(sample) == 16) {
result = audio_dma_setup_playback(&self->left_dma, sample, loop, false, 0,
false /* output unsigned */,
right_channel_reg,
right_channel_trigger);
left_channel_reg,
left_channel_trigger);
} else {
result = audio_dma_setup_playback(&self->left_dma, sample, loop, true, 0,
false /* output unsigned */,
left_channel_reg,
left_channel_trigger);
if (right_channel_reg != 0 && result == AUDIO_DMA_OK) {
result = audio_dma_setup_playback(&self->right_dma, sample, loop, true, 1,
false /* output unsigned */,
right_channel_reg,
right_channel_trigger);
}
}
#endif
if (result != AUDIO_DMA_OK) {