Skip to main content
aciuf
Associate III
August 2, 2024
Question

STM32F746 cannot read level of audio input signal

  • August 2, 2024
  • 6 replies
  • 2584 views

I would like to read the level of audio input signal to use like a vu-meter instead of use analog input.

 

This is my code but I read always 0dB on both channels.

 

 

void AUDIO_PLAYER_Init2()
{

/* Allocat mem for Smr */

pSmrPersistentMem = malloc(smr_persistent_mem_size); /* smr_persistent_mem_size 0x188 */

pSmrScratchMem = malloc(smr_scratch_mem_size); /* smr_scratch_mem_size 0xF04 */

 

 

if (BSP_AUDIO_IN_Init(INPUT_DEVICE_INPUT_LINE_1, 80, AUDIO_FREQUENCY_48K) != 0)

LCD_LOG_SetHeader((uint8_t *)"Audio SMR Application KO");

else

LCD_LOG_SetHeader((uint8_t *)"Audio SMR Application OK");

}

 

void Audio_Process2()
{

    int32_t error = SMR_ERROR_NONE;

    __HAL_RCC_CRC_CLK_ENABLE();

    CRC->CR = CRC_CR_RESET;

   

    error = smr_reset(pSmrPersistentMem, pSmrScratchMem);

    if (error != SMR_ERROR_NONE)

    {

        BSP_LCD_DisplayStringAt(10, 20, (uint8_t *)"--err0--", LEFT_MODE);

        return (AUDIO_ERROR_SMR);

    }

 

    smr_static_param.sampling_rate = 48000; /* only sampling rate supported */

    error = smr_setParam(&smr_static_param, pSmrPersistentMem);

    if (error != SMR_ERROR_NONE)

    {

       BSP_LCD_DisplayStringAt(10, 20, (uint8_t *)"--err1--", LEFT_MODE);

       return (AUDIO_ERROR_SMR);

    }

    smr_dynamic_param.enable = 1; /* SMR module enabler */

    smr_dynamic_param.averaging_time = AUDIO_CFG_SMR_AVGTIME_DEFAULT;

    smr_dynamic_param.filter_type = SMR_PREFILTER_AWEIGHTING;

 

    error = smr_setConfig(&smr_dynamic_param, pSmrPersistentMem);

    if (error != SMR_ERROR_NONE)

    {

        BSP_LCD_DisplayStringAt(10, 20, (uint8_t *)"--err2--", LEFT_MODE);

       return (AUDIO_ERROR_SMR);

    }

    error = smr_getConfig(&smr_dynamic_param, pSmrPersistentMem);

    if (error != SMR_ERROR_NONE)

    {

       BSP_LCD_DisplayStringAt(10, 20, (uint8_t *)"--err4--", LEFT_MODE);

       return AUDIO_ERROR_SMR;

   }

 

   BufferHandler.nb_bytes_per_Sample = 2; /* 16-bit */

   BufferHandler.nb_channels = 2; /* stereo */

   BufferHandler.data_ptr = PCM_Data_SMR;

   BufferHandler.buffer_size = 32/2; /* just half buffer is process (size per channel) */

   BufferHandler.mode = INTERLEAVED;

   BufferHandler.data_ptr = &BufferCtl.buff[AUDIO_OUT_BUFFER_SIZE /2];

 

   error = smr_process(pBufferHandler, pBufferHandler, pSmrPersistentMem);

   if (error != SMR_ERROR_NONE)

  {

     BSP_LCD_DisplayStringAt(10, 20, (uint8_t *)"--err5--", LEFT_MODE);

     return (AUDIO_ERROR_SMR);

  }

 

   error = smr_getConfig(&smr_dynamic_param, pSmrPersistentMem);

   if (error != SMR_ERROR_NONE)

   {

      BSP_LCD_DisplayStringAt(10, 20, (uint8_t *)"--err6--", LEFT_MODE);

      return AUDIO_ERROR_SMR;

   }

 

sprintf((char *)str_pwr, "Left mean power: %ld dB",(int32_t)((float)smr_dynamic_param.mean_level_left*0.25));

BSP_LCD_DisplayStringAt(CHAR(0), LINE(10), (uint8_t *)str_pwr, LEFT_MODE);

sprintf((char *)str_pwr, "Right mean power: %ld dB",(int32_t)((float)smr_dynamic_param.mean_level_right*0.25));

BSP_LCD_DisplayStringAt(CHAR(0), LINE(11), (uint8_t *)str_pwr, LEFT_MODE);

}

6 replies

KnarfB
Super User
August 2, 2024

BSP_AUDIO_IN_Init(INPUT_DEVICE_INPUT_LINE_1, 80, AUDIO_FREQUENCY_48K)

doesn't match the implentation in 

32f746gdiscovery-bsp/stm32746g_discovery_audio.c at 64c20f758a907cd873e368502cf16e498934d0ec · STMicroelectronics/32f746gdiscovery-bsp (github.com)

hth

KnarfB

aciuf
aciufAuthor
Associate III
August 2, 2024

I am using a STM32F746-DISCO so INPUT_DEVICE_INPUT_LINE_1 should be the line input.

aciuf
aciufAuthor
Associate III
August 2, 2024

Now I see some values but still not good

 

 

 

void AUDIO_PLAYER_Init2()
{
	int32_t error = SMR_ERROR_NONE;

	pSmrPersistentMem = malloc(smr_persistent_mem_size); /* smr_persistent_mem_size 0x188 */
	pSmrScratchMem = malloc(smr_scratch_mem_size); /* smr_scratch_mem_size 0xF04 */


	if (BSP_AUDIO_IN_Init(INPUT_DEVICE_INPUT_LINE_1, 100, AUDIO_FREQUENCY_48K) != 0)
	//if (BSP_AUDIO_IN_Init(INPUT_DEVICE_DIGITAL_MICROPHONE_2, 80, AUDIO_FREQUENCY_48K) != 0)
		LCD_LOG_SetHeader((uint8_t *)"Audio SMR Application KO");
	else
		LCD_LOG_SetHeader((uint8_t *)"Audio SMR Application OK");

	 __HAL_RCC_CRC_CLK_ENABLE();

	CRC->CR = CRC_CR_RESET;

	error = smr_reset(pSmrPersistentMem, pSmrScratchMem);
	if (error != SMR_ERROR_NONE)
	{
	 	BSP_LCD_DisplayStringAt(10, 20, (uint8_t *)"--smr_reset--", LEFT_MODE);
	 return (AUDIO_ERROR_SMR);
	}

	smr_static_param.sampling_rate = 48000; /* only sampling rate supported */

	error = smr_setParam(&smr_static_param, pSmrPersistentMem);
	if (error != SMR_ERROR_NONE)
	{
	 BSP_LCD_DisplayStringAt(10, 20, (uint8_t *)"--smr_setParam--", LEFT_MODE);
	 return (AUDIO_ERROR_SMR);
	}

	/* SMR dynamic parameters that can be updated here every frame if required */
	smr_dynamic_param.enable = 1; /* SMR module enabler */
	smr_dynamic_param.averaging_time = AUDIO_CFG_SMR_AVGTIME_DEFAULT;
	smr_dynamic_param.filter_type = SMR_PREFILTER_AWEIGHTING;

	error = smr_setConfig(&smr_dynamic_param, pSmrPersistentMem);
	if (error != SMR_ERROR_NONE)
	{
		BSP_LCD_DisplayStringAt(10, 20, (uint8_t *)"--smr_setConfig--", LEFT_MODE);
	 return (AUDIO_ERROR_SMR);
	}
	/* I/O buffers settings */
	BufferHandler.nb_bytes_per_Sample = 2;			/* 16-bit */
	BufferHandler.nb_channels = 2; 					/* stereo */
	BufferHandler.data_ptr = PCM_Data_SMR;
	BufferHandler.buffer_size = 32/2; 		/* just half buffer is process (size per channel) */
	BufferHandler.mode = INTERLEAVED;
}

void Audio_Process2()
{
	int32_t error = SMR_ERROR_NONE;

	uint16_t pbuf[100];

 error = smr_process(pBufferHandler, pBufferHandler, pSmrPersistentMem);
	if (error != SMR_ERROR_NONE)
 {
	 BSP_LCD_DisplayStringAt(10, 20, (uint8_t *)"--smr_process--", LEFT_MODE);
 return (AUDIO_ERROR_SMR);
 }

 error = smr_getConfig(&smr_dynamic_param, pSmrPersistentMem);
 if (error != SMR_ERROR_NONE)
 {
 	BSP_LCD_DisplayStringAt(10, 20, (uint8_t *)"--smr_getConfig--", LEFT_MODE);
 return AUDIO_ERROR_SMR;
 }
 sprintf((char *)str_pwr, "Left mean power: %ld dB",(int32_t)((float)smr_dynamic_param.mean_level_left*0.25));
 BSP_LCD_DisplayStringAt(CHAR(0), LINE(10), (uint8_t *)str_pwr, LEFT_MODE);
 sprintf((char *)str_pwr, "Right mean power: %ld dB",(int32_t)((float)smr_dynamic_param.mean_level_right*0.25));
 BSP_LCD_DisplayStringAt(CHAR(0), LINE(11), (uint8_t *)str_pwr, LEFT_MODE);
}
Andrew Neil
Super User
August 2, 2024

@aciuf wrote:

I would like to read the level of audio input signal


What "audio input signal"? On what board?

https://community.st.com/t5/community-guidelines/how-to-write-your-question-to-maximize-your-chances-to-find-a/ta-p/575228

 


@aciuf wrote:

but I read always 0dB on both channels.


Have you checked that there is actually any signal present at all?

Is the signal sufficient to read above 0 dB ?

 


@aciuf wrote:

This is my code 


So what testing / investigation / debugging have you done on your code to find what's wrong with it?

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
aciuf
aciufAuthor
Associate III
August 2, 2024

Using this last code the dB print without input signal start from 0dB and decrease

https://youtu.be/PohM2AMRxFI

aciuf
aciufAuthor
Associate III
August 2, 2024

In the main I call at the begin

AUDIO_PLAYER_Init2

and in a loop

Audio_Process2

 

 

 

aciuf
aciufAuthor
Associate III
August 3, 2024

New version

Now I see some correlation from input signal and dB print but still not correct

 

void *pSmrPersistentMem = NULL;
void *pSmrScratchMem = NULL;

static smr_static_param_t smr_static_param;
static smr_dynamic_param_t smr_dynamic_param;

static buffer_t BufferHandler;
static buffer_t *pBufferHandler = &BufferHandler;

static uint8_t str_pwr[100];

uint16_t PCM_Data_SMR[32]; 		/* PCM data buffer */



void AUDIO_PLAYER_Init2()
{
	int32_t error = SMR_ERROR_NONE;

	pSmrPersistentMem = malloc(smr_persistent_mem_size); /* smr_persistent_mem_size 0x188 */
	pSmrScratchMem = malloc(smr_scratch_mem_size); /* smr_scratch_mem_size 0xF04 */


	if (BSP_AUDIO_IN_Init(INPUT_DEVICE_INPUT_LINE_1, 100, AUDIO_FREQUENCY_48K) != 0)
	//if (BSP_AUDIO_IN_Init(INPUT_DEVICE_DIGITAL_MICROPHONE_2, 80, AUDIO_FREQUENCY_48K) != 0)
		LCD_LOG_SetHeader((uint8_t *)"Audio SMR Application KO");
	else
		LCD_LOG_SetHeader((uint8_t *)"Audio SMR Application OK");

	 __HAL_RCC_CRC_CLK_ENABLE();

	CRC->CR = CRC_CR_RESET;

	error = smr_reset(pSmrPersistentMem, pSmrScratchMem);
	if (error != SMR_ERROR_NONE)
	{
	 	BSP_LCD_DisplayStringAt(10, 20, (uint8_t *)"--smr_reset--", LEFT_MODE);
	 return (AUDIO_ERROR_SMR);
	}

	smr_static_param.sampling_rate = AUDIO_FREQUENCY_48K; /* only sampling rate supported */

	error = smr_setParam(&smr_static_param, pSmrPersistentMem);
	if (error != SMR_ERROR_NONE)
	{
	 BSP_LCD_DisplayStringAt(10, 20, (uint8_t *)"--smr_setParam--", LEFT_MODE);
	 return (AUDIO_ERROR_SMR);
	}

	/* SMR dynamic parameters that can be updated here every frame if required */
	smr_dynamic_param.enable = 1; /* SMR module enabler */
	smr_dynamic_param.averaging_time = 100; //AUDIO_CFG_SMR_AVGTIME_DEFAULT;
	smr_dynamic_param.filter_type = SMR_PREFILTER_AWEIGHTING;

	error = smr_setConfig(&smr_dynamic_param, pSmrPersistentMem);
	if (error != SMR_ERROR_NONE)
	{
		BSP_LCD_DisplayStringAt(10, 20, (uint8_t *)"--smr_setConfig--", LEFT_MODE);
	 return (AUDIO_ERROR_SMR);
	}
	/* I/O buffers settings */
	BufferHandler.nb_bytes_per_Sample = 2;			/* 16-bit */
	BufferHandler.nb_channels = 2; 					/* stereo */
	//BufferHandler.data_ptr = PCM_Data_SMR;
	BufferHandler.buffer_size = 32/2; 		/* just half buffer is process (size per channel) */
	BufferHandler.mode = INTERLEAVED;
}

void Audio_Process2()
{
	int32_t error = SMR_ERROR_NONE;

	BSP_AUDIO_IN_Record(&BufferCtl.buff[0], 32/2);

	BufferHandler.data_ptr = &BufferCtl.buff[0];

 error = smr_process(pBufferHandler, pBufferHandler, pSmrPersistentMem);
	if (error != SMR_ERROR_NONE)
 {
	 BSP_LCD_DisplayStringAt(10, 20, (uint8_t *)"--smr_process--", LEFT_MODE);
 return (AUDIO_ERROR_SMR);
 }

 error = smr_getConfig(&smr_dynamic_param, pSmrPersistentMem);
 if (error != SMR_ERROR_NONE)
 {
 	BSP_LCD_DisplayStringAt(10, 20, (uint8_t *)"--smr_getConfig--", LEFT_MODE);
 return AUDIO_ERROR_SMR;
 }
 sprintf((char *)str_pwr, "Left mean power: %ld dB",(int32_t)((float)smr_dynamic_param.mean_level_left*0.25));
 BSP_LCD_DisplayStringAt(10, 100, (uint8_t *)str_pwr, LEFT_MODE);
 sprintf((char *)str_pwr, "Right mean power: %ld dB",(int32_t)((float)smr_dynamic_param.mean_level_right*0.25));
 BSP_LCD_DisplayStringAt(10, 120, (uint8_t *)str_pwr, LEFT_MODE);
}

 

Andrew Neil
Super User
August 3, 2024

@aciuf wrote:

Now I see some correlation from input signal and dB print but still not correct


Again, what exactly does that mean??

Give some specific numbers!

Show the signal that you're applying. Show the results that you're getting. Explain why you think the results are "not correct".

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
aciuf
aciufAuthor
Associate III
August 3, 2024

So, ...

no signal -31dB

1.3Vrms  ->  -2dB

0.4Vrms -> -2dB

0.144Vrms -> -2dB

5mVrms -> -5dB

 

 

 

aciuf
aciufAuthor
Associate III
August 3, 2024

The problem could be on the evaluation board because the line input is a mic input, so probably I saturate the input with my signal.

I will check tomorrow if this is true.

 

aciuf_0-1722705199228.png

aciuf_1-1722705231327.png

 

aciuf
aciufAuthor
Associate III
August 4, 2024

I have modified the source WM8994.c to exclude the +30dB gain on input

Now the my signal does not saturate the input but still strange output:

input
   0dB  1.349Vrms   ->   on lcd read  -1dB
 -3dB   0.97Vrms    ->   on lcd read   -7dB
-10dB   0.43Vrms    ->   on lcd read -35dB

disconnected signal on lcd read -96dB

Do I have to apply a conversion to the smr_dynamic_param value ? because in the example there is a * 0.25.

 

 case INPUT_DEVICE_INPUT_LINE_1 :
 	BSP_LCD_DisplayStringAt(10, 80, (uint8_t *)"--INPUT_DEVICE_INPUT_LINE_1--", 0);

 /* IN1LN_TO_IN1L, IN1LP_TO_VMID, IN1RN_TO_IN1R, IN1RP_TO_VMID */
 // 0x0011 = 00010001
 // | +- IN1RN_TO_IN1R
 // +-- IN1LN_TO_IN1L
 counter += CODEC_IO_Write(DeviceAddr, 0x28, 0x0011);

 /* Disable mute on IN1L_TO_MIXINL and +30dB on IN1L PGA output */
 //counter += CODEC_IO_Write(DeviceAddr, 0x29, 0x0035);
 // 0x0035 = 00110101
 // |||
 // +++ 0dB
 // + +30dB
 // + unmute IN1L
 // 0x0025 = 001000101
 // |||
 // +++ 0dB
 // +-- 0dB
 // +--- unmute IN1L
 counter += CODEC_IO_Write(DeviceAddr, 0x29, 0x0025);

 /* Disable mute on IN1R_TO_MIXINL, Gain = +30dB */
 counter += CODEC_IO_Write(DeviceAddr, 0x2A, 0x0025);

 

 

 

 

 

 

aciuf
aciufAuthor
Associate III
August 5, 2024

If I multiply by 0.25

sprintf((char *)str_pwr, "Left mean power: %ld dB",(int32_t)((float)smr_dynamic_param.mean_level_left*0.25));

I can read after power on -87dB but after applying any signal and stopping it never goes back to -87 and stops at -24 as if the read buffer remains dirty.

Last version here:

 

#define AUDIO_OUT_BUFFER_SIZE 3840 /* 480 * 2 (half + half) * 2 (stereo) * 2 (bytes x sample) */
//#define AUDIO_OUT_BUFFER_SIZE (24 * 1024)
//#define AUDIO_IN_BUFFER_SIZE (10 * 2304) /* buffer size in half-word */


void AUDIO_PLAYER_Init2()
{
	int32_t error = SMR_ERROR_NONE;

	pSmrPersistentMem = malloc(smr_persistent_mem_size); /* smr_persistent_mem_size 0x188 */
	pSmrScratchMem = malloc(smr_scratch_mem_size); /* smr_scratch_mem_size 0xF04 */


	if (BSP_AUDIO_IN_Init(INPUT_DEVICE_INPUT_LINE_1, 80, AUDIO_FREQUENCY_48K) != 0)
		LCD_LOG_SetHeader((uint8_t *)"Audio SMR Application KO");
	else
		LCD_LOG_SetHeader((uint8_t *)"Audio SMR Application OK");

	 __HAL_RCC_CRC_CLK_ENABLE();

	CRC->CR = CRC_CR_RESET;

	error = smr_reset(pSmrPersistentMem, pSmrScratchMem);
	if (error != SMR_ERROR_NONE)
	{
	 	BSP_LCD_DisplayStringAt(10, 20, (uint8_t *)"--smr_reset--", LEFT_MODE);
	 return (AUDIO_ERROR_SMR);
	}

	smr_static_param.sampling_rate = AUDIO_FREQUENCY_48K; /* only sampling rate supported */

	error = smr_setParam(&smr_static_param, pSmrPersistentMem);
	if (error != SMR_ERROR_NONE)
	{
	 BSP_LCD_DisplayStringAt(10, 20, (uint8_t *)"--smr_setParam--", LEFT_MODE);
	 return (AUDIO_ERROR_SMR);
	}

	smr_dynamic_param.enable = 1; /* SMR module enabler */
	smr_dynamic_param.averaging_time = AUDIO_CFG_SMR_AVGTIME_DEFAULT;
	smr_dynamic_param.filter_type = SMR_PREFILTER_AWEIGHTING ; // SMR_PREFILTER_NONE;

	error = smr_setConfig(&smr_dynamic_param, pSmrPersistentMem);
	if (error != SMR_ERROR_NONE)
	{
		BSP_LCD_DisplayStringAt(10, 20, (uint8_t *)"--smr_setConfig--", LEFT_MODE);
	 return (AUDIO_ERROR_SMR);
	}
	BufferHandler.nb_bytes_per_Sample = 2;			/* 16-bit */
	BufferHandler.nb_channels = 2; 					/* stereo */
	//BufferHandler.data_ptr = PCM_Data_SMR;
	//BufferHandler.buffer_size = 32/2; 		/* just half buffer is process (size per channel) */
	BufferHandler.buffer_size = AUDIO_OUT_BUFFER_SIZE/(2*4);
	BufferHandler.mode = INTERLEAVED;

	BufferCtl.state = BUFFER_OFFSET_NONE;

	error = BSP_AUDIO_IN_Record(&BufferCtl.buff[0], AUDIO_OUT_BUFFER_SIZE/2);
	if (error > 0)
	{
		 BSP_LCD_DisplayStringAt(10, 20, (uint8_t *)"--BSP_AUDIO_IN_Record-", LEFT_MODE);
	 return (AUDIO_ERROR_SMR);
	}
}

void Audio_Process2()
{
	int32_t error = SMR_ERROR_NONE;

	if (BufferCtl.state == BUFFER_OFFSET_HALF)
	{
		BufferHandler.data_ptr = &BufferCtl.buff[0];

		error = smr_process(pBufferHandler, pBufferHandler, pSmrPersistentMem);
		if (error != SMR_ERROR_NONE)
		{
			BSP_LCD_DisplayStringAt(10, 20, (uint8_t *)"--smr_process--", LEFT_MODE);
			return (AUDIO_ERROR_SMR);
		}
	 error = smr_getConfig(&smr_dynamic_param, pSmrPersistentMem);
	 if (error != SMR_ERROR_NONE)
	 {
	 	BSP_LCD_DisplayStringAt(10, 20, (uint8_t *)"--smr_getConfig--", LEFT_MODE);
	 return AUDIO_ERROR_SMR;
	 }
	 sprintf((char *)str_pwr, "Left mean power: %ld dB",(int32_t)((float)smr_dynamic_param.mean_level_left*0.25));
	 BSP_LCD_DisplayStringAt(10, 100, (uint8_t *)str_pwr, LEFT_MODE);
	 sprintf((char *)str_pwr, "Right mean power: %ld dB",(int32_t)((float)smr_dynamic_param.mean_level_right*0.25));
	 BSP_LCD_DisplayStringAt(10, 120, (uint8_t *)str_pwr, LEFT_MODE);


	 BufferCtl.state = BUFFER_OFFSET_NONE;
	}
	else if (BufferCtl.state == BUFFER_OFFSET_FULL)
	{
		BufferHandler.data_ptr = &BufferCtl.buff[AUDIO_OUT_BUFFER_SIZE /2];

		error = smr_process(pBufferHandler, pBufferHandler, pSmrPersistentMem);
		if (error != SMR_ERROR_NONE)
		{
			BSP_LCD_DisplayStringAt(10, 20, (uint8_t *)"--smr_process--", LEFT_MODE);
			return (AUDIO_ERROR_SMR);
		}
		error = smr_getConfig(&smr_dynamic_param, pSmrPersistentMem);
		if (error != SMR_ERROR_NONE)
		{
			BSP_LCD_DisplayStringAt(10, 20, (uint8_t *)"--smr_getConfig--", LEFT_MODE);
			return AUDIO_ERROR_SMR;
		}
		sprintf((char *)str_pwr, "Left mean power: %ld dB",(int32_t)((float)smr_dynamic_param.mean_level_left*0.25));
		BSP_LCD_DisplayStringAt(10, 100, (uint8_t *)str_pwr, LEFT_MODE);
		sprintf((char *)str_pwr, "Right mean power: %ld dB",(int32_t)((float)smr_dynamic_param.mean_level_right*0.25));
		BSP_LCD_DisplayStringAt(10, 120, (uint8_t *)str_pwr, LEFT_MODE);

		BufferCtl.state = BUFFER_OFFSET_NONE;
	}
	else
	{

	}
}

void BSP_AUDIO_IN_TransferComplete_CallBack(void)
{
	BufferCtl.state = BUFFER_OFFSET_FULL;
}

void BSP_AUDIO_IN_HalfTransfer_CallBack(void)
{
	BufferCtl.state = BUFFER_OFFSET_HALF;
}