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