1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156 |
- /*
- * Copyright (c) 2019 Actions Semiconductor Co., Ltd
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- /**
- * @file bluetooth tws observer interface
- */
- #include "bluetooth_tws_observer.h"
- #include "utils/acts_ringbuf.h"
- #define SYS_LOG_NO_NEWLINE
- #ifdef SYS_LOG_DOMAIN
- #undef SYS_LOG_DOMAIN
- #endif
- #define SYS_LOG_DOMAIN "bt_tws"
- /*
- 1、如果两边都处于等待播放状态,设备收到对方的splay后,
- 若收到的对方的起始播放时钟小于当前bt时钟,则做出错处理
- 包号相同,则用时间较晚的中断时钟作为开始播放时间,重新设置tws中断时间
- 若包号不同,则以包号大的作为起始播放包号和时钟,设置为PLAYER_TWS_USE_LOCAL_SPLAY模式,丢弃包号小的码流包
- 2、如果当前设备已经开始播放,收到到对方的splay包,
- 则从当前缓存的码流包中,挑选一个比较靠后的包,计算播放时间,给对方发一个PLAYER_TWS_USE_LOCAL_SPLAY
- 若码流缓存信息不足,则向对方发送PLAYER_TWS_NEED_NEW_SPLAY,对方收到消息后,重新发送splay过来
- */
- //tws中断启动最小间隔,us
- #define TWS_MIN_INTERVAL (20000)
- /* splay_flag的说明
- * 1: 本端处于PLAYING状态, 暂时只支持对端处于WAIT PLAY状态, 希望对端重新发一次splay包过来, 因为本端缓存的包里面没有对端的包号
- * 2: 本端处于PLAYING状态, 希望对端以本端的包号和时间来播放
- * 3: 本端处于WAIT PLAY状态, 若对端不是PLAYING, 希望对端考虑是否接受本端的包号和时间, 若对端是PLAYING, 希望对端提供可以播放的包号和时间
- */
- #define PLAYER_TWS_NEED_NEW_SPLAY 1
- #define PLAYER_TWS_USE_LOCAL_SPLAY 2
- #define PLAYER_TWS_USE_START_SPLAY 3
- #define PLAYER_TWS_SYNCITEM_MAXNUM 10 /* TWS同步信息包最大缓存个数 */
- #define PLAYER_TWS_ERRCOUNT_MAXNUM 10 /* TWS失去同步状态的超时时间 */
- #define PLAYER_TWS_DATA_MAXNUM 5 /* 暂存从对端接收到的消息个数 */
- #define PLAYER_TWS_MSG_MAXNUM 5 /* 暂存从中间件api接收到的消息个数 */
- #define BT_TWS_TIMER_INTERVAL (3)
- typedef enum
- {
- TWS_STARTPLAY_PKT = 1, /* 启动播放包 */
- TWS_STARTSTOP_PKT, /* 停止播放包 */
- TWS_SYNCINFO_PKT, /* 同步信息包 */
- TWS_PLAYRATE_PKT, /* 速度调节包 */
- TWS_INTTIME_PKT, /* 中断时间包 */
- TWS_BTTIME_PKT, /* 蓝牙时间包 */
- } player_tws_type_e;
- /* TWS数据包, 需和tws_sync_cmd_t保持一致
- */
- typedef struct
- {
- uint8_t group; /* 参考 player_tws_group_e */
- uint8_t type; /* 参考 player_tws_type_e */
- uint8_t reserve;
- uint8_t payload_len;
- uint8_t payload_data[16]; /* buf需要4字节对齐, 避免直接赋值导致死机 */
- } player_tws_pkt_t;
- typedef struct
- {
- uint8_t scene; /* 播放场景, 避免不同场景的数据包误判, player_id_e */
- uint8_t splay_flag; /* 本端发送SPLAY的时候告知对端的操作类型, PLAYER_TWS_NEED_NEW_SPLAY... */
- uint16_t pkt_num; /* 开始播放的首包号 */
- uint64_t splay_time; /* 开始播放的时钟 us */
- uint32_t first_clk; /* 本端接收到第一个数据包时的时钟 */
- } player_tws_startplay_pkt_t;
- typedef struct
- {
- uint8_t scene; /* 播放场景, 避免不同场景的数据包误判 */
- uint8_t reserve[3];
- uint64_t startstop_time; /* 开始播放的时钟 us */
- } player_tws_startstop_pkt_t;
- typedef struct
- {
- uint8_t scene;
- uint16_t pkt_num; /* 表示播放的数据包号 */
- uint8_t reserve;
- uint64_t bttime_us; /* 表示播放对应包号时对应的蓝牙时钟 us */
- } player_tws_syncinfo_pkt_t;
- typedef struct
- {
- uint8_t scene;
- uint8_t aps_level;
- uint8_t reserve[2];
- uint64_t inttime; /* 中断时间 us */
- } player_tws_playrate_pkt_t;
- typedef enum
- {
- PLAYER_TWS_STATUS_INIT, /* 执行init后的状态 */
- PLAYER_TWS_STATUS_WAIT, /* 执行wait play后的状态 */
- PLAYER_TWS_STATUS_DEAL_WAIT,/* 执行deal start play后的状态 */
- PLAYER_TWS_STATUS_PLAY, /* 真正播放数据的状态 */
- } player_tws_status_e;
- typedef struct
- {
- uint16_t pkt_num; /* 包号 */
- uint16_t pkt_len; /* 包的数据长度 */
- uint16_t samples; /* 样点数 */
- uint64_t pkt_bttime_us; /* 蓝牙时钟 us */
- } player_tws_pinfo_unit_t;
- /* TWS消息
- */
- typedef struct
- {
- uint8_t type; /* 参考 player_tws_type_e */
- uint8_t data[15];
- } __attribute__((packed)) player_tws_msg_t;
- typedef struct {
- bt_tws_observer_t tws_observer;
- media_observer_t *media_observer;
- struct k_timer timer;
- uint8_t format;
- uint16_t sample_rate; //hz
- uint16_t first_pktnum;
- uint32_t first_clk;
- //以下信息会被中断函数访问
- uint8_t tws_status;
- int8_t aps_level_pending; /* 即将要设置的aps等级 */
- uint64_t aps_inttime;
- //以下信息会被多线程访问
- struct acts_ringbuf tws_data_buffer;
- player_tws_pkt_t tws_data[PLAYER_TWS_DATA_MAXNUM];
- uint8_t tws_role;
- uint8_t last_sinfo_flag;
- uint8_t first_pkt_flag;
- uint8_t sync_error_count; /* 同步错误计数 */
- int8_t adjust_shake_flag; /* 防抖,master和slave前后两个包的时间差一致 */
- uint64_t splay_local_time; /* 近端开始播放的时间 */
- uint64_t forbit_aps_time; /* 在此时间前禁止调节水位aps */
-
- struct acts_ringbuf sinfo_master_buffer;
- struct acts_ringbuf sinfo_slave_buffer;
- struct acts_ringbuf msg_buffer;
- player_tws_syncinfo_pkt_t sinfo_master[PLAYER_TWS_SYNCITEM_MAXNUM];
- player_tws_syncinfo_pkt_t sinfo_slave[PLAYER_TWS_SYNCITEM_MAXNUM];
- player_tws_msg_t msg_data[PLAYER_TWS_MSG_MAXNUM];
- /* 包信息单元
- */
- uint8_t pinfo_unit_idx;
- uint8_t save_pinfo_count; /* 包信息保存计数 */
- player_tws_pinfo_unit_t pinfo_unit[2];
- uint16_t BM_TWS_WPlay_Mintime;
- uint16_t BM_TWS_WPlay_Maxtime;
- uint16_t BM_TWS_Sync_interval;
- } bt_tws_observer_inner_t;
- static bt_tws_observer_inner_t observer_inner;
- /*----------------------------------------------------------------------------------------------------*/
- //callback from irq
- static void _tws_irq_handle(uint64_t bt_clk_us)
- {
- bt_tws_observer_inner_t *handle = &observer_inner;
- tws_runtime_observer_t *observer = (tws_runtime_observer_t *)handle->media_observer->tws_observer;
-
- if(handle->tws_status == PLAYER_TWS_STATUS_DEAL_WAIT)
- {
- handle->tws_status = PLAYER_TWS_STATUS_PLAY;
- handle->media_observer->start_playback(handle->media_observer->media_handle);
- printf("[ATW]start playback\n");
- return;
- }
- /* 调节速度中断(TWS播放时才有效)
- */
- if((handle->aps_level_pending >= 0)
- && (handle->aps_inttime == bt_clk_us)
- && (handle->tws_status == PLAYER_TWS_STATUS_PLAY))
- {
- handle->media_observer->set_base_aps_level(handle->media_observer->media_handle, handle->aps_level_pending);
- printf("[ATW]aps int:%d\n", handle->aps_level_pending);
- handle->aps_level_pending = -1;
- }
- }
- //callback from normal thread
- static void _tws_recv_pkt_handle(void *buf, int32_t size)
- {
- bt_tws_observer_inner_t *handle = &observer_inner;
- tws_runtime_observer_t *observer = (tws_runtime_observer_t *)handle->media_observer->tws_observer;
- player_tws_pkt_t *pkt = (player_tws_pkt_t*)buf;
- if(handle->tws_status == PLAYER_TWS_STATUS_INIT)
- return;
- if(size != sizeof(player_tws_pkt_t))
- {
- SYS_LOG_ERR("size: %d invalid, normal size: %d", size, sizeof(player_tws_pkt_t));
- return;
- }
- if(acts_ringbuf_space(&handle->tws_data_buffer) < sizeof(player_tws_pkt_t))
- {
- SYS_LOG_ERR("tws data buffer full");
- return;
- }
-
- acts_ringbuf_put(&handle->tws_data_buffer, buf, size);
- }
- /*----------------------------------------------------------------------------------------------------*/
- static int32_t _tws_send_start_play(bt_tws_observer_inner_t *handle, player_tws_startplay_pkt_t *startplay)
- {
- tws_runtime_observer_t *observer = (tws_runtime_observer_t *)handle->media_observer->tws_observer;
- player_tws_pkt_t pkt;
- int32_t ret;
- SYS_LOG_INF("set SPlay, pktnum: %d, time: %lld, fclk: %d, flag: %d",
- startplay->pkt_num, startplay->splay_time, startplay->first_clk, startplay->splay_flag);
- startplay->scene = handle->format;
- pkt.group = 0;
- pkt.type = TWS_STARTPLAY_PKT;
- pkt.payload_len = sizeof(player_tws_startplay_pkt_t);
- memcpy(pkt.payload_data, startplay, sizeof(player_tws_startplay_pkt_t));
-
- ret = observer->send_pkt(&pkt, sizeof(pkt));
- if(ret != sizeof(pkt))
- return -1;
- return 0;
- }
- /* 返回0: 表示数据包没有发送出去
- */
- static int32_t _tws_send_start_stop(bt_tws_observer_inner_t *handle, player_tws_startstop_pkt_t *startstop)
- {
- tws_runtime_observer_t *observer = (tws_runtime_observer_t *)handle->media_observer->tws_observer;
- player_tws_pkt_t pkt;
- int32_t ret;
- SYS_LOG_INF("set SStop: %lld", startstop->startstop_time);
- startstop->scene = handle->format;
- pkt.group = 0;
- pkt.type = TWS_STARTSTOP_PKT;
- pkt.payload_len = sizeof(player_tws_startstop_pkt_t);
- memcpy(pkt.payload_data, startstop, sizeof(player_tws_startstop_pkt_t));
- ret = observer->send_pkt(&pkt, sizeof(pkt));
- if(ret != sizeof(pkt))
- return -1;
- return 0;
- }
- /* 返回0: 表示数据包没有发送出去
- */
- static int32_t _tws_send_sync_info(bt_tws_observer_inner_t *handle, player_tws_syncinfo_pkt_t *syncinfo)
- {
- tws_runtime_observer_t *observer = (tws_runtime_observer_t *)handle->media_observer->tws_observer;
- player_tws_pkt_t pkt;
- int32_t ret;
- SYS_LOG_INF("set SInfo, pktnum: %d, time: %lld", syncinfo->pkt_num, syncinfo->bttime_us);
- syncinfo->scene = handle->format;
- pkt.group = 0;
- pkt.type = TWS_SYNCINFO_PKT;
- pkt.payload_len = sizeof(player_tws_syncinfo_pkt_t);
- memcpy(pkt.payload_data, syncinfo, sizeof(player_tws_syncinfo_pkt_t));
- ret = observer->send_pkt(&pkt, sizeof(pkt));
- if(ret != sizeof(pkt))
- return -1;
- return 0;
- }
- /* 返回0: 表示数据包没有发送出去
- */
- static int32_t _tws_send_play_rate(bt_tws_observer_inner_t *handle, player_tws_playrate_pkt_t *playrate)
- {
- tws_runtime_observer_t *observer = (tws_runtime_observer_t *)handle->media_observer->tws_observer;
- player_tws_pkt_t pkt;
- int32_t ret;
- SYS_LOG_INF("set PRate, aps: %d, time: %lld\n", playrate->aps_level, playrate->inttime);
- playrate->scene = handle->format;
- pkt.group = 0;
- pkt.type = TWS_PLAYRATE_PKT;
- pkt.payload_len = sizeof(player_tws_playrate_pkt_t);
- memcpy(pkt.payload_data, (uint8_t *)playrate, sizeof(player_tws_playrate_pkt_t));
- ret = observer->send_pkt(&pkt, sizeof(pkt));
- if(ret != sizeof(pkt))
- return -1;
- return 0;
- }
- /* 检测包信息: 0 表示不保存包信息单元, -1 表示需要重启播放器, 1 表示正常存储包信息单元
- */
- static int32_t _tws_check_pinfo_unit(bt_tws_observer_inner_t *handle, uint16_t cur_pkt_num, uint16_t cur_pkt_len, uint16_t samples)
- {
- if(cur_pkt_len == 0)
- return 0;
- if((cur_pkt_num == handle->pinfo_unit[handle->pinfo_unit_idx].pkt_num)
- && (handle->pinfo_unit[handle->pinfo_unit_idx].pkt_len != 0))
- {
- handle->pinfo_unit[handle->pinfo_unit_idx].samples += samples;
- return 0;
- }
- if(cur_pkt_num != (handle->pinfo_unit[handle->pinfo_unit_idx].pkt_num + 1))
- {
- /* 正在播放如果包号不连续立即重启播放(!=1:避免包号循环, !=0:避免包号开始)
- */
- if((cur_pkt_num != 1) && (handle->pinfo_unit[handle->pinfo_unit_idx].pkt_num != 0))
- return -1;
- }
- return 1;
- }
- static int32_t _tws_update_sync_info(bt_tws_observer_inner_t *handle, tws_pkt_info_t *pkt_info)
- {
- /* 更新idx及其内容
- */
- handle->pinfo_unit_idx ++;
- if(handle->pinfo_unit_idx > 1)
- handle->pinfo_unit_idx = 0;
- handle->pinfo_unit[handle->pinfo_unit_idx].pkt_len = pkt_info->pkt_len;
- handle->pinfo_unit[handle->pinfo_unit_idx].pkt_num = pkt_info->pkt_num;
- handle->pinfo_unit[handle->pinfo_unit_idx].samples = pkt_info->samples;
- handle->pinfo_unit[handle->pinfo_unit_idx].pkt_bttime_us = pkt_info->pkt_bttime_us;
- /* 确保3次之后才处理SPLAY包避免开始的包不全导致计算对端播放时间出错
- */
- handle->save_pinfo_count ++;
- if(handle->save_pinfo_count > 3)
- handle->save_pinfo_count = 3;
- return 0;
- }
- /* 返回-1:slave_pool或maste_pool没有item
- 返回 0:遍历完后没有找到相同包号的item
- 返回 1:找到相同包号的item并从参数传出来
- */
- static int32_t _tws_search_sinfo_item(bt_tws_observer_inner_t *handle, player_tws_syncinfo_pkt_t *slave, player_tws_syncinfo_pkt_t *maste)
- {
- uint8_t slave_keep = 1, maste_keep = 1;
- player_tws_syncinfo_pkt_t slave_item, maste_item;
- uint8_t item_size = sizeof(player_tws_syncinfo_pkt_t);
- struct acts_ringbuf *slave_pool = &handle->sinfo_slave_buffer;
- struct acts_ringbuf *maste_pool = &handle->sinfo_master_buffer;
- for(;;)
- {
- if(slave_keep == 1)
- {
- if(acts_ringbuf_length(slave_pool) < item_size)
- return -1;
-
- slave_keep = 0;
- acts_ringbuf_peek(slave_pool, &slave_item, item_size);
- }
- if(maste_keep == 1)
- {
- if(acts_ringbuf_length(maste_pool) < item_size)
- return -1;
-
- maste_keep = 0;
- acts_ringbuf_peek(maste_pool, &maste_item, item_size);
- }
- if(slave_item.pkt_num > maste_item.pkt_num)
- {
- maste_keep = 1;
- acts_ringbuf_get(maste_pool, NULL, item_size);
- printf("[ATW]item mkp:%d_%d\n", maste_item.pkt_num, slave_item.pkt_num);
- }
- else if(slave_item.pkt_num < maste_item.pkt_num)
- {
- slave_keep = 1;
- acts_ringbuf_get(slave_pool, NULL, item_size);
- printf("[ATW]item skp:%d_%d\n", maste_item.pkt_num, slave_item.pkt_num);
- }
- else
- {
- printf("[ATW]item get:%d\n", maste_item.pkt_num);
- acts_ringbuf_get(maste_pool, NULL, item_size);
- acts_ringbuf_get(slave_pool, NULL, item_size);
- memcpy(slave, &slave_item, item_size);
- memcpy(maste, &maste_item, item_size);
- break;
- }
- }
- return 1;
- }
- static int32_t _tws_align_samples(bt_tws_observer_inner_t *handle)
- {
- player_tws_syncinfo_pkt_t slave_item, maste_item;
- int32_t clk_diff;
- int32_t result = 0;
- uint8_t item_size = sizeof(player_tws_syncinfo_pkt_t);
- int8_t shake_flag;
- result = _tws_search_sinfo_item(handle, &slave_item, &maste_item);
- if(result <= 0)
- {
- handle->sync_error_count = (result == 0) ? (handle->sync_error_count + 1) : 0;
- if(handle->sync_error_count >= PLAYER_TWS_ERRCOUNT_MAXNUM)
- {
- SYS_LOG_ERR("long time no sync info");
- handle->sync_error_count = 0;
- //todo: restart playback
- }
- return 0;
- }
-
- handle->sync_error_count = 0;
- if(slave_item.bttime_us == maste_item.bttime_us)
- return 0;
- clk_diff = (int32_t)(maste_item.bttime_us - slave_item.bttime_us);
- shake_flag = (clk_diff < 0) ? 1 : -1;
- if((slave_item.pkt_num % handle->BM_TWS_Sync_interval) == 0)
- {
- handle->adjust_shake_flag = shake_flag;
- printf("[ATW]adjust e1:%d_%d\n", slave_item.pkt_num, clk_diff);
- return 0;
- }
- if(handle->adjust_shake_flag == 0)
- return 0;
-
- if(handle->adjust_shake_flag == shake_flag)
- {
- printf("[ATW]adjust e2:%d_%d\n", slave_item.pkt_num, clk_diff);
- handle->media_observer->notify_time_diff(handle->media_observer->media_handle, clk_diff);
- }
-
- handle->adjust_shake_flag = 0;
- return 0;
- }
- /* 根据本端和对端的当前信息计算对端的SPLAY
- */
- static int32_t _tws_calculate_new_splay(bt_tws_observer_inner_t *handle, player_tws_startplay_pkt_t *startplay)
- {
- uint8_t first_idx = (handle->pinfo_unit_idx == 1) ? 0 : 1;
- /* 要求对端以指定帧播放(当本端还没有足够的播放信息时, 让对端重新发起SPLAY)
- */
- if(handle->save_pinfo_count < 3)
- {
- printf("[ATW]need new splay\n");
- startplay->splay_flag = PLAYER_TWS_NEED_NEW_SPLAY;
- return 0;
- }
-
- startplay->splay_flag = PLAYER_TWS_USE_LOCAL_SPLAY;
- startplay->first_clk = handle->first_clk;
- if(startplay->pkt_num < (handle->pinfo_unit[handle->pinfo_unit_idx].pkt_num + 10))
- startplay->pkt_num = handle->pinfo_unit[handle->pinfo_unit_idx].pkt_num + 10;
- //todo: 根据已经接收的码流计算时间,sbc包长可能会变
- startplay->splay_time = handle->pinfo_unit[first_idx].pkt_bttime_us
- + (startplay->pkt_num - handle->pinfo_unit[first_idx].pkt_num)
- * handle->pinfo_unit[first_idx].samples * 1000000ll / handle->sample_rate;
- printf("[ATW]new splay:%u_%u_%u_%u, %u_%u_%u\n",
- startplay->pkt_num, startplay->first_clk,
- (uint32_t)(startplay->splay_time >> 32) & 0xffffffff,
- (uint32_t)startplay->splay_time & 0xffffffff,
- handle->pinfo_unit[first_idx].pkt_num,
- handle->first_clk,
- handle->pinfo_unit[first_idx].samples);
- return 0;
- }
- /* 对端要求本端发相同的SPLAY过去
- */
- static int32_t _tws_handle_newly_splay(bt_tws_observer_inner_t *handle, player_tws_startplay_pkt_t *startplay, uint64_t *bttus)
- {
- tws_runtime_observer_t *observer = (tws_runtime_observer_t *)handle->media_observer->tws_observer;
- if((handle->tws_status == PLAYER_TWS_STATUS_PLAY)
- || (handle->tws_status == PLAYER_TWS_STATUS_DEAL_WAIT))
- {
- SYS_LOG_ERR("%u_%u, %u_%u, %u_%u",
- startplay->pkt_num, handle->first_pktnum,
- (uint32_t)(handle->splay_local_time >> 32) & 0xffffffff,
- (uint32_t)handle->splay_local_time & 0xffffffff,
- (uint32_t)(startplay->splay_time >> 32) & 0xffffffff,
- (uint32_t)startplay->splay_time & 0xffffffff);
- return 0;
- }
- startplay->splay_flag = PLAYER_TWS_USE_START_SPLAY;
- startplay->pkt_num = handle->first_pktnum;
- startplay->splay_time = bttus + handle->BM_TWS_WPlay_Mintime * 1000;
- startplay->first_clk = handle->first_clk;
- if(_tws_send_start_play(handle, &startplay) < 0)
- {
- SYS_LOG_ERR("_tws_send_start_play fail.");
- return -1;
- }
- handle->splay_local_time = startplay->splay_time;
- handle->forbit_aps_time = startplay->splay_time + 1500000;
- observer->set_interrupt_time(startplay.splay_time);
- printf("[ATW]handle new splay:%u_%u_%u\n",
- handle->first_pktnum,
- (uint32_t)(startplay->splay_time >> 32) & 0xffffffff,
- (uint32_t)startplay->splay_time & 0xffffffff);
- return 0;
- }
- /* 对端要求本端解码指定的包播放
- */
- static int32_t _tws_handle_local_splay(bt_tws_observer_inner_t *handle, player_tws_startplay_pkt_t *startplay, uint64_t *bttus)
- {
- tws_runtime_observer_t *observer = (tws_runtime_observer_t *)handle->media_observer->tws_observer;
- if((handle->tws_status == PLAYER_TWS_STATUS_PLAY)
- || (handle->tws_status == PLAYER_TWS_STATUS_DEAL_WAIT))
- {
- SYS_LOG_ERR("%u_%u, %u_%u, %u_%u",
- startplay->pkt_num, handle->first_pktnum,
- (uint32_t)(handle->splay_local_time >> 32) & 0xffffffff,
- (uint32_t)handle->splay_local_time & 0xffffffff,
- (uint32_t)(startplay->splay_time >> 32) & 0xffffffff,
- (uint32_t)startplay->splay_time & 0xffffffff);
- return 0;
- }
-
- /* 对端的包号小于本端则对端需要继续播放并重新指定解码包
- */
- if((startplay->pkt_num < handle->first_pktnum)
- || (bttus >= (startplay->splay_time - TWS_MIN_INTERVAL)))
- {
- SYS_LOG_ERR("%u_%u, %u_%u, %u_%u",
- startplay->pkt_num, handle->first_pktnum,
- (uint32_t)(bttus >> 32) & 0xffffffff,
- (uint32_t)bttus & 0xffffffff,
- (uint32_t)(startplay->splay_time >> 32) & 0xffffffff,
- (uint32_t)startplay->splay_time & 0xffffffff);
- return _tws_handle_newly_splay(handle, startplay, bttus);
- }
- handle->splay_local_time = startplay.splay_time;
- handle->first_pktnum = startplay.pkt_num;
- observer->set_interrupt_time(startplay.splay_time);
- printf("[ATW]handle local splay:%u_%u_%u\n",
- handle->first_pktnum,
- (uint32_t)(startplay->splay_time >> 32) & 0xffffffff,
- (uint32_t)startplay->splay_time & 0xffffffff);
- return 0;
- }
- /* 对端告诉本端正在启动播放
- */
- static int32_t _tws_handle_start_splay(bt_tws_observer_inner_t *handle, player_tws_startplay_pkt_t *startplay, uint64_t *bttus)
- {
- tws_runtime_observer_t *observer = (tws_runtime_observer_t *)handle->media_observer->tws_observer;
- uint32_t flags;
- if((handle->tws_status == PLAYER_TWS_STATUS_PLAY)
- || (handle->tws_status == PLAYER_TWS_STATUS_DEAL_WAIT))
- {
- /* 确定对端开始播放的蓝牙时钟
- */
- if(_tws_calculate_new_splay(handle, startplay) < 0)
- {
- SYS_LOG_ERR("_tws_calculate_new_splay fail");
- return -1;
- }
- /* 发送给对端样机
- */
- if(_tws_send_start_play(handle, startplay) < 0)
- {
- SYS_LOG_ERR("_tws_send_start_play fail.");
- return -1;
- }
-
- flags = irq_lock();
- //有接入时一段时间不能进行缓冲区调节
- handle->forbit_aps_time = bttus + 1500000;
- handle->aps_level_pending = -1;
- //对端接入后使用基准时钟播放
- handle->media_observer->set_base_aps_level(handle->media_observer->media_handle, 0xFF);
- irq_unlock(flags);
- printf("[ATW]handle start splay @1\n");
- return 0;
- }
- /* 对端包号小于当前包号, 使用当前包号, 否则使用对端包号和时间)
- */
- if((startplay->pkt_num > handle->first_pktnum)
- || ((startplay->pkt_num == handle->first_pktnum)
- && (handle->splay_local_time < startplay->splay_time)))
- {
- handle->first_pktnum = startplay->pkt_num;
- handle->splay_local_time = startplay->splay_time;
- observer->set_interrupt_time(startplay->splay_time);
- printf("[ATW]handle start splay @2:%u_%u_%u\n",
- (uint32_t)(startplay->splay_time >> 32) & 0xffffffff,
- (uint32_t)startplay->splay_time & 0xffffffff,
- startplay->pkt_num);
- }
- return 0;
- }
- /* 返回-1: 表示失败, 需重启播放器
- */
- static void _tws_deal_startplay(bt_tws_observer_inner_t *handle, player_tws_pkt_t *tws_pkt)
- {
- tws_runtime_observer_t *observer = (tws_runtime_observer_t *)handle->media_observer->tws_observer;
- player_tws_startplay_pkt_t *startplay = (player_tws_startplay_pkt_t *)(tws_pkt->payload_data);
- uint64_t bt_clk;
- if((startplay->scene != handle->format) || (tws_pkt->type != TWS_STARTPLAY_PKT))
- return;
- bt_clk = observer->get_bt_clk_us();
- if(bt_clk == 0)
- {
- SYS_LOG_ERR("get_bt_clk_us fail");
- return;
- }
- printf("[ATW]deal SPlay:%u_%u_%u_%u_%u, %u_%u_%u_%u_%u\n",
- startplay->pkt_num, startplay->first_clk,
- (uint32_t)(startplay->splay_time >> 32) & 0xffffffff, (uint32_t)startplay->splay_time & 0xffffffff,
- startplay->splay_flag,
- handle->first_pktnum, handle->first_clk,
- (uint32_t)(handle->splay_local_time >> 32) & 0xffffffff, (uint32_t)handle->splay_local_time & 0xffffffff,
- handle->tws_status);
- switch(startplay->splay_flag)
- {
- case PLAYER_TWS_NEED_NEW_SPLAY:
- _tws_handle_newly_splay(handle, startplay, bt_clk);
- break;
- case PLAYER_TWS_USE_LOCAL_SPLAY:
- _tws_handle_local_splay(handle, startplay, bt_clk);
- break;
- case PLAYER_TWS_USE_START_SPLAY:
- _tws_handle_start_splay(handle, startplay, bt_clk);
- break;
- default:
- SYS_LOG_ERR("splay_flag invalid");
- break;
- }
- }
- /* 返回-1: 表示失败, 需重启播放器
- */
- static int32_t _tws_deal_startstop(bt_tws_observer_inner_t *handle, player_tws_pkt_t *tws_pkt)
- {
- //todo
- return 0;
- }
- static int32_t _tws_deal_syncinfo(bt_tws_observer_inner_t *handle, player_tws_pkt_t *tws_pkt)
- {
- player_tws_syncinfo_pkt_t *syncinfo = (player_tws_syncinfo_pkt_t *)(tws_pkt->payload_data);
- if((syncinfo->scene != handle->format) || (tws_pkt->type != TWS_SYNCINFO_PKT))
- return 0;
- printf("[ATW]deal SInfo:%d_%u_%u_%d\n",
- syncinfo->pkt_num,
- (uint32_t)(syncinfo->bttime_us >> 32) & 0xffffffff,
- (uint32_t) syncinfo->bttime_us & 0xffffffff,
- handle->tws_status);
- if(handle->tws_status != PLAYER_TWS_STATUS_PLAY)
- return -1;
- if(acts_ringbuf_space(&handle->sinfo_master_buffer) < sizeof(player_tws_syncinfo_pkt_t))
- {
- SYS_LOG_ERR("sinfo_master_buffer full");
- acts_ringbuf_get(&handle->sinfo_master_buffer, NULL, sizeof(player_tws_syncinfo_pkt_t));
- }
-
- acts_ringbuf_put(&handle->sinfo_master_buffer, syncinfo, sizeof(player_tws_syncinfo_pkt_t));
- return 1;
- }
- static int32_t _tws_deal_playrate(bt_tws_observer_inner_t *handle, player_tws_pkt_t *tws_pkt)
- {
- tws_runtime_observer_t *observer = (tws_runtime_observer_t *)handle->media_observer->tws_observer;
- player_tws_playrate_pkt_t *playrate = (player_tws_playrate_pkt_t *)(tws_pkt->payload_data);
- uint32_t flags;
- if((playrate->scene != handle->format) || (tws_pkt->type != TWS_PLAYRATE_PKT))
- return 0;
- printf("[ATW]deal APSInfo:%u_%u_%u_%u\n",
- (uint32_t)(playrate->inttime >> 32) & 0xffffffff,
- (uint32_t)playrate->inttime & 0xffffffff,
- handle->tws_status,
- playrate->aps_level);
- if(handle->tws_status != PLAYER_TWS_STATUS_PLAY)
- return 0;
- /* 设置中断
- */
- observer->set_interrupt_time(playrate->inttime);
- /* 加入中断信号队列
- */
- flags = irq_lock();
- handle->aps_level_pending = playrate->aps_level;
- handle->aps_inttime = playrate.inttime;
- irq_unlock(flags);
- return 0;
- }
- static int32_t _tws_handle_aps_change_request(bt_tws_observer_inner_t *handle, uint8_t level)
- {
- tws_runtime_observer_t *observer = (tws_runtime_observer_t *)handle->media_observer->tws_observer;
- player_tws_playrate_pkt_t playrate;
- uint32_t flags;
- if((handle->tws_role == BTSRV_TWS_SLAVE)
- || (handle->tws_status != PLAYER_TWS_STATUS_PLAY)
- || (handle->aps_level_pending == level))
- return 0;
- if(handle->tws_role == BTSRV_TWS_NONE)
- goto ERROUT;
- /* 获取蓝牙时钟
- */
- playrate.inttime = observer->get_bt_clk_us();
- if(playrate.inttime == 0)
- {
- SYS_LOG_ERR("get_bt_clk_us fail.");
- goto ERROUT;
- }
- if(playrate.inttime < handle->forbit_aps_time)
- return 0;
- /* 告诉对端调节速度
- */
- playrate.aps_level = level;
- playrate.inttime += 150000; /* 150 ms */
- if(_tws_send_play_rate(handle, &playrate) < 0)
- {
- SYS_LOG_ERR("_tws_send_play_rate fail.");
- goto ERROUT;
- }
- /* 设置中断
- */
- observer->set_interrupt_time(playrate.inttime);
- /* 加入中断信号队列
- */
- flags = irq_lock();
- handle->aps_level_pending = level;
- handle->aps_inttime = playrate.inttime;
- irq_unlock(flags);
- return 0;
- ERROUT:
- handle->media_observer->set_base_aps_level(handle->media_observer->media_handle, level);
- return 0;
- }
- static int32_t _tws_handle_new_pkt_info(bt_tws_observer_inner_t *handle, tws_pkt_info_t *info)
- {
- tws_runtime_observer_t *observer = (tws_runtime_observer_t *)handle->media_observer->tws_observer;
- int32_t ret;
- if(handle->tws_status != PLAYER_TWS_STATUS_PLAY)
- return 0;
-
- //aac两包一帧,第一包解码没有输出,清除包信息,避免时间计算不准确
- if(info->samples == 0)
- {
- SYS_LOG_INF("AAC output 0");
- goto ERROUT;
- }
- //丢弃不完整的包避免统计时间不正确
- if(handle->first_pkt_flag)
- {
- if(handle->first_pkt_flag == 1)
- {
- handle->first_pktnum = info->pkt_num;
- handle->first_pkt_flag = 2;
- }
-
- if(info->pkt_num == handle->first_pktnum)
- return 0;
- handle->first_pkt_flag = 0;
- }
-
- /* 检查包头信息
- */
- ret = _tws_check_pinfo_unit(handle, info->pkt_num, info->pkt_len, info->samples);
- if(ret == 0)
- return 0;
- if(ret < 0)
- {
- SYS_LOG_ERR("pkt miss, restart: %u_%u",
- info->pkt_num, handle->pinfo_unit[handle->pinfo_unit_idx].pkt_num);
- goto ERROUT;
- }
-
- _tws_update_sync_info(handle, info);
- if(((info->pkt_num % handle->BM_TWS_Sync_interval) == 0) || (handle->last_sinfo_flag == 1))
- {
- player_tws_syncinfo_pkt_t syncinfo;
- if(handle->last_sinfo_flag == 1)
- handle->last_sinfo_flag = 0;
- if((info->pkt_num % handle->BM_TWS_Sync_interval) == 0)
- handle->last_sinfo_flag = 1;
- memset(&syncinfo, 0, sizeof(player_tws_syncinfo_pkt_t));
- syncinfo.pkt_num = info->pkt_num;
- syncinfo.bttime_us = handle->pinfo_unit[handle->pinfo_unit_idx].pkt_bttime_us;
- if(acts_ringbuf_space(&handle->sinfo_slave_buffer) < sizeof(player_tws_syncinfo_pkt_t))
- acts_ringbuf_get(&handle->sinfo_slave_buffer, NULL, sizeof(player_tws_syncinfo_pkt_t));
- acts_ringbuf_put(&handle->sinfo_slave_buffer, &syncinfo, sizeof(player_tws_syncinfo_pkt_t));
- if(handle->tws_role == BTSRV_TWS_MASTER)
- _tws_send_sync_info(handle, &syncinfo);
- printf("[ATW]SInfo:%u_%d_%u_%u\n", info->pkt_num, info->pkt_len,
- (uint32_t)(syncinfo.bttime_us >> 32) & 0xffffffff, (uint32_t)syncinfo.bttime_us & 0xffffffff);
- }
- return 0;
- ERROUT:
- handle->pinfo_unit_idx = 0;
- handle->save_pinfo_count = 0;
- memset(handle->pinfo_unit, 0, sizeof(handle->pinfo_unit));
- //丢包重启播放
- if((info->samples != 0) && (handle->tws_role != BTSRV_TWS_NONE))
- ;//todo: restart playback
- return 0;
- }
- static void _bt_tws_loop(struct k_timer *timer)
- {
- bt_tws_observer_inner_t *handle = &observer_inner;
- tws_runtime_observer_t *observer = (tws_runtime_observer_t *)handle->media_observer->tws_observer;
- int32_t role;
- role = observer->get_role();
- if(role != handle->tws_role)
- {
- acts_ringbuf_drop_all(&handle->sinfo_master_buffer);
-
- handle->aps_level_pending = -1;
- handle->forbit_aps_time = observer->get_bt_clk_us() + 1500000;
- handle->tws_role = role;
- }
- while(acts_ringbuf_length(&handle->tws_data_buffer) >= sizeof(tws_pkt))
- {
- player_tws_pkt_t tws_pkt;
-
- acts_ringbuf_get(&handle->tws_data_buffer, &tws_pkt, sizeof(tws_pkt));
-
- switch(tws_pkt.type)
- {
- case TWS_STARTPLAY_PKT:
- _tws_deal_startplay(handle, tws_pkt);
- break;
- case TWS_STARTSTOP_PKT:
- _tws_deal_startstop(handle, tws_pkt);
- break;
- case TWS_SYNCINFO_PKT:
- if(role == BTSRV_TWS_SLAVE)
- _tws_deal_syncinfo(handle, tws_pkt);
- break;
- case TWS_PLAYRATE_PKT:
- if(role == BTSRV_TWS_SLAVE)
- _tws_deal_playrate(handle, tws_pkt);
- break;
- default:
- SYS_LOG_ERR("recv invalid pkt, group: %d, type: %d, len: %d",
- tws_pkt.group, tws_pkt.type, tws_pkt.payload_len);
- break;
- }
- }
- while(acts_ringbuf_length(&handle->msg_buffer) >= sizeof(player_tws_msg_t))
- {
- player_tws_msg_t tws_msg;
-
- acts_ringbuf_get(&handle->msg_buffer, &tws_msg, sizeof(tws_msg));
-
- switch(tws_msg.type)
- {
- case TWS_SYNCINFO_PKT:
- _tws_handle_new_pkt_info(handle, (tws_pkt_info_t*)tws_msg.data);
- break;
- case TWS_PLAYRATE_PKT:
- _tws_handle_aps_change_request(handle, tws_msg.data[0]);
- break;
- default:
- SYS_LOG_ERR("recv invalid msg, type: %d", tws_msg.type);
- break;
- }
- }
- if((handle->tws_status == PLAYER_TWS_STATUS_PLAY) && (role == BTSRV_TWS_SLAVE))
- _tws_align_samples(handle);
- if(handle->tws_status == PLAYER_TWS_STATUS_WAIT)
- {
- uint64_t bt_clk;
-
- bt_clk = observer->get_bt_clk_us();
- if(bt_clk == 0)
- {
- SYS_LOG_ERR("get_bt_clk_us fail");
- return;
- }
- bt_clk += TWS_MIN_INTERVAL;
- if(bt_clk >= handle->splay_local_time)
- {
- handle->tws_status == PLAYER_TWS_STATUS_DEAL_WAIT;
- handle->media_observer->set_start_pkt_num(handle->media_observer, handle->first_pktnum);
- }
- }
- }
- /*----------------------------------------------------------------------------------------------------*/
- static uint64_t _bt_tws_get_bt_clk_us(void)
- {
- bt_tws_observer_inner_t *handle = &observer_inner;
- tws_runtime_observer_t *observer = (tws_runtime_observer_t *)handle->media_observer->tws_observer;
- return observer->get_bt_clk_us();
- }
- static uint8_t _bt_tws_get_role(void)
- {
- bt_tws_observer_inner_t *handle = &observer_inner;
- return handle->tws_role;
- }
- static int32_t _bt_tws_set_stream_info(uint8_t format, uint16_t first_pktnum, uint16_t sample_rate)
- {
- bt_tws_observer_inner_t *handle = &observer_inner;
- tws_runtime_observer_t *observer = (tws_runtime_observer_t *)handle->media_observer->tws_observer;
- player_tws_startplay_pkt_t startplay;
- if(handle->tws_status != PLAYER_TWS_STATUS_INIT)
- {
- SYS_LOG_ERR("bt tws status: %d", handle->tws_status);
- return -1;
- }
-
- handle->format = format;
- handle->first_pktnum = first_pktnum;
- handle->sample_rate = sample_rate;
- handle->first_clk = observer->get_first_pkt_clk();
-
- handle->tws_status = PLAYER_TWS_STATUS_WAIT;
- handle->aps_level_pending = -1;
- handle->first_pkt_flag = 1;
-
- if(format == MSBC_TYPE || format == CVSD_TYPE)
- {
- handle->BM_TWS_WPlay_Mintime = 80;
- handle->BM_TWS_WPlay_Maxtime = 600;
- handle->BM_TWS_Sync_interval = 200;
- }
- else
- {
- handle->BM_TWS_WPlay_Mintime = 100;
- handle->BM_TWS_WPlay_Maxtime = 1000;
- handle->BM_TWS_Sync_interval = 40;
- }
- if(handle->tws_role == BTSRV_TWS_NONE)
- goto ERROUT;
- startplay.splay_flag = PLAYER_TWS_USE_START_SPLAY;
- startplay.pkt_num = first_pktnum;
- startplay.splay_time = observer->get_bt_clk_us() + handle->BM_TWS_WPlay_Mintime * 1000;
- startplay.first_clk = handle->first_clk;
- if(_tws_send_start_play(handle, &startplay) < 0)
- {
- SYS_LOG_ERR("_tws_send_start_play fail.");
- goto ERROUT;
- }
- handle->splay_local_time = startplay.splay_time;
- handle->forbit_aps_time = startplay.splay_time + 1500000;
- observer->set_interrupt_time(startplay.splay_time);
- os_timer_start(&handle->timer, BT_TWS_TIMER_INTERVAL, BT_TWS_TIMER_INTERVAL);
-
- return 0;
- ERROUT:
- handle->tws_status = PLAYER_TWS_STATUS_PLAY;
- handle->media_observer->set_start_pkt_num(handle->media_observer->media_handle, first_pktnum);
- handle->media_observer->start_playback(handle->media_observer->media_handle);
- return 0;
- }
- static int32_t _bt_tws_aps_change_request(uint8_t level)
- {
- bt_tws_observer_inner_t *handle = &observer_inner;
- player_tws_msg_t tws_msg;
- int32_t wait_time = 5;
- if(handle->tws_status == PLAYER_TWS_STATUS_INIT)
- return -1;
- tws_msg.type = TWS_PLAYRATE_PKT;
- tws_msg.data[0] = level;
- while(acts_ringbuf_space(&handle->msg_buffer) < sizeof(player_tws_msg_t))
- {
- if(wait_time <= 0)
- {
- SYS_LOG_ERR("msg buffer full");
- return -1;
- }
-
- os_sleep(1);
- wait_time--;
- }
-
- acts_ringbuf_put(&handle->msg_buffer, &tws_msg, sizeof(tws_msg));
- return 0;
- }
- static int32_t _bt_tws_set_pkt_info(tws_pkt_info_t *info)
- {
- bt_tws_observer_inner_t *handle = &observer_inner;
- player_tws_msg_t tws_msg;
- int32_t wait_time = 5;
- if(handle->tws_status == PLAYER_TWS_STATUS_INIT)
- return -1;
- tws_msg.type = TWS_SYNCINFO_PKT;
- memcpy(tws_msg.data, info, sizeof(tws_pkt_info_t));
- while(acts_ringbuf_space(&handle->msg_buffer) < sizeof(player_tws_msg_t))
- {
- if(wait_time <= 0)
- {
- SYS_LOG_ERR("msg buffer full");
- return -1;
- }
-
- os_sleep(1);
- wait_time--;
- }
-
- acts_ringbuf_put(&handle->msg_buffer, &tws_msg, sizeof(tws_msg));
- return 0;
- }
- bt_tws_observer_t* bluetooth_tws_observer_init(media_observer_t *media_observer)
- {
- bt_tws_observer_inner_t *handle = &observer_inner;
- tws_runtime_observer_t *observer = (tws_runtime_observer_t *)media_observer->tws_observer;
- memset(handle, 0, sizeof(bt_tws_observer_inner_t));
-
- acts_ringbuf_init(&handle->tws_data_buffer, handle->tws_data, sizeof(handle->tws_data));
- acts_ringbuf_init(&handle->sinfo_master_buffer, handle->sinfo_master, sizeof(handle->sinfo_master));
- acts_ringbuf_init(&handle->sinfo_slave_buffer, handle->sinfo_slave, sizeof(handle->sinfo_slave));
- acts_ringbuf_init(&handle->msg_buffer, handle->msg_data, sizeof(handle->msg_data));
-
- handle->media_observer = media_observer;
- handle->tws_observer.get_bt_clk_us = _bt_tws_get_bt_clk_us;
- handle->tws_observer.get_role = _bt_tws_get_role;
- handle->tws_observer.set_stream_info = _bt_tws_set_stream_info;
- handle->tws_observer.aps_change_request = _bt_tws_aps_change_request;
- handle->tws_observer.set_pkt_info = _bt_tws_set_pkt_info;
- handle->tws_status = PLAYER_TWS_STATUS_INIT;
- handle->aps_level_pending = -1;
- handle->tws_role = observer->get_role();
- os_timer_init(&handle->timer, _bt_tws_loop, NULL);
- observer->set_interrupt_cb(_tws_irq_handle);
- observer->set_recv_pkt_cb(_tws_recv_pkt_handle);
- SYS_LOG_ERR("sizeof(player_tws_msg_t): %d, %d", sizeof(player_tws_msg_t), sizeof(tws_pkt_info_t));
- return &handle->tws_observer;
- }
- void bluetooth_tws_observer_deinit(bt_tws_observer_t *tws_observer)
- {
- bt_tws_observer_inner_t *handle = &observer_inner;
- tws_runtime_observer_t *observer = (tws_runtime_observer_t *)media_observer->tws_observer;
- uint32_t flags;
- flags = irq_lock();
- handle->aps_level_pending = -1;
- handle->tws_status = PLAYER_TWS_STATUS_INIT;
- irq_unlock(flags);
- os_timer_stop(&handle->timer);
- observer->set_interrupt_time(0);
- observer->set_interrupt_cb(NULL);
- observer->set_recv_pkt_cb(NULL);
- }
|