1 /*
2 This file is part of Deadbeef Player source code
3 http://deadbeef.sourceforge.net
4
5 streamer implementation
6
7 Copyright (C) 2009-2013 Alexey Yakovenko
8
9 This software is provided 'as-is', without any express or implied
10 warranty. In no event will the authors be held liable for any damages
11 arising from the use of this software.
12
13 Permission is granted to anyone to use this software for any purpose,
14 including commercial applications, and to alter it and redistribute it
15 freely, subject to the following restrictions:
16
17 1. The origin of this software must not be misrepresented; you must not
18 claim that you wrote the original software. If you use this software
19 in a product, an acknowledgment in the product documentation would be
20 appreciated but is not required.
21 2. Altered source versions must be plainly marked as such, and must not be
22 misrepresented as being the original software.
23 3. This notice may not be removed or altered from any source distribution.
24
25 Alexey Yakovenko waker@users.sourceforge.net
26 */
27 #include <stdlib.h>
28 #include <string.h>
29 #include <stdio.h>
30 #include <assert.h>
31 #include <unistd.h>
32 #ifdef __linux__
33 #include <sys/prctl.h>
34 #endif
35 #include <sys/time.h>
36 #include <errno.h>
37 #include "threading.h"
38 #include "playlist.h"
39 #include "common.h"
40 #include "streamer.h"
41 #include "messagepump.h"
42 #include "conf.h"
43 #include "plugins.h"
44 #include "fastftoi.h"
45 #include "volume.h"
46 #include "vfs.h"
47 #include "premix.h"
48 #include "ringbuf.h"
49 #include "replaygain.h"
50 #include "fft.h"
51 #include "handler.h"
52 #include "plugins/libparser/parser.h"
53 #include "strdupa.h"
54 #include "playqueue.h"
55
56 //#define trace(...) { fprintf(stderr, __VA_ARGS__); }
57 #define trace(fmt,...)
58
59 //#define WRITE_DUMP 1
60 //#define DETECT_PL_LOCK_RC 1
61
62 #if WRITE_DUMP
63 FILE *out;
64 #endif
65
66 #define MAX_PLAYLIST_DOWNLOAD_SIZE 25000
67 #define STREAMER_HINTS (DDB_DECODER_HINT_NEED_BITRATE|DDB_DECODER_HINT_CAN_LOOP)
68
69 static int
70 streamer_read_async (char *bytes, int size);
71
72 static int
73 streamer_set_output_format (void);
74
75 static intptr_t streamer_tid;
76 static ddb_dsp_context_t *dsp_chain;
77 static float dsp_ratio = 1;
78
79 static DB_dsp_t *eqplug;
80 static ddb_dsp_context_t *eq;
81
82 static int dsp_on = 0;
83
84 static char *dsp_input_buffer;
85 static int dsp_input_buffer_size;
86
87 static char *dsp_temp_buffer;
88 static int dsp_temp_buffer_size;
89
90 static int autoconv_8_to_16 = 1;
91
92 static int autoconv_16_to_24 = 0;
93
94 static int trace_bufferfill = 0;
95
96 static int stop_after_current = 0;
97 static int stop_after_album = 0;
98
99 static int conf_streamer_nosleep = 0;
100
101 static int streaming_terminate;
102
103 // buffer up to 3 seconds at 44100Hz stereo
104 #define STREAM_BUFFER_SIZE 0x80000 // slightly more than 3 seconds of 44100 stereo
105
106 // how much bigger should read-buffer be to allow upsampling.
107 // e.g. 8000Hz -> 192000Hz upsampling requires 24x buffer size,
108 // so if we originally request 4096 bytes blocks -
109 // that will require 24x buffer size, which is 98304 bytes buffer
110 #define MAX_DSP_RATIO 24
111
112 #define MIN_BLOCK_SIZE 4096
113 #define MAX_BLOCK_SIZE 16384
114 #define READBUFFER_SIZE (MAX_BLOCK_SIZE * MAX_DSP_RATIO)
115 static char readbuffer[READBUFFER_SIZE];
116
117 static ringbuf_t streamer_ringbuf;
118 static char streambuffer[STREAM_BUFFER_SIZE];
119
120 static int bytes_until_next_song = 0;
121 static uintptr_t mutex;
122 static uintptr_t currtrack_mutex;
123 static uintptr_t wdl_mutex; // wavedata listener
124
125 static int nextsong = -1;
126 static int nextsong_pstate = -1;
127 static int badsong = -1;
128
129 static float last_seekpos = -1;
130
131 static float playpos = 0; // play position of current song
132 static int avg_bitrate = -1; // avg bitrate of current song
133 static int last_bitrate = -1; // last bitrate of current song
134
135 static playlist_t *streamer_playlist;
136 static playItem_t *playing_track;
137 static float playtime; // total playtime of playing track
138 static time_t started_timestamp; // result of calling time(NULL)
139 static playItem_t *streaming_track;
140 static playItem_t *playlist_track;
141
142 static ddb_waveformat_t output_format; // format that was requested after DSP
143 static ddb_waveformat_t orig_output_format; // format that was requested before DSP
144 static int formatchanged;
145
146 static DB_fileinfo_t *fileinfo;
147 static DB_FILE *fileinfo_file;
148 static DB_fileinfo_t *new_fileinfo;
149 static DB_FILE *new_fileinfo_file;
150
151 static int streamer_buffering;
152
153 // to allow interruption of stall file requests
154 static DB_FILE *streamer_file;
155
156 // for vis plugins
157 static float freq_data[DDB_FREQ_BANDS * DDB_FREQ_MAX_CHANNELS];
158 static float audio_data[DDB_FREQ_BANDS * 2 * DDB_FREQ_MAX_CHANNELS];
159 static int audio_data_fill = 0;
160 static int audio_data_channels = 0;
161
162 // message queue
163 static struct handler_s *handler;
164
165 // visualization stuff
166 typedef struct wavedata_listener_s {
167 void *ctx;
168 void (*callback)(void *ctx, ddb_audio_data_t *data);
169 struct wavedata_listener_s *next;
170 } wavedata_listener_t;
171
172 static wavedata_listener_t *waveform_listeners;
173 static wavedata_listener_t *spectrum_listeners;
174
175 #if DETECT_PL_LOCK_RC
176 volatile pthread_t streamer_lock_tid = 0;
177 #endif
178 void
streamer_lock(void)179 streamer_lock (void) {
180 #if DETECT_PL_LOCK_RC
181 extern pthread_t pl_lock_tid;
182 assert (pl_lock_tid != pthread_self()); // not permitted to lock streamer from inside of pl_lock
183 #endif
184 mutex_lock (mutex);
185 #if DETECT_PL_LOCK_RC
186 streamer_lock_tid = pthread_self();
187 #endif
188 }
189
190 void
streamer_unlock(void)191 streamer_unlock (void) {
192 #if DETECT_PL_LOCK_RC
193 streamer_lock_tid = 0;
194 #endif
195 mutex_unlock (mutex);
196 }
197
198 static void
199 streamer_set_nextsong_real (int song, int pstate);
200
201 static int
202 streamer_move_to_nextsong_real (int r);
203
204 static int
205 streamer_move_to_prevsong_real (int r);
206
207 static int
208 streamer_move_to_randomsong_real (int r);
209
210 static void
211 streamer_play_current_track_real (void);
212
213 static void
214 streamer_set_current_playlist_real (int plt);
215
216
217 static void
streamer_abort_files(void)218 streamer_abort_files (void) {
219 DB_FILE *file = fileinfo_file;
220 DB_FILE *newfile = new_fileinfo_file;
221 DB_FILE *strfile = streamer_file;
222 trace ("\033[0;33mstreamer_abort_files\033[37;0m\n");
223 trace ("%p %p %p\n", file, newfile, strfile);
224
225 if (file) {
226 deadbeef->fabort (file);
227 }
228 if (newfile) {
229 deadbeef->fabort (newfile);
230 }
231 if (strfile) {
232 deadbeef->fabort (strfile);
233 }
234
235 }
236
237 static void
streamer_set_replaygain(playItem_t * it)238 streamer_set_replaygain (playItem_t *it) {
239 // setup replaygain
240 pl_lock ();
241 const char *gain;
242 gain = pl_find_meta (it, ":REPLAYGAIN_ALBUMGAIN");
243 float albumgain = gain ? atof (gain) : 1000;
244 float albumpeak = pl_get_item_replaygain (it, DDB_REPLAYGAIN_ALBUMPEAK);
245
246 gain = pl_find_meta (it, ":REPLAYGAIN_TRACKGAIN");
247 float trackgain = gain ? atof (gain) : 1000;
248 float trackpeak = pl_get_item_replaygain (it, DDB_REPLAYGAIN_TRACKPEAK);
249 pl_unlock ();
250 replaygain_set_values (albumgain, albumpeak, trackgain, trackpeak);
251 }
252
253 static void
send_songstarted(playItem_t * trk)254 send_songstarted (playItem_t *trk) {
255 ddb_event_track_t *pev = (ddb_event_track_t *)messagepump_event_alloc (DB_EV_SONGSTARTED);
256 pev->track = DB_PLAYITEM (trk);
257 pl_item_ref (trk);
258 pev->playtime = 0;
259 pev->started_timestamp = time(NULL);
260 messagepump_push_event ((ddb_event_t*)pev, 0, 0);
261 }
262
263 static void
send_songfinished(playItem_t * trk)264 send_songfinished (playItem_t *trk) {
265 ddb_event_track_t *pev = (ddb_event_track_t *)messagepump_event_alloc (DB_EV_SONGFINISHED);
266 pev->track = DB_PLAYITEM (trk);
267 pl_item_ref (trk);
268 pev->playtime = playtime;
269 pev->started_timestamp = started_timestamp;
270 messagepump_push_event ((ddb_event_t*)pev, 0, 0);
271 }
272
273 static void
send_trackchanged(playItem_t * from,playItem_t * to)274 send_trackchanged (playItem_t *from, playItem_t *to) {
275 ddb_event_trackchange_t *event = (ddb_event_trackchange_t *)messagepump_event_alloc (DB_EV_SONGCHANGED);
276 event->playtime = playtime;
277 event->started_timestamp = started_timestamp;
278 if (from) {
279 pl_item_ref (from);
280 }
281 if (to) {
282 pl_item_ref (to);
283 }
284 event->from = (DB_playItem_t *)from;
285 event->to = (DB_playItem_t *)to;
286 messagepump_push_event ((ddb_event_t *)event, 0, 0);
287 }
288
289 static void
streamer_start_playback(playItem_t * from,playItem_t * it)290 streamer_start_playback (playItem_t *from, playItem_t *it) {
291 if (from) {
292 pl_item_ref (from);
293 }
294 if (it) {
295 pl_item_ref (it);
296 }
297 // free old copy of playing
298 if (playing_track) {
299 pl_item_unref (playing_track);
300 playing_track = NULL;
301 }
302 pl_lock ();
303 playlist_track = it;
304 pl_unlock ();
305 // assign new
306 playing_track = it;
307 if (playing_track) {
308 pl_item_ref (playing_track);
309
310 playing_track->played = 1;
311 trace ("from=%p (%s), to=%p (%s) [2]\n", from, from ? pl_find_meta (from, ":URI") : "null", it, it ? pl_find_meta (it, ":URI") : "null");
312 send_trackchanged (from, it);
313 started_timestamp = time (NULL);
314 }
315 if (from) {
316 pl_item_unref (from);
317 }
318 if (it) {
319 pl_item_unref (it);
320 }
321 trace ("streamer_start_playback %s\n", playing_track ? pl_find_meta (playing_track, ":URI") : "null");
322 }
323
324 playItem_t *
streamer_get_streaming_track(void)325 streamer_get_streaming_track (void) {
326 if (streaming_track) {
327 pl_item_ref (streaming_track);
328 }
329 return streaming_track;
330 }
331
332 playItem_t *
streamer_get_playing_track(void)333 streamer_get_playing_track (void) {
334 playItem_t *it = playing_track;// ? playing_track : playlist_track;
335 if (it) {
336 pl_item_ref (it);
337 }
338 return it;
339 }
340
341 int
str_get_idx_of(playItem_t * it)342 str_get_idx_of (playItem_t *it) {
343 pl_lock ();
344 if (!streamer_playlist) {
345 streamer_playlist = plt_get_curr ();
346 }
347 playItem_t *c = streamer_playlist->head[PL_MAIN];
348 int idx = 0;
349 while (c && c != it) {
350 c = c->next[PL_MAIN];
351 idx++;
352 }
353 if (!c) {
354 pl_unlock ();
355 return -1;
356 }
357 pl_unlock ();
358 return idx;
359 }
360
361 playItem_t *
str_get_for_idx(int idx)362 str_get_for_idx (int idx) {
363 pl_lock ();
364 if (!streamer_playlist) {
365 streamer_playlist = plt_get_curr ();
366 }
367 playItem_t *it = streamer_playlist->head[PL_MAIN];
368 while (idx--) {
369 if (!it) {
370 pl_unlock ();
371 return NULL;
372 }
373 it = it->next[PL_MAIN];
374 }
375 if (it) {
376 pl_item_ref (it);
377 }
378 pl_unlock ();
379 return it;
380 }
381
382 static int
stop_after_album_check(playItem_t * cur,playItem_t * next)383 stop_after_album_check (playItem_t *cur, playItem_t *next) {
384 if (!stop_after_album) {
385 return 0;
386 }
387
388 if (!cur) {
389 return 0;
390 }
391
392 if (!next) {
393 streamer_buffering = 0;
394 streamer_set_nextsong_real (-2, -2);
395 if (conf_get_int ("playlist.stop_after_album_reset", 0)) {
396 conf_set_int ("playlist.stop_after_album", 0);
397 stop_after_album = 0;
398 deadbeef->sendmessage (DB_EV_CONFIGCHANGED, 0, 0, 0);
399 }
400 return 1;
401 }
402
403 const char *cur_album = pl_find_meta_raw (cur, "album");
404 const char *next_album = pl_find_meta_raw (next, "album");
405
406 const char *keys[] = {
407 "band",
408 "album artist",
409 "albumartist",
410 "artist",
411 NULL
412 };
413
414 const char *cur_artist = NULL;
415 const char *next_artist = NULL;
416 for (int i = 0; keys[i]; i++) {
417 if (!cur_artist) {
418 cur_artist = pl_find_meta_raw (cur, keys[i]);
419 }
420 if (!next_artist) {
421 next_artist = pl_find_meta_raw (next, keys[i]);
422 }
423 if (cur_artist && next_artist) {
424 break;
425 }
426 }
427
428 if (cur_artist == next_artist && cur_album == next_album) {
429 return 0;
430 }
431
432 streamer_buffering = 0;
433 streamer_set_nextsong_real (-2, -2);
434 if (conf_get_int ("playlist.stop_after_album_reset", 0)) {
435 conf_set_int ("playlist.stop_after_album", 0);
436 stop_after_album = 0;
437 deadbeef->sendmessage (DB_EV_CONFIGCHANGED, 0, 0, 0);
438 }
439
440 return 1;
441 }
442
443 static int
streamer_move_to_nextsong_real(int reason)444 streamer_move_to_nextsong_real (int reason) {
445 if (reason) {
446 plug_get_output ()->stop ();
447 }
448 trace ("streamer_move_to_nextsong (%d)\n", reason);
449 pl_lock ();
450 if (!streamer_playlist) {
451 streamer_playlist = plt_get_curr ();
452 }
453
454 playItem_t *curr = playlist_track;
455
456 while (playqueue_getcount ()) {
457 trace ("playqueue_getnext\n");
458 playItem_t *it = playqueue_getnext ();
459 if (it) {
460 if (stop_after_album_check(curr, it)) {
461 pl_unlock ();
462 return -1;
463 }
464
465 playqueue_pop ();
466 int r = str_get_idx_of (it);
467 if (r >= 0) {
468 pl_item_unref (it);
469 pl_unlock ();
470 streamer_set_nextsong_real (r, 1);
471 return 0;
472 }
473 else {
474 trace ("%s not found in current streaming playlist\n", pl_find_meta (it, ":URI"));
475
476 playlist_t *p = pl_get_playlist (it);
477 if (p) {
478 if (streamer_playlist) {
479 plt_unref (streamer_playlist);
480 }
481 streamer_playlist = p;
482 int r = str_get_idx_of (it);
483 if (r >= 0) {
484 pl_item_unref (it);
485 pl_unlock ();
486 streamer_set_nextsong_real (r, 3);
487 return 0;
488 }
489 }
490 trace ("%s not found in any playlists\n", pl_find_meta (it, ":URI"));
491 pl_item_unref (it);
492 }
493 }
494 }
495
496 if (reason == 1) {
497 if (streamer_playlist) {
498 plt_unref (streamer_playlist);
499 }
500 streamer_playlist = plt_get_curr ();
501 // check if prev song is in this playlist
502 if (-1 == str_get_idx_of (curr)) {
503 curr = NULL;
504 }
505 }
506
507 playlist_t *plt = streamer_playlist;
508 if (!plt->head[PL_MAIN]) {
509 pl_unlock ();
510 streamer_set_nextsong_real (-2, 1);
511 return 0;
512 }
513 int pl_order = pl_get_order ();
514
515 int pl_loop_mode = conf_get_int ("playback.loop", 0);
516
517 if (reason == 0 && pl_loop_mode == PLAYBACK_MODE_LOOP_SINGLE) { // song finished, loop mode is "loop 1 track"
518 int r = str_get_idx_of (playing_track);
519 pl_unlock ();
520 if (r == -1) {
521 streamer_set_nextsong_real (-2, 1);
522 }
523 else {
524 streamer_set_nextsong_real (r, 1);
525 }
526 return 0;
527 }
528
529 if (pl_order == PLAYBACK_ORDER_SHUFFLE_TRACKS || pl_order == PLAYBACK_ORDER_SHUFFLE_ALBUMS) { // shuffle
530 if (!curr || pl_order == PLAYBACK_ORDER_SHUFFLE_TRACKS) {
531 // find minimal notplayed
532 playItem_t *pmin = NULL; // notplayed minimum
533 for (playItem_t *i = plt->head[PL_MAIN]; i; i = i->next[PL_MAIN]) {
534 if (i->played) {
535 continue;
536 }
537 if (!pmin || i->shufflerating < pmin->shufflerating) {
538 pmin = i;
539 }
540 }
541 playItem_t *it = pmin;
542 // although it is possible that, although it == NULL, reshuffling the playlist
543 // will result in the next track belonging to the same album as this one, this
544 // is most likely not what the user wants.
545 if (stop_after_album_check(curr, it)) {
546 pl_unlock ();
547 return -1;
548 }
549 if (!it) {
550 // all songs played, reshuffle and try again
551 if (pl_loop_mode == PLAYBACK_MODE_LOOP_ALL) { // loop
552 plt_reshuffle (streamer_playlist, &it, NULL);
553 }
554 }
555 if (!it) {
556 streamer_buffering = 0;
557 send_trackinfochanged (streaming_track);
558 playItem_t *temp;
559 plt_reshuffle (streamer_playlist, &temp, NULL);
560 pl_unlock ();
561 streamer_set_nextsong_real (-2, -2);
562 return -1;
563 }
564 int r = str_get_idx_of (it);
565 pl_unlock ();
566 streamer_set_nextsong_real (r, 1);
567 return 0;
568 }
569 else {
570 trace ("pl_next_song: reason=%d, loop=%d\n", reason, pl_loop_mode);
571 // find minimal notplayed above current
572 int rating = curr->shufflerating;
573 playItem_t *pmin = NULL; // notplayed minimum
574 for (playItem_t *i = plt->head[PL_MAIN]; i; i = i->next[PL_MAIN]) {
575 if (i->played || i->shufflerating < rating) {
576 continue;
577 }
578 if (!pmin || i->shufflerating < pmin->shufflerating) {
579 pmin = i;
580 }
581 }
582 playItem_t *it = pmin;
583 if (stop_after_album_check(curr, it)) {
584 pl_unlock ();
585 return -1;
586 }
587 if (!it) {
588 // all songs played, reshuffle and try again
589 if (pl_loop_mode == PLAYBACK_MODE_LOOP_ALL || reason == 1) { // loop
590 trace ("all songs played! reshuffle\n");
591 plt_reshuffle (streamer_playlist, &it, NULL);
592 }
593 }
594 if (!it) {
595 streamer_buffering = 0;
596 send_trackinfochanged (streaming_track);
597 playItem_t *temp;
598 plt_reshuffle (streamer_playlist, &temp, NULL);
599 pl_unlock ();
600 streamer_set_nextsong_real (-2, -2);
601 return -1;
602 }
603 int r = str_get_idx_of (it);
604 pl_unlock ();
605 streamer_set_nextsong_real (r, 1);
606 return 0;
607 }
608 }
609 else if (pl_order == PLAYBACK_ORDER_LINEAR) { // linear
610 DB_output_t *output = plug_get_output ();
611 playItem_t *it = NULL;
612 if (!curr && output->state () == OUTPUT_STATE_STOPPED) {
613 int cur = plt_get_cursor (streamer_playlist, PL_MAIN);
614 if (cur != -1) {
615 curr = plt_get_item_for_idx (streamer_playlist, cur, PL_MAIN);
616 pl_item_unref (curr);
617 }
618 }
619 if (curr) {
620 it = curr->next[PL_MAIN];
621 }
622 else {
623 it = streamer_playlist->head[PL_MAIN];
624 }
625 if (stop_after_album_check(curr, it)) {
626 pl_unlock ();
627 return -1;
628 }
629 if (!it) {
630 trace ("streamer_move_nextsong: was last track\n");
631 if (pl_loop_mode == PLAYBACK_MODE_LOOP_ALL) {
632 it = plt->head[PL_MAIN];
633 }
634 else {
635 streamer_buffering = 0;
636 send_trackinfochanged (streaming_track);
637 badsong = -1;
638 pl_unlock ();
639 streamer_set_nextsong_real (-2, -2);
640 return 0;
641 }
642 }
643 if (!it) {
644 pl_unlock ();
645 return -1;
646 }
647 int r = str_get_idx_of (it);
648 pl_unlock ();
649 streamer_set_nextsong_real (r, 1);
650 return 0;
651 }
652 else if (pl_order == PLAYBACK_ORDER_RANDOM) { // random
653 pl_unlock ();
654 int res = streamer_move_to_randomsong_real (0);
655 if (res == -1) {
656 trace ("streamer_move_to_randomsong error\n");
657 streamer_set_nextsong_real (-2, 1);
658 return -1;
659 }
660 return 0;
661 }
662 pl_unlock ();
663 return -1;
664 }
665
666 static int
streamer_move_to_prevsong_real(int r)667 streamer_move_to_prevsong_real (int r) {
668 if (r) {
669 plug_get_output ()->stop ();
670 }
671 pl_lock ();
672 if (streamer_playlist) {
673 plt_unref (streamer_playlist);
674 }
675 streamer_playlist = plt_get_curr ();
676 // check if prev song is in this playlist
677 if (-1 == str_get_idx_of (playlist_track)) {
678 playlist_track = NULL;
679 }
680
681 playlist_t *plt = streamer_playlist;
682 playqueue_clear ();
683 if (!plt->head[PL_MAIN]) {
684 pl_unlock ();
685 streamer_set_nextsong_real (-2, 1);
686 return 0;
687 }
688 int pl_order = conf_get_int ("playback.order", 0);
689 int pl_loop_mode = conf_get_int ("playback.loop", 0);
690 if (pl_order == PLAYBACK_ORDER_SHUFFLE_TRACKS || pl_order == PLAYBACK_ORDER_SHUFFLE_ALBUMS) { // shuffle
691 if (!playlist_track) {
692 pl_unlock ();
693 return streamer_move_to_nextsong_real (0);
694 }
695 else {
696 playlist_track->played = 0;
697 // find already played song with maximum shuffle rating below prev song
698 int rating = playlist_track->shufflerating;
699 playItem_t *pmax = NULL; // played maximum
700 playItem_t *amax = NULL; // absolute maximum
701 for (playItem_t *i = plt->head[PL_MAIN]; i; i = i->next[PL_MAIN]) {
702 if (i != playlist_track && i->played && (!amax || i->shufflerating > amax->shufflerating)) {
703 amax = i;
704 }
705 if (i == playlist_track || i->shufflerating > rating || !i->played) {
706 continue;
707 }
708 if (!pmax || i->shufflerating > pmax->shufflerating) {
709 pmax = i;
710 }
711 }
712
713 if (pmax && pl_order == PLAYBACK_ORDER_SHUFFLE_ALBUMS) {
714 while (pmax && pmax->next[PL_MAIN] && pmax->next[PL_MAIN]->played && pmax->shufflerating == pmax->next[PL_MAIN]->shufflerating) {
715 pmax = pmax->next[PL_MAIN];
716 }
717 }
718
719 playItem_t *it = pmax;
720 if (!it) {
721 // that means 1st in playlist, take amax
722 if (pl_loop_mode == PLAYBACK_MODE_LOOP_ALL) {
723 if (!amax) {
724 plt_reshuffle (streamer_playlist, NULL, &amax);
725 }
726 it = amax;
727 }
728 }
729
730 if (!it) {
731 pl_unlock ();
732 streamer_set_nextsong_real (-2, 1);
733 return -1;
734 }
735 int r = str_get_idx_of (it);
736 pl_unlock ();
737 streamer_set_nextsong_real (r, 1);
738 return 0;
739 }
740 }
741 else if (pl_order == PLAYBACK_ORDER_LINEAR) { // linear
742 DB_output_t *output = plug_get_output ();
743 playItem_t *it = NULL;
744 if (!playlist_track && output->state () == OUTPUT_STATE_STOPPED) {
745 int cur = plt_get_cursor (streamer_playlist, PL_MAIN);
746 if (cur != -1) {
747 playlist_track = plt_get_item_for_idx (streamer_playlist, cur, PL_MAIN);
748 pl_item_unref (playlist_track);
749 }
750 }
751 if (playlist_track) {
752 it = playlist_track->prev[PL_MAIN];
753 }
754 if (!it) {
755 if (pl_loop_mode == PLAYBACK_MODE_LOOP_ALL) {
756 it = plt->tail[PL_MAIN];
757 }
758 }
759 if (!it) {
760 pl_unlock ();
761 streamer_set_nextsong_real (-2, 1);
762 return -1;
763 }
764 int r = str_get_idx_of (it);
765 pl_unlock ();
766 streamer_set_nextsong_real (r, 1);
767 return 0;
768 }
769 else if (pl_order == PLAYBACK_ORDER_RANDOM) { // random
770 pl_unlock ();
771 int res = streamer_move_to_randomsong_real (0);
772 if (res == -1) {
773 streamer_set_nextsong_real (-2, 1);
774 trace ("streamer_move_to_randomsong error\n");
775 return -1;
776 }
777 return 0;
778 }
779 pl_unlock ();
780 return -1;
781 }
782
783 static int
streamer_move_to_randomsong_real(int reason)784 streamer_move_to_randomsong_real (int reason) {
785 if (reason) {
786 plug_get_output ()->stop ();
787 }
788 if (!streamer_playlist) {
789 streamer_playlist = plt_get_curr ();
790 }
791 playlist_t *plt = streamer_playlist;
792 int cnt = plt->count[PL_MAIN];
793 if (!cnt) {
794 trace ("empty playlist\n");
795 return -1;
796 }
797 int curr = str_get_idx_of (playing_track);
798 int r = rand () / (float)RAND_MAX * cnt;
799 if (r == curr) {
800 r++;
801 if (r >= cnt) {
802 r = 0;
803 }
804 }
805
806 streamer_set_nextsong_real (r, 1);
807 return 0;
808 }
809
810 int
streamer_move_to_nextsong(int r)811 streamer_move_to_nextsong (int r) {
812 if (r) {
813 streamer_abort_files ();
814 }
815 handler_push (handler, STR_EV_NEXT, 0, r, 0);
816 return 0;
817 }
818
819 int
streamer_move_to_prevsong(int r)820 streamer_move_to_prevsong (int r) {
821 if (r) {
822 streamer_abort_files ();
823 }
824 handler_push (handler, STR_EV_PREV, 0, r, 0);
825 return 0;
826 }
827
828 int
streamer_move_to_randomsong(int r)829 streamer_move_to_randomsong (int r) {
830 if (r) {
831 streamer_abort_files ();
832 }
833 handler_push (handler, STR_EV_RAND, 0, r, 0);
834 return 0;
835 }
836
837 // playlist must call that whenever item was removed
838 void
streamer_song_removed_notify(playItem_t * it)839 streamer_song_removed_notify (playItem_t *it) {
840 if (!mutex) {
841 return; // streamer is not running
842 }
843 if (it == playlist_track) {
844 playlist_track = playlist_track->prev[PL_MAIN];
845 }
846 }
847
848 #define CTMAP_MAX_PLUGINS 5
849
850 typedef struct ctmap_s {
851 char *ct;
852 char *plugins[CTMAP_MAX_PLUGINS];
853 struct ctmap_s *next;
854 } ctmap_t;
855
856 static ctmap_t *streamer_ctmap;
857 static char conf_network_ctmapping[2048];
858 static uintptr_t ctmap_mutex;
859
860 static void
ctmap_init_mutex(void)861 ctmap_init_mutex (void) {
862 ctmap_mutex = mutex_create ();
863 }
864
865 static void
ctmap_free_mutex(void)866 ctmap_free_mutex (void) {
867 if (ctmap_mutex) {
868 mutex_free (ctmap_mutex);
869 ctmap_mutex = 0;
870 }
871 }
872
873 static void
ctmap_lock(void)874 ctmap_lock (void) {
875 mutex_lock (ctmap_mutex);
876 }
877
878 static void
ctmap_unlock(void)879 ctmap_unlock (void) {
880 mutex_unlock (ctmap_mutex);
881 }
882
883 static void
ctmap_free(void)884 ctmap_free (void) {
885 while (streamer_ctmap) {
886 ctmap_t *ct = streamer_ctmap;
887 free (ct->ct);
888 for (int i = 0; ct->plugins[i]; i++) {
889 free (ct->plugins[i]);
890 }
891 streamer_ctmap = ct->next;
892 free (ct);
893 }
894 }
895
896 static void
ctmap_init(void)897 ctmap_init (void) {
898 ctmap_free ();
899 char *mapstr = conf_network_ctmapping;
900
901 const char *p = mapstr;
902 char t[MAX_TOKEN];
903 char ct[MAX_TOKEN];
904 char plugins[MAX_TOKEN*5];
905
906 ctmap_t *tail = NULL;
907
908 for (;;) {
909 p = gettoken (p, t);
910
911 if (!p) {
912 break;
913 }
914
915 ctmap_t *ctmap = malloc (sizeof (ctmap_t));
916 memset (ctmap, 0, sizeof (ctmap_t));
917 ctmap->ct = strdup (t);
918
919 int n = 0;
920
921 p = gettoken (p, t);
922 if (!p || strcmp (t, "{")) {
923 free (ctmap->ct);
924 free (ctmap);
925 break;
926 }
927
928 plugins[0] = 0;
929 for (;;) {
930 p = gettoken (p, t);
931 if (!p || !strcmp (t, "}") || n >= CTMAP_MAX_PLUGINS-1) {
932 break;
933 }
934
935 ctmap->plugins[n++] = strdup (t);
936 }
937 ctmap->plugins[n] = NULL;
938 if (tail) {
939 tail->next = ctmap;
940 }
941 tail = ctmap;
942 if (!streamer_ctmap) {
943 streamer_ctmap = ctmap;
944 }
945 }
946 }
947
948 static int
is_remote_stream(playItem_t * it)949 is_remote_stream (playItem_t *it) {
950 int remote = 0;
951 pl_lock ();
952 const char *uri = pl_find_meta (it, ":URI");
953 if (uri && !plug_is_local_file (uri)) {
954 remote = 1;
955 }
956 pl_unlock ();
957 return remote;
958 }
959
dec_open(DB_decoder_t * dec,uint32_t hints,playItem_t * it)960 static DB_fileinfo_t *dec_open (DB_decoder_t *dec, uint32_t hints, playItem_t *it) {
961 if (dec->plugin.api_vminor >= 7 && dec->open2) {
962 DB_fileinfo_t *fi = dec->open2 (hints, DB_PLAYITEM (it));
963 return fi;
964 }
965 return dec->open (hints);
966 }
967
968 // that must be called after last sample from str_playing_song was done reading
969 static int
streamer_set_current(playItem_t * it)970 streamer_set_current (playItem_t *it) {
971 trace ("streamer_set_current %s\n", playing_track ? pl_find_meta (playing_track, ":URI") : "null");
972 DB_output_t *output = plug_get_output ();
973 int err = 0;
974 int do_songstarted = 0;
975 playItem_t *from, *to;
976 // need to add refs here, because streamer_start_playback can destroy items
977 from = playing_track;
978 to = it;
979 if (from) {
980 pl_item_ref (from);
981 }
982 if (to) {
983 pl_item_ref (to);
984 }
985 trace ("\033[0;35mstreamer_set_current from %p to %p\033[37;0m\n", from, it);
986 trace ("\033[0;35moutput state: %d\033[37;0m\n", output->state ());
987 if (!playing_track || output->state () == OUTPUT_STATE_STOPPED) {
988 streamer_buffering = 1;
989 trace ("\033[0;35mstreamer_start_playback[1] from %p to %p\033[37;0m\n", from, it);
990 do_songstarted = 1;
991 streamer_start_playback (from, it);
992 bytes_until_next_song = -1;
993 }
994
995 trace ("streamer_set_current %p, buns=%d\n", it, bytes_until_next_song);
996 mutex_lock (currtrack_mutex);
997 if (streaming_track) {
998 pl_item_unref (streaming_track);
999 streaming_track = NULL;
1000 }
1001
1002 mutex_unlock (currtrack_mutex);
1003
1004 int paused_stream = 0;
1005 if (it && nextsong_pstate == 2) {
1006 paused_stream = is_remote_stream (it);
1007 }
1008
1009 if (!it || paused_stream) {
1010 goto success;
1011 }
1012 if (to) {
1013 trace ("draw before init: %p->%p, playing_track=%p, playlist_track=%p\n", from, to, playing_track, playlist_track);
1014 send_trackinfochanged (to);
1015 }
1016 if (from) {
1017 send_trackinfochanged (from);
1018 }
1019 char decoder_id[100] = "";
1020 char filetype[100] = "";
1021 pl_lock ();
1022 const char *dec = pl_find_meta (it, ":DECODER");
1023 if (dec) {
1024 strncpy (decoder_id, dec, sizeof (decoder_id));
1025 }
1026
1027 if (!decoder_id[0]) {
1028 // some decoders set filetype override,
1029 // but the override is invalid when decoder is not set.
1030 // reset to default here, so that tracks become playable after failures
1031 pl_delete_meta(it, "!FILETYPE");
1032 }
1033
1034 const char *ft = pl_find_meta (it, ":FILETYPE");
1035 if (ft) {
1036 strncpy (filetype, ft, sizeof (filetype));
1037 }
1038 pl_unlock ();
1039 char *plugs[CTMAP_MAX_PLUGINS] = {NULL};
1040 if (!decoder_id[0] && (!strcmp (filetype, "content") || !filetype[0])) {
1041 // try to get content-type
1042 trace ("\033[0;34mopening file %s\033[37;0m\n", pl_find_meta (it, ":URI"));
1043 pl_lock ();
1044 char *uri = strdupa (pl_find_meta (it, ":URI"));
1045 pl_unlock ();
1046 DB_FILE *fp = streamer_file = vfs_fopen (uri);
1047 trace ("\033[0;34mgetting content-type\033[37;0m\n");
1048 if (!fp) {
1049 err = -1;
1050 goto error;
1051 }
1052 const char *ct = vfs_get_content_type (fp);
1053 if (!ct) {
1054 vfs_fclose (fp);
1055 fp = NULL;
1056 streamer_file = NULL;
1057 err = -1;
1058 goto error;
1059 }
1060 trace ("got content-type: %s\n", ct);
1061 char *cct = strdupa (ct);
1062 char *sc = strchr (cct, ';');
1063 if (sc) {
1064 *sc = 0;
1065 }
1066
1067 ctmap_lock ();
1068 ctmap_t *ctmap = streamer_ctmap;
1069 while (ctmap) {
1070 if (!strcmp (cct, ctmap->ct)) {
1071 break;
1072 }
1073 ctmap = ctmap->next;
1074 }
1075 if (ctmap) {
1076 int i;
1077 for (i = 0; ctmap->plugins[i]; i++) {
1078 plugs[i] = strdupa (ctmap->plugins[i]);
1079 }
1080 plugs[i] = NULL;
1081 }
1082 ctmap_unlock ();
1083
1084 if (!plugs[0] && (!strcmp (cct, "audio/x-mpegurl") || !strncmp (cct, "text/html", 9) || !strncmp (cct, "audio/x-scpls", 13) || !strncmp (cct, "application/octet-stream", 9))) {
1085 // download playlist into temp file
1086 trace ("downloading playlist into temp file...\n");
1087 char *buf = NULL;
1088 int fd = -1;
1089 FILE *out = NULL;
1090 char tempfile[1000] = "";
1091
1092 int size = vfs_fgetlength (fp);
1093 if (size <= 0) {
1094 size = MAX_PLAYLIST_DOWNLOAD_SIZE;
1095 }
1096 buf = malloc (size);
1097 if (!buf) {
1098 trace ("failed to alloc %d bytes for playlist buffer\n", size);
1099 goto m3u_error;
1100 }
1101 trace ("reading %d bytes\n", size);
1102 int rd = vfs_fread (buf, 1, size, fp);
1103 if (rd <= 0) {
1104 trace ("failed to download %d bytes (got %d bytes)\n", size, rd);
1105 goto m3u_error;
1106 }
1107 const char *tmpdir = getenv ("TMPDIR");
1108 if (!tmpdir) {
1109 tmpdir = "/tmp";
1110 }
1111 snprintf (tempfile, sizeof (tempfile), "%s/ddbm3uXXXXXX", tmpdir);
1112
1113 fd = mkstemp (tempfile);
1114 if (fd == -1) {
1115 trace ("failed to open temp file %s\n", tempfile);
1116 goto m3u_error;
1117 }
1118 trace ("writing to %s\n", tempfile);
1119 out = fdopen (fd, "w+b");
1120 if (!out) {
1121 trace ("fdopen failed for %s\n", tempfile);
1122 goto m3u_error;
1123 }
1124 int rw = fwrite (buf, 1, rd, out);
1125 if (rw != rd) {
1126 trace ("failed to write %d bytes into file %s\n", size, tempfile);
1127 goto m3u_error;
1128 }
1129 fclose (out);
1130 fd = -1;
1131 out = NULL;
1132
1133 trace ("loading playlist from %s\n", tempfile);
1134 // load playlist
1135 playlist_t *plt = plt_alloc ("temp");
1136 DB_playlist_t **plug = plug_get_playlist_list ();
1137 int p, e;
1138 DB_playItem_t *m3u = NULL;
1139 for (p = 0; plug[p]; p++) {
1140 if (plug[p]->load) {
1141 m3u = plug[p]->load ((ddb_playlist_t *)plt, NULL, tempfile, NULL, NULL, NULL);
1142 if (m3u) {
1143 break;
1144 }
1145 }
1146 }
1147 if (!m3u) {
1148 trace ("failed to load playlist from %s using any of the installed playlist plugins\n", tempfile);
1149 plt_free (plt);
1150 goto m3u_error;
1151 }
1152
1153 // hack: need to sleep here, some servers like to reject frequent connections
1154 usleep(conf_get_int ("streamer.wait_ms_after_m3u_link", 400000));
1155
1156 // for every playlist uri: override stream uri with the one from playlist, and try to play it
1157 playItem_t *i = (playItem_t *)m3u;
1158 pl_item_ref (i);
1159 int res = -1;
1160 while (i) {
1161 pl_lock ();
1162 pl_replace_meta (it, "!URI", pl_find_meta_raw (i, ":URI"));
1163 pl_unlock ();
1164 res = streamer_set_current (it);
1165 if (!res) {
1166 pl_item_unref (i);
1167 break;
1168 }
1169 playItem_t *next = pl_get_next (i, PL_MAIN);
1170 pl_item_unref (i);
1171 i = next;
1172 }
1173 plt_free (plt);
1174 if (res == 0) {
1175 // succeeded -- playing now
1176 if (from) {
1177 pl_item_unref (from);
1178 }
1179 if (to) {
1180 pl_item_unref (to);
1181 }
1182 if (buf) {
1183 free (buf);
1184 }
1185 unlink (tempfile);
1186 return res;
1187 }
1188
1189 m3u_error:
1190 if (*tempfile) {
1191 unlink (tempfile);
1192 }
1193 err = -1;
1194 if (buf) {
1195 free (buf);
1196 }
1197 if (out) {
1198 fclose (out);
1199 }
1200 else if (fd != -1) {
1201 close (fd);
1202 }
1203 goto error;
1204 }
1205 streamer_file = NULL;
1206 vfs_fclose (fp);
1207 }
1208 playlist_track = it;
1209
1210 int plug_idx = 0;
1211 for (;;) {
1212 if (!decoder_id[0] && plugs[0] && !plugs[plug_idx]) {
1213 it->played = 1;
1214 trace ("decoder->init returned %p\n", new_fileinfo);
1215 streamer_buffering = 0;
1216 if (playlist_track == it) {
1217 trace ("redraw track %p; playing_track=%p; playlist_track=%p\n", to, playing_track, playlist_track);
1218 send_trackinfochanged (to);
1219 }
1220 err = -1;
1221 goto error;
1222 }
1223
1224 DB_decoder_t *dec = NULL;
1225
1226 if (decoder_id[0]) {
1227 dec = plug_get_decoder_for_id (decoder_id);
1228 decoder_id[0] = 0;
1229 if (!dec) {
1230 // find new decoder by file extension
1231 pl_lock ();
1232 const char *fname = pl_find_meta (it, ":URI");
1233 const char *ext = strrchr (fname, '.');
1234 if (ext) {
1235 ext++;
1236 DB_decoder_t **decs = plug_get_decoder_list ();
1237 for (int i = 0; decs[i]; i++) {
1238 const char **exts = decs[i]->exts;
1239 if (exts) {
1240 for (int j = 0; exts[j]; j++) {
1241 if (!strcasecmp (exts[j], ext) || !strcmp (exts[j], "*")) {
1242 fprintf (stderr, "streamer: %s : changed decoder plugin to %s\n", fname, decs[i]->plugin.id);
1243 pl_replace_meta (it, "!DECODER", decs[i]->plugin.id);
1244 pl_replace_meta (it, "!FILETYPE", ext);
1245 dec = decs[i];
1246 break;
1247 }
1248 }
1249 }
1250 }
1251 }
1252 pl_unlock ();
1253 }
1254 }
1255 else if (plugs[0]) {
1256 // match by decoder
1257 dec = plug_get_decoder_for_id (plugs[plug_idx]);
1258 if (dec) {
1259 pl_replace_meta (it, "!DECODER", dec->plugin.id);
1260 }
1261 plug_idx++;
1262 }
1263
1264 if (!dec) {
1265 trace ("no decoder in playitem!\n");
1266 it->played = 1;
1267 streamer_buffering = 0;
1268 if (playlist_track == it) {
1269 send_trackinfochanged (to);
1270 }
1271 if (from) {
1272 pl_item_unref (from);
1273 }
1274 if (to) {
1275 pl_item_unref (to);
1276 }
1277 return -1;
1278 }
1279
1280 trace ("\033[0;33minit decoder for %s (%s)\033[37;0m\n", pl_find_meta (it, ":URI"), dec->plugin.id);
1281 new_fileinfo = dec_open (dec, STREAMER_HINTS, it);
1282 if (new_fileinfo->file) {
1283 new_fileinfo_file = new_fileinfo->file;
1284 }
1285 if (new_fileinfo && dec->init (new_fileinfo, DB_PLAYITEM (it)) != 0) {
1286 trace ("\033[0;31mfailed to init decoder\033[37;0m\n");
1287 pl_delete_meta (it, "!DECODER");
1288 dec->free (new_fileinfo);
1289 new_fileinfo = NULL;
1290 new_fileinfo_file = NULL;
1291 }
1292
1293 if (!new_fileinfo) {
1294 trace ("decoder %s failed\n", dec->plugin.id);
1295 continue;
1296 }
1297 else {
1298 new_fileinfo_file = new_fileinfo->file;
1299 if (streaming_track) {
1300 pl_item_unref (streaming_track);
1301 }
1302 streaming_track = it;
1303 if (streaming_track) {
1304 pl_item_ref (streaming_track);
1305 streamer_set_replaygain (streaming_track);
1306 }
1307
1308 trace ("bps=%d, channels=%d, samplerate=%d\n", new_fileinfo->fmt.bps, new_fileinfo->fmt.channels, new_fileinfo->fmt.samplerate);
1309 break;
1310 }
1311 }
1312 success:
1313 if (fileinfo) {
1314 fileinfo->plugin->free (fileinfo);
1315 fileinfo = NULL;
1316 fileinfo_file = NULL;
1317 }
1318 if (new_fileinfo) {
1319 fileinfo = new_fileinfo;
1320 new_fileinfo = NULL;
1321 new_fileinfo_file = NULL;
1322 }
1323 if (do_songstarted && playing_track) {
1324 trace ("songstarted %s\n", playing_track ? pl_find_meta (playing_track, ":URI") : "null");
1325 playtime = 0;
1326 send_songstarted (playing_track);
1327 }
1328 send_trackinfochanged (to);
1329
1330 trace ("\033[0;32mstr: %p (%s), ply: %p (%s)\033[37;0m\n", streaming_track, streaming_track ? pl_find_meta (streaming_track, ":URI") : "null", playing_track, playing_track ? pl_find_meta (playing_track, ":URI") : "null");
1331
1332 error:
1333 if (from) {
1334 pl_item_unref (from);
1335 }
1336 if (to) {
1337 pl_item_unref (to);
1338 }
1339
1340 return err;
1341 }
1342
1343 float
streamer_get_playpos(void)1344 streamer_get_playpos (void) {
1345 float seek = last_seekpos;
1346 if (seek >= 0) {
1347 return seek;
1348 }
1349 return playpos;
1350 }
1351
1352 void
streamer_set_bitrate(int bitrate)1353 streamer_set_bitrate (int bitrate) {
1354 if (bytes_until_next_song <= 0) { // prevent next track from resetting current playback bitrate
1355 last_bitrate = bitrate;
1356 }
1357 }
1358
1359 int
streamer_get_apx_bitrate(void)1360 streamer_get_apx_bitrate (void) {
1361 return avg_bitrate;
1362 }
1363
1364 void
streamer_set_nextsong(int song,int pstate)1365 streamer_set_nextsong (int song, int pstate) {
1366 // pthread_t tid = pthread_self ();
1367 // assert (tid != streamer_tid);
1368 if (pstate == 0) {
1369 // this is a stop query -- clear the queue
1370 handler_reset (handler);
1371 }
1372 streamer_abort_files ();
1373 handler_push (handler, STR_EV_PLAY_TRACK_IDX, 0, song, pstate);
1374 }
1375
1376 static void
streamer_set_nextsong_real(int song,int pstate)1377 streamer_set_nextsong_real (int song, int pstate) {
1378 DB_output_t *output = plug_get_output ();
1379 if (pstate != 4) {
1380 int n = 0;
1381 }
1382 trace ("\033[0;35mstreamer_set_nextsong %d %d\033[37;0m\n", song, pstate);
1383 if (pstate == 4) {
1384 pstate = 1;
1385 output->stop ();
1386 }
1387 streamer_lock ();
1388 nextsong = song;
1389 nextsong_pstate = pstate;
1390 if (output->state () == OUTPUT_STATE_STOPPED) {
1391 if (pstate == 1) { // means user initiated this
1392 pl_lock ();
1393 if (streamer_playlist) {
1394 plt_unref (streamer_playlist);
1395 }
1396 streamer_playlist = plt_get_curr ();
1397 pl_unlock ();
1398 }
1399 // no sense to wait until end of previous song, reset buffer
1400 bytes_until_next_song = 0;
1401 playpos = 0;
1402 last_seekpos = -1;
1403 }
1404 if (pl_get_order () == PLAYBACK_ORDER_SHUFFLE_ALBUMS) {
1405 plt_init_shuffle_albums (streamer_playlist, song);
1406 }
1407 streamer_unlock ();
1408 }
1409
1410 static void
streamer_set_generic_output_format(void)1411 streamer_set_generic_output_format (void) {
1412 output_format.bps = 16;
1413 output_format.is_float = 0;
1414 output_format.channels = 2;
1415 output_format.samplerate = 44100;
1416 output_format.channelmask = 3;
1417 streamer_set_output_format ();
1418 }
1419
1420 void
streamer_set_seek(float pos)1421 streamer_set_seek (float pos) {
1422 last_seekpos = pos;
1423 handler_push (handler, STR_EV_SEEK, 0, *((uint32_t *)&pos), 0);
1424 }
1425
1426 static void
streamer_start_new_song(void)1427 streamer_start_new_song (void) {
1428 trace ("nextsong=%d (badsong=%d)\n", nextsong, badsong);
1429 streamer_lock ();
1430 DB_output_t *output = plug_get_output ();
1431 int sng = nextsong;
1432 int initsng = nextsong;
1433 int pstate = nextsong_pstate;
1434 nextsong = -1;
1435 streamer_unlock ();
1436 if (badsong == sng) {
1437 trace ("looped to bad file. stopping...\n");
1438 streamer_set_nextsong_real (-2, -2);
1439 badsong = -1;
1440 return;
1441 }
1442 playItem_t *try = str_get_for_idx (sng);
1443 if (!try) { // track is not in playlist
1444 trace ("track #%d is not in playlist; stopping playback\n", sng);
1445 output->stop ();
1446
1447 mutex_lock (currtrack_mutex);
1448 if (playing_track) {
1449 pl_item_unref (playing_track);
1450 playing_track = NULL;
1451 }
1452 if (streaming_track) {
1453 pl_item_unref (streaming_track);
1454 streaming_track = NULL;
1455 }
1456 mutex_unlock (currtrack_mutex);
1457
1458 send_trackchanged (NULL, NULL);
1459 return;
1460 }
1461 int ret = streamer_set_current (try);
1462
1463 if (ret < 0) {
1464 trace ("\033[0;31mfailed to play track %s, skipping (current=%p/%p)...\033[37;0m\n", pl_find_meta (try, ":URI"), streaming_track, playlist_track);
1465 pl_item_unref (try);
1466 try = NULL;
1467 // remember bad song number in case of looping
1468 if (badsong == -1) {
1469 badsong = sng;
1470 }
1471 trace ("\033[0;34mbadsong=%d\033[37;0m\n", badsong);
1472 // try jump to next song
1473 if (nextsong == -1) {
1474 trace ("streamer_move_to_nextsong after skip\n");
1475 streamer_move_to_nextsong_real (1);
1476 usleep (50000);
1477 }
1478 else {
1479 trace ("nextsong changed from %d to %d by another thread, reinit\n", initsng, nextsong);
1480 badsong = -1;
1481 }
1482 return;
1483 }
1484 pl_item_unref (try);
1485 try = NULL;
1486 badsong = -1;
1487 trace ("pstate = %d\n", pstate);
1488 trace ("playback state = %d\n", output->state ());
1489 if (pstate == 0) {
1490 output->stop ();
1491 }
1492 else if (pstate == 1 || pstate == 3) {
1493 last_bitrate = -1;
1494 avg_bitrate = -1;
1495 if (output->state () != OUTPUT_STATE_PLAYING) {
1496 streamer_reset (1);
1497 if (fileinfo && memcmp (&orig_output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t))) {
1498 memcpy (&output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t));
1499 memcpy (&orig_output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t));
1500 // fprintf (stderr, "streamer_set_output_format %dbit %s %dch %dHz channelmask=%X\n", output_format.bps, output_format.is_float ? "float" : "int", output_format.channels, output_format.samplerate, output_format.channelmask);
1501 streamer_set_output_format ();
1502 }
1503 if (0 != output->play ()) {
1504 // give a chance to DSP plugins to convert format to something
1505 // supported
1506 streamer_set_generic_output_format ();
1507 if (0 != output->play ()) {
1508 memset (&orig_output_format, 0, sizeof (orig_output_format));
1509 fprintf (stderr, "streamer: failed to start playback (start track)\n");
1510 streamer_set_nextsong_real (-2, 0);
1511 }
1512 }
1513 }
1514 }
1515 else if (pstate == 2) {
1516 if (output->state () == OUTPUT_STATE_STOPPED) {
1517 last_bitrate = -1;
1518 avg_bitrate = -1;
1519 streamer_reset (1);
1520 if (fileinfo && memcmp (&orig_output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t))) {
1521 memcpy (&orig_output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t));
1522 memcpy (&output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t));
1523 streamer_set_output_format ();
1524 }
1525 // we need to start playback before we can pause it
1526 if (0 != output->play ()) {
1527 memset (&orig_output_format, 0, sizeof (orig_output_format));
1528 fprintf (stderr, "streamer: failed to start playback (start track)\n");
1529 streamer_set_nextsong_real (-2, 0);
1530 }
1531 }
1532 output->pause ();
1533 }
1534 }
1535
1536 static void
streamer_next(int bytesread)1537 streamer_next (int bytesread) {
1538 streamer_lock ();
1539 bytes_until_next_song = streamer_ringbuf.remaining + bytesread;
1540 streamer_unlock ();
1541 if (stop_after_current) {
1542 streamer_buffering = 0;
1543 streamer_set_nextsong_real (-2, -2);
1544 if (conf_get_int ("playlist.stop_after_current_reset", 0)) {
1545 conf_set_int ("playlist.stop_after_current", 0);
1546 stop_after_current = 0;
1547 deadbeef->sendmessage (DB_EV_CONFIGCHANGED, 0, 0, 0);
1548 }
1549 }
1550 else {
1551 trace ("streamer_move_to_nextsong (0) called from streamer_next\n");
1552 streamer_move_to_nextsong_real (0);
1553 }
1554 }
1555
1556 static void
1557 streamer_dsp_postinit (void);
1558
1559 static void
1560 streamer_set_dsp_chain_real (ddb_dsp_context_t *chain);
1561
1562 static void
1563 streamer_notify_order_changed_real (int prev_order, int new_order);
1564
1565 static void
1566 free_dsp_buffers (void);
1567
1568 void
streamer_thread(void * ctx)1569 streamer_thread (void *ctx) {
1570 #ifdef __linux__
1571 prctl (PR_SET_NAME, "deadbeef-stream", 0, 0, 0, 0);
1572 #endif
1573
1574 while (!streaming_terminate) {
1575 float seekpos = -1;
1576
1577 struct timeval tm1;
1578 DB_output_t *output = plug_get_output ();
1579 gettimeofday (&tm1, NULL);
1580
1581 uint32_t id;
1582 uintptr_t ctx;
1583 uint32_t p1, p2;
1584 if (!handler_pop (handler, &id, &ctx, &p1, &p2)) {
1585 switch (id) {
1586 case STR_EV_PLAY_TRACK_IDX:
1587 streamer_set_nextsong_real (p1, p2);
1588 break;
1589 case STR_EV_PLAY_CURR:
1590 streamer_play_current_track_real ();
1591 break;
1592 case STR_EV_NEXT:
1593 streamer_move_to_nextsong_real (p1);
1594 break;
1595 case STR_EV_PREV:
1596 streamer_move_to_prevsong_real (p1);
1597 break;
1598 case STR_EV_RAND:
1599 streamer_move_to_randomsong_real (p1);
1600 break;
1601 case STR_EV_SEEK:
1602 seekpos = *((float *)&p1);
1603 break;
1604 case STR_EV_SET_CURR_PLT:
1605 streamer_set_current_playlist_real (p1);
1606 break;
1607 case STR_EV_DSP_RELOAD:
1608 streamer_dsp_postinit ();
1609 break;
1610 case STR_EV_SET_DSP_CHAIN:
1611 streamer_set_dsp_chain_real ((ddb_dsp_context_t *)ctx);
1612 break;
1613 case STR_EV_ORDER_CHANGED:
1614 streamer_notify_order_changed_real(p1, p2);
1615 break;
1616 }
1617 }
1618
1619 if (nextsong >= 0) { // start streaming next song
1620 trace ("\033[0;34mnextsong=%d\033[37;0m\n", nextsong);
1621 streamer_start_new_song ();
1622 if (nextsong_pstate == 2) {
1623 nextsong_pstate = -1;
1624 }
1625 // it's totally possible that song was switched
1626 // while streamer_set_current was running,
1627 // so we need to restart here
1628 continue;
1629 }
1630 else if (nextsong == -2 && (nextsong_pstate==0 || bytes_until_next_song == 0)) {
1631 streamer_lock ();
1632 playItem_t *from = playing_track;
1633 bytes_until_next_song = -1;
1634 trace ("nextsong=-2\n");
1635 nextsong = -1;
1636 if (playing_track) {
1637 trace ("sending songfinished to plugins [1]\n");
1638 send_songfinished (playing_track);
1639 }
1640 if (from) {
1641 pl_item_ref (from);
1642 }
1643 streamer_set_current (NULL);
1644 if (playing_track) {
1645 pl_item_unref (playing_track);
1646 playing_track = NULL;
1647 }
1648 send_trackchanged (from, NULL);
1649 if (from) {
1650 pl_item_unref (from);
1651 }
1652 streamer_unlock ();
1653 output->stop ();
1654 continue;
1655 }
1656 else if (output->state () == OUTPUT_STATE_STOPPED) {
1657 usleep (50000);
1658 continue;
1659 }
1660
1661 if (bytes_until_next_song == 0) {
1662 streamer_lock ();
1663 if (!streaming_track) {
1664 // means last song was deleted during final drain
1665 nextsong = -1;
1666 output->stop ();
1667 streamer_set_current (NULL);
1668 streamer_unlock ();
1669 continue;
1670 }
1671 trace ("bytes_until_next_song=0, starting playback of new song\n");
1672 //playItem_t *from = playing_track;
1673 //playItem_t *to = streaming_track;
1674 trace ("sending songchanged\n");
1675 bytes_until_next_song = -1;
1676 // plugin will get pointer to str_playing_song
1677 if (playing_track) {
1678 trace ("sending songfinished to plugins [2]\n");
1679 send_songfinished (playing_track);
1680 }
1681 // copy streaming into playing
1682 trace ("\033[0;35mstreamer_start_playback[2] from %p to %p\033[37;0m\n", playing_track, streaming_track);
1683 streamer_start_playback (playing_track, streaming_track);
1684 trace ("songstarted %s\n", playing_track ? pl_find_meta (playing_track, ":URI") : "null");
1685 playtime = 0;
1686 send_songstarted (playing_track);
1687 last_bitrate = -1;
1688 avg_bitrate = -1;
1689 playlist_track = playing_track;
1690 playpos = 0;
1691 last_seekpos = -1;
1692 seekpos = -1;
1693
1694 // don't switch if unchanged
1695 ddb_waveformat_t prevfmt;
1696 memcpy (&prevfmt, &output->fmt, sizeof (ddb_waveformat_t));
1697 if (memcmp (&orig_output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t))) {
1698 memcpy (&orig_output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t));
1699 memcpy (&output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t));
1700 formatchanged = 1;
1701 }
1702 streamer_unlock ();
1703 }
1704
1705 if (formatchanged && bytes_until_next_song <= 0) {
1706 streamer_set_output_format ();
1707 formatchanged = 0;
1708 }
1709
1710 float seek = seekpos;
1711 if (seek >= 0 && pl_get_item_duration (playing_track) > 0) {
1712 playpos = seek;
1713 trace ("seeking to %f\n", seek);
1714 float pos = seek;
1715
1716 if (playing_track != streaming_track) {
1717 trace ("streamer already switched to next track\n");
1718
1719 // restart playing from new position
1720
1721 mutex_lock (currtrack_mutex);
1722 if(fileinfo) {
1723 fileinfo->plugin->free (fileinfo);
1724 fileinfo = NULL;
1725 fileinfo_file = NULL;
1726 pl_item_unref (streaming_track);
1727 streaming_track = NULL;
1728 }
1729 streaming_track = playing_track;
1730 if (streaming_track) {
1731 pl_item_ref (streaming_track);
1732 streamer_set_replaygain (streaming_track);
1733 }
1734 mutex_unlock (currtrack_mutex);
1735
1736 bytes_until_next_song = -1;
1737 streamer_buffering = 1;
1738 if (streaming_track) {
1739 send_trackinfochanged (streaming_track);
1740 }
1741
1742 DB_decoder_t *dec = NULL;
1743 pl_lock ();
1744 const char *decoder_id = pl_find_meta (streaming_track, ":DECODER");
1745 if (decoder_id) {
1746 dec = plug_get_decoder_for_id (decoder_id);
1747 }
1748 pl_unlock ();
1749 if (dec) {
1750 fileinfo = dec_open (dec, STREAMER_HINTS, streaming_track);
1751 if (fileinfo && dec->init (fileinfo, DB_PLAYITEM (streaming_track)) != 0) {
1752 dec->free (fileinfo);
1753 fileinfo = NULL;
1754 fileinfo_file = NULL;
1755 }
1756 }
1757 else {
1758 if (fileinfo) {
1759 fileinfo_file = fileinfo->file;
1760 }
1761 }
1762
1763 if (!dec || !fileinfo) {
1764 if (streaming_track) {
1765 send_trackinfochanged (streaming_track);
1766 }
1767 trace ("failed to restart prev track on seek, trying to jump to next track\n");
1768 trace ("streamer_move_to_nextsong from seek\n");
1769 streamer_move_to_nextsong (0);
1770 usleep (50000);
1771 continue;
1772 }
1773 }
1774
1775 bytes_until_next_song = -1;
1776 streamer_buffering = 1;
1777 if (streaming_track) {
1778 send_trackinfochanged (streaming_track);
1779 }
1780 float dur = pl_get_item_duration (playing_track);
1781 if (fileinfo && playing_track && dur > 0) {
1782 if (pos >= dur) {
1783 output->stop ();
1784 streamer_move_to_nextsong (1);
1785 continue;
1786 }
1787 streamer_lock ();
1788 streamer_reset (1);
1789 if (fileinfo->plugin->seek (fileinfo, pos) >= 0) {
1790 playpos = fileinfo->readpos;
1791 }
1792 last_bitrate = -1;
1793 avg_bitrate = -1;
1794 streamer_unlock();
1795 }
1796 ddb_event_playpos_t *ev = (ddb_event_playpos_t *)messagepump_event_alloc (DB_EV_SEEKED);
1797 ev->track = DB_PLAYITEM (playing_track);
1798 if (playing_track) {
1799 pl_item_ref (playing_track);
1800 }
1801 ev->playpos = playpos;
1802 messagepump_push_event ((ddb_event_t*)ev, 0, 0);
1803 }
1804 last_seekpos = -1;
1805
1806 // read ahead at 2x speed of output samplerate, in 4k blocks
1807 int rate = output->fmt.samplerate;
1808 if (!rate) {
1809 trace ("str: got 0 output samplerate\n");
1810 usleep(20000);
1811 continue;
1812 }
1813 int channels = output->fmt.channels;
1814 int bytes_in_one_second = rate * (output->fmt.bps>>3) * channels;
1815 int blocksize = bytes_in_one_second / 120;
1816
1817 if (blocksize < MIN_BLOCK_SIZE) {
1818 blocksize = MIN_BLOCK_SIZE;
1819 }
1820 else if (blocksize > MAX_BLOCK_SIZE) {
1821 blocksize = MAX_BLOCK_SIZE;
1822 }
1823
1824 blocksize &= ~3; // 4byte alignment is required
1825
1826 if (bytes_in_one_second < blocksize) {
1827 bytes_in_one_second = blocksize;
1828 }
1829
1830 int alloc_time = 1000 / (bytes_in_one_second / blocksize);
1831
1832 int skip = 0;
1833 if (bytes_until_next_song >= 0) {
1834 // check if streaming format differs from output
1835 if (memcmp(&fileinfo->fmt, &orig_output_format, sizeof (ddb_waveformat_t))) {
1836 skip = 1;
1837 streamer_buffering = 0;
1838 }
1839 }
1840 streamer_lock ();
1841
1842 if (!formatchanged && !skip && streamer_ringbuf.remaining < (STREAM_BUFFER_SIZE-blocksize * MAX_DSP_RATIO)) {
1843 int sz = STREAM_BUFFER_SIZE - streamer_ringbuf.remaining;
1844 int minsize = blocksize;
1845
1846 // speed up buffering when empty
1847 if (streamer_ringbuf.remaining < MAX_BLOCK_SIZE) {
1848 minsize *= 4;
1849 alloc_time *= 4;
1850 }
1851 sz = min (minsize, sz);
1852 assert ((sz&3) == 0);
1853 // buffer must be larger enough to accomodate resamplers/pitchers/...
1854 // FIXME: bounds checking
1855 streamer_unlock ();
1856
1857 // ensure that size is possible with current format
1858 int samplesize = output->fmt.channels * (output->fmt.bps>>3);
1859 if (sz % samplesize) {
1860 sz -= (sz % samplesize);
1861 }
1862 int bytesread = 0;
1863 do {
1864 int prev_buns = bytes_until_next_song;
1865 int nb = streamer_read_async (readbuffer+bytesread,sz-bytesread);
1866 if (nb <= 0) {
1867 break;
1868 }
1869 bytesread += nb;
1870 struct timeval tm2;
1871 gettimeofday (&tm2, NULL);
1872 int ms = (tm2.tv_sec*1000+tm2.tv_usec/1000) - (tm1.tv_sec*1000+tm1.tv_usec/1000);
1873 if (ms >= alloc_time) {
1874 break;
1875 }
1876 if (prev_buns != bytes_until_next_song) {
1877 break;
1878 }
1879 } while (bytesread < sz-100);
1880 streamer_lock ();
1881
1882 if (bytesread > 0) {
1883 ringbuf_write (&streamer_ringbuf, readbuffer, bytesread);
1884 }
1885
1886 if (trace_bufferfill >= 1) {
1887 fprintf (stderr, "fill: %d, read: %d, size=%d, blocksize=%d\n", (int)streamer_ringbuf.remaining, (int)bytesread, (int)STREAM_BUFFER_SIZE, (int)blocksize);
1888 }
1889 }
1890 streamer_unlock ();
1891 if ((streamer_ringbuf.remaining > 128000 && streamer_buffering) || !streaming_track) {
1892 streamer_buffering = 0;
1893 if (streaming_track) {
1894 send_trackinfochanged (streaming_track);
1895 }
1896 }
1897 struct timeval tm2;
1898 gettimeofday (&tm2, NULL);
1899
1900 int ms = (tm2.tv_sec*1000+tm2.tv_usec/1000) - (tm1.tv_sec*1000+tm1.tv_usec/1000);
1901 if (trace_bufferfill >= 2) {
1902 fprintf (stderr, "slept %dms (alloc=%dms, bytespersec=%d, chan=%d, blocksize=%d), fill: %d/%d (cursor=%d)\n", (int)(alloc_time-ms), (int)alloc_time, (int)bytes_in_one_second, output->fmt.channels, blocksize, (int)streamer_ringbuf.remaining, STREAM_BUFFER_SIZE, (int)streamer_ringbuf.cursor);
1903 }
1904
1905 // add 1ms here to compensate the rounding error
1906 // and another 1ms to buffer slightly faster then playing
1907 alloc_time -= ms+2;
1908 if (streamer_buffering) {
1909 alloc_time = 0;
1910 }
1911 else if (streamer_ringbuf.remaining < STREAM_BUFFER_SIZE / 2) {
1912 alloc_time >>= 2; // speed-up loading a little
1913 }
1914
1915 //printf ("sleep: %d, buffering: %d, buffer_starving: %d (%d/%d)\n", alloc_time, streamer_buffering, streamer_ringbuf.remaining < STREAM_BUFFER_SIZE / 2, streamer_ringbuf.remaining, STREAM_BUFFER_SIZE / 2);
1916
1917 if (alloc_time > 0 && !conf_streamer_nosleep) {
1918 usleep (alloc_time * 1000);
1919 }
1920 else if (bytes_until_next_song > 0) {
1921 usleep (20000);
1922 }
1923 }
1924
1925 // stop streaming song
1926 if (fileinfo) {
1927 fileinfo->plugin->free (fileinfo);
1928 fileinfo = NULL;
1929 fileinfo_file = NULL;
1930 }
1931 mutex_lock (currtrack_mutex);
1932 if (streaming_track) {
1933 pl_item_unref (streaming_track);
1934 streaming_track = NULL;
1935 }
1936 if (playing_track) {
1937 pl_item_unref (playing_track);
1938 playing_track = NULL;
1939 }
1940 mutex_unlock (currtrack_mutex);
1941 }
1942
1943 void
streamer_dsp_chain_free(ddb_dsp_context_t * dsp_chain)1944 streamer_dsp_chain_free (ddb_dsp_context_t *dsp_chain) {
1945 while (dsp_chain) {
1946 ddb_dsp_context_t *next = dsp_chain->next;
1947 dsp_chain->plugin->close (dsp_chain);
1948 dsp_chain = next;
1949 }
1950 }
1951
1952 ddb_dsp_context_t *
streamer_dsp_chain_load(const char * fname)1953 streamer_dsp_chain_load (const char *fname) {
1954 int err = 1;
1955 FILE *fp = fopen (fname, "rt");
1956 if (!fp) {
1957 return NULL;
1958 }
1959
1960 char temp[100];
1961 ddb_dsp_context_t *chain = NULL;
1962 ddb_dsp_context_t *tail = NULL;
1963 for (;;) {
1964 // plugin enabled {
1965 int enabled = 0;
1966 int err = fscanf (fp, "%99s %d {\n", temp, &enabled);
1967 if (err == EOF) {
1968 break;
1969 }
1970 else if (2 != err) {
1971 fprintf (stderr, "error plugin name\n");
1972 goto error;
1973 }
1974
1975 DB_dsp_t *plug = (DB_dsp_t *)deadbeef->plug_get_for_id (temp);
1976 if (!plug) {
1977 fprintf (stderr, "streamer_dsp_chain_load: plugin %s not found. preset will not be loaded\n", temp);
1978 goto error;
1979 }
1980 ddb_dsp_context_t *ctx = plug->open ();
1981 if (!ctx) {
1982 fprintf (stderr, "streamer_dsp_chain_load: failed to open ctxance of plugin %s\n", temp);
1983 goto error;
1984 }
1985
1986 if (tail) {
1987 tail->next = ctx;
1988 tail = ctx;
1989 }
1990 else {
1991 tail = chain = ctx;
1992 }
1993
1994 int n = 0;
1995 for (;;) {
1996 char value[1000];
1997 if (!fgets (temp, sizeof (temp), fp)) {
1998 fprintf (stderr, "streamer_dsp_chain_load: unexpected eof while reading plugin params\n");
1999 goto error;
2000 }
2001 if (!strcmp (temp, "}\n")) {
2002 break;
2003 }
2004 else if (1 != sscanf (temp, "\t%1000[^\n]\n", value)) {
2005 fprintf (stderr, "streamer_dsp_chain_load: error loading param %d\n", n);
2006 goto error;
2007 }
2008 if (plug->num_params) {
2009 plug->set_param (ctx, n, value);
2010 }
2011 n++;
2012 }
2013 ctx->enabled = enabled;
2014 }
2015
2016 err = 0;
2017 error:
2018 if (err) {
2019 fprintf (stderr, "streamer_dsp_chain_load: error loading %s\n", fname);
2020 }
2021 if (fp) {
2022 fclose (fp);
2023 }
2024 if (err && chain) {
2025 streamer_dsp_chain_free (chain);
2026 chain = NULL;
2027 }
2028 return chain;
2029 }
2030
2031 int
streamer_dsp_chain_save_internal(const char * fname,ddb_dsp_context_t * chain)2032 streamer_dsp_chain_save_internal (const char *fname, ddb_dsp_context_t *chain) {
2033 char tempfile[PATH_MAX];
2034 snprintf (tempfile, sizeof (tempfile), "%s.tmp", fname);
2035 FILE *fp = fopen (tempfile, "w+t");
2036 if (!fp) {
2037 return -1;
2038 }
2039
2040 ddb_dsp_context_t *ctx = chain;
2041 while (ctx) {
2042 if (fprintf (fp, "%s %d {\n", ctx->plugin->plugin.id, (int)ctx->enabled) < 0) {
2043 fprintf (stderr, "write to %s failed (%s)\n", tempfile, strerror (errno));
2044 goto error;
2045 }
2046 if (ctx->plugin->num_params) {
2047 int n = ctx->plugin->num_params ();
2048 int i;
2049 for (i = 0; i < n; i++) {
2050 char v[1000];
2051 ctx->plugin->get_param (ctx, i, v, sizeof (v));
2052 if (fprintf (fp, "\t%s\n", v) < 0) {
2053 fprintf (stderr, "write to %s failed (%s)\n", tempfile, strerror (errno));
2054 goto error;
2055 }
2056 }
2057 }
2058 if (fprintf (fp, "}\n") < 0) {
2059 fprintf (stderr, "write to %s failed (%s)\n", tempfile, strerror (errno));
2060 goto error;
2061 }
2062 ctx = ctx->next;
2063 }
2064
2065 fclose (fp);
2066 if (rename (tempfile, fname) != 0) {
2067 fprintf (stderr, "dspconfig rename %s -> %s failed: %s\n", tempfile, fname, strerror (errno));
2068 return -1;
2069 }
2070 return 0;
2071 error:
2072 fclose (fp);
2073 return -1;
2074 }
2075
2076 int
streamer_dsp_chain_save(void)2077 streamer_dsp_chain_save (void) {
2078 char fname[PATH_MAX];
2079 snprintf (fname, sizeof (fname), "%s/dspconfig", plug_get_config_dir ());
2080 return streamer_dsp_chain_save_internal (fname, dsp_chain);
2081 }
2082
2083 static void
streamer_dsp_postinit(void)2084 streamer_dsp_postinit (void) {
2085 // note about EQ hack:
2086 // we 1st check if there's an EQ in dsp chain, and just use it
2087 // if not -- we add our own
2088
2089 // eq plug
2090 if (eqplug) {
2091 ddb_dsp_context_t *p;
2092
2093 for (p = dsp_chain; p; p = p->next) {
2094 if (!strcmp (p->plugin->plugin.id, "supereq")) {
2095 break;
2096 }
2097 }
2098 if (p) {
2099 eq = p;
2100 }
2101 else {
2102 eq = eqplug->open ();
2103 eq->enabled = 0;
2104 eq->next = dsp_chain;
2105 dsp_chain = eq;
2106 }
2107
2108 }
2109 ddb_dsp_context_t *ctx = dsp_chain;
2110 while (ctx) {
2111 if (ctx->enabled) {
2112 break;
2113 }
2114 ctx = ctx->next;
2115 }
2116 if (!ctx && fileinfo) {
2117 if (memcmp (&orig_output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t))) {
2118 memcpy (&orig_output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t));
2119 memcpy (&output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t));
2120 formatchanged = 1;
2121 }
2122 dsp_on = 0;
2123 }
2124 else if (ctx) {
2125 dsp_on = 1;
2126 // set some very generic format, this will allow playback of weird
2127 // formats after fixing them with dsp plugins
2128 streamer_set_generic_output_format ();
2129 }
2130 else if (!ctx) {
2131 dsp_on = 0;
2132 }
2133 }
2134
2135 void
streamer_dsp_refresh(void)2136 streamer_dsp_refresh (void) {
2137 handler_push (handler, STR_EV_DSP_RELOAD, 0, 0, 0);
2138 }
2139
2140 static void
streamer_dsp_init(void)2141 streamer_dsp_init (void) {
2142 // load dsp chain from file
2143 char fname[PATH_MAX];
2144 snprintf (fname, sizeof (fname), "%s/dspconfig", plug_get_config_dir ());
2145 dsp_chain = streamer_dsp_chain_load (fname);
2146 if (!dsp_chain) {
2147 // first run, let's add resampler
2148 DB_dsp_t *src = (DB_dsp_t *)plug_get_for_id ("SRC");
2149 if (src) {
2150 ddb_dsp_context_t *inst = src->open ();
2151 inst->enabled = 1;
2152 src->set_param (inst, 0, "48000"); // samplerate
2153 src->set_param (inst, 1, "2"); // quality=SINC_FASTEST
2154 src->set_param (inst, 2, "1"); // auto
2155 inst->next = dsp_chain;
2156 dsp_chain = inst;
2157 }
2158 }
2159
2160 eqplug = (DB_dsp_t *)plug_get_for_id ("supereq");
2161 streamer_dsp_postinit ();
2162
2163 // load legacy eq settings from pre-0.5
2164 if (eq && eqplug && conf_find ("eq.", NULL)) {
2165 eq->enabled = deadbeef->conf_get_int ("eq.enable", 0);
2166 char s[50];
2167
2168 // 0.4.4 was writing buggy settings, need to multiply by 2 to compensate
2169 conf_get_str ("eq.preamp", "0", s, sizeof (s));
2170 snprintf (s, sizeof (s), "%f", atof(s)*2);
2171 eqplug->set_param (eq, 0, s);
2172 for (int i = 0; i < 18; i++) {
2173 char key[100];
2174 snprintf (key, sizeof (key), "eq.band%d", i);
2175 conf_get_str (key, "0", s, sizeof (s));
2176 snprintf (s, sizeof (s), "%f", atof(s)*2);
2177 eqplug->set_param (eq, 1+i, s);
2178 }
2179 // delete obsolete settings
2180 conf_remove_items ("eq.");
2181 }
2182 }
2183
2184 int
streamer_init(void)2185 streamer_init (void) {
2186 streaming_terminate = 0;
2187 handler = handler_alloc (100);
2188 #if WRITE_DUMP
2189 out = fopen ("out.raw", "w+b");
2190 #endif
2191 mutex = mutex_create ();
2192 currtrack_mutex = mutex_create ();
2193 wdl_mutex = mutex_create ();
2194
2195 ringbuf_init (&streamer_ringbuf, streambuffer, STREAM_BUFFER_SIZE);
2196
2197 pl_set_order (conf_get_int ("playback.order", 0));
2198
2199 streamer_dsp_init ();
2200
2201 replaygain_set (conf_get_int ("replaygain_mode", 0), conf_get_int ("replaygain_scale", 1), conf_get_float ("replaygain_preamp", 0), conf_get_float ("global_preamp", 0));
2202
2203 ctmap_init_mutex ();
2204 deadbeef->conf_get_str ("network.ctmapping", DDB_DEFAULT_CTMAPPING, conf_network_ctmapping, sizeof (conf_network_ctmapping));
2205 ctmap_init ();
2206
2207 streamer_tid = thread_start (streamer_thread, NULL);
2208 return 0;
2209 }
2210
2211 void
streamer_free(void)2212 streamer_free (void) {
2213 #if WRITE_DUMP
2214 fclose (out);
2215 #endif
2216
2217 if (playing_track) {
2218 send_trackchanged (playing_track, NULL);
2219 }
2220 streamer_abort_files ();
2221 streaming_terminate = 1;
2222 thread_join (streamer_tid);
2223
2224 if (streaming_track) {
2225 pl_item_unref (streaming_track);
2226 streaming_track = NULL;
2227 }
2228 if (playing_track) {
2229 pl_item_unref (playing_track);
2230 playing_track = NULL;
2231 }
2232 if (playlist_track) {
2233 playlist_track = NULL;
2234 }
2235 if (streamer_playlist) {
2236 plt_unref (streamer_playlist);
2237 streamer_playlist = NULL;
2238 }
2239
2240 ctmap_free ();
2241 ctmap_free_mutex ();
2242
2243 mutex_free (currtrack_mutex);
2244 currtrack_mutex = 0;
2245 mutex_free (mutex);
2246 mutex = 0;
2247 mutex_free (wdl_mutex);
2248 wdl_mutex = 0;
2249
2250 streamer_dsp_chain_save();
2251
2252 streamer_dsp_chain_free (dsp_chain);
2253 dsp_chain = NULL;
2254
2255 free_dsp_buffers ();
2256
2257 eqplug = NULL;
2258 eq = NULL;
2259
2260 if (handler) {
2261 handler_free (handler);
2262 handler = NULL;
2263 }
2264 }
2265
2266 void
streamer_reset(int full)2267 streamer_reset (int full) { // must be called when current song changes by external reasons
2268 if (!mutex) {
2269 fprintf (stderr, "ERROR: someone called streamer_reset after exit\n");
2270 return; // failsafe, in case someone calls streamer reset after deinit
2271 }
2272 if (full) {
2273 streamer_lock ();
2274 streamer_ringbuf.remaining = 0;
2275 streamer_unlock ();
2276 }
2277
2278 // reset dsp
2279 ddb_dsp_context_t *dsp = dsp_chain;
2280 while (dsp) {
2281 if (dsp->plugin->reset) {
2282 dsp->plugin->reset (dsp);
2283 }
2284 dsp = dsp->next;
2285 }
2286 }
2287
2288 static int
streamer_set_output_format(void)2289 streamer_set_output_format (void) {
2290 DB_output_t *output = plug_get_output ();
2291 int playing = (output->state () == OUTPUT_STATE_PLAYING);
2292
2293 trace ("streamer_set_output_format %dbit %s %dch %dHz channelmask=%X, bufferfill: %d\n", output_format.bps, output_format.is_float ? "float" : "int", output_format.channels, output_format.samplerate, output_format.channelmask, streamer_ringbuf.remaining);
2294 ddb_waveformat_t fmt;
2295 memcpy (&fmt, &output_format, sizeof (ddb_waveformat_t));
2296 if (autoconv_8_to_16) {
2297 if (fmt.bps == 8) {
2298 fmt.bps = 16;
2299 }
2300 }
2301 if (autoconv_16_to_24) {
2302 if (fmt.bps == 16) {
2303 fmt.bps = 24;
2304 }
2305 }
2306 output->setformat (&fmt);
2307 streamer_buffering = 1;
2308 if (playing && output->state () != OUTPUT_STATE_PLAYING) {
2309 if (0 != output->play ()) {
2310 memset (&output_format, 0, sizeof (output_format));
2311 fprintf (stderr, "streamer: failed to start playback (streamer_read format change)\n");
2312 streamer_set_nextsong_real (-2, 0);
2313 return -1;
2314 }
2315 }
2316 return 0;
2317 }
2318
2319 static char *
ensure_dsp_input_buffer(int size)2320 ensure_dsp_input_buffer (int size) {
2321 if (!size) {
2322 if (dsp_input_buffer) {
2323 free (dsp_input_buffer);
2324 dsp_input_buffer = NULL;
2325 }
2326 return 0;
2327 }
2328 if (size != dsp_input_buffer_size) {
2329 dsp_input_buffer = realloc (dsp_input_buffer, size);
2330 dsp_input_buffer_size = size;
2331 }
2332 return dsp_input_buffer;
2333 }
2334
2335
2336 static char *
ensure_dsp_temp_buffer(int size)2337 ensure_dsp_temp_buffer (int size) {
2338 if (!size) {
2339 if (dsp_temp_buffer) {
2340 free (dsp_temp_buffer);
2341 dsp_temp_buffer = NULL;
2342 }
2343 return NULL;
2344 }
2345 if (size != dsp_temp_buffer_size) {
2346 dsp_temp_buffer = realloc (dsp_temp_buffer, size);
2347 dsp_temp_buffer_size = size;
2348 }
2349 return dsp_temp_buffer;
2350 }
2351
2352 static void
free_dsp_buffers(void)2353 free_dsp_buffers (void) {
2354 ensure_dsp_input_buffer (0);
2355 ensure_dsp_temp_buffer (0);
2356 }
2357
2358 // decodes data and converts to current output format
2359 // returns number of bytes been read
2360 static int
streamer_read_async(char * bytes,int size)2361 streamer_read_async (char *bytes, int size) {
2362 DB_output_t *output = plug_get_output ();
2363 int initsize = size;
2364 int bytesread = 0;
2365 if (!fileinfo) {
2366 // means there's nothing left to stream, so just do nothing
2367 return 0;
2368 }
2369 int is_eof = 0;
2370
2371 if (fileinfo->fmt.samplerate != -1) {
2372 int outputsamplesize = output->fmt.channels * output->fmt.bps / 8;
2373 int inputsamplesize = fileinfo->fmt.channels * fileinfo->fmt.bps / 8;
2374
2375 ddb_waveformat_t dspfmt;
2376 memcpy (&dspfmt, &fileinfo->fmt, sizeof (ddb_waveformat_t));
2377 dspfmt.bps = 32;
2378 dspfmt.is_float = 1;
2379 int can_bypass = 0;
2380 if (dsp_on) {
2381 // check if DSP can be passed through
2382 ddb_dsp_context_t *dsp = dsp_chain;
2383 while (dsp) {
2384 if (dsp->enabled) {
2385 if (dsp->plugin->plugin.api_vminor >= 1) {
2386 if (dsp->plugin->can_bypass && !dsp->plugin->can_bypass (dsp, &dspfmt)) {
2387 break;
2388 }
2389 }
2390 else {
2391 break;
2392 }
2393 }
2394 dsp = dsp->next;
2395 }
2396 if (!dsp) {
2397 can_bypass = 1;
2398 }
2399 }
2400
2401 if (!memcmp (&fileinfo->fmt, &output->fmt, sizeof (ddb_waveformat_t)) && (!dsp_on || can_bypass)) {
2402 // pass through from input to output
2403 bytesread = fileinfo->plugin->read (fileinfo, bytes, size);
2404
2405 if (bytesread != size) {
2406 is_eof = 1;
2407 }
2408 }
2409 else if (dsp_on) {
2410 // convert to float, pass through streamer DSP chain
2411 int dspsamplesize = fileinfo->fmt.channels * sizeof (float);
2412 int dsp_num_frames = size / (output->fmt.channels * output->fmt.bps / 8);
2413
2414 int inputsize = dsp_num_frames * inputsamplesize;
2415 char *input = ensure_dsp_input_buffer (inputsize);
2416
2417 // decode pcm
2418 int nb = fileinfo->plugin->read (fileinfo, input, inputsize);
2419 if (nb != inputsize) {
2420 is_eof = 1;
2421 }
2422 inputsize = nb;
2423
2424 if (inputsize > 0) {
2425 // make *MAX_DSP_RATIO sized buffer for float data
2426 int tempbuf_size = inputsize/inputsamplesize * dspsamplesize * MAX_DSP_RATIO;
2427 char *tempbuf = ensure_dsp_temp_buffer (tempbuf_size);
2428
2429 // convert to float
2430 int tempsize = pcm_convert (&fileinfo->fmt, input, &dspfmt, tempbuf, inputsize);
2431 int nframes = inputsize / inputsamplesize;
2432 ddb_dsp_context_t *dsp = dsp_chain;
2433 float ratio = 1.f;
2434 int maxframes = tempbuf_size / dspsamplesize;
2435 while (dsp) {
2436 if (dsp->enabled) {
2437 float r = 1;
2438 nframes = dsp->plugin->process (dsp, (float *)tempbuf, nframes, maxframes, &dspfmt, &r);
2439 ratio *= r;
2440 }
2441 dsp = dsp->next;
2442 }
2443 dsp_ratio = ratio;
2444
2445 ddb_waveformat_t outfmt;
2446 // preserve sampleformat, but take channels, samplerate
2447 outfmt.bps = fileinfo->fmt.bps;
2448 outfmt.is_float = fileinfo->fmt.is_float;
2449 // channelmask from dsp chain
2450 outfmt.channels = dspfmt.channels;
2451 outfmt.samplerate = dspfmt.samplerate;
2452 outfmt.channelmask = dspfmt.channelmask;
2453 outfmt.is_bigendian = fileinfo->fmt.is_bigendian;
2454 if (bytes_until_next_song <= 0 && memcmp (&output_format, &outfmt, sizeof (ddb_waveformat_t))) {
2455 memcpy (&output_format, &outfmt, sizeof (ddb_waveformat_t));
2456 streamer_set_output_format ();
2457 }
2458
2459 //printf ("convert from %dbit %s %dch %dHz channelmask=%X to %dbit %s %dch %dHz channelmask=%X\n", dspfmt.bps, dspfmt.is_float ? "float" : "int", dspfmt.channels, dspfmt.samplerate, dspfmt.channelmask, output->fmt.bps, output->fmt.is_float ? "float" : "int", output->fmt.channels, output->fmt.samplerate, output->fmt.channelmask);
2460
2461 int n = pcm_convert (&dspfmt, tempbuf, &output->fmt, bytes, nframes * dspfmt.channels * sizeof (float));
2462
2463 bytesread = n;
2464 }
2465 }
2466 else {
2467 #ifdef ANDROID
2468 // if we not compensate here, the streamer loop will go crazy
2469 if (fileinfo->fmt.samplerate != output->fmt.samplerate) {
2470 if ((fileinfo->fmt.samplerate / output->fmt.samplerate) == 2 && (fileinfo->fmt.samplerate % output->fmt.samplerate) == 0) {
2471 size <<= 1;
2472 }
2473 else if ((fileinfo->fmt.samplerate / output->fmt.samplerate) == 4 && (fileinfo->fmt.samplerate % output->fmt.samplerate) == 0) {
2474 size <<= 2;
2475 }
2476 }
2477 #endif
2478 // convert from input fmt to output fmt
2479 int inputsize = size/outputsamplesize*inputsamplesize;
2480 char input[inputsize];
2481 int nb = fileinfo->plugin->read (fileinfo, input, inputsize);
2482 if (nb != inputsize) {
2483 bytesread = nb;
2484 is_eof = 1;
2485 }
2486 inputsize = nb;
2487 // trace ("convert %d|%d|%d|%d|%d|%d to %d|%d|%d|%d|%d|%d\n"
2488 // , fileinfo->fmt.bps, fileinfo->fmt.channels, fileinfo->fmt.samplerate, fileinfo->fmt.channelmask, fileinfo->fmt.is_float, fileinfo->fmt.is_bigendian
2489 // , output->fmt.bps, output->fmt.channels, output->fmt.samplerate, output->fmt.channelmask, output->fmt.is_float, output->fmt.is_bigendian);
2490 bytesread = pcm_convert (&fileinfo->fmt, input, &output->fmt, bytes, inputsize);
2491
2492 #ifdef ANDROID
2493 // downsample
2494 if (fileinfo->fmt.samplerate > output->fmt.samplerate) {
2495 if ((fileinfo->fmt.samplerate / output->fmt.samplerate) == 2 && (fileinfo->fmt.samplerate % output->fmt.samplerate) == 0) {
2496 // clip to multiple of 2 samples
2497 int outsamplesize = output->fmt.channels * (output->fmt.bps>>3) * 2;
2498 if ((bytesread % outsamplesize) != 0) {
2499 bytesread -= (bytesread % outsamplesize);
2500 }
2501
2502 // 2x downsample
2503 int nframes = bytesread / (output->fmt.bps >> 3) / output->fmt.channels;
2504 int16_t *in = (int16_t *)bytes;
2505 int16_t *out = in;
2506 for (int f = 0; f < nframes/2; f++) {
2507 for (int c = 0; c < output->fmt.channels; c++) {
2508 out[f*output->fmt.channels+c] = (in[f*2*output->fmt.channels+c] + in[(f*2+1)*output->fmt.channels+c]) >> 1;
2509 }
2510 }
2511 bytesread >>= 1;
2512 }
2513 else if ((fileinfo->fmt.samplerate / output->fmt.samplerate) == 4 && (fileinfo->fmt.samplerate % output->fmt.samplerate) == 0) {
2514 // clip to multiple of 4 samples
2515 int outsamplesize = output->fmt.channels * (output->fmt.bps>>3) * 4;
2516 if ((bytesread % outsamplesize) != 0) {
2517 bytesread -= (bytesread % outsamplesize);
2518 }
2519
2520
2521 // 4x downsample
2522 int nframes = bytesread / (output->fmt.bps >> 3) / output->fmt.channels;
2523 assert (bytesread % ((output->fmt.bps >> 3) * output->fmt.channels) == 0);
2524 int16_t *in = (int16_t *)bytes;
2525 for (int f = 0; f < nframes/4; f++) {
2526 for (int c = 0; c < output->fmt.channels; c++) {
2527 in[f*output->fmt.channels+c] = (in[f*4*output->fmt.channels+c]
2528 + in[(f*4+1)*output->fmt.channels+c]
2529 + in[(f*4+2)*output->fmt.channels+c]
2530 + in[(f*4+3)*output->fmt.channels+c]) >> 2;
2531 }
2532 }
2533 bytesread >>= 2;
2534 }
2535 }
2536 assert ((bytesread%2) == 0);
2537 #endif
2538
2539 }
2540 #if WRITE_DUMP
2541 if (bytesread) {
2542 fwrite (bytes, 1, bytesread, out);
2543 }
2544 #endif
2545
2546 replaygain_apply (&output->fmt, streaming_track, bytes, bytesread);
2547 }
2548 if (!is_eof) {
2549 return bytesread;
2550 }
2551 else {
2552 // that means EOF
2553 // trace ("streamer: EOF! buns: %d, bytesread: %d, buffering: %d, bufferfill: %d\n", bytes_until_next_song, bytesread, streamer_buffering, streamer_ringbuf.remaining);
2554
2555 // EOF or error while buffering -- stop buffering
2556 if (bytesread <= 0 && bytes_until_next_song >= 0 && streamer_buffering) {
2557 streamer_buffering = 0;
2558 return bytesread;
2559 }
2560
2561 // if track finished playing -- go to next
2562 if (bytes_until_next_song < 0) {
2563 streamer_next (bytesread);
2564 }
2565 }
2566 return bytesread;
2567 }
2568
2569 int
streamer_read(char * bytes,int size)2570 streamer_read (char *bytes, int size) {
2571 #if 0
2572 struct timeval tm1;
2573 gettimeofday (&tm1, NULL);
2574 #endif
2575 if (!playing_track) {
2576 return -1;
2577 }
2578 DB_output_t *output = plug_get_output ();
2579 streamer_lock ();
2580 int sz = min (size, streamer_ringbuf.remaining);
2581 if (sz) {
2582 ringbuf_read (&streamer_ringbuf, bytes, sz);
2583 playpos += (float)sz/output->fmt.samplerate/((output->fmt.bps>>3)*output->fmt.channels) * dsp_ratio;
2584 playtime += (float)sz/output->fmt.samplerate/((output->fmt.bps>>3)*output->fmt.channels);
2585 if (bytes_until_next_song > 0) {
2586 bytes_until_next_song -= sz;
2587 if (bytes_until_next_song < 0) {
2588 bytes_until_next_song = 0;
2589 }
2590 }
2591 }
2592 streamer_unlock ();
2593
2594 // approximate bitrate
2595 if (last_bitrate != -1) {
2596 if (avg_bitrate == -1) {
2597 avg_bitrate = last_bitrate;
2598 }
2599 else {
2600 if (avg_bitrate < last_bitrate) {
2601 avg_bitrate += 5;
2602 if (avg_bitrate > last_bitrate) {
2603 avg_bitrate = last_bitrate;
2604 }
2605 }
2606 else if (avg_bitrate > last_bitrate) {
2607 avg_bitrate -= 5;
2608 if (avg_bitrate < last_bitrate) {
2609 avg_bitrate = last_bitrate;
2610 }
2611 }
2612 }
2613 // printf ("apx bitrate: %d (last %d)\n", avg_bitrate, last_bitrate);
2614 }
2615 else {
2616 avg_bitrate = -1;
2617 }
2618
2619 #if 0
2620 struct timeval tm2;
2621 gettimeofday (&tm2, NULL);
2622
2623 int ms = (tm2.tv_sec*1000+tm2.tv_usec/1000) - (tm1.tv_sec*1000+tm1.tv_usec/1000);
2624 printf ("streamer_read took %d ms\n", ms);
2625 #endif
2626
2627 if (waveform_listeners || spectrum_listeners) {
2628 int in_frame_size = (output->fmt.bps >> 3) * output->fmt.channels;
2629 int in_frames = sz / in_frame_size;
2630 ddb_waveformat_t out_fmt = {
2631 .bps = 32,
2632 .channels = output->fmt.channels,
2633 .samplerate = output->fmt.samplerate,
2634 .channelmask = output->fmt.channelmask,
2635 .is_float = 1,
2636 .is_bigendian = 0
2637 };
2638
2639 float temp_audio_data[in_frames * out_fmt.channels];
2640 pcm_convert (&output->fmt, bytes, &out_fmt, (char *)temp_audio_data, sz);
2641 ddb_audio_data_t data;
2642 data.fmt = &out_fmt;
2643 data.data = temp_audio_data;
2644 data.nframes = in_frames;
2645 mutex_lock (wdl_mutex);
2646 for (wavedata_listener_t *l = waveform_listeners; l; l = l->next) {
2647 l->callback (l->ctx, &data);
2648 }
2649 mutex_unlock (wdl_mutex);
2650
2651 if (out_fmt.channels != audio_data_channels || !spectrum_listeners) {
2652 audio_data_fill = 0;
2653 audio_data_channels = out_fmt.channels;
2654 }
2655
2656 if (spectrum_listeners) {
2657 int remaining = in_frames;
2658 do {
2659 int sz = DDB_FREQ_BANDS * 2 -audio_data_fill;
2660 sz = min (sz, remaining);
2661 for (int c = 0; c < audio_data_channels; c++) {
2662 for (int s = 0; s < sz; s++) {
2663 audio_data[DDB_FREQ_BANDS * 2 * c + audio_data_fill + s] = temp_audio_data[(in_frames-remaining + s) * audio_data_channels + c];
2664 }
2665 }
2666 // memcpy (&audio_data[audio_data_fill], &temp_audio_data[in_frames-remaining], sz * sizeof (float));
2667 audio_data_fill += sz;
2668 remaining -= sz;
2669 if (audio_data_fill == DDB_FREQ_BANDS * 2) {
2670 for (int c = 0; c < audio_data_channels; c++) {
2671 calc_freq (&audio_data[DDB_FREQ_BANDS * 2 * c], &freq_data[DDB_FREQ_BANDS * c]);
2672 }
2673 ddb_audio_data_t data;
2674 data.fmt = &out_fmt;
2675 data.data = freq_data;
2676 data.nframes = DDB_FREQ_BANDS;
2677 mutex_lock (wdl_mutex);
2678 for (wavedata_listener_t *l = spectrum_listeners; l; l = l->next) {
2679 l->callback (l->ctx, &data);
2680 }
2681 mutex_unlock (wdl_mutex);
2682 audio_data_fill = 0;
2683 }
2684 } while (remaining > 0);
2685 }
2686 }
2687
2688 if (!output->has_volume) {
2689 int mult = 1-audio_is_mute ();
2690 char *stream = bytes;
2691 int bytesread = sz;
2692 if (output->fmt.bps == 16) {
2693 mult *= 1000;
2694 int16_t ivolume = volume_get_amp () * mult;
2695 if (ivolume != 1000) {
2696 int half = bytesread/2;
2697 for (int i = 0; i < half; i++) {
2698 int16_t sample = *((int16_t*)stream);
2699 *((int16_t*)stream) = (int16_t)(((int32_t)sample) * ivolume / 1000);
2700 stream += 2;
2701 }
2702 }
2703 }
2704 else if (output->fmt.bps == 8) {
2705 mult *= 255;
2706 int16_t ivolume = volume_get_amp () * mult;
2707 if (ivolume != 255) {
2708 for (int i = 0; i < bytesread; i++) {
2709 *stream = (int8_t)(((int32_t)(*stream)) * ivolume / 1000);
2710 stream++;
2711 }
2712 }
2713 }
2714 else if (output->fmt.bps == 24) {
2715 mult *= 1000;
2716 int16_t ivolume = volume_get_amp () * mult;
2717 if (ivolume != 1000) {
2718 int third = bytesread/3;
2719 for (int i = 0; i < third; i++) {
2720 int32_t sample = ((unsigned char)stream[0]) | ((unsigned char)stream[1]<<8) | (stream[2]<<16);
2721 int32_t newsample = (int64_t)sample * ivolume / 1000;
2722 stream[0] = (newsample&0x0000ff);
2723 stream[1] = (newsample&0x00ff00)>>8;
2724 stream[2] = (newsample&0xff0000)>>16;
2725 stream += 3;
2726 }
2727 }
2728 }
2729 else if (output->fmt.bps == 32 && !output->fmt.is_float) {
2730 mult *= 1000;
2731 int16_t ivolume = volume_get_amp () * mult;
2732 if (ivolume != 1000) {
2733 for (int i = 0; i < bytesread/4; i++) {
2734 int32_t sample = *((int32_t*)stream);
2735 int32_t newsample = (int64_t)sample * ivolume / 1000;
2736 *((int32_t*)stream) = newsample;
2737 stream += 4;
2738 }
2739 }
2740 }
2741 else if (output->fmt.bps == 32 && output->fmt.is_float) {
2742 float fvolume = volume_get_amp () * (1-audio_is_mute ());
2743 if (fvolume != 1.f) {
2744 for (int i = 0; i < bytesread/4; i++) {
2745 *((float*)stream) = (*((float*)stream)) * fvolume;
2746 stream += 4;
2747 }
2748 }
2749 }
2750 }
2751
2752 return sz;
2753 }
2754
2755 static int
streamer_get_fill(void)2756 streamer_get_fill (void) {
2757 return streamer_ringbuf.remaining;
2758 }
2759
2760 int
streamer_ok_to_read(int len)2761 streamer_ok_to_read (int len) {
2762 DB_output_t *output = plug_get_output ();
2763 if (formatchanged && bytes_until_next_song <= 0 && len >= 0) {
2764 streamer_set_output_format ();
2765 formatchanged = 0;
2766 }
2767 if (len >= 0 && (bytes_until_next_song > 0 || streamer_ringbuf.remaining >= (len*2))) {
2768 return 1;
2769 }
2770 else {
2771 return 1-streamer_buffering;
2772 }
2773 return 0;
2774 }
2775
2776 void
streamer_configchanged(void)2777 streamer_configchanged (void) {
2778 replaygain_set (conf_get_int ("replaygain_mode", 0), conf_get_int ("replaygain_scale", 1), conf_get_float ("replaygain_preamp", 0), conf_get_float ("global_preamp", 0));
2779 pl_set_order (conf_get_int ("playback.order", 0));
2780 if (playing_track) {
2781 playing_track->played = 1;
2782 }
2783 int conf_autoconv_8_to_16 = conf_get_int ("streamer.8_to_16", 1);
2784 if (conf_autoconv_8_to_16 != autoconv_8_to_16) {
2785 autoconv_8_to_16 = conf_autoconv_8_to_16;
2786 formatchanged = 1;
2787 streamer_reset (1);
2788 }
2789 int conf_autoconv_16_to_24 = conf_get_int ("streamer.16_to_24",0);
2790 if (conf_autoconv_16_to_24 != autoconv_16_to_24) {
2791 autoconv_16_to_24 = conf_autoconv_16_to_24;
2792 formatchanged = 1;
2793 streamer_reset (1);
2794 }
2795
2796 trace_bufferfill = conf_get_int ("streamer.trace_buffer_fill",0);
2797
2798 stop_after_current = conf_get_int ("playlist.stop_after_current", 0);
2799 stop_after_album = conf_get_int ("playlist.stop_after_album", 0);
2800
2801 char mapstr[2048];
2802 deadbeef->conf_get_str ("network.ctmapping", DDB_DEFAULT_CTMAPPING, mapstr, sizeof (mapstr));
2803 if (strcmp (mapstr, conf_network_ctmapping)) {
2804 ctmap_init ();
2805 }
2806
2807 conf_streamer_nosleep = conf_get_int ("streamer.nosleep", 0);
2808 }
2809
2810 static void
streamer_play_current_track_real(void)2811 streamer_play_current_track_real (void) {
2812 playlist_t *plt = plt_get_curr ();
2813 DB_output_t *output = plug_get_output ();
2814 if (output->state () == OUTPUT_STATE_PAUSED && playing_track) {
2815 if (is_remote_stream (playing_track) && pl_get_item_duration (playing_track) < 0) {
2816 streamer_reset (1);
2817 streamer_set_current (NULL);
2818 streamer_set_current (playing_track);
2819 if (fileinfo && memcmp (&orig_output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t))) {
2820 memcpy (&output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t));
2821 memcpy (&orig_output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t));
2822 streamer_set_output_format ();
2823 }
2824 }
2825 // unpause currently paused track
2826 output->unpause ();
2827 messagepump_push (DB_EV_PAUSED, 0, 0, 0);
2828 }
2829 else if (plt->current_row[PL_MAIN] != -1) {
2830 // play currently selected track in current playlist
2831 output->stop ();
2832 // get next song in queue
2833 int idx = -1;
2834 playItem_t *next = playqueue_getnext ();
2835 if (next) {
2836 idx = str_get_idx_of (next);
2837 playqueue_pop ();
2838 pl_item_unref (next);
2839 }
2840 else {
2841 idx = plt->current_row[PL_MAIN];
2842 }
2843
2844 streamer_set_nextsong_real (idx, 1);
2845 pl_lock ();
2846 if (streamer_playlist) {
2847 plt_unref (streamer_playlist);
2848 }
2849 streamer_playlist = plt;
2850 pl_unlock ();
2851 return;
2852 }
2853 else {
2854 output->stop ();
2855 streamer_move_to_nextsong (1);
2856 }
2857 if (plt) {
2858 plt_unref (plt);
2859 }
2860 }
2861
2862 void
streamer_play_current_track(void)2863 streamer_play_current_track (void) {
2864 handler_push (handler, STR_EV_PLAY_CURR, 0, 0, 0);
2865 }
2866
2867 struct DB_fileinfo_s *
streamer_get_current_fileinfo(void)2868 streamer_get_current_fileinfo (void) {
2869 return fileinfo;
2870 }
2871
2872 static void
streamer_set_current_playlist_real(int plt)2873 streamer_set_current_playlist_real (int plt) {
2874 pl_lock ();
2875 if (streamer_playlist) {
2876 plt_unref (streamer_playlist);
2877 }
2878 streamer_playlist = plt_get_for_idx (plt);
2879 pl_unlock ();
2880 }
2881
2882 void
streamer_set_current_playlist(int plt)2883 streamer_set_current_playlist (int plt) {
2884 handler_push (handler, STR_EV_SET_CURR_PLT, 0, plt, 0);
2885 }
2886
2887 int
streamer_get_current_playlist(void)2888 streamer_get_current_playlist (void) {
2889 pl_lock ();
2890 if (!streamer_playlist) {
2891 streamer_playlist = plt_get_curr ();
2892 }
2893 int idx = plt_get_idx_of (streamer_playlist);
2894 pl_unlock ();
2895 return idx;
2896 }
2897
2898 void
streamer_notify_playlist_deleted(playlist_t * plt)2899 streamer_notify_playlist_deleted (playlist_t *plt) {
2900 // this is only called from playlist code, no lock required
2901 if (plt == streamer_playlist) {
2902 plt_unref (streamer_playlist);
2903 streamer_playlist = NULL;
2904 }
2905 }
2906
2907 ddb_dsp_context_t *
streamer_get_dsp_chain(void)2908 streamer_get_dsp_chain (void) {
2909 return dsp_chain;
2910 }
2911
2912 static ddb_dsp_context_t *
dsp_clone(ddb_dsp_context_t * from)2913 dsp_clone (ddb_dsp_context_t *from) {
2914 ddb_dsp_context_t *dsp = from->plugin->open ();
2915 char param[2000];
2916 if (from->plugin->num_params) {
2917 int n = from->plugin->num_params ();
2918 for (int i = 0; i < n; i++) {
2919 from->plugin->get_param (from, i, param, sizeof (param));
2920 dsp->plugin->set_param (dsp, i, param);
2921 }
2922 }
2923 dsp->enabled = from->enabled;
2924 return dsp;
2925 }
2926
2927 static void
streamer_set_dsp_chain_real(ddb_dsp_context_t * chain)2928 streamer_set_dsp_chain_real (ddb_dsp_context_t *chain) {
2929 streamer_dsp_chain_free (dsp_chain);
2930 dsp_chain = chain;
2931 eq = NULL;
2932 streamer_dsp_postinit ();
2933 if (fileinfo) {
2934 memcpy (&orig_output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t));
2935 memcpy (&output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t));
2936 formatchanged = 1;
2937 }
2938
2939 streamer_dsp_chain_save();
2940 streamer_reset (1);
2941
2942 DB_output_t *output = plug_get_output ();
2943 if (playing_track && output->state () != OUTPUT_STATE_STOPPED) {
2944 streamer_set_seek (playpos);
2945 }
2946 messagepump_push (DB_EV_DSPCHAINCHANGED, 0, 0, 0);
2947 }
2948
2949 void
streamer_set_dsp_chain(ddb_dsp_context_t * chain)2950 streamer_set_dsp_chain (ddb_dsp_context_t *chain) {
2951 ddb_dsp_context_t *new_chain = NULL;
2952 ddb_dsp_context_t *tail = NULL;
2953 while (chain) {
2954 ddb_dsp_context_t *new = dsp_clone (chain);
2955 if (tail) {
2956 tail->next = new;
2957 tail = new;
2958 }
2959 else {
2960 new_chain = tail = new;
2961 }
2962 chain = chain->next;
2963 }
2964
2965 handler_push (handler, STR_EV_SET_DSP_CHAIN, (uintptr_t)new_chain, 0, 0);
2966 }
2967
2968 void
streamer_get_output_format(ddb_waveformat_t * fmt)2969 streamer_get_output_format (ddb_waveformat_t *fmt) {
2970 memcpy (fmt, &output_format, sizeof (ddb_waveformat_t));
2971 }
2972
2973 static void
streamer_notify_order_changed_real(int prev_order,int new_order)2974 streamer_notify_order_changed_real (int prev_order, int new_order) {
2975 if (prev_order != PLAYBACK_ORDER_SHUFFLE_ALBUMS && new_order == PLAYBACK_ORDER_SHUFFLE_ALBUMS) {
2976 streamer_lock ();
2977 playItem_t *curr = playing_track;
2978 if (curr) {
2979
2980 pl_lock ();
2981 const char *alb = pl_find_meta_raw (curr, "album");
2982 const char *art = pl_find_meta_raw (curr, "artist");
2983 playItem_t *next = curr->prev[PL_MAIN];
2984 while (next) {
2985 if (alb == pl_find_meta_raw (next, "album") && art == pl_find_meta_raw (next, "artist")) {
2986 next->played = 1;
2987 next = next->prev[PL_MAIN];
2988 }
2989 else {
2990 break;
2991 }
2992 }
2993 pl_unlock ();
2994 }
2995 streamer_unlock ();
2996 }
2997 }
2998
2999 void
streamer_notify_order_changed(int prev_order,int new_order)3000 streamer_notify_order_changed (int prev_order, int new_order) {
3001 handler_push (handler, STR_EV_ORDER_CHANGED, 0, prev_order, new_order);
3002 }
3003
3004 void
vis_waveform_listen(void * ctx,void (* callback)(void * ctx,ddb_audio_data_t * data))3005 vis_waveform_listen (void *ctx, void (*callback)(void *ctx, ddb_audio_data_t *data)) {
3006 mutex_lock (wdl_mutex);
3007 wavedata_listener_t *l = malloc (sizeof (wavedata_listener_t));
3008 memset (l, 0, sizeof (wavedata_listener_t));
3009 l->ctx = ctx;
3010 l->callback = callback;
3011 l->next = waveform_listeners;
3012 waveform_listeners = l;
3013 mutex_unlock (wdl_mutex);
3014 }
3015
3016 void
vis_waveform_unlisten(void * ctx)3017 vis_waveform_unlisten (void *ctx) {
3018 mutex_lock (wdl_mutex);
3019 wavedata_listener_t *l, *prev = NULL;
3020 for (l = waveform_listeners; l; prev = l, l = l->next) {
3021 if (l->ctx == ctx) {
3022 if (prev) {
3023 prev->next = l->next;
3024 }
3025 else {
3026 waveform_listeners = l->next;
3027 }
3028 free (l);
3029 break;
3030 }
3031 }
3032 mutex_unlock (wdl_mutex);
3033 }
3034
3035 void
vis_spectrum_listen(void * ctx,void (* callback)(void * ctx,ddb_audio_data_t * data))3036 vis_spectrum_listen (void *ctx, void (*callback)(void *ctx, ddb_audio_data_t *data)) {
3037 mutex_lock (wdl_mutex);
3038 wavedata_listener_t *l = malloc (sizeof (wavedata_listener_t));
3039 memset (l, 0, sizeof (wavedata_listener_t));
3040 l->ctx = ctx;
3041 l->callback = callback;
3042 l->next = spectrum_listeners;
3043 spectrum_listeners = l;
3044 mutex_unlock (wdl_mutex);
3045 }
3046
3047 void
vis_spectrum_unlisten(void * ctx)3048 vis_spectrum_unlisten (void *ctx) {
3049 mutex_lock (wdl_mutex);
3050 wavedata_listener_t *l, *prev = NULL;
3051 for (l = spectrum_listeners; l; prev = l, l = l->next) {
3052 if (l->ctx == ctx) {
3053 if (prev) {
3054 prev->next = l->next;
3055 }
3056 else {
3057 spectrum_listeners = l->next;
3058 }
3059 free (l);
3060 break;
3061 }
3062 }
3063 mutex_unlock (wdl_mutex);
3064 }
3065
3066 void
streamer_set_streamer_playlist(playlist_t * plt)3067 streamer_set_streamer_playlist (playlist_t *plt) {
3068 if (streamer_playlist) {
3069 plt_unref (streamer_playlist);
3070 }
3071 streamer_playlist = plt;
3072 if (streamer_playlist) {
3073 plt_ref (streamer_playlist);
3074 }
3075 }
3076
3077 struct handler_s *
streamer_get_handler(void)3078 streamer_get_handler (void) {
3079 return handler;
3080 }
3081
3082 void
streamer_set_playing_track(playItem_t * it)3083 streamer_set_playing_track (playItem_t *it) {
3084 if (playing_track) {
3085 pl_item_unref (playing_track);
3086 }
3087 playing_track = it;
3088 if (playing_track) {
3089 pl_item_ref (playing_track);
3090 }
3091 }
3092