cancel
Showing results for 
Search instead for 
Did you mean: 

i2s PCM volume adjustment problem

TMich.1
Associate III

I figured to increase the volume of the pcm data i just multiply it, because it is pretty much a sine wave sampled? I use this to increase the volume of the audio from the microphone connected to i2s and it works great. I do this when the audio is still 24 bit( 32bit frame) and later convert it to 16 bit as this is the required format for my android application. But when i receive 16 bit audio send from the android app to the stm32 and i multiply the 16 bit value by any number, there is a huge amount of noise. any idea why? (microphone uses i2s and dac uses sai in i2s mode) (and i convert the stereo to mono in my microphone function).

if(uart_to_audio_rd_ptr != uart_to_audio_wr_ptr){
		for(int i =0; i < buffer_size/2; i+=2){
			int16_t little_endian_value = ((int16_t)uart_to_audio_buffer[uart_to_audio_rd_ptr+i+1] << 8) | (int16_t)uart_to_audio_buffer[uart_to_audio_rd_ptr+i];
			int16_t big_endian = (int16_t)__REV16(little_endian_value);
			int32_t out = big_endian*1;
			if(out>32767) out = 32767;
			else if(out<-32768) out = -32768;
			int16_t out2 = out & 0xFFFF;
			audio_out[i] =(out2>> 8) & 0xFF;
			audio_out[i+1] = out2 & 0xFF;
		}
		uart_to_audio_rd_ptr += buffer_size/2;
		if(uart_to_audio_rd_ptr >= main_buffer_size) uart_to_audio_rd_ptr = 0;
	}
}

void HAL_I2S_RxHalfCpltCallback (I2S_HandleTypeDef *hi2s){
	for (uint16_t i = 0; i < buffer_size/4; i++) {
		int lSample = (int) (audio_in[4*i+2]<<16)|audio_in[4*i+2+1];
		lSample = lSample*10;
		if(lSample>2147418112)
		{
			lSample = 2147418112;
		}
		else if(lSample<-2147483648)
		{
			lSample = -2147483648;
		}
		int16_t top16 = (lSample >> 16) & 0xFFFF;
		int16_t little_endian_value = (int16_t)__REV16(top16);
		audio_to_uart_buffer[audio_to_uart_wr_ptr + 2*i] = (little_endian_value >> 8) & 0xFF;
		audio_to_uart_buffer[audio_to_uart_wr_ptr + 2*i+1] = little_endian_value & 0xFF;
		top16 = 0;
	}
 
	audio_to_uart_wr_ptr += buffer_size/2;
	if(audio_to_uart_wr_ptr >= main_buffer_size){
		audio_to_uart_wr_ptr = 0;
	}
	if(audio_to_uart_data_behind<20) audio_to_uart_data_behind++;
	if(uart_tx_state == 0){
		send_audio();
	}
}

5 REPLIES 5
AScha.3
Chief III

how you send/get data from mobile ? usb-> CDC device?

is there a way to "sync" to the data? (like word-clk in I2S)

+

noise in received 16b : if no "volume" multiplication, just as coming in, is there noise also?

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

Via uart, with dma as well. There is zero noise with no multiplication ​

AScha.3
Chief III

so obviously something around your "volume" multiplication is wrong.

pointer -cast , shift, endianess , swap hi / lo byte ... whatever.

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

and ??

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

I tried changing the byte swap but nothing fixed it. I left it alone got now. It works good enough and I do not have much time. Thank you for your help.