123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- #include "include.h"
- #include "warning_play.h"
- #define TRACE_EN 1
- #if TRACE_EN
- #define TRACE(...) printf(__VA_ARGS__)
- #define TRACE_R(...) print_r(__VA_ARGS__)
- #else
- #define TRACE(...)
- #define TRACE_R(...)
- #endif // TRACE_EN
- #define TRACE_ERR(...) printf(__VA_ARGS__)
- u32 waring_get_digvol_cb(void);
- void wsbc_kick_start(void);
- void peri_nr_init(void);
- #if WARNING_WSBC_EN
- enum {
- PLAY_STA_IDLE,
- PLAY_STA_INITING,
- PLAY_STA_STOP,
- PLAY_STA_STOPING,
- PLAY_STA_DEC_1ST,
- PLAY_STA_W4_KICK,
- PLAY_STA_PROC,
- };
- #define HEADER_LEN 8
- warning_cb_t warning_cb;
- volatile u8 warning_play_state = PLAY_STA_IDLE;
- AT(.text.warning)
- static u8 *warning_ptr_get(void)
- {
- return warning_cb.res_ptr+warning_cb.rd_pos;
- }
- static ALWAYS_INLINE u32 warning_remain_len_get(void)
- {
- return (warning_cb.res_size - warning_cb.rd_pos);
- }
- AT(.text.warning.proc)
- void warning_fill_stream(void)
- {
- u32 cbuf_reamin_len = CACHE_BUF_SIZE - warning_cb.res_ring_buf.total;
- u8 *warning_ptr = warning_ptr_get();
- u32 warning_remain_len = warning_remain_len_get();
- while (cbuf_reamin_len >= (CACHE_BUF_SIZE/2) && warning_remain_len > 0) {
- if (warning_remain_len >= cbuf_reamin_len) {
- ring_buf_put((void *)&warning_cb.res_ring_buf, warning_ptr, cbuf_reamin_len);
- warning_cb.rd_pos += cbuf_reamin_len;
- } else {
- ring_buf_put((void *)&warning_cb.res_ring_buf, warning_ptr, warning_remain_len);
- warning_cb.rd_pos += warning_remain_len;
- }
- cbuf_reamin_len = CACHE_BUF_SIZE - warning_cb.res_ring_buf.total;
- warning_ptr = warning_ptr_get();
- warning_remain_len = warning_remain_len_get();
- if (!warning_remain_len) {
- return;
- }
- }
- }
- AT(.text.warning)
- static bool warning_init(u8 *ptr, u32 size, u8 *spr_idx)
- {
- u16 sample_rate;
- memset((u8 *)&warning_cb, 0, sizeof(warning_cb));
- warning_cb.res_ptr = ptr + HEADER_LEN;
- warning_cb.res_size = size - HEADER_LEN;
- ring_buf_init(&warning_cb.res_ring_buf, warning_cb.ibuf, CACHE_BUF_SIZE, 0);
- warning_fill_stream();
- if(!wsbc_play_init(ptr, &sample_rate, &warning_cb.frame_size)) {
- return false;
- }
- if(sample_rate == 8000) {
- *spr_idx = SPR_8000;
- } else if(sample_rate == 16000) {
- *spr_idx = SPR_16000;
- } else {
- return false;
- }
- return true;
- }
- AT(.text.warning)
- static void warning_start(u8 spr_idx)
- {
- dac1_aubuf_init();
- dac1_vol_set(waring_get_digvol_cb());
- dac1_spr_set(spr_idx);
- dac1_fade_in();
- dac1_fade_wait();
- warning_play_state = PLAY_STA_DEC_1ST;
- TRACE("res_play_start\n");
- }
- AT(.text.warning)
- static void warning_stop(void)
- {
- aubuf1_dma_w4_done();
- dac1_fade_out();
- dac1_put_zero(128); //使OBUF播放完
- dac1_aubuf_w4_empty();
- dac1_fade_wait();
- dac1_vol_set(0);
- AUBUF1CON |= BIT(0); //Reset audio Buffer
- DACDIGCON0 &= ~BIT(8); //SRC1 disable
- TRACE("res_play_stop\n");
- warning_play_state = PLAY_STA_IDLE;
- }
- AT(.com_text.warning)
- bool warning_is_playing(void)
- {
- return warning_play_state != PLAY_STA_IDLE;
- }
- AT(.com_text.warning)
- void warning_dec_check_kick(void)
- {
- u8 play_state = warning_play_state;
- if(play_state >= PLAY_STA_DEC_1ST) { //解码状态
- if(!aubuf1_dma_is_busy()) { //上一帧DMA是否完成
- wsbc_kick_start();
- }
- }
- }
- AT(.com_text.warning)
- void warning_kick_dac_dma(void)
- {
- uint samples = warning_cb.samples;
- if(samples > 0) {
- ///注意obuf放eram时不支持dma方式推dac
- aubuf1_dma_kick(warning_cb.obuf, samples, 1, 0);
- // print_r((u8 *)serial, frame_len);
- }
- }
- static void warning_dec_callback(uint8_t *buf, uint16_t len)
- {
- memcpy(warning_cb.serial, buf, len);
- }
- AT(.text.wsbc.proc)
- void warning_dec_proc(void)
- {
- u16 frame_len = warning_cb.frame_size;
- u8 play_state = warning_play_state;
- if(play_state == PLAY_STA_PROC || play_state == PLAY_STA_DEC_1ST) {
- if (ring_buf_get((void *)&warning_cb.res_ring_buf, warning_dec_callback, frame_len)) {
- aubuf1_dma_w4_done();
- warning_cb.samples = wsbc_play_proc(warning_cb.serial, warning_cb.obuf, frame_len);
- if(play_state == PLAY_STA_DEC_1ST) {
- warning_play_state = PLAY_STA_W4_KICK;
- } else {
- warning_kick_dac_dma();
- }
- } else {
- if(warning_remain_len_get() < frame_len) {
- warning_play_state = PLAY_STA_STOP;
- }
- }
- } else if(play_state == PLAY_STA_STOPING) {
- warning_play_state = PLAY_STA_STOP;
- }
- }
- AT(.text.wsbc.proc)
- void alg_wsbc_dec_process(void)
- {
- warning_dec_proc();
- }
- AT(.com_text.wsbc.warning)
- void warning_play_kick(void)
- {
- GLOBAL_INT_DISABLE();
- if(warning_play_state == PLAY_STA_W4_KICK) {
- warning_play_state = PLAY_STA_PROC;
- warning_kick_dac_dma();
- GLOBAL_INT_RESTORE();
- } else {
- GLOBAL_INT_RESTORE();
- }
- }
- AT(.text.warning)
- int warning_play_init(u8 *ptr, u32 size, bool kick_start)
- {
- u8 spr_idx = SPR_16000;
- TRACE("res_play_init: %x, %x\n", ptr, size);
- if ((size == 0) || (ptr == 0)) {
- return -1;
- }
- warning_play_state = PLAY_STA_INITING;
- #if BT_SCO_FAR_NR_EN
- if (sco_is_connected()) {
- bt_peri_nr_wait_done();
- bt_peri_nr_exit();
- }
- #endif
- if(!warning_init(ptr, size, &spr_idx)) {
- #if BT_SCO_FAR_NR_EN
- if (sco_is_connected()) {
- peri_nr_init();
- }
- #endif
- warning_play_state = PLAY_STA_IDLE;
- return -2;
- }
- warning_start(spr_idx);
- return 0;
- }
- AT(.text.warning.proc)
- int warning_play_proc(void)
- {
- //避免错过kick时间
- warning_play_kick();
- //循环填充位流
- u8 play_state = warning_play_state;
- if(play_state == PLAY_STA_STOPING) {
- return 0;
- } else if(play_state > PLAY_STA_STOP) {
- u32 res_len = warning_remain_len_get();
- u32 cbuf_len = warning_cb.res_ring_buf.total;
- if(cbuf_len < warning_cb.frame_size && res_len > 0) {
- TRACE_ERR("\n====res_less: (%d,%d)\n", cbuf_len, res_len);
- }
- warning_fill_stream();
- return 0;
- }
- return 1;
- }
- ALIGNED(64)
- void warning_play_exit(void)
- {
- u8 tout = 8;
- GLOBAL_INT_DISABLE();
- if(warning_play_state > PLAY_STA_STOPING) {
- warning_play_state = PLAY_STA_STOPING;
- }
- GLOBAL_INT_RESTORE();
- TRACE("res_play_exit\n");
- while(warning_play_state == PLAY_STA_STOPING && tout--) {
- delay_5ms(1);
- }
- warning_stop();
- #if BT_SCO_FAR_NR_EN
- if (sco_is_connected()) {
- peri_nr_init();
- }
- #endif
- }
- #endif // WARNING_WSBC_EN
|