espressif / esp-adf

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

Codec Device Test application does not build (AUD-5198) #1145

Open crosswick opened 8 months ago

crosswick commented 8 months ago

Environment

Problem Description

application in folder https://github.com/espressif/esp-adf/tree/master/components/esp_codec_dev/test does not build, gives CMake errors, see below. please advise what the suggested method is for building this application.

@TempoTian

Executing action: all (aliases: build)
Running cmake in directory /Users/steven/.espressif/esp-adf/components/esp_codec_dev/test/build
Executing "cmake -G Ninja -DPYTHON_DEPS_CHECKED=1 -DPYTHON=/Users/steven/.espressif/python_env/idf5.3_py3.11_env/bin/python -DESP_PLATFORM=1 -DCCACHE_ENABLE=0 /Users/steven/.espressif/esp-adf/components/esp_codec_dev/test"...
CMake Warning (dev) in CMakeLists.txt:
  No project() command is present.  The top-level CMakeLists.txt file must
  contain a literal, direct call to the project() command.  Add a line of
  code such as

    project(ProjectName)

  near the top of the file, but after cmake_minimum_required().

  CMake is pretending there is a "project(Project)" command on the first
  line.
This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Warning (dev) in CMakeLists.txt:
  cmake_minimum_required() should be called prior to this top-level project()
  call.  Please see the cmake-commands(7) manual for usage documentation of
  both commands.
This warning is for project developers.  Use -Wno-dev to suppress it.

-- The C compiler identification is AppleClang 14.0.0.14000029
-- The CXX compiler identification is AppleClang 14.0.0.14000029
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Error at CMakeLists.txt:1 (idf_component_register):
  Unknown CMake command "idf_component_register".

CMake Warning (dev) in CMakeLists.txt:
  No cmake_minimum_required command is present.  A line of code such as

    cmake_minimum_required(VERSION 3.28)

  should be added at the top of the file.  The version specified may be lower
  if you wish to support older CMake versions for this project.  For more
  information run "cmake --help-policy CMP0000".
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Configuring incomplete, errors occurred!
cmake failed with exit code 1, output of the command is in the /Users/steven/.espressif/esp-adf/components/esp_codec_dev/test/build/log/idf_py_stderr_output_29116 and /Users/steven/.espressif/esp-adf/components/esp_codec_dev/test/build/log/idf_py_stdout_output_29116
TempoTian commented 8 months ago

esp_codec_dev test code is buit on old IDF, which means it must build from unit_test_app folder.
Steps like following

1.  cd $IDF_PATH/tools/unit-test_app
2. Modify CMakeLists.txt and add esp_codec_dev module path into it
   list(APPEND EXTRA_COMPONENT_DIRS "your_adf_path/esp-adf-internal/components/esp_codec_dev")
3. Build, Flash then test it
crosswick commented 8 months ago

Thank you, it builds after changing the path into "your_adf_path/components/esp_codec_dev"

While monitoring, I get a prompt saying Here's the test menu, pick your combo: but it doesn't show anything.

How do I run the codec tests, please?

crosswick commented 8 months ago

Does the unit test app perhaps need more modification? When building it, it does not seem to add the esp_codec_dev component at all.

TempoTian commented 8 months ago

If you are using IDF5.x or higher you need modify the CMakeLists.txt as

idf_component_register(SRC_DIRS .
                       PRIV_INCLUDE_DIRS .
                       PRIV_REQUIRES unity esp_codec_dev
                       WHOLE_ARCHIVE
                       )
crosswick commented 7 months ago

When I add those lines to the top-level CMakeLists.txt (in the unit-test-app folder), I get these errors:

CMake Error at /Users/steven/esp/esp-idf/tools/cmake/component.cmake:439 (message): Called idf_component_register from a non-component directory. Call Stack (most recent call first): CMakeLists.txt:11 (idf_component_register)

Do you perhaps mean a different CMakeLists.txt? And should I add any other files or folders from esp_codec_dev/test manually?

Really what I'm trying to accomplish is a simple audio passthru example using an ESP32S3_KORVO2_V3, or a LILYGO T7-S3 and a separate ES8388 prototyping board.

Preferably with a buffer modification function like this third-party implementation: https://github.com/Jeija/esp32-lyrat-passthrough/tree/master - that uses a very old version of IDF though.

This test app seemed like a good first step for this.

TempoTian commented 7 months ago

Yes, the modified CMakeLists.txt is for esp_codec_dev/test folder, when build with unit_test_app makesure you are building use command like idf.py -T esp_codec_dev -p /dev/ttyUSB* flash monitor

For es8388 passthrough support you can use following test code and put int into test_board.c to test it.

TEST_CASE("Test for ES88 Passthrough", "[esp_codec_dev]")
{
    // Need install driver (i2c and i2s) firstly
    int ret = ut_i2c_init(0);
    TEST_ESP_OK(ret);
    ret = ut_i2s_init(0);
    TEST_ESP_OK(ret);
    // Do initialize of related interface: data_if, ctrl_if and gpio_if
    audio_codec_i2s_cfg_t i2s_cfg = {
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
        .rx_handle = i2s_keep[0]->rx_handle,
        .tx_handle = i2s_keep[0]->tx_handle,
#endif
    };
    const audio_codec_data_if_t *data_if = audio_codec_new_i2s_data(&i2s_cfg);
    TEST_ASSERT_NOT_NULL(data_if);
    // Change to your actual address
    audio_codec_i2c_cfg_t i2c_cfg = {.addr = ES8388_CODEC_DEFAULT_ADDR};
    const audio_codec_ctrl_if_t *ctrl_if = audio_codec_new_i2c_ctrl(&i2c_cfg);
    TEST_ASSERT_NOT_NULL(ctrl_if);

    const audio_codec_gpio_if_t *gpio_if = audio_codec_new_gpio();
    TEST_ASSERT_NOT_NULL(gpio_if);
    // New output codec interface
    es8388_codec_cfg_t es8388_cfg = {
        .codec_mode = ESP_CODEC_DEV_WORK_MODE_BOTH,
        .ctrl_if = ctrl_if,
        .gpio_if = gpio_if,
        .pa_pin = TEST_BOARD_PA_PIN,
    };
    const audio_codec_if_t *codec_if = es8388_codec_new(&es8388_cfg);
    TEST_ASSERT_NOT_NULL(codec_if);

    // New output codec device
    esp_codec_dev_cfg_t dev_cfg = {
        .codec_if = codec_if,
        .data_if = data_if,
        .dev_type = ESP_CODEC_DEV_TYPE_IN_OUT,
    };
    esp_codec_dev_handle_t codec_dev = esp_codec_dev_new(&dev_cfg);
    TEST_ASSERT_NOT_NULL(codec_dev);

    ret = esp_codec_dev_set_out_vol(codec_dev, 60.0);
    TEST_ESP_OK(ret);
    ret = esp_codec_dev_set_in_gain(codec_dev, 30.0);
    TEST_ESP_OK(ret);

    esp_codec_dev_sample_info_t fs = {
        .sample_rate = 48000,
        .channel = 2,
        .bits_per_sample = 16,
    };
    ret = esp_codec_dev_open(codec_dev, &fs);
    TEST_ESP_OK(ret);

    ret = esp_codec_dev_open(codec_dev, &fs);
    TEST_ESP_OK(ret);
    uint8_t *data = (uint8_t *) malloc(512);
    int limit_size = 10 * fs.sample_rate * fs.channel * (fs.bits_per_sample >> 3);
    int got_size = 0;
    int max_sample = 0;
    // Playback the recording content directly
    while (got_size < limit_size) {
        ret = esp_codec_dev_read(codec_dev, data, 512);
        TEST_ESP_OK(ret);
        ret = esp_codec_dev_write(codec_dev, data, 512);
        TEST_ESP_OK(ret);
        int max_value = codec_max_sample(data, 512);
        if (max_value > max_sample) {
            max_sample = max_value;
        }
        got_size += 512;
    }
    // Verify recording data not zero
    TEST_ASSERT(max_sample > 0);
    free(data);
    ret = esp_codec_dev_close(codec_dev);
    TEST_ESP_OK(ret);
    esp_codec_dev_delete(codec_dev);

    // Delete codec interface
    audio_codec_delete_codec_if(codec_if);
    // Delete codec control interface
    audio_codec_delete_ctrl_if(ctrl_if);
    audio_codec_delete_gpio_if(gpio_if);
    // Delete codec data interface
    audio_codec_delete_data_if(data_if);

    ut_i2c_deinit(0);
    ut_i2s_deinit(0);
}
crosswick commented 7 months ago

Thank you - I am still running into issues with the existing unit-test-app though.

After applying the CMakeLists.txt modification in the esp_codec_dev/test folder, running the idf.py -T esp_codec_dev -p /dev/cu.usbserial-FD140 flash monitor command and selecting test 1, I get this:

Enter test for running.
1
Running esp codec dev test using S3 board...
I (12365) ES8311: Work in Slave mode
I (12369) gpio: GPIO[48]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
I (12372) ES7210: Work in Slave mode
I (12380) ES7210: Enable ES7210_INPUT_MIC1
I (12383) ES7210: Enable ES7210_INPUT_MIC2
I (12387) ES7210: Enable ES7210_INPUT_MIC3
I (12391) ES7210: Enable TDM mode
I (12398) I2S_IF: channel mode 0 bits:16/16 channel:2 mask:3
I (12398) I2S_IF: STD Mode 1 bits:16/16 channel:2 sample_rate:48000 mask:3
E (12410) I2C_If: Fail to read from dev 30
I (12423) Adev_Codec: Open codec device OK
E (12423) i2s_common: i2s_channel_disable(1030): the channel has not been enabled yet
I (12425) I2S_IF: channel mode 0 bits:16/16 channel:2 mask:3
I (12432) I2S_IF: STD Mode 0 bits:16/16 channel:2 sample_rate:48000 mask:3
I (12440) ES7210: Bits 8
I (12450) ES7210: Enable ES7210_INPUT_MIC1
I (12454) ES7210: Enable ES7210_INPUT_MIC2
I (12457) ES7210: Enable ES7210_INPUT_MIC3
I (12461) ES7210: Enable TDM mode
I (12467) ES7210: Unmuted
I (12467) Adev_Codec: Open codec device OK
I (22445) I2S_IF: Pending out channel for in channel running
E (22456) i2s_common: i2s_channel_disable(1030): the channel has not been enabled yet
E (22456) i2s_common: i2s_channel_disable(1030): the channel has not been enabled yet
MALLOC_CAP_8BIT usage: Free memory delta: -172 Leak threshold: -1024 
MALLOC_CAP_32BIT usage: Free memory delta: -172 Leak threshold: -1024 
/Users/steven/.espressif/esp-adf/components/esp_codec_dev/test/test_board.c:187:esp codec dev test using S3 board:PASS
Test ran in 10143ms

-----------------------
1 Tests 0 Failures 0 Ignored 
OK

with no sound coming from the speaker connected to the ESP32S3_KORVO2_V3 and these lines in red:

E (12410) I2C_If: Fail to read from dev 30
E (12423) i2s_common: i2s_channel_disable(1030): the channel has not been enabled yet
E (22456) i2s_common: i2s_channel_disable(1030): the channel has not been enabled yet
E (22456) i2s_common: i2s_channel_disable(1030): the channel has not been enabled yet

so it is unclear to me why this test is a PASS.

the first of these errors (dev 30) sometimes does not show.

perhaps there is an issue with my ESP32S3_KORVO2_V3 board being hardware version V3.1?

crosswick commented 7 months ago

In the meantime I've also tried to get your ES8388 passthrough code to work on my Lilygo T7 S3; unfortunately the unit-test-app will not work on it, with or without that extra code. It does show Press ENTER to see the list of tests. on the monitor, but then does not respond to ENTER, or any other keyboard input.

I have tried on two separate T7 S3 boards that both run the blink and helloworld examples fine.

TempoTian commented 7 months ago

If the unit test app is not built with esp_codec_dev, perhaps you forget to add esp_codec_dev into EXTRA_COMPONENT_DIRS. Or you can manually call test code in app_main function directly without run the unit test codes using console.

Also you need check the ES8388 board pin configuration, it will have different I2C address if codec CE pin keep low or high.

#define ES8388_CODEC_DEFAULT_ADDR   (0x20)
#define ES8388_CODEC_DEFAULT_ADDR_1 (0x22)
crosswick commented 7 months ago

I have reinstalled ESP-IDF 5.1.2 and ESP-ADF Master.

I have modified /Users/steven/esp/esp-idf/tools/unit-test-app/CMakeLists.txt into:

# The following lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)

list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/components/driver/test_apps/components")
list(APPEND EXTRA_COMPONENT_DIRS "/Users/steven/esp/esp-adf/components/esp_codec_dev")

include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(unit-test-app)

I have modified /Users/steven/esp/esp-adf/components/esp_codec_dev/test/CMakeLists.txt into:

idf_component_register(SRC_DIRS .
                       PRIV_INCLUDE_DIRS .
                       PRIV_REQUIRES unity esp_codec_dev
                       WHOLE_ARCHIVE
                       )

I have run idf.py set-target esp32s3
and idf.py -T esp_codec_dev -p /dev/cu.usbserial-FD140 flash monitor in /Users/steven/esp/esp-idf/tools/unit-test-app

it still gives me the same errors, with the ESP32S3_KORVO2_V3 board attached and selecting test 1:

E (6835) I2C_If: Fail to write to dev 30
E (6838) I2C_If: Fail to write to dev 30
E (6849) i2s_common: i2s_channel_disable(1030): the channel has not been enabled yet
E (16886) i2s_common: i2s_channel_disable(1030): the channel has not been enabled yet
E (16887) i2s_common: i2s_channel_disable(1030): the channel has not been enabled yet

Question: there is no esp-adf-internal folder in my adf path, should there be? You specified that earlier. And again, please: my specific board has the marking "ESP32-S3-Korvo-2 V3.1", perhaps the device number differs between V3 and V3.1?