Git Product home page Git Product logo

Comments (4)

jason-mao avatar jason-mao commented on August 28, 2024

@payday1991 Thanks for your report. Let's check and reply.

from esp-adf.

jason-mao avatar jason-mao commented on August 28, 2024

It's fixed on b3add92

from esp-adf.

majingjing123 avatar majingjing123 commented on August 28, 2024

Hi, this issue is already fixed. If you only need mix, you can use example audio_mixer_tone.
If you must use audio forege, for your needs, you can use this test code
`
/* Multiple pipeline playback with audio processing.

This example code is in the Public Domain (or CC0 licensed, at your option.)

Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/

#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_log.h"
#include "audio_element.h"
#include "audio_pipeline.h"
#include "audio_event_iface.h"
#include "i2s_stream.h"
#include "mp3_decoder.h"
#include "fatfs_stream.h"
#include "audio_forge.h"
#include "raw_stream.h"
#include "board.h"
#include "periph_button.h"

static const char *TAG = "AUDIO_FORGE_PIPELINE";

#define DEFAULT_SAMPLERATE 44100
#define DEFAULT_CHANNEL 2
#define DEST_SAMPLERATE 11025
#define DEST_CHANNEL 1
#define TRANSMITTIME 0
#define MUSIC_GAIN_DB -10
#define NUMBER_SOURCE_FILE 2

int audio_forge_wr_cb(audio_element_handle_t el, char *buf, int len, TickType_t wait_time, void *ctx)
{
audio_element_handle_t i2s_wr = (audio_element_handle_t)ctx;
int ret = audio_element_output(i2s_wr, buf, len);
return ret;
}

void app_main(void)
{
audio_pipeline_handle_t pipeline[NUMBER_SOURCE_FILE] = {NULL};
audio_element_handle_t fats_rd_el[NUMBER_SOURCE_FILE] = {NULL};
audio_element_handle_t mp3_decoder[NUMBER_SOURCE_FILE] = {NULL};
audio_element_handle_t el_raw_write[NUMBER_SOURCE_FILE] = {NULL};

esp_log_level_set("*", ESP_LOG_INFO);
esp_log_level_set(TAG, ESP_LOG_INFO);

ESP_LOGI(TAG, "[1.0] Start audio codec chip");
audio_board_handle_t board_handle = audio_board_init();
audio_hal_ctrl_codec(board_handle->audio_hal, AUDIO_HAL_CODEC_MODE_DECODE, AUDIO_HAL_CTRL_START);

ESP_LOGI(TAG, "[2.0] Start and wait for SDCARD to mount");
esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG();
esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg);
audio_board_sdcard_init(set, SD_MODE_1_LINE);
audio_board_key_init(set);

ESP_LOGI(TAG, "[3.0] Create pipeline_mix to mix");
audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG();
audio_pipeline_handle_t pipeline_mix = audio_pipeline_init(&pipeline_cfg);

ESP_LOGI(TAG, "[3.1] Create audio_forge");
audio_forge_cfg_t audio_forge_cfg = AUDIO_FORGE_CFG_DEFAULT();
audio_forge_cfg.audio_forge.component_select = AUDIO_FORGE_SELECT_RESAMPLE | AUDIO_FORGE_SELECT_DOWNMIX | AUDIO_FORGE_SELECT_ALC | AUDIO_FORGE_SELECT_EQUALIZER | AUDIO_FORGE_SELECT_SONIC;
audio_forge_cfg.audio_forge.dest_samplerate = DEST_SAMPLERATE;
audio_forge_cfg.audio_forge.dest_channel = DEST_CHANNEL;
audio_forge_cfg.audio_forge.source_num = NUMBER_SOURCE_FILE;
audio_forge_cfg.audio_forge.max_sample = 128;
audio_forge_cfg.task_prio = 4;
audio_element_handle_t audio_forge = audio_forge_init(&audio_forge_cfg);
audio_forge_src_info_t source_information = {
    .samplerate = DEFAULT_SAMPLERATE,
    .channel = DEFAULT_CHANNEL,
    .bit_num = 16,
};

audio_forge_downmix_t downmix_information = {
    .gain = {0, MUSIC_GAIN_DB},
    .transit_time = TRANSMITTIME,
};
audio_forge_src_info_t source_info[NUMBER_SOURCE_FILE] = {0};
audio_forge_downmix_t downmix_info[NUMBER_SOURCE_FILE];
for (int i = 0; i < NUMBER_SOURCE_FILE; i++) {
    source_info[i] = source_information;
    downmix_info[i] = downmix_information;
}
audio_forge_source_info_init(audio_forge, source_info, downmix_info);

ESP_LOGI(TAG, "[3.2] Create i2s stream to read audio data from codec chip");
i2s_stream_cfg_t i2s_cfg = I2S_STREAM_CFG_DEFAULT();
i2s_cfg.type = AUDIO_STREAM_WRITER;
i2s_cfg.task_stack = 0;
i2s_cfg.out_rb_size = 0;

#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
i2s_cfg.chan_cfg.auto_clear = true;
#else
i2s_cfg.i2s_config.tx_desc_auto_clear = true;
#endif
audio_element_handle_t i2s_writer = i2s_stream_init(&i2s_cfg);
i2s_stream_set_clk(i2s_writer, DEST_SAMPLERATE, 16, DEST_CHANNEL);

ESP_LOGI(TAG, "[3.3] Link elements together audio_forge-->i2s_writer");
audio_pipeline_register(pipeline_mix, audio_forge, "audio_forge");
audio_element_set_write_cb(audio_forge, audio_forge_wr_cb, i2s_writer);
audio_element_process_init(i2s_writer);


ESP_LOGI(TAG, "[3.4] Link elements together audio_forge-->i2s_stream-->[codec_chip]");
audio_pipeline_link(pipeline_mix, (const char *[]) {"audio_forge"}, 1);

ESP_LOGI(TAG, "[4.0] Create Fatfs stream to read input data");
fatfs_stream_cfg_t fatfs_cfg = FATFS_STREAM_CFG_DEFAULT();
fatfs_cfg.type = AUDIO_STREAM_READER;

ESP_LOGI(TAG, "[4.1] Create mp3 decoder to decode mp3 file");
mp3_decoder_cfg_t mp3_cfg = DEFAULT_MP3_DECODER_CONFIG();
mp3_cfg.task_core = 0;

ESP_LOGI(TAG, "[4.2] Create raw stream of base mp3 to write data");
raw_stream_cfg_t raw_cfg = RAW_STREAM_CFG_DEFAULT();
raw_cfg.type = AUDIO_STREAM_WRITER;

ESP_LOGI(TAG, "[5.0] Set up  event listener");
audio_event_iface_cfg_t evt_cfg = AUDIO_EVENT_IFACE_DEFAULT_CFG();
audio_event_iface_handle_t evt = audio_event_iface_init(&evt_cfg);

char str_name[18] = "/sdcard/test";
char num = '1';
for (int i = 0; i < NUMBER_SOURCE_FILE; i++) {
    pipeline[i] = audio_pipeline_init(&pipeline_cfg);
    mem_assert(pipeline[i]);
    fats_rd_el[i] = fatfs_stream_init(&fatfs_cfg);
    str_name[12] = num + i;
    str_name[13] = '.';
    str_name[14] = 'm';
    str_name[15] = 'p';
    str_name[16] = '3';
    audio_element_set_uri(fats_rd_el[i], str_name);
    mp3_cfg.task_core = i; // mp3 decoder set to differen cpu core
    // mp3_cfg.task_prio = 12 - i - i;
    mp3_decoder[i] = mp3_decoder_init(&mp3_cfg);
    el_raw_write[i] = raw_stream_init(&raw_cfg);
    audio_pipeline_register(pipeline[i], fats_rd_el[i], "file");
    audio_pipeline_register(pipeline[i], mp3_decoder[i], "mp3");
    audio_pipeline_register(pipeline[i], el_raw_write[i], "raw");
      
    const char *link_tag[3] = {"file", "mp3", "raw"};
    audio_pipeline_link(pipeline[i], &link_tag[0], 3);
    ringbuf_handle_t rb = audio_element_get_input_ringbuf(el_raw_write[i]);
    if (NUMBER_SOURCE_FILE != 1) {
        audio_element_set_multi_input_ringbuf(audio_forge, rb, i);
    } else {
        audio_element_set_input_ringbuf(audio_forge, rb);
    }
    audio_pipeline_set_listener(pipeline[i], evt);
}
audio_pipeline_set_listener(pipeline_mix, evt);
ESP_LOGI(TAG, "[5.1] Listening event from peripherals");
audio_event_iface_set_listener(esp_periph_set_get_event_iface(set), evt);
audio_forge_downmix_set_transit_time(audio_forge, 100, 0);
audio_forge_downmix_set_transit_time(audio_forge, 100, 1);
for (int i = 0; i < NUMBER_SOURCE_FILE; i++) {
    audio_pipeline_run(pipeline[i]);
}
audio_pipeline_run(pipeline_mix);
while (1) {
    audio_event_iface_msg_t msg;
    esp_err_t ret = audio_event_iface_listen(evt, &msg, portMAX_DELAY);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "[ * ] Event interface error : %d", ret);
        continue;
    }

    for (int i = 0; i < NUMBER_SOURCE_FILE; i++) {
        if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *)mp3_decoder[i]
            && msg.cmd == AEL_MSG_CMD_REPORT_MUSIC_INFO) {
            audio_element_info_t music_info = {0};
            audio_element_getinfo(mp3_decoder[i], &music_info);
            ESP_LOGW(TAG, "[ * ] Receive music info from wav decoder, sample_rates=%d, bits=%d, ch=%d",
                     music_info.sample_rates, music_info.bits, music_info.channels);
            audio_forge_src_info_t src_info = {
                .samplerate = music_info.sample_rates,
                .channel = music_info.channels,
                .bit_num = music_info.bits,
            };
            audio_forge_set_src_info(audio_forge, src_info, i);
        }
    }
    /* Stop when the last pipeline element (fatfs_writer in this case) receives stop event */
    if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT
        && msg.source == (void *) audio_forge
        && msg.cmd == AEL_MSG_CMD_REPORT_STATUS
        && (((int)msg.data == AEL_STATUS_STATE_STOPPED)
            || ((int)msg.data == AEL_STATUS_STATE_FINISHED))) {
        break;
    }
}

ESP_LOGI(TAG, "[6.0] Stop pipelines");
for (int i = 0; i < NUMBER_SOURCE_FILE; i++) {
    audio_pipeline_stop(pipeline[i]);
    audio_pipeline_wait_for_stop(pipeline[i]);
    audio_pipeline_terminate(pipeline[i]);
    audio_pipeline_unregister_more(pipeline[i], fats_rd_el[i], mp3_decoder[i], el_raw_write[i], NULL);
    audio_pipeline_remove_listener(pipeline[i]);
}
audio_pipeline_stop(pipeline_mix);
audio_pipeline_wait_for_stop(pipeline_mix);
audio_pipeline_terminate(pipeline_mix);
audio_pipeline_unregister_more(pipeline_mix, audio_forge, NULL);
audio_pipeline_remove_listener(pipeline_mix);

/* Stop all peripherals before removing the listener */
esp_periph_set_stop_all(set);
audio_event_iface_remove_listener(esp_periph_set_get_event_iface(set), evt);

/* Make sure audio_pipeline_remove_listener & audio_event_iface_remove_listener are called before destroying event_iface */
audio_event_iface_destroy(evt);

for (int i = 0; i < NUMBER_SOURCE_FILE; i++) {
    /* Release resources */
    audio_pipeline_deinit(pipeline[i]);
    audio_element_deinit(fats_rd_el[i]);
    audio_element_deinit(mp3_decoder[i]);
    audio_element_deinit(el_raw_write[i]);
}
/* Release resources */
audio_pipeline_deinit(pipeline_mix);
audio_element_deinit(audio_forge);
audio_element_deinit(i2s_writer);
esp_periph_set_destroy(set);

}
`

from esp-adf.

payday1991 avatar payday1991 commented on August 28, 2024

Thank you.

from esp-adf.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.