cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H745 DISCO line in audio

jokerhung
Associate II

I have wrote software for recording audio from line in to wav file for STM32H745 discovery board.

But output file is distortion (original file and output file is in attachment) 

Input file and output file is the same sample rate (32khz, 16 bit, 2 channel)

I have compared 2 file in audacity in following picture.

Could anyone have experiment to fix this problem ?

 
566d2d3e-9fad-4d38-82af-b911108f5231.jfif

 

 

5 REPLIES 5
AScha.3
Chief II

Mickey Mouse speaking ... 🙂

So you have mixed up the data , maybe 16b -> 2x 8b -> 2x16b , producing like double speed audio.

Check, how you handle the data flow.

If you feel a post has answered your question, please click "Accept as Solution".

I posted my source code below, could you tell me what is wrong ?

 

/* Define buffer */
#define AUDIO_BUFF_SIZE  (6400)
#define WR_BUFFER_SIZE   (8*AUDIO_BUFF_SIZE)
ALIGN_32BYTES (uint16_t RecPlayback[AUDIO_BUFF_SIZE]);
ALIGN_32BYTES (uint16_t WrBuffer[WR_BUFFER_SIZE]);

/* Start recording */ 
AudioInInit.Device = AUDIO_IN_DEVICE_ANALOG_MIC;
AudioInInit.ChannelsNbr = channel_nbr;
AudioInInit.SampleRate = *AudioFreq_ptr;
AudioInInit.BitsPerSample = AUDIO_RESOLUTION_16B;
AudioInInit.Volume = VolumeLevel;
BSP_AUDIO_IN_Init(0, &AudioInInit);
BSP_AUDIO_IN_GetState(0, &InState);
BSP_AUDIO_IN_Record(0, (uint8_t*)&RecPlayback[0], 2*AUDIO_BUFF_SIZE);

/* Write buffer to file */
if(AUDIODataReady == 1)
{	
write2wave_file((uint8_t*)(WrBuffer+AudioRecordOffset), WR_BUFFER_SIZE);
AUDIODataReady = 0;
}

/* Full transfer */
void BSP_AUDIO_IN_TransferComplete_CallBack(uint32_t Instance)
{
  /* Clean Data Cache to update the content of the SRAM */
  SCB_CleanDCache_by_Addr((uint32_t*)&RecPlayback[0], 2*AUDIO_BUFF_SIZE);
		
  /* Copy data in internal buffer */
  memcpy((uint8_t*)&WrBuffer[ITCounter * (AUDIO_BUFF_SIZE)], (uint8_t*)&RecPlayback[0], 2*AUDIO_BUFF_SIZE);
  if(ITCounter == (WR_BUFFER_SIZE/(AUDIO_BUFF_SIZE*2))-1)
  {
    ITCounter++;
    AudioRecordOffset = 0;
    AUDIODataReady = 1;
  }
  else if(ITCounter == (WR_BUFFER_SIZE/(AUDIO_BUFF_SIZE))-1)
  {
    ITCounter = 0;
    AudioRecordOffset = WR_BUFFER_SIZE/2;
    AUDIODataReady = 1;
  }
  else
  {
    ITCounter++;
  }
  AudioAnalogOffset = BUFFER_OFFSET_FULL;
}

/* Half transfer */
void BSP_AUDIO_IN_HalfTransfer_CallBack(uint32_t Instance)
{
  /* Clean Data Cache to update the content of the SRAM */
  SCB_CleanDCache_by_Addr((uint32_t*)&RecPlayback[0], 2*AUDIO_BUFF_SIZE);
		
  /* Copy data in internal buffer */
  memcpy((uint8_t*)&WrBuffer[ITCounter * (AUDIO_BUFF_SIZE)], (uint8_t*)&RecPlayback[0], 2*AUDIO_BUFF_SIZE);
  if(ITCounter == (WR_BUFFER_SIZE/(AUDIO_BUFF_SIZE*2))-1)
  {
    AUDIODataReady = 1;
    AudioRecordOffset = 0;
    ITCounter++;
  }
  else if(ITCounter == (WR_BUFFER_SIZE/(AUDIO_BUFF_SIZE))-1)
  {
    AUDIODataReady = 1;
    AudioRecordOffset = WR_BUFFER_SIZE/2;
    ITCounter = 0;
  }
  else
  {
    ITCounter++;
  }
  AudioAnalogOffset = BUFFER_OFFSET_HALF;
}

 

No.

First you should tell, what and how you do :

- data from..to .. (onboard codec ? to sd-card ?)

- copy from STM bsp example  or your own ?

- data flow: input (2x 16b stereo ?) to ..? sd-card...or ? and play live to output or from file or on PC from card ?

- using SAI + DMA ...circular ? for input and output ?

- move buffers with memcpy in 8b values with casting - why ? a simple read-write loop with uint32 is much faster.

 

If you feel a post has answered your question, please click "Accept as Solution".
jokerhung
Associate II

I answered your question:

"- data from..to .. (onboard codec ? to sd-card ?)"

=> data from onboard codec (wm8994) to onboard eMMC (by fatfs)

"- copy from STM bsp example  or your own ?"

=> I modified file audio_record.c from BSP project

"- data flow: input (2x 16b stereo ?) to ..? sd-card...or ? and play live to output or from file or on PC from card ?"

=> no play live, only write to eMMC 

=> data from line in (32khz, 16bit, stereo) -> codec -> CPU (via SAI) DMA => RecPlayback variable => copy to WrBuffer buffer => write to eMMC using function write2wave_file() if half of WrBuffer buffer is full

"using SAI + DMA ...circular ? for input and output ?"

=> using SAI + DMA for input from codec (haft transfer, full transfer interrupt)

"move buffers with memcpy in 8b values with casting - why ? a simple read-write loop with uint32 is much faster."

=> read-write loop with uint32 is better but I don't think this is problem of this bug

Ok, but how you play or get data from mmc fat file? And create wav header or just raw data block? 

If you feel a post has answered your question, please click "Accept as Solution".