Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

解码完pcm全是空 #124

Open
loongkobe opened this issue Aug 6, 2024 · 2 comments
Open

解码完pcm全是空 #124

loongkobe opened this issue Aug 6, 2024 · 2 comments

Comments

@loongkobe
Copy link

loongkobe commented Aug 6, 2024

typedef struct {
    unsigned char *pcm_buf;
    int pcm_length; 
} MusicTaskParams;

void music(void *pvParameters)
{
    MusicTaskParams *params = (MusicTaskParams*)pvParameters;
    unsigned char *pcm_buf = params->pcm_buf;
    int pcm_length = params->pcm_length;
    volatile long long int i2s_table_size = 0;
    while (1)
    {
        for (int i = 0; i < 1000; ++i) {
            printf("PCM 数据[%d]: %d\n", i, ((short*)pcm_buf)[i]);
        }

        if (i2s_table_size >= pcm_length)
        {
            audio_stop();
            vTaskDelay(10);
            break;
        }
        i2s_table_size = i2s_table_size + i2s_tx_write(pcm_buf, WAV_TX_BUFSIZE);
        vTaskDelay(1);
        
    }
    vTaskDelete(NULL);
}

int decode(mp3dec_t *dec, mp3dec_frame_info_t *info, unsigned char *data, int *length, unsigned char *decoded, int *decoded_length) {
    int samples;
    short pcm[MINIMP3_MAX_SAMPLES_PER_FRAME];
    samples = mp3dec_decode_frame(dec, data, *length, pcm, info);
    *decoded_length = samples * info->channels * 2;
    *length -= info->frame_bytes;
    unsigned char buffer[samples * info->channels * 2];
    memcpy(buffer, (unsigned char*)&(pcm), sizeof(short) * samples * info->channels);
    memcpy(decoded, buffer, sizeof(short) * samples * info->channels);
    return info->frame_bytes;
}
int mp3_play(const unsigned char* audio_data, int audio_length){
    es8388_adda_cfg(1, 0);                                      /* 开启DAC关闭ADC */
    es8388_output_cfg(1, 1);                                    /* DAC选择通道1输出 */
    int remaining_audio_length = audio_length; 
    printf("解码的音频长度为%d\n",audio_length);
    mp3dec_init(&mp3d);
    mp3dec_frame_info_t info;
    int total_bytes_consumed = 0;
    int pcm_total_length = 0;
    int max_pcm_size = (audio_length / 1152 + 1) * MINIMP3_MAX_SAMPLES_PER_FRAME;
    unsigned char* pcm_buffer = (unsigned char*)malloc(max_pcm_size * sizeof(short));
    if (!pcm_buffer) {
        printf("内存分配失败\n");
        return 1;
    }

    while (audio_length > 0) {
        unsigned char decoded[MINIMP3_MAX_SAMPLES_PER_FRAME * 2];
        int decoded_length = 0;
        
        int frame_bytes = decode(&mp3d, &info, (unsigned char *)(audio_data + total_bytes_consumed), &remaining_audio_length, decoded, &decoded_length);
        if (frame_bytes == 0) {
            break; // 如果 frame_bytes 为 0,表示数据不足以解码一帧
        }

        memcpy(pcm_buffer + pcm_total_length,decoded, decoded_length);
        pcm_total_length += decoded_length;
        total_bytes_consumed += frame_bytes;
    }
    es8388_sai_cfg(0, 3);
    i2s_set_samplerate_bits_sample(info.hz,I2S_BITS_PER_SAMPLE_16BIT);
        // 创建任务参数结构体
    MusicTaskParams *taskParams = (MusicTaskParams*)malloc(sizeof(MusicTaskParams));
    taskParams->pcm_buf = pcm_buffer;
    taskParams->pcm_length = pcm_total_length;
    audio_stop();
    if (MUSICTask_Handler == NULL)
    {
        taskENTER_CRITICAL(&my_spinlock);
                /* 创建任务1 */
        xTaskCreatePinnedToCore((TaskFunction_t )music,                 /* 任务函数 */
                                (const char*    )"music",               /* 任务名称 */
                                (uint16_t       )MUSIC_STK_SIZE,        /* 任务堆栈大小 */
                                (void*          )taskParams,            /* 传入给任务函数的参数 */
                                (UBaseType_t    )MUSIC_PRIO,            /* 任务优先级 */
                                (TaskHandle_t*  )&MUSICTask_Handler,    /* 任务句柄 */
                                (BaseType_t     ) 0);                   /* 该任务哪个内核运行 */
        taskEXIT_CRITICAL(&my_spinlock);
    }
    audio_start();
    vTaskDelay(100);
    return 0;
}

size_t i2s_tx_write(uint8_t *buffer, uint32_t frame_size)
{
    size_t bytes_written;
    i2s_write(I2S_NUM, buffer, frame_size, &bytes_written, 100);
    return bytes_written;
}

这是我利用minimp3库进行mp3解码然后输送到i2s进行播放,开发板式esp32,开发工具是esp-idf,但是解码到得到的pcm数据始终为空,是我使用方法有问题吗?也找不到具体的使用文档

@vmsh0
Copy link

vmsh0 commented Aug 20, 2024

Hi,
I do not understand Chinese, but you might be interested in my implementation of MP3 decoding with minimp3 on ESP-IDF: https://github.com/vmsh0/gaga

Please note that, as indicated in the README.md, I have used a different fork of minimp3. If you wish to use the original (this one), then you will need to set an appropriate stack size for your decoding task.

@loongkobe
Copy link
Author

Hi, I do not understand Chinese, but you might be interested in my implementation of MP3 decoding with minimp3 on ESP-IDF: https://github.com/vmsh0/gaga

Please note that, as indicated in the README.md, I have used a different fork of minimp3. If you wish to use the original (this one), then you will need to set an appropriate stack size for your decoding task.

thank you, i modify this and it works

    while (total_bytes_written < (size_t)pcm_length) {
        i2s_write(I2S_NUM, pcm_buf + total_bytes_written, 
                  pcm_length - total_bytes_written, &bytes_written, portMAX_DELAY);
        total_bytes_written += bytes_written;
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants