cancel
Showing results for 
Search instead for 
Did you mean: 

How do I get independent stereo audio output on STM32F469I-DISCO board?

Kneepatch
Associate III

I am having trouble getting independent stereo audio output on the STM32F469I-DISCO development board. I am passing data to the cirrus audio codec using the stm32469i_discovery_audio.h functions:

BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_BOTH, 80, 48);

BSP_AUDIO_OUT_Play(dataI2S, (uint32_t)32);

dataI2S is an array that has my audio data which is a calculated sine wave. From what I understand, the odd indices of the array go to one side of the audio (i.e left) and the even indices go to the other side of the audio output (i.e. right). What I am seeing on the oscilloscope is that both sides display the same sine wave, just slightly shifted in time. This occurs even if I zero out the even indices of the array.

Can someone please point me in the right direction here? Please let me know if you have any additional details that you want me to provide!

18 REPLIES 18
MM..1
Chief II

Show here your dataI2S array values for example first ten values as in memory debuger screenshot...

Kneepatch
Associate III

0693W00000HoOvsQAF.png

Kneepatch
Associate III

Here are screenshots of the oscilloscope for both sides L and R:

0693W00000HoP38QAF.bmp0693W00000HoP1SQAV.bmp

MM..1
Chief II

for output same signals need data be equal [0]=[1] [2]=[3]

and too need check BSP support for 16bit data

Kneepatch
Associate III

That’s exactly my point, one side has all zeros but it produces the same exact wave, just time shifted. And the HAL library asks for my data in a 16-bit buffer, so I am pretty sure that means it supports 16-bit data.

MM..1
Chief II

Maybe use BSP need more info from example code is here mix chaos for pointer to data

typedef struct {
  uint8_t buff[AUDIO_BUFFER_SIZE];
  uint32_t fptr;
  BUFFER_StateTypeDef state;
  uint32_t AudioFileSize;
  uint32_t *SrcAddress;
}AUDIO_BufferTypeDef;

primary buff in example is uint8

call is converted

  if(bytesread > 0)
  {
    BSP_AUDIO_OUT_Play((uint16_t *)&buffer_ctl.buff[0], AUDIO_BUFFER_SIZE);

and in BSP back to 8

uint8_t BSP_AUDIO_OUT_Play(uint16_t* pBuffer, uint32_t Size)
{
  uint8_t ret = AUDIO_OK;
 
  /* Call the audio Codec Play function */
  if(audio_drv->Play(AUDIO_I2C_ADDRESS, pBuffer, Size) != 0)
  {  
    ret = AUDIO_ERROR;
  }
 
  /* Initiate a DMA transfer of PCM samples towards the serial audio interface */  
  if(ret == AUDIO_OK)
  {
    if (HAL_SAI_Transmit_DMA(&haudio_out_sai, (uint8_t*) pBuffer, DMA_MAX(Size / AUDIODATA_SIZE))!= HAL_OK)
    {
      ret = AUDIO_ERROR;
    }
  }
        
  return ret;
}

but seems your screenshot data isnt real filled with sine and too i mean your init call is bad

/**
  * @brief  Configures the audio peripherals.
  * @param  OutputDevice: OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
  *                       or OUTPUT_DEVICE_BOTH.
  * @param  Volume: Initial volume level (from 0 (Mute) to 100 (Max))
  * @param  AudioFreq: Audio frequency used to play the audio stream.
  * @note   The SAI PLL input clock must be done in the user application.  
  * @retval AUDIO_OK if correct communication, else wrong communication
  */
uint8_t BSP_AUDIO_OUT_Init(uint16_t OutputDevice, 
                           uint8_t Volume, 
                           uint32_t AudioFreq)
{

and this call audio codec init maybe set mono , need check all.for error returned

  if(ret == AUDIO_OK)
  {
    /* Initialize the audio codec internal registers */
    if (audio_drv->Init(AUDIO_I2C_ADDRESS,
                        OutputDevice, 
                        Volume, 
                        AudioFreq) != AUDIO_OK)
    {
      ret = AUDIO_ERROR;
    }
  }
 
  return ret;

Thanks for the response, I've been thinking over it this past week with my co-workers.

I am still not convinced that the audio data size is 8-bit. In the code that you show me, the 8-bit input seems to be for DMA, but the code still accepts 16-bits for the audio buffer. Here is another consideration, because in the stm32469i_discovery_audio.c header it has the following notes for limitations (see 3 and 4 bolded below):

Known Limitations:

------------------

  1- If the TDM Format used to paly in parallel 2 audio Stream (the first Stream is configured in codec SLOT0 and second

   Stream in SLOT1) the Pause/Resume, volume and mute feature will control the both streams.

  2- Parsing of audio file is not implemented (in order to determine audio file properties: Mono/Stereo, Data size,

   File size, Audio Frequency, Audio Data header size ...). The configuration is fixed for the given audio file.

  3- Supports only Stereo audio streaming.

  4- Supports only 16-bits audio data size.

==============================================================================*/

Based on this note, it makes me think that we are already streaming Stereo audio and it's 16-bits for the data size. Am I wrong?

Try playing back something else, e.g. a sawtooth waveform.

Cube is open source, so you can read the sources to find out how exactly given functions work.

JW

MM..1
Chief II

As i write you

    if (HAL_SAI_Transmit_DMA(&haudio_out_sai, (uint8_t*) pBuffer, DMA_MAX(Size / AUDIODATA_SIZE))!= HAL_OK)

you call this BSP_AUDIO_OUT_Play(dataI2S, (uint32_t)32); , but your buffer size is 1000 16bit then real byte size is 2000.

Then in your size 32 entered here DMA_MAX(Size / AUDIODATA_SIZE) result to ...

This SAI interface is initialized and you need check this init. For example if is initialised to 32 bit for one channel then your data is send as left + right 16bit to left 32 and sample 2 left+right to right ... result to bad freq and shift and bad playback in both .