output_bt.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. #include "squeezelite.h"
  2. #include "perf_trace.h"
  3. static log_level loglevel;
  4. static bool running = true;
  5. extern struct outputstate output;
  6. extern struct buffer *outputbuf;
  7. extern struct buffer *streambuf;
  8. #define LOCK mutex_lock(outputbuf->mutex)
  9. #define UNLOCK mutex_unlock(outputbuf->mutex)
  10. #ifdef USE_BT_RING_BUFFER
  11. size_t bt_buffer_size=0;
  12. uint8_t bt_buf_used_threshold = 25;
  13. uint16_t output_bt_thread_heartbeat_ms=1000;
  14. thread_type thread_bt;
  15. #define LOCK_BT mutex_lock(btbuf->mutex)
  16. #define UNLOCK_BT mutex_unlock(btbuf->mutex)
  17. thread_cond_type output_bt_suspend_cond;
  18. mutex_type output_bt_suspend_mutex;
  19. static struct buffer bt_buf_structure;
  20. struct buffer *btbuf=&bt_buf_structure;
  21. static void *output_thread_bt();
  22. extern void wait_for_frames(size_t frames, uint8_t pct);
  23. #else
  24. uint8_t * btout;
  25. #endif
  26. #define FRAME_BLOCK MAX_SILENCE_FRAMES
  27. extern u8_t *silencebuf;
  28. void hal_bluetooth_init(log_level);
  29. static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR,
  30. s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr);
  31. #define DECLARE_ALL_MIN_MAX \
  32. DECLARE_MIN_MAX(req);\
  33. DECLARE_MIN_MAX(rec);\
  34. DECLARE_MIN_MAX(o);\
  35. DECLARE_MIN_MAX(s);\
  36. DECLARE_MIN_MAX(locbtbuff);\
  37. DECLARE_MIN_MAX(under);\
  38. DECLARE_MIN_MAX_DURATION(mutex1);\
  39. DECLARE_MIN_MAX_DURATION(mutex2);\
  40. DECLARE_MIN_MAX_DURATION(buffering);\
  41. DECLARE_MIN_MAX_DURATION(sleep_time);
  42. #define RESET_ALL_MIN_MAX \
  43. RESET_MIN_MAX(o); \
  44. RESET_MIN_MAX(s); \
  45. RESET_MIN_MAX(locbtbuff); \
  46. RESET_MIN_MAX(req); \
  47. RESET_MIN_MAX(rec); \
  48. RESET_MIN_MAX(under); \
  49. RESET_MIN_MAX_DURATION(mutex1); \
  50. RESET_MIN_MAX_DURATION(mutex2); \
  51. RESET_MIN_MAX_DURATION(sleep_time); \
  52. RESET_MIN_MAX_DURATION(buffering);
  53. #if CONFIG_BTAUDIO
  54. void set_volume_bt(unsigned left, unsigned right) {
  55. LOG_DEBUG("setting internal gain left: %u right: %u", left, right);
  56. LOCK;
  57. output.gainL = left;
  58. output.gainR = right;
  59. UNLOCK;
  60. }
  61. #endif
  62. void output_bt_check_buffer()
  63. {
  64. #ifdef USE_BT_RING_BUFFER
  65. LOCK_BT;
  66. uint8_t tot_buf_used_pct=100*_buf_used(btbuf)/btbuf->size;
  67. UNLOCK_BT;
  68. if(tot_buf_used_pct<bt_buf_used_threshold)
  69. {
  70. // tell the thread to resume
  71. LOG_SDEBUG("Below threshold. Locking suspend mutex.");
  72. mutex_lock(output_bt_suspend_mutex);
  73. LOG_SDEBUG("Broadcasting suspend condition.");
  74. mutex_broadcast_cond(output_bt_suspend_cond);
  75. LOG_SDEBUG("Unlocking suspend mutex.");
  76. mutex_unlock(output_bt_suspend_mutex);
  77. }
  78. #endif
  79. }
  80. void output_bt_suspend()
  81. {
  82. #ifdef USE_BT_RING_BUFFER
  83. struct timespec ts;
  84. struct timeval tp;
  85. int rc;
  86. // if suspended, suspend until resumed
  87. LOG_SDEBUG("Locking suspend mutex.");
  88. mutex_lock(output_bt_suspend_mutex);
  89. LOG_SDEBUG("Waiting on condition to be signaled.");
  90. // suspend for up to a predetermined wait time.
  91. // this will allow flushing the BT buffer when the
  92. // playback stops.
  93. gettimeofday(&tp, NULL);
  94. /* Convert from timeval to timespec */
  95. ts.tv_sec = tp.tv_sec;
  96. ts.tv_nsec = tp.tv_usec * 1000;
  97. ts.tv_nsec += output_bt_thread_heartbeat_ms*1000000; // micro seconds to nanosecs
  98. rc = pthread_cond_timedwait(&output_bt_suspend_cond,&output_bt_suspend_mutex,&ts);
  99. if(rc==ETIMEDOUT)
  100. {
  101. LOG_SDEBUG("Wait timed out. Resuming output.");
  102. }
  103. LOG_SDEBUG("Unlocking suspend mutex.");
  104. mutex_unlock(output_bt_suspend_mutex);
  105. #endif
  106. }
  107. void output_init_bt(log_level level, char *device, unsigned output_buf_size, char *params, unsigned rates[], unsigned rate_delay, unsigned idle) {
  108. loglevel = level;
  109. LOG_INFO("init output BT");
  110. memset(&output, 0, sizeof(output));
  111. // ensure output rate is specified to avoid test open
  112. if (!rates[0]) {
  113. rates[0] = 44100;
  114. }
  115. hal_bluetooth_init(loglevel);
  116. /*
  117. * Bluetooth audio source init Start
  118. */
  119. device = CONFIG_OUTPUT_NAME;
  120. output_init_common(level, device, output_buf_size, rates, idle);
  121. #ifdef USE_BT_RING_BUFFER
  122. LOG_DEBUG("Allocating local BT transfer buffer of %u bytes.",bt_buffer_size);
  123. buf_init(btbuf, bt_buffer_size );
  124. if (!btbuf->buf) {
  125. LOG_ERROR("unable to malloc BT buffer");
  126. exit(0);
  127. }
  128. mutex_create_p(output_bt_suspend_mutex);
  129. mutex_cond_init(output_bt_suspend_cond);
  130. PTHREAD_SET_NAME("output_bt");
  131. #if LINUX || OSX || FREEBSD || POSIX
  132. pthread_attr_t attr;
  133. pthread_attr_init(&attr);
  134. #ifdef PTHREAD_STACK_MIN
  135. pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN + OUTPUT_THREAD_STACK_SIZE);
  136. #endif
  137. pthread_create(&thread_bt, &attr, output_thread_bt, NULL);
  138. #endif
  139. pthread_attr_destroy(&attr);
  140. #if WIN
  141. thread = CreateThread(NULL, OUTPUT_THREAD_STACK_SIZE, (LPTHREAD_START_ROUTINE)&output_thread_bt, NULL, 0, NULL);
  142. #endif
  143. #else
  144. output.start_frames = FRAME_BLOCK;
  145. output.write_cb = &_write_frames;
  146. output.rate_delay = rate_delay;
  147. #endif
  148. LOG_INFO("Init completed.");
  149. }
  150. /****************************************************************************************
  151. * Main output thread
  152. */
  153. #ifdef USE_BT_RING_BUFFER
  154. static void *output_thread_bt() {
  155. frames_t frames=0;
  156. frames_t requested_frames=0;
  157. uint32_t timer_start=0, mutex_start=0;
  158. unsigned btbuf_used=0;
  159. output_state state;
  160. DECLARE_ALL_MIN_MAX;
  161. while (running) {
  162. frames=0;
  163. requested_frames=0;
  164. TIME_MEASUREMENT_START(timer_start);
  165. // Get output state
  166. TIME_MEASUREMENT_START(mutex_start);
  167. LOCK;
  168. state=output.state;
  169. SET_MIN_MAX(TIME_MEASUREMENT_GET(mutex_start),mutex1);
  170. if(state < OUTPUT_STOPPED ){
  171. // Flushing the buffer will automatically
  172. // lock the mutex
  173. LOG_SDEBUG("Flushing BT buffer");
  174. buf_flush(btbuf);
  175. }
  176. if (state == OUTPUT_OFF) {
  177. UNLOCK;
  178. LOG_SDEBUG("Output state is off.");
  179. usleep(200000);
  180. continue;
  181. }
  182. output.device_frames = 0; // todo: check if this is the right way do to this.
  183. output.updated = gettime_ms();
  184. output.frames_played_dmp = output.frames_played;
  185. TIME_MEASUREMENT_START(mutex_start);
  186. LOCK_BT;
  187. SET_MIN_MAX(TIME_MEASUREMENT_GET(mutex_start),mutex2);
  188. btbuf_used=_buf_used(btbuf);
  189. SET_MIN_MAX_SIZED(btbuf_used,locbtbuff,btbuf->size);
  190. // only output more frames if we need them
  191. // so we can release the mutex as quickly as possible
  192. requested_frames = min(_buf_space(btbuf), _buf_cont_write(btbuf))/BYTES_PER_FRAME;
  193. SET_MIN_MAX( requested_frames*BYTES_PER_FRAME,req);
  194. SET_MIN_MAX_SIZED(_buf_used(outputbuf),o,outputbuf->size);
  195. SET_MIN_MAX_SIZED(_buf_used(streambuf),s,streambuf->size);
  196. if(requested_frames>0)
  197. {
  198. frames = _output_frames( requested_frames ); // Keep the transfer buffer full
  199. SET_MIN_MAX(frames*BYTES_PER_FRAME,rec);
  200. if(requested_frames>frames){
  201. SET_MIN_MAX((requested_frames-frames)*BYTES_PER_FRAME,under);
  202. }
  203. }
  204. UNLOCK;
  205. UNLOCK_BT;
  206. SET_MIN_MAX( TIME_MEASUREMENT_GET(timer_start),buffering);
  207. SET_MIN_MAX( requested_frames,req);
  208. // When playback has started, we want to
  209. // hold the BT out thread
  210. // so the BT data callback isn't constantly interrupted.
  211. TIME_MEASUREMENT_START(timer_start);
  212. if(state>OUTPUT_BUFFER){
  213. output_bt_suspend();
  214. }
  215. SET_MIN_MAX(TIME_MEASUREMENT_GET(timer_start),sleep_time);
  216. /*
  217. * Statistics reporting
  218. */
  219. static time_t lastTime=0;
  220. if (lastTime <= gettime_ms() )
  221. {
  222. #define STATS_PERIOD_MS 15000
  223. lastTime = gettime_ms() + STATS_PERIOD_MS;
  224. LOG_DEBUG(LINE_MIN_MAX_FORMAT_HEAD1);
  225. LOG_DEBUG(LINE_MIN_MAX_FORMAT_HEAD2);
  226. LOG_DEBUG(LINE_MIN_MAX_FORMAT_HEAD3);
  227. LOG_DEBUG(LINE_MIN_MAX_FORMAT_HEAD4);
  228. LOG_DEBUG(LINE_MIN_MAX_FORMAT_STREAM, LINE_MIN_MAX_STREAM("stream",s));
  229. LOG_DEBUG(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("output",o));
  230. LOG_DEBUG(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("local bt buf",locbtbuff));
  231. LOG_DEBUG(LINE_MIN_MAX_FORMAT_FOOTER );
  232. LOG_DEBUG(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("requested",req));
  233. LOG_DEBUG(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("received",rec));
  234. LOG_DEBUG(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("Underrun",under));
  235. LOG_DEBUG(LINE_MIN_MAX_FORMAT_FOOTER );
  236. LOG_DEBUG("");
  237. LOG_DEBUG(" ----------+----------+-----------+-----------+ ");
  238. LOG_DEBUG(" max (us) | min (us) | avg(us) | count | ");
  239. LOG_DEBUG(" ----------+----------+-----------+-----------+ ");
  240. LOG_DEBUG(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("Buffering(us)",buffering));
  241. LOG_DEBUG(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("Output mux(us)",mutex1));
  242. LOG_DEBUG(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("BT mux(us)",mutex2));
  243. LOG_DEBUG(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("sleep(us)",mutex2));
  244. LOG_DEBUG(" ----------+----------+-----------+-----------+");
  245. RESET_ALL_MIN_MAX;
  246. }
  247. /*
  248. * End Statistics reporting
  249. */
  250. }
  251. return NULL;
  252. }
  253. #endif
  254. void output_close_bt(void) {
  255. LOG_INFO("close output");
  256. LOCK;
  257. running = false;
  258. UNLOCK;
  259. #ifdef USE_BT_RING_BUFFER
  260. LOCK_BT;
  261. buf_destroy(btbuf);
  262. UNLOCK_BT;
  263. #endif
  264. output_close_common();
  265. }
  266. static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR,
  267. s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr) {
  268. #ifdef USE_BT_RING_BUFFER
  269. if (!silence ) {
  270. DEBUG_LOG_TIMED(200,"Not silence, Writing audio out.");
  271. // TODO need 16 bit fix
  272. if (output.fade == FADE_ACTIVE && output.fade_dir == FADE_CROSS && *cross_ptr) {
  273. _apply_cross(outputbuf, out_frames, cross_gain_in, cross_gain_out, cross_ptr);
  274. }
  275. if (gainL != FIXED_ONE || gainR!= FIXED_ONE) {
  276. _apply_gain(outputbuf, out_frames, gainL, gainR);
  277. }
  278. #if BYTES_PER_FRAME == 4
  279. memcpy(btbuf->writep, outputbuf->readp, out_frames * BYTES_PER_FRAME);
  280. _buf_inc_writep(btbuf,out_frames * BYTES_PER_FRAME);
  281. #else
  282. {
  283. frames_t count = out_frames;
  284. s32_t *_iptr = (s32_t*) outputbuf->readp;
  285. s16_t *_optr = (s16_t*) bt_optr;
  286. while (count--) {
  287. *_optr++ = *_iptr++ >> 16;
  288. *_optr++ = *_iptr++ >> 16;
  289. }
  290. }
  291. #endif
  292. } else if(output.state >OUTPUT_BUFFER){
  293. // Don't fill our local buffer with silence frames.
  294. u8_t *buf = silencebuf;
  295. memcpy(btbuf->writep, buf, out_frames * BYTES_PER_FRAME);
  296. _buf_inc_writep(btbuf,out_frames * BYTES_PER_FRAME);
  297. }
  298. #else
  299. assert(btout!=NULL);
  300. if (!silence ) {
  301. DEBUG_LOG_TIMED(200,"Not silence, Writing audio out.");
  302. // TODO need 16 bit fix
  303. if (output.fade == FADE_ACTIVE && output.fade_dir == FADE_CROSS && *cross_ptr) {
  304. _apply_cross(outputbuf, out_frames, cross_gain_in, cross_gain_out, cross_ptr);
  305. }
  306. if (gainL != FIXED_ONE || gainR!= FIXED_ONE) {
  307. _apply_gain(outputbuf, out_frames, gainL, gainR);
  308. }
  309. #if BYTES_PER_FRAME == 4
  310. memcpy(btout, outputbuf->readp, out_frames * BYTES_PER_FRAME);
  311. #else
  312. {
  313. frames_t count = out_frames;
  314. s32_t *_iptr = (s32_t*) outputbuf->readp;
  315. s16_t *_optr = (s16_t*) bt_optr;
  316. while (count--) {
  317. *_optr++ = *_iptr++ >> 16;
  318. *_optr++ = *_iptr++ >> 16;
  319. }
  320. }
  321. #endif
  322. } else {
  323. u8_t *buf = silencebuf;
  324. memcpy(btout, buf, out_frames * BYTES_PER_FRAME);
  325. }
  326. #endif
  327. return (int)out_frames;
  328. }