espressif / esp-adf

Espressif Audio Development Framework
Other
1.54k stars 676 forks source link

How to disable or enable right or left microphone? (AUD-2445) #490

Closed utkutpcgl closed 3 years ago

utkutpcgl commented 3 years ago

For a long time, I have been trying to disable the left microphone and using only the right microphone with i2s_stream (reader). Yet, I have been unsuccessful, I tried to modify many registers with es8388_write_reg() method. I might not be able to find the appropriate one. Also, it was not clear for me where to put es8388_write_reg(). Is it sufficient to put s8388_write_reg() before starting the codec, after starting the pipeline or after initializing the codec?

So how can I disable left microphone while leaving the right microphone active? It is also okey if I manage to disable LIN1 (left mic in) signal be directed to speaker outputs (or other outputs). I would be nice if you could show me the correct registers to modify and where to put it in my code.

I use Lyrat, idf-4.1 and adf-latest versions.
Thanks in advance.

Sugggestion: It would be great if there were specific functions that have detailed explanations in the documentation included in esp-adf for es8388. I had to try out many register control values without success.

utkutpcgl commented 3 years ago

More precisely, I want one microphone's input to go to one speaker and the other microphone's input to the other speaker. I noticed that it can be done by modifying the buffers carrying the i2s data, however, it adds delay to the code, and rb_write(ringbuf_speaker, buf, send_to_speaker_bytes, 0) adds enormous delay sometimes ( 10 - 60 ms delay). If we consider I modify the i2s buffers once every 15 ms, the delay that is added by rb_writeis unacceptable.

Should I use audio_element_input and audio_element_output functions to modify i2s audio elements data directly instead of modifying the output ringbuffer of i2s_read and input ringbuffer of i2s_write.

Easily stated, I want to control two microphones and speakers separately. Thanks in advance.

HengYongChao commented 3 years ago

@utkutpcgl Check from es8388 datasheet, Reg-03 can be turned off either L or R. Reg-03 can be configured with 0x50 or 0xA0 just to turn it off. Try it please.

utkutpcgl commented 3 years ago

Thanks, I will share the results later.

utkutpcgl commented 3 years ago

Changing register 3 to 0x50 (This turns right ADC and right analog input off) has no impact, I guess that only LIN and Left ADC are fed to speakers. When I set register 3 to 0xA0 (This turns left ADC and left analog input off) then there is no sound neither at left speaker nor right speaker. Maybe, mixL and mixR both use LIN and DACL as input, but not RIN and DACR.

Both, left and right microphone use one ADC (left by default) and I can not turn off one microphone without affecting the other one. I have tried many registers and read the ES8388 datasheet and searched the internet. Some important ones are 29 and 11. I assured that the input type was stereo and connected right data to right ADC and left data to left ADC. Then when I disable left ADC there is no sound at neither left speaker nor right speaker.

I also checked the i2s data to reassure that the microphones are connected to one ADC. I have seen that turning left ADC down resulted in all zero i2s data ( left and right). This means that in my current configuration I can not utilize two ADCs for i2s_reader.

I have 240 Mhz cpu and my i2s configuration is the following:

audio_hal_codec_i2s_iface_t codec_i2s_iface ={
    .mode = AUDIO_HAL_MODE_MASTER, //AUDIO_HAL_MODE_SLAVE ,AUDIO_HAL_MODE_MASTER
    .fmt = AUDIO_HAL_I2S_NORMAL, //AUDIO_HAL_I2S_RIGHT   AUDIO_HAL_I2S_NORMAL
    .samples = AUDIO_HAL_16K_SAMPLES , // AUDIO_HAL_16K_SAMPLES AUDIO_HAL_08K_SAMPLES
    .bits = AUDIO_HAL_BIT_LENGTH_16BITS,
};

`printf("2 \n");
audio_hal_codec_config_t codec_config = {
    .adc_input =AUDIO_HAL_ADC_INPUT_ALL, //  AUDIO_HAL_ADC_INPUT_ALL , (AUDIO_HAL_ADC_INPUT_LINE2 (for aux in),AUDIO_HAL_ADC_INPUT_LINE1 (FOR microphones))
    .dac_output=AUDIO_HAL_DAC_OUTPUT_ALL, //AUDIO_HAL_DAC_OUTPUT_LINE1 ,AUDIO_HAL_DAC_OUTPUT_LINE2, AUDIO_HAL_DAC_OUTPUT_ALL
    .codec_mode=AUDIO_HAL_CODEC_MODE_BOTH, // what is this AUDIO_HAL_CODEC_MODE_LINE_IN
    .i2s_iface= codec_i2s_iface, // TODO might there be an error here. DONE: no!
};`

My codec configuration is: audio_hal_init(&codec_config, board_handle->audio_hal);

audio_hal_ctrl_codec(board_handle->audio_hal, AUDIO_HAL_CODEC_MODE_BOTH, AUDIO_HAL_CTRL_START);

Please help me out. Thanks in advance.

By the way, I have noticed that there is very little sound going to the right speaker from the right microphone. It should be fixed, I mentioned it in another issue also.

HengYongChao commented 3 years ago

Changing register 3 to 0x50 (This turns right ADC and right analog input off) has no impact, I guess that only LIN and Left ADC are fed to speakers. When I set register 3 to 0xA0 (This turns left ADC and left analog input off) then there is no sound neither at left speaker nor right speaker. Maybe, mixL and mixR both use LIN and DACL as input, but not RIN and DACR.

Both, left and right microphone use one ADC (left by default) and I can not turn off one microphone without affecting the other one. I have tried many registers and read the ES8388 datasheet and searched the internet. Some important ones are 29 and 11. I assured that the input type was stereo and connected right data to right ADC and left data to left ADC. Then when I disable left ADC there is no sound at neither left speaker nor right speaker.

I also checked the i2s data to reassure that the microphones are connected to one ADC. I have seen that turning left ADC down resulted in all zero i2s data ( left and right). This means that in my current configuration I can not utilize two ADCs for i2s_reader.

I have 240 Mhz cpu and my i2s configuration is the following:

audio_hal_codec_i2s_iface_t codec_i2s_iface ={
    .mode = AUDIO_HAL_MODE_MASTER, //AUDIO_HAL_MODE_SLAVE ,AUDIO_HAL_MODE_MASTER
    .fmt = AUDIO_HAL_I2S_NORMAL, //AUDIO_HAL_I2S_RIGHT   AUDIO_HAL_I2S_NORMAL
    .samples = AUDIO_HAL_16K_SAMPLES , // AUDIO_HAL_16K_SAMPLES AUDIO_HAL_08K_SAMPLES
    .bits = AUDIO_HAL_BIT_LENGTH_16BITS,
};

`printf("2 \n");
audio_hal_codec_config_t codec_config = {
    .adc_input =AUDIO_HAL_ADC_INPUT_ALL, //  AUDIO_HAL_ADC_INPUT_ALL , (AUDIO_HAL_ADC_INPUT_LINE2 (for aux in),AUDIO_HAL_ADC_INPUT_LINE1 (FOR microphones))
    .dac_output=AUDIO_HAL_DAC_OUTPUT_ALL, //AUDIO_HAL_DAC_OUTPUT_LINE1 ,AUDIO_HAL_DAC_OUTPUT_LINE2, AUDIO_HAL_DAC_OUTPUT_ALL
    .codec_mode=AUDIO_HAL_CODEC_MODE_BOTH, // what is this AUDIO_HAL_CODEC_MODE_LINE_IN
    .i2s_iface= codec_i2s_iface, // TODO might there be an error here. DONE: no!
};`

My codec configuration is: audio_hal_init(&codec_config, board_handle->audio_hal);

audio_hal_ctrl_codec(board_handle->audio_hal, AUDIO_HAL_CODEC_MODE_BOTH, AUDIO_HAL_CTRL_START);

Please help me out. Thanks in advance.

By the way, I have noticed that there is very little sound going to the right speaker from the right microphone. It should be fixed, I mentioned it in another issue also.

Hi @utkutpcgl Sorry for the late reply.

I notice that you configure the ADC input as AUDIO_HAL_ADC_INPUT_ALL, the source es8388.c(https://github.com/espressif/esp-adf/blob/master/components/audio_hal/driver/es8388/es8388.c#L288) shows only two cases of input are supported.

    tmp = 0;
    if (AUDIO_HAL_ADC_INPUT_LINE1 == cfg->adc_input) {
         tmp = ADC_INPUT_LINPUT1_RINPUT1;
    } else if (AUDIO_HAL_ADC_INPUT_LINE2 == cfg->adc_input) {
         tmp = ADC_INPUT_LINPUT2_RINPUT2;
    } else {
         tmp = ADC_INPUT_DIFFERENCE;
    }
    res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL2, tmp); 

You can see Lyrat v4.3 's schematic diagram, there are two MICs connected to codec es8388, currently we only use one channel of MIC(J9 MIC near AUX_IN is linked to CODEC 8388 LIN1) in some applications.

The source code(https://github.com/espressif/esp-adf/blob/master/components/audio_board/lyrat_v4_3/board_def.h#L49) default config codec 8388 adc input as AUDIO_HAL_ADC_INPUT_LINE1. This is say the board will ONLY use ONE MIC(J9) to record sound.

The datasheet of es8388 says register10 controls the adc input selection. I'm sorry that ADF does not provide an API for selecting MIC input. Currently, you need to configure this register10 to select MIC input.

Feel free to ask if any problem in adf.