output_bt.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  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. size_t bt_buffer_size=0;
  9. static struct buffer bt_buf_structure;
  10. struct buffer *btbuf=&bt_buf_structure;
  11. #define LOCK mutex_lock(outputbuf->mutex)
  12. #define UNLOCK mutex_unlock(outputbuf->mutex)
  13. #define LOCK_BT mutex_lock(btbuf->mutex)
  14. #define UNLOCK_BT mutex_unlock(btbuf->mutex)
  15. #define FRAME_BLOCK MAX_SILENCE_FRAMES
  16. #define BUFFERING_FRAME_BLOCK FRAME_BLOCK*2
  17. extern u8_t *silencebuf;
  18. void hal_bluetooth_init(log_level);
  19. static void *output_thread_bt();
  20. static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR,
  21. s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr);
  22. extern void wait_for_frames(size_t frames, uint8_t pct);
  23. #define DECLARE_ALL_MIN_MAX \
  24. DECLARE_MIN_MAX(req, long,LONG); \
  25. DECLARE_MIN_MAX(rec, long,LONG); \
  26. DECLARE_MIN_MAX(o, long,LONG); \
  27. DECLARE_MIN_MAX(s, long,LONG); \
  28. DECLARE_MIN_MAX(d, long,LONG); \
  29. DECLARE_MIN_MAX(locbtbuff, long,LONG); \
  30. DECLARE_MIN_MAX(mutex1, long,LONG); \
  31. DECLARE_MIN_MAX(mutex2, long,LONG); \
  32. DECLARE_MIN_MAX(total, long,LONG); \
  33. DECLARE_MIN_MAX(buffering, long,LONG);
  34. #define RESET_ALL_MIN_MAX \
  35. RESET_MIN_MAX(d,LONG); \
  36. RESET_MIN_MAX(o,LONG); \
  37. RESET_MIN_MAX(s,LONG); \
  38. RESET_MIN_MAX(locbtbuff, LONG); \
  39. RESET_MIN_MAX(req,LONG); \
  40. RESET_MIN_MAX(rec,LONG); \
  41. RESET_MIN_MAX(mutex1,LONG); \
  42. RESET_MIN_MAX(mutex2,LONG); \
  43. RESET_MIN_MAX(total,LONG); \
  44. RESET_MIN_MAX(buffering,LONG);
  45. #if CONFIG_BTAUDIO
  46. void set_volume_bt(unsigned left, unsigned right) {
  47. LOG_DEBUG("setting internal gain left: %u right: %u", left, right);
  48. LOCK;
  49. output.gainL = left;
  50. output.gainR = right;
  51. UNLOCK;
  52. }
  53. #endif
  54. static thread_type thread_bt;
  55. void output_init_bt(log_level level, char *device, unsigned output_buf_size, char *params, unsigned rates[], unsigned rate_delay, unsigned idle) {
  56. loglevel = level;
  57. LOG_INFO("init output BT");
  58. memset(&output, 0, sizeof(output));
  59. output.start_frames = FRAME_BLOCK; //CONFIG_ //FRAME_BLOCK * 2;
  60. output.write_cb = &_write_frames;
  61. output.rate_delay = rate_delay;
  62. // ensure output rate is specified to avoid test open
  63. if (!rates[0]) {
  64. rates[0] = 44100;
  65. }
  66. hal_bluetooth_init(loglevel);
  67. /*
  68. * Bluetooth audio source init Start
  69. */
  70. device = CONFIG_OUTPUT_NAME;
  71. output_init_common(level, device, output_buf_size, rates, idle);
  72. bt_buffer_size = 3*FRAME_BLOCK*get_bytes_per_frame(output.format);
  73. LOG_DEBUG("Allocating local BT transfer buffer of %u bytes.",bt_buffer_size);
  74. buf_init(btbuf, bt_buffer_size );
  75. if (!btbuf->buf) {
  76. LOG_ERROR("unable to malloc BT buffer");
  77. exit(0);
  78. }
  79. #if LINUX || OSX || FREEBSD || POSIX
  80. pthread_attr_t attr;
  81. pthread_attr_init(&attr);
  82. #ifdef PTHREAD_STACK_MIN
  83. pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN + OUTPUT_THREAD_STACK_SIZE);
  84. #endif
  85. pthread_create(&thread_bt, &attr, output_thread_bt, NULL);
  86. pthread_attr_destroy(&attr);
  87. #endif
  88. #if WIN
  89. thread = CreateThread(NULL, OUTPUT_THREAD_STACK_SIZE, (LPTHREAD_START_ROUTINE)&output_thread_bt, NULL, 0, NULL);
  90. #endif
  91. LOG_INFO("Init completed.");
  92. }
  93. /****************************************************************************************
  94. * Main output thread
  95. */
  96. static void *output_thread_bt() {
  97. frames_t frames=0;
  98. frames_t available_frames_space=0;
  99. uint32_t timer_start=0, mutex_start=0, total_start=0;
  100. static int count = 0;
  101. DECLARE_ALL_MIN_MAX;
  102. while (running) {
  103. frames=0;
  104. available_frames_space=0;
  105. TIME_MEASUREMENT_START(timer_start);
  106. TIME_MEASUREMENT_START(total_start);
  107. TIME_MEASUREMENT_START(mutex_start);
  108. LOCK;
  109. SET_MIN_MAX(TIME_MEASUREMENT_GET(mutex_start),mutex1);
  110. if (output.state == OUTPUT_OFF) {
  111. UNLOCK;
  112. LOG_SDEBUG("Output state is off.");
  113. usleep(500000);
  114. continue;
  115. }
  116. TIME_MEASUREMENT_START(mutex_start);
  117. LOCK_BT;
  118. SET_MIN_MAX(TIME_MEASUREMENT_GET(mutex_start),mutex2);
  119. available_frames_space = min(_buf_space(btbuf), _buf_cont_write(btbuf))/BYTES_PER_FRAME;
  120. SET_MIN_MAX( available_frames_space,req);
  121. SET_MIN_MAX(_buf_used(outputbuf)/BYTES_PER_FRAME,o);
  122. SET_MIN_MAX(_buf_used(streambuf)/BYTES_PER_FRAME,s);
  123. if(available_frames_space==0)
  124. {
  125. UNLOCK;
  126. UNLOCK_BT;
  127. usleep(10000);
  128. continue;
  129. }
  130. frames = _output_frames( available_frames_space ); // Keep the transfer buffer full
  131. SET_MIN_MAX(_buf_used(btbuf),locbtbuff);
  132. UNLOCK;
  133. UNLOCK_BT;
  134. //LOG_SDEBUG("Current buffer free: %10d, cont read: %10d",_buf_space(btbuf),_buf_cont_read(btbuf));
  135. SET_MIN_MAX( TIME_MEASUREMENT_GET(timer_start),buffering);
  136. SET_MIN_MAX( available_frames_space,req);
  137. SET_MIN_MAX(frames,rec);
  138. // if(frames>0 ){
  139. // // let's hold processing a bit, while frames are being processed
  140. // // we're waiting long enough to avoid hogging the CPU too much
  141. // // while we're ramping up this transfer buffer
  142. // wait_for_frames(frames,95);
  143. // }
  144. wait_for_frames(FRAME_BLOCK,100);
  145. /*
  146. * Statistics reporting
  147. */
  148. #define STATS_PERIOD_MS 10000
  149. count++;
  150. TIMED_SECTION_START_MS(STATS_PERIOD_MS);
  151. if(count>1){
  152. LOG_INFO( "count:%d, current sample rate: %d, avg cycle duration (ms): %d",count,output.current_sample_rate, STATS_PERIOD_MS/count);
  153. LOG_INFO( " ----------+----------+-----------+-----------+ +----------+----------+----------------+----------------+----------------+");
  154. LOG_INFO( " max | min | avg | current| | max | min | average | count | current |");
  155. LOG_INFO( " (ms) | (ms) | (ms)| (ms) | | (bytes) | (bytes) | (bytes) | | (bytes) |");
  156. LOG_INFO( " ----------+----------+-----------+-----------+ +----------+----------+----------------+----------------+----------------+");
  157. LOG_INFO(LINE_MIN_MAX_FORMAT_STREAM, LINE_MIN_MAX_STREAM("stream",s));
  158. LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("output",o));
  159. LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("requested",req));
  160. LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("received",rec));
  161. LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("local bt buf",locbtbuff));
  162. LOG_INFO(" ----------+----------+-----------+-----------+ +----------+----------+----------------+----------------+");
  163. LOG_INFO("");
  164. LOG_INFO(" ----------+----------+-----------+-----------+-----------+ ");
  165. LOG_INFO(" max (us) | min (us) | avg(us) | count |current(us)| ");
  166. LOG_INFO(" ----------+----------+-----------+-----------+-----------+ ");
  167. LOG_INFO(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("Buffering(us)",buffering));
  168. LOG_INFO(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("Output mux(us)",mutex1));
  169. LOG_INFO(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("BT mux(us)",mutex2));
  170. LOG_INFO(" ----------+----------+-----------+-----------+-----------+");
  171. RESET_ALL_MIN_MAX;
  172. count=0;
  173. }
  174. TIMED_SECTION_END;
  175. /*
  176. * End Statistics reporting
  177. */
  178. }
  179. return 0;
  180. }
  181. void output_close_bt(void) {
  182. LOG_INFO("close output");
  183. LOCK;
  184. running = false;
  185. UNLOCK;
  186. output_close_common();
  187. }
  188. static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR,
  189. s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr) {
  190. if (!silence ) {
  191. DEBUG_LOG_TIMED(200,"Not silence, Writing audio out.");
  192. // TODO need 16 bit fix
  193. if (output.fade == FADE_ACTIVE && output.fade_dir == FADE_CROSS && *cross_ptr) {
  194. _apply_cross(outputbuf, out_frames, cross_gain_in, cross_gain_out, cross_ptr);
  195. }
  196. if (gainL != FIXED_ONE || gainR!= FIXED_ONE) {
  197. _apply_gain(outputbuf, out_frames, gainL, gainR);
  198. }
  199. #if BYTES_PER_FRAME == 4
  200. memcpy(btbuf->writep, outputbuf->readp, out_frames * BYTES_PER_FRAME);
  201. #else
  202. {
  203. frames_t count = out_frames;
  204. s32_t *_iptr = (s32_t*) outputbuf->readp;
  205. s16_t *_optr = (s16_t*) bt_optr;
  206. while (count--) {
  207. *_optr++ = *_iptr++ >> 16;
  208. *_optr++ = *_iptr++ >> 16;
  209. }
  210. }
  211. #endif
  212. } else {
  213. DEBUG_LOG_TIMED(200,"Silence flag true. Writing silence to audio out.");
  214. u8_t *buf = silencebuf;
  215. memcpy(btbuf->writep, buf, out_frames * BYTES_PER_FRAME);
  216. }
  217. _buf_inc_writep(btbuf,out_frames * BYTES_PER_FRAME);
  218. return (int)out_frames;
  219. }