lieff / minimp3

Minimalistic MP3 decoder single header library
Creative Commons Zero v1.0 Universal
1.58k stars 214 forks source link

解码完pcm全是空 #124

Open loongkobe opened 1 month ago

loongkobe commented 1 month ago
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 commented 3 weeks ago

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 commented 3 weeks ago

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;
    }