#if 1 #include "asm/includes.h" #include "media/includes.h" #include "system/includes.h" #include "app_config.h" #include "audio_config.h" #include "audio_decode.h" #include "app_main.h" /* #include "audio_dec.h" */ /* #include "clock_cfg.h" */ struct demo_frame_decoder { u8 start; // 解码开始 u8 wait_resume; // 需要激活 int coding_type; // 解码类型 int sr; // struct audio_decoder decoder; // 解码器 struct audio_res_wait wait; // 资源等待句柄 struct audio_mixer_ch mix_ch; // 叠加句柄 struct audio_stream *stream; // 音频流 struct audio_fmt *fmt; //解码参数配置 #ifndef CONFIG_MEDIA_DEVELOP_ENABLE u8 remain; struct audio_src_handle *src_sync; #endif }; struct demo_frame_decoder *demo_frame_dec = NULL; extern struct audio_mixer mixer; extern struct audio_dac_hdl dac_hdl; /* extern struct audio_decoder_task decode_task; */ struct audio_decoder_task decode_task; int demo_frame_media_get_packet(u8 **frame); void demo_frame_media_free_packet(void *_packet); void *demo_frame_media_fetch_packet(int *len, void *prev_packet); int demo_frame_media_get_packet_num(void); extern void audio_pwm_open(void); int demo_frame_dec_close(void); struct demo_frame_media_rx_bulk { struct list_head entry; int data_len; u8 data[0]; }; //697n 耳机sdk 调用此解码demo时要注意时钟要大于等于48M,不然时钟容易不够跑 static u32 *demo_frame_media_buf = NULL; static LIST_HEAD(demo_frame_media_head); u16 demo_frame_test_tmr = 0; static u32 demo_frame_cnt = 0; #define DEMO_FRAME_TIME 5 #define DEC_DATA_POINTS 37// 42 //每次解码的字节数,要等于一帧编码数据的字节数 #define DEC_DATA_SAMPRATE 16000 /* #define DEC_DEMO_CLK 48*1000000L //设置编码时候的时钟 */ static unsigned char enc_data[] = { //编码数据改下 //lc3编码后的数据 #if 0 //lc3编码后的数据 0x28, 0x00, 0xce, 0xeb, 0xe5, 0xd6, 0xdd, 0x8b, 0xa4, 0xa4, 0x76, 0x87, 0x10, 0x7D, 0x2c, 0xaf, 0xA0, 0x9d, 0xf4, 0x4b, 0xa6, 0x19, 0xe2, 0x89, 0xd5, 0x56, 0xaa, 0x64, 0xb4, 0xaa, 0x8f, 0x52, 0x97, 0xba, 0xcf, 0x3a, 0x91, 0x73, 0xc4, 0x6c, 0xce, 0x4f, 0x28, 0x00, 0xe9, 0x08, 0xd8, 0xba, 0x74, 0x83, 0xbc, 0xbc, 0xd7, 0xbf, 0x47, 0x92, 0xe1, 0x4d, 0x99, 0x24, 0xc6, 0x07, 0x30, 0x3c, 0x40, 0xa0, 0x71, 0xf0, 0x56, 0xf0, 0xb6, 0x0f, 0x96, 0x8f, 0xfd, 0xc3, 0x35, 0x38, 0xc0, 0xdf, 0x50, 0xe4, 0xba, 0x4f, 0x28, 0x00, 0xfb, 0x0c, 0xaf, 0x21, 0xdf, 0x89, 0x61, 0xc0, 0xe8, 0x82, 0x8c, 0x93, 0xfa, 0x51, 0x9b, 0xa2, 0xc7, 0xee, 0xa5, 0x42, 0x1b, 0xaa, 0xaa, 0xaa, 0xb5, 0x54, 0x69, 0x3b, 0x75, 0x6a, 0xc4, 0x38, 0xcf, 0xc0, 0x19, 0xe8, 0xa0, 0xe4, 0xb9, 0x4f, 0x28, 0x00, 0xf9, 0xa5, 0x51, 0xef, 0x21, 0x4d, 0x48, 0x1f, 0xeb, 0x2b, 0x22, 0x37, 0x3a, 0xc3, 0x0b, 0xe1, 0x78, 0x97, 0x73, 0x26, 0x90, 0xd4, 0xb4, 0xd6, 0xab, 0x5a, 0x2c, 0x66, 0x2e, 0xa2, 0xa4, 0x29, 0x75, 0x86, 0xca, 0x0a, 0x20, 0xe4, 0xbb, 0x4f #endif #if 1 //USBC编码后的数据 0xE6, 0x55, 0x44, 0x34, 0xDC, 0xCA, 0x9A, 0x72, 0x68, 0x6D, 0xB6, 0x0D, 0x9B, 0x6C, 0x70, 0x86, 0xDC, 0x4B, 0x96, 0x34, 0xEE, 0x3D, 0x45, 0xEE, 0x2D, 0xCB, 0xAA, 0x64, 0x76, 0xDB, 0x32, 0x1D, 0xB6, 0xC9, 0x68, 0x6D, 0xB0, 0xE6, 0x55, 0x44, 0x44, 0x82, 0x3A, 0x44, 0x37, 0x25, 0x4D, 0x1C, 0x94, 0x36, 0xD5, 0x82, 0xCD, 0xB5, 0x1C, 0x43, 0x6D, 0x52, 0xEB, 0x1A, 0x6B, 0x8E, 0xA2, 0xE7, 0x8A, 0xE5, 0xD4, 0x99, 0x3B, 0x6D, 0x4C, 0x8E, 0xDB, 0x50, 0xE6, 0x55, 0x44, 0x44, 0x25, 0xC3, 0x6D, 0x60, 0x8E, 0x91, 0x0D, 0xC9, 0x53, 0x47, 0x25, 0x0D, 0xB5, 0x60, 0xB3, 0x6D, 0x47, 0x10, 0xDB, 0x54, 0xBA, 0xC6, 0x9A, 0xE3, 0xA8, 0xB9, 0xE2, 0xB9, 0x75, 0x26, 0x4E, 0xDB, 0x50, 0xE6, 0x55, 0x44, 0x44, 0x32, 0x3B, 0x6D, 0x49, 0x70, 0xDB, 0x58, 0x23, 0xA4, 0x43, 0x72, 0x54, 0xD1, 0xC9, 0x43, 0x6D, 0x58, 0x2C, 0xDB, 0x51, 0xC4, 0x36, 0xD5, 0x2E, 0xB1, 0xA6, 0xB8, 0xEA, 0x2E, 0x78, 0xAE, 0x5D, 0x40, 0xE6, 0x55, 0x44, 0x44, 0x99, 0x3B, 0x6D, 0x4C, 0x8E, 0xDB, 0x52, 0x5C, 0x36, 0xD6, 0x08, 0xE9, 0x10, 0xDC, 0x95, 0x34, 0x72, 0x50, 0xDB, 0x56, 0x0B, 0x36, 0xD4, 0x71, 0x0D, 0xB5, 0x4B, 0xAC, 0x69, 0xAE, 0x3A, 0x8B, 0x90, 0xE6, 0x54, 0x44, 0x44, 0xE2, 0xB9, 0x75, 0x26, 0x4E, 0xD3, 0x53, 0x23, 0xB6, 0xD4, 0x97, 0x0D, 0xB5, 0x82, 0x3A, 0x24, 0x37, 0x25, 0x45, 0x1C, 0x94, 0x36, 0xD5, 0x82, 0xCD, 0x35, 0x1C, 0x43, 0x6D, 0x52, 0xEB, 0x22, 0x60, 0xE6, 0x55, 0x44, 0x44, 0xB8, 0xEA, 0x2E, 0x78, 0xAE, 0x5D, 0x49, 0x93, 0xB6, 0xD4, 0xC8, 0xED, 0xB5, 0x25, 0xC3, 0x6D, 0x60, 0x8E, 0x91, 0x0D, 0xC9, 0x53, 0x47, 0x25, 0x0D, 0xB5, 0x60, 0xB3, 0x6D, 0x47, 0x10, 0xDB, 0x50, 0xE6, 0x55, 0x44, 0x44, 0x4B, 0xAC, 0x69, 0xAE, 0x3A, 0x8B, 0x9E, 0x2B, 0x97, 0x52, 0x64, 0xED, 0xB5, 0x32, 0x3B, 0x6D, 0x49, 0x70, 0xDB, 0x58, 0x23, 0xA4, 0x43, 0x72, 0x54, 0xD1, 0xC9, 0x43, 0x6D, 0x58, 0x2C, 0xDB, 0x50, 0xE6, 0x55, 0x44, 0x44, 0x1C, 0x43, 0x6D, 0x52, 0xEB, 0x1A, 0x6B, 0x8E, 0xA2, 0xE7, 0x8A, 0xE5, 0xD4, 0x99, 0x3B, 0x6D, 0x4C, 0x8E, 0xDB, 0x52, 0x5C, 0x36, 0xD6, 0x08, 0xE9, 0x10, 0xDC, 0x95, 0x34, 0x72, 0x50, 0xDB, 0x50, 0xE6, 0x55, 0x44, 0x44, 0x60, 0xB3, 0x6D, 0x47, 0x10, 0xDB, 0x54, 0xBA, 0xC6, 0x9A, 0xE3, 0xA8, 0xB9, 0xE2, 0xB9, 0x75, 0x26, 0x4E, 0xDB, 0x53, 0x23, 0xB6, 0xD4, 0x97, 0x0D, 0xB5, 0x82, 0x3A, 0x44, 0x37, 0x25, 0x4D, 0x10, 0xE6, 0x55, 0x44, 0x44, 0xC9, 0x43, 0x6D, 0x58, 0x2C, 0xDB, 0x51, 0xC4, 0x36, 0xD5, 0x2E, 0xB1, 0xA6, 0xB8, 0xEA, 0x2E, 0x78, 0xAE, 0x5D, 0x49, 0x93, 0xB6, 0xD4, 0xC8, 0xED, 0xB5, 0x25, 0xC3, 0x6D, 0x60, 0x8E, 0x91, 0x00 #endif }; // 解码获取数据 static int demo_frame_dec_get_frame(struct audio_decoder *decoder, u8 **frame) { struct demo_frame_decoder *dec = container_of(decoder, struct demo_frame_decoder, decoder); u8 *packet = NULL; int len = 0; // 获取数据 len = demo_frame_media_get_packet(&packet); if (len <= 0) { // 失败 putchar('X'); dec->wait_resume = 1; return len; } *frame = packet; return len; } // 解码释放数据空间 static void demo_frame_dec_put_frame(struct audio_decoder *decoder, u8 *frame) { struct demo_frame_decoder *dec = container_of(decoder, struct demo_frame_decoder, decoder); if (frame) { demo_frame_media_free_packet((void *)(frame)); } } // 解码查询数据 static int demo_frame_dec_fetch_frame(struct audio_decoder *decoder, u8 **frame) { struct demo_frame_decoder *dec = container_of(decoder, struct demo_frame_decoder, decoder); u8 *packet = NULL; int len = 0; u32 wait_timeout = 0; if (!dec->start) { wait_timeout = jiffies + msecs_to_jiffies(500); } __retry_fetch: packet = demo_frame_media_fetch_packet(&len, NULL); if (packet) { *frame = packet; } else if (!dec->start) { // 解码启动前获取数据来做格式信息获取等 if (time_before(jiffies, wait_timeout)) { os_time_dly(1); goto __retry_fetch; } } return len; } static const struct audio_dec_input demo_frame_input = { .coding_type = AUDIO_CODING_USBC, .data_type = AUDIO_INPUT_FRAME, .ops = { .frame = { .fget = demo_frame_dec_get_frame, .fput = demo_frame_dec_put_frame, .ffetch = demo_frame_dec_fetch_frame, } } }; // 解码预处理 static int demo_frame_dec_probe_handler(struct audio_decoder *decoder) { struct demo_frame_decoder *dec = container_of(decoder, struct demo_frame_decoder, decoder); if (demo_frame_media_get_packet_num() < 1) { // 没有数据时返回负数,等有数据时激活解码 #if defined(CONFIG_MEDIA_DEVELOP_ENABLE) audio_decoder_suspend(decoder); #else audio_decoder_suspend(decoder, 0); #endif dec->wait_resume = 1; return -EINVAL; } return 0; } // 解码后处理 static int demo_frame_dec_post_handler(struct audio_decoder *decoder) { return 0; } //解码后输出 #ifndef CONFIG_MEDIA_DEVELOP_ENABLE static int demo_frame_dec_output_handler(struct audio_decoder *decoder, s16 *data, int len, void *priv) { struct demo_frame_decoder *dec = container_of(decoder, struct demo_frame_decoder, decoder); char err = 0; int rlen = len; int wlen = 0; if (decoder == NULL) { r_printf("decoder NULL"); } wdt_clear(); printf("demo data len:%d \n", len); put_buf(data, len); return len; } #endif static const struct audio_dec_handler demo_frame_dec_handler = { .dec_probe = demo_frame_dec_probe_handler, .dec_post = demo_frame_dec_post_handler, #ifndef CONFIG_MEDIA_DEVELOP_ENABLE .dec_output = demo_frame_dec_output_handler, #endif }; // 解码释放 static void demo_frame_dec_release(void) { // 删除解码资源等待 audio_decoder_task_del_wait(&decode_task, &demo_frame_dec->wait); /* clock_remove(DEC_SBC_CLK); */ // 释放空间 local_irq_disable(); free(demo_frame_dec); demo_frame_dec = NULL; local_irq_enable(); } // 解码关闭 static void demo_frame_audio_res_close(void) { if (demo_frame_dec->start == 0) { printf("demo_frame_dec->start == 0"); return ; } // 关闭数据流节点 demo_frame_dec->start = 0; #if 0 audio_decoder_close(&demo_frame_dec->decoder); audio_mixer_ch_close(&demo_frame_dec->mix_ch); // 先关闭各个节点,最后才close数据流 #if defined(CONFIG_MEDIA_DEVELOP_ENABLE) if (demo_frame_dec->stream) { audio_stream_close(demo_frame_dec->stream); demo_frame_dec->stream = NULL; } #endif app_audio_state_exit(APP_AUDIO_STATE_MUSIC); #endif } // 解码事件处理 static void demo_frame_dec_event_handler(struct audio_decoder *decoder, int argc, int *argv) { switch (argv[0]) { case AUDIO_DEC_EVENT_END: printf("AUDIO_DEC_EVENT_END\n"); demo_frame_dec_close(); break; } } // 解码数据流激活 static void demo_frame_out_stream_resume(void *p) { struct demo_frame_decoder *dec = (struct demo_frame_decoder *)p; audio_decoder_resume(&dec->decoder); } // 收到数据后的处理 void demo_frame_media_rx_notice_to_decode(void) { if (demo_frame_dec && demo_frame_dec->start && demo_frame_dec->wait_resume) { demo_frame_dec->wait_resume = 0; audio_decoder_resume(&demo_frame_dec->decoder); } } // 解码start static int demo_frame_dec_start(void) { int err; struct audio_fmt *fmt; struct demo_frame_decoder *dec = demo_frame_dec; if (!demo_frame_dec) { return -EINVAL; } printf("demo_frame_dec_start: in\n"); // 打开demo_frame解码 err = audio_decoder_open(&dec->decoder, &demo_frame_input, &decode_task); if (err) { goto __err1; } // 设置运行句柄 audio_decoder_set_handler(&dec->decoder, &demo_frame_dec_handler); struct audio_fmt f = {0}; f.coding_type = dec->coding_type; dec->decoder.fmt.channel = dec->fmt->channel; dec->decoder.fmt.sample_rate = dec->sr; dec->decoder.fmt.bit_rate = dec->fmt->bit_rate; dec->decoder.fmt.frame_len = dec->fmt->frame_len; err = audio_decoder_set_fmt(&dec->decoder, &f); if (err) { goto __err2; } // 获取解码格式 err = audio_decoder_get_fmt(&dec->decoder, &fmt); if (err) { goto __err2; } // 使能事件回调 audio_decoder_set_event_handler(&dec->decoder, demo_frame_dec_event_handler, 0); fmt->sample_rate = dec->sr; #if 0 #if defined(CONFIG_MEDIA_DEVELOP_ENABLE) // 设置输出声道类型 audio_decoder_set_output_channel(&dec->decoder, audio_output_channel_type()); // 配置mixer通道参数 audio_mixer_ch_open_head(&dec->mix_ch, &mixer); // 挂载到mixer最前面 audio_mixer_ch_set_src(&dec->mix_ch, 1, 0); audio_mixer_ch_set_no_wait(&dec->mix_ch, 1, 20); // 超时自动丢数 /* audio_mixer_ch_set_sample_rate(&dec->mix_ch, fmt->sample_rate); */ // 数据流串联 struct audio_stream_entry *entries[8] = {NULL}; u8 entry_cnt = 0; entries[entry_cnt++] = &dec->decoder.entry; // 添加自定义数据流节点等 // 最后输出到mix数据流节点 entries[entry_cnt++] = &dec->mix_ch.entry; // 创建数据流,把所有节点连接起来 dec->stream = audio_stream_open(dec, demo_frame_out_stream_resume); audio_stream_add_list(dec->stream, entries, entry_cnt); // 设置音频输出类型 audio_output_set_start_volume(APP_AUDIO_STATE_MUSIC); #else // 设置输出声道类型 enum audio_channel channel; int dac_output = audio_dac_get_channel(&dac_hdl); if (dac_output == DAC_OUTPUT_LR) { channel = AUDIO_CH_LR; } else if (dac_output == DAC_OUTPUT_MONO_L) { channel = AUDIO_CH_L; } else if (dac_output == DAC_OUTPUT_MONO_R) { channel = AUDIO_CH_R; } else { channel = AUDIO_CH_DIFF; } audio_decoder_set_output_channel(&dec->decoder, channel); audio_mixer_ch_open(&dec->mix_ch, &mixer); audio_mixer_ch_set_resume_handler(&dec->mix_ch, (void *)&dec->decoder, (void (*)(void *))audio_decoder_resume); audio_mixer_ch_set_sample_rate(&dec->mix_ch, fmt->sample_rate); app_audio_state_switch(APP_AUDIO_STATE_MUSIC, get_max_sys_vol()); app_audio_set_volume(APP_AUDIO_STATE_MUSIC, 16, 1); #endif #endif // 开始解码 dec->start = 1; err = audio_decoder_start(&dec->decoder); if (err) { goto __err3; } clk_set("sys", 96 * 1000000L); /* clock_set_cur(); */ return 0; __err3: dec->start = 0; #if 0 audio_mixer_ch_close(&dec->mix_ch); // 先关闭各个节点,最后才close数据流 #if defined(CONFIG_MEDIA_DEVELOP_ENABLE) if (dec->stream) { audio_stream_close(dec->stream); dec->stream = NULL; } #endif #endif __err2: audio_decoder_close(&dec->decoder); __err1: demo_frame_dec_release(); return err; } // 解码资源等待回调 static int demo_frame_wait_res_handler(struct audio_res_wait *wait, int event) { int err = 0; y_printf("demo_frame_wait_res_handler: %d\n", event); if (event == AUDIO_RES_GET) { // 可以开始解码 err = demo_frame_dec_start(); } else if (event == AUDIO_RES_PUT) { // 被打断 if (demo_frame_dec->start) { demo_frame_audio_res_close(); } } return err; } // 打开解码 int demo_frame_dec_open(int sr, u32 coding_type, struct audio_fmt *fmt) //采样率,解码类型,fmt里面配置除采样率和解码类型外的参数 { struct demo_frame_decoder *dec; if (demo_frame_dec) { return 0; } printf("demo_frame_dec_open \n"); dec = zalloc(sizeof(*dec)); ASSERT(dec); /* clock_add(DEC_SBC_CLK); */ demo_frame_dec = dec; struct audio_fmt fmt_default = { //lc3解码需要配置这三个参数 .channel = 1, .frame_len = 50, .bit_rate = 64000 }; if (fmt != NULL) { dec->fmt = fmt; } else { dec->fmt = &fmt_default; } dec->sr = sr; //采样率 dec->coding_type = coding_type; // 解码类型 dec->wait.priority = 4; // 解码优先级 dec->wait.preemption = 0; // 不使能直接抢断解码 dec->wait.snatch_same_prio = 1; // 可抢断同优先级解码 dec->wait.handler = demo_frame_wait_res_handler; audio_decoder_task_add_wait(&decode_task, &dec->wait); return 0; } // 关闭解码 int demo_frame_dec_close(void) { if (!demo_frame_dec) { return 0; } if (demo_frame_dec->start) { demo_frame_audio_res_close(); } demo_frame_dec_release(); /* clock_set_cur(); */ printf("demo_frame_dec_close: exit\n"); return 1; } // 获取frame数据 int demo_frame_media_get_packet(u8 **frame) { struct demo_frame_media_rx_bulk *p; local_irq_disable(); if (demo_frame_media_head.next != &demo_frame_media_head) { p = list_entry((&demo_frame_media_head)->next, typeof(*p), entry); list_del(&p->entry); *frame = p->data; local_irq_enable(); return p->data_len; } local_irq_enable(); return 0; } // 释放frame数据 void demo_frame_media_free_packet(void *data) { struct demo_frame_media_rx_bulk *rx = container_of(data, struct demo_frame_media_rx_bulk, data); local_irq_disable(); list_del(&rx->entry); local_irq_enable(); lbuf_free(rx); } // 检查frame数据 void *demo_frame_media_fetch_packet(int *len, void *prev_packet) { struct demo_frame_media_rx_bulk *p; local_irq_disable(); if (demo_frame_media_head.next != &demo_frame_media_head) { if (prev_packet) { p = container_of(prev_packet, struct demo_frame_media_rx_bulk, data); if (p->entry.next != &demo_frame_media_head) { p = list_entry(p->entry.next, typeof(*p), entry); *len = p->data_len; local_irq_enable(); return p->data; } } else { p = list_entry((&demo_frame_media_head)->next, typeof(*p), entry); *len = p->data_len; local_irq_enable(); return p->data; } } local_irq_enable(); return NULL; } // 获取数据量 int demo_frame_media_get_packet_num(void) { struct demo_frame_media_rx_bulk *p; u32 num = 0; local_irq_disable(); list_for_each_entry(p, &demo_frame_media_head, entry) { num++; } local_irq_enable(); return num; } /* __attribute__((weak)) */ /* void demo_frame_media_rx_notice_to_decode(void) */ /* { */ /* } */ // 用timer模拟填数 static void demo_frame_test_time_func(void *param) { struct demo_frame_media_rx_bulk *p; while (1) { p = lbuf_alloc((struct lbuff_head *)demo_frame_media_buf, sizeof(*p) + DEC_DATA_POINTS); if (!p) { break; } u32 data_num = DEC_DATA_POINTS > sizeof(enc_data) ? sizeof(enc_data) : DEC_DATA_POINTS; // 填数 p->data_len = data_num; memcpy(p->data, &enc_data[demo_frame_cnt * data_num], data_num); demo_frame_cnt ++; if (demo_frame_cnt >= sizeof(enc_data) / data_num) { demo_frame_cnt = 0; } local_irq_disable(); list_add_tail(&p->entry, &demo_frame_media_head); local_irq_enable(); // 告诉上层有数据 demo_frame_media_rx_notice_to_decode(); } } // 模拟定时关闭 static void demo_frame_test_close(void *param) { y_printf("%s,%d \n", __func__, __LINE__); if (demo_frame_test_tmr) { sys_timer_del(demo_frame_test_tmr); demo_frame_test_tmr = 0; } demo_frame_dec_close(); local_irq_disable(); list_del_init(&demo_frame_media_head); if (demo_frame_media_buf) { free(demo_frame_media_buf); demo_frame_media_buf = NULL; } local_irq_enable(); } void demo_frame_test(void); static int demo_frame_test_again(int param) { demo_frame_test(); return 0; } // 模拟定时关闭 static void demo_frame_test_to_close(void *param) { demo_frame_test_close(NULL); #if 1 y_printf("demo_frame_sbc_test_to_close, again \n"); int argv[3]; argv[0] = (int)demo_frame_test_again; argv[1] = 1; argv[2] = (int)0; os_taskq_post_type("app_core", Q_CALLBACK, ARRAY_SIZE(argv), argv); #endif } void demo_frame_test(void) { printf("%s,%d \n", __func__, __LINE__); demo_frame_test_close(NULL); // 申请空间 u32 buf_size = 2 * 1024; void *buf = malloc(buf_size); ASSERT(buf); // 初始化lbuf local_irq_disable(); demo_frame_media_buf = buf; lbuf_init(demo_frame_media_buf, buf_size, 4, 0); local_irq_enable(); demo_frame_test_time_func(NULL); // 用timer模拟填数 demo_frame_test_tmr = sys_timer_add(NULL, demo_frame_test_time_func, DEMO_FRAME_TIME); y_printf("id:%d \n", demo_frame_test_tmr); // 模拟定时关闭 /* sys_timeout_add(NULL, demo_frame_test_close, 10 * 1000); */ // 启动解码 demo_frame_dec_open(DEC_DATA_SAMPRATE, AUDIO_CODING_USBC, NULL); //创建一个解码 } int audio_dec_init() { int err; printf("audio_dec_init\n"); tone_play_init(); // 创建解码任务 err = audio_decoder_task_create(&decode_task, "audio_dec"); audio_pwm_open(); return err; } #endif