1 /*
2     MusePack decoder plugin for DeaDBeeF Player
3     Copyright (C) 2009-2014 Alexey Yakovenko
4     Uses Musepack SV8 libs (r435), (C) 2005-2009, The Musepack Development Team
5 
6     This software is provided 'as-is', without any express or implied
7     warranty.  In no event will the authors be held liable for any damages
8     arising from the use of this software.
9 
10     Permission is granted to anyone to use this software for any purpose,
11     including commercial applications, and to alter it and redistribute it
12     freely, subject to the following restrictions:
13 
14     1. The origin of this software must not be misrepresented; you must not
15      claim that you wrote the original software. If you use this software
16      in a product, an acknowledgment in the product documentation would be
17      appreciated but is not required.
18 
19     2. Altered source versions must be plainly marked as such, and must not be
20      misrepresented as being the original software.
21 
22     3. This notice may not be removed or altered from any source distribution.
23 */
24 
25 #include <string.h>
26 #include <stdlib.h>
27 #include <assert.h>
28 #include <limits.h>
29 #include <unistd.h>
30 #include <math.h>
31 #include "mpc/mpcdec.h"
32 #ifdef HAVE_CONFIG_H
33 #  include <config.h>
34 #endif
35 #include "../../deadbeef.h"
36 
37 #define min(x,y) ((x)<(y)?(x):(y))
38 #define max(x,y) ((x)>(y)?(x):(y))
39 
40 //#define trace(...) { fprintf (stderr, __VA_ARGS__); }
41 #define trace(fmt,...)
42 
43 static DB_decoder_t plugin;
44 static DB_functions_t *deadbeef;
45 
46 typedef struct {
47     DB_fileinfo_t info;
48     mpc_streaminfo si;
49     mpc_demux *demux;
50 //    mpc_decoder *mpcdec;
51     mpc_reader reader;
52     int currentsample;
53     int startsample;
54     int endsample;
55     mpc_uint32_t vbr_update_acc;
56     mpc_uint32_t vbr_update_bits;
57     MPC_SAMPLE_FORMAT buffer[MPC_DECODER_BUFFER_LENGTH];
58     int remaining;
59 } musepack_info_t;
60 
musepack_vfs_read(mpc_reader * r,void * ptr,mpc_int32_t size)61 mpc_int32_t musepack_vfs_read (mpc_reader *r, void *ptr, mpc_int32_t size) {
62     return deadbeef->fread(ptr, 1, size, (DB_FILE *)r->data);
63 }
64 
65 /// Seeks to byte position offset.
musepack_vfs_seek(mpc_reader * r,mpc_int32_t offset)66 mpc_bool_t musepack_vfs_seek (mpc_reader *r, mpc_int32_t offset) {
67     int res = deadbeef->fseek ((DB_FILE *)r->data, offset, SEEK_SET);
68     if (res == 0) {
69         return 1;
70     }
71     return 0;
72 }
73 
74 /// Returns the current byte offset in the stream.
musepack_vfs_tell(mpc_reader * r)75 mpc_int32_t musepack_vfs_tell (mpc_reader *r) {
76     return deadbeef->ftell ((DB_FILE *)r->data);
77 }
78 
79 /// Returns the total length of the source stream, in bytes.
musepack_vfs_get_size(mpc_reader * r)80 mpc_int32_t musepack_vfs_get_size (mpc_reader *r) {
81     return deadbeef->fgetlength ((DB_FILE *)r->data);
82 }
83 
84 /// True if the stream is a seekable stream.
musepack_vfs_canseek(mpc_reader * r)85 mpc_bool_t musepack_vfs_canseek (mpc_reader *r) {
86     return 1;
87 }
88 
89 static DB_fileinfo_t *
musepack_open(uint32_t hints)90 musepack_open (uint32_t hints) {
91     DB_fileinfo_t *_info = malloc (sizeof (musepack_info_t));
92     musepack_info_t *info = (musepack_info_t *)_info;
93     memset (info, 0, sizeof (musepack_info_t));
94     return _info;
95 }
96 
97 static int
musepack_init(DB_fileinfo_t * _info,DB_playItem_t * it)98 musepack_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
99     musepack_info_t *info = (musepack_info_t *)_info;
100 
101     info->reader.read = musepack_vfs_read;
102     info->reader.seek = musepack_vfs_seek;
103     info->reader.tell = musepack_vfs_tell;
104     info->reader.get_size = musepack_vfs_get_size;
105     info->reader.canseek = musepack_vfs_canseek;
106 
107     deadbeef->pl_lock ();
108     DB_FILE *fp = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI"));
109     deadbeef->pl_unlock ();
110     if (!fp) {
111         return -1;
112     }
113     info->reader.data = fp;
114 
115     info->demux = mpc_demux_init (&info->reader);
116     if (!info->demux) {
117         fprintf (stderr, "mpc: mpc_demux_init failed\n");
118         deadbeef->fclose (fp);
119         info->reader.data = NULL;
120         return -1;
121     }
122     mpc_demux_get_info (info->demux, &info->si);
123 
124     info->vbr_update_acc = 0;
125     info->vbr_update_bits = 0;
126     info->remaining = 0;
127 
128     _info->fmt.is_float = 1;
129     _info->fmt.bps = 32;
130     _info->fmt.channels = info->si.channels;
131     _info->fmt.samplerate = info->si.sample_freq;
132     int i;
133     for (i = 0; i < _info->fmt.channels; i++) {
134         _info->fmt.channelmask |= 1 << i;
135     }
136     _info->readpos = 0;
137     _info->plugin = &plugin;
138 
139     if (it->endsample > 0) {
140         info->startsample = it->startsample;
141         info->endsample = it->endsample;
142         plugin.seek_sample (_info, 0);
143     }
144     else {
145         info->startsample = 0;
146         info->endsample = mpc_streaminfo_get_length_samples (&info->si)-1;
147     }
148 
149     return 0;
150 }
151 
152 static void
musepack_free(DB_fileinfo_t * _info)153 musepack_free (DB_fileinfo_t *_info) {
154     musepack_info_t *info = (musepack_info_t *)_info;
155     if (info) {
156         if (info->demux) {
157             mpc_demux_exit (info->demux);
158             info->demux = NULL;
159         }
160         if (info->reader.data) {
161             deadbeef->fclose ((DB_FILE *)info->reader.data);
162             info->reader.data = NULL;
163         }
164         free (info);
165     }
166 }
167 
168 #if 0
169 static int
170 musepack_read (DB_fileinfo_t *_info, char *bytes, int size) {
171     musepack_info_t *info = (musepack_info_t *)_info;
172 
173     int samplesize = _info->fmt.bps / 8 * _info->fmt.channels;
174     if (info->currentsample + size / samplesize > info->endsample) {
175         size = (info->endsample - info->currentsample + 1) * samplesize;
176         if (size <= 0) {
177             return 0;
178         }
179     }
180 
181     int initsize = size;
182 
183     while (size > 0) {
184         if (info->remaining > 0) {
185             int n = size / samplesize;
186             n = min (n, info->remaining);
187             int nn = n;
188             float *p = info->buffer;
189             while (n > 0) {
190                 int sample = (int)(*p * 32767.0f);
191                 if (sample > 32767) {
192                     sample = 32767;
193                 }
194                 else if (sample < -32768) {
195                     sample = -32768;
196                 }
197                 *((int16_t *)bytes) = (int16_t)sample;
198                 bytes += 2;
199                 if (_info->fmt.channels == 2) {
200                     sample = (int)(*(p+1) * 32767.0f);
201                     if (sample > 32767) {
202                         sample = 32767;
203                     }
204                     else if (sample < -32768) {
205                         sample = -32768;
206                     }
207                     *((int16_t *)bytes) = (int16_t)sample;
208                     bytes += 2;
209                 }
210                 n--;
211                 size -= samplesize;
212                 p += info->si.channels;
213             }
214             if (info->remaining > nn) {
215                 memmove (info->buffer, p, (info->remaining - nn) * sizeof (float) * _info->fmt.channels);
216             }
217             info->remaining -= nn;
218         }
219 
220         if (size > 0 && !info->remaining) {
221             mpc_frame_info frame;
222             frame.buffer = info->buffer;
223             mpc_status err = mpc_demux_decode (info->demux, &frame);
224             if (err != 0 || frame.bits == -1) {
225                 break;
226             }
227 
228             info->remaining = frame.samples;
229         }
230     }
231     info->currentsample += (initsize-size) / samplesize;
232     return initsize-size;
233 }
234 #endif
235 
236 static int
musepack_read(DB_fileinfo_t * _info,char * bytes,int size)237 musepack_read (DB_fileinfo_t *_info, char *bytes, int size) {
238     musepack_info_t *info = (musepack_info_t *)_info;
239     int samplesize = _info->fmt.bps / 8 * _info->fmt.channels;
240 
241     if (info->currentsample + size / samplesize > info->endsample) {
242         size = (info->endsample - info->currentsample + 1) * samplesize;
243         if (size <= 0) {
244             return 0;
245         }
246     }
247 
248     int initsize = size;
249 
250     while (size > 0) {
251         if (info->remaining > 0) {
252             int n = size / samplesize;
253             n = min (n, info->remaining);
254 
255             memcpy (bytes, info->buffer, n * samplesize);
256 
257             size -= n * samplesize;
258             bytes += n * samplesize;
259 
260             if (info->remaining > n) {
261                 memmove (info->buffer, ((char *)info->buffer) + n * samplesize, (info->remaining - n) * samplesize);
262             }
263             info->remaining -= n;
264         }
265 
266         if (size > 0 && !info->remaining) {
267             mpc_frame_info frame;
268             frame.buffer = info->buffer;
269             mpc_status err = mpc_demux_decode (info->demux, &frame);
270             if (err != 0 || frame.bits == -1) {
271                 break;
272             }
273 
274             info->remaining = frame.samples;
275         }
276     }
277     info->currentsample += (initsize-size) / samplesize;
278     return initsize-size;
279 }
280 
281 static int
musepack_seek_sample(DB_fileinfo_t * _info,int sample)282 musepack_seek_sample (DB_fileinfo_t *_info, int sample) {
283     musepack_info_t *info = (musepack_info_t *)_info;
284     mpc_status err = mpc_demux_seek_sample (info->demux, sample + info->startsample);
285     if (err != 0) {
286         fprintf (stderr, "musepack: seek failed\n");
287         return -1;
288     }
289     info->currentsample = sample + info->startsample;
290     _info->readpos = (float)sample / _info->fmt.samplerate;
291     info->remaining = 0;
292     return 0;
293 }
294 
295 static int
musepack_seek(DB_fileinfo_t * _info,float time)296 musepack_seek (DB_fileinfo_t *_info, float time) {
297     musepack_info_t *info = (musepack_info_t *)_info;
298     return musepack_seek_sample (_info, time * _info->fmt.samplerate);
299 }
300 
301 void
mpc_set_trk_properties(DB_playItem_t * it,mpc_streaminfo * si,int64_t fsize)302 mpc_set_trk_properties (DB_playItem_t *it, mpc_streaminfo *si, int64_t fsize) {
303     char s[100];
304     snprintf (s, sizeof (s), "%lld", fsize);
305     deadbeef->pl_add_meta (it, ":FILE_SIZE", s);
306     deadbeef->pl_add_meta (it, ":BPS", "32");
307     snprintf (s, sizeof (s), "%d", si->channels);
308     deadbeef->pl_add_meta (it, ":CHANNELS", s);
309     snprintf (s, sizeof (s), "%d", si->sample_freq);
310     deadbeef->pl_add_meta (it, ":SAMPLERATE", s);
311     snprintf (s, sizeof (s), "%d", (int)(si->average_bitrate/1000));
312     deadbeef->pl_add_meta (it, ":BITRATE", s);
313     snprintf (s, sizeof (s), "%f", si->profile);
314     deadbeef->pl_add_meta (it, ":MPC_QUALITY_PROFILE", s);
315     deadbeef->pl_add_meta (it, ":MPC_PROFILE_NAME", si->profile_name);
316     deadbeef->pl_add_meta (it, ":MPC_ENCODER", si->encoder);
317     snprintf (s, sizeof (s), "%d.%d", (si->encoder_version&0xff000000)>>24, (si->encoder_version&0x00ff0000)>>16);
318     deadbeef->pl_add_meta (it, ":MPC_ENCODER_VERSION", s);
319     deadbeef->pl_add_meta (it, ":MPC_PNS_USED", si->pns ? "1" : "0");
320     deadbeef->pl_add_meta (it, ":MPC_TRUE_GAPLESS", si->is_true_gapless ? "1" : "0");
321     snprintf (s, sizeof (s), "%lld", (int64_t)si->beg_silence);
322     deadbeef->pl_add_meta (it, ":MPC_BEG_SILENCE", s);
323     snprintf (s, sizeof (s), "%d", si->stream_version);
324     deadbeef->pl_add_meta (it, ":MPC_STREAM_VERSION", s);
325     snprintf (s, sizeof (s), "%d", si->max_band);
326     deadbeef->pl_add_meta (it, ":MPC_MAX_BAND", s);
327     deadbeef->pl_add_meta (it, ":MPC_MS", si->ms ? "1" : "0");
328     deadbeef->pl_add_meta (it, ":MPC_FAST_SEEK", si->fast_seek ? "1" : "0");
329 }
330 
331 static DB_playItem_t *
musepack_insert(ddb_playlist_t * plt,DB_playItem_t * after,const char * fname)332 musepack_insert (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname) {
333     trace ("mpc: inserting %s\n", fname);
334     mpc_reader reader = {
335         .read = musepack_vfs_read,
336         .seek = musepack_vfs_seek,
337         .tell = musepack_vfs_tell,
338         .get_size = musepack_vfs_get_size,
339         .canseek = musepack_vfs_canseek,
340     };
341 
342     DB_FILE *fp = deadbeef->fopen (fname);
343     if (!fp) {
344         trace ("mpc: insert failed to open %s\n", fname);
345         return NULL;
346     }
347     int64_t fsize = deadbeef->fgetlength (fp);
348     reader.data = fp;
349 
350     mpc_demux *demux = mpc_demux_init (&reader);
351     if (!demux) {
352         trace ("mpc: mpc_demux_init failed\n");
353         deadbeef->fclose (fp);
354         return NULL;
355     }
356 
357     mpc_streaminfo si;
358     //mpc_streaminfo_init (&si);
359     mpc_demux_get_info (demux, &si);
360 
361     int totalsamples = mpc_streaminfo_get_length_samples (&si);
362     double dur = mpc_streaminfo_get_length (&si);
363 
364     // replay gain
365     float gain_title = 0.f;
366     float gain_album = 0.f;
367     float peak_title = 1.f;
368     float peak_album = 1.f;
369     if (si.gain_title != 0) {
370         gain_title = 64.82-si.gain_title/256.0;
371     }
372     if (si.gain_album != 0) {
373         gain_album = 64.82-si.gain_album/256.0;
374     }
375     if (si.peak_title != 0) {
376         peak_title = pow (10, si.peak_title / (20.0 * 256.0)) / (1<<15);
377     }
378     if (si.peak_album != 0) {
379         peak_album = pow (10, si.peak_album / (20.0 * 256.0)) / (1<<15);
380     }
381 
382     // chapters
383     int nchapters = mpc_demux_chap_nb (demux);
384     DB_playItem_t *prev = NULL;
385     DB_playItem_t *meta = NULL;
386     if (nchapters > 1) {
387         int i;
388         for (i = 0; i < nchapters; i++) {
389             const mpc_chap_info *ch = mpc_demux_chap (demux, i);
390             DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, plugin.plugin.id);
391             deadbeef->pl_add_meta (it, ":FILETYPE", "MusePack");
392             deadbeef->pl_set_meta_int (it, ":TRACKNUM", i);
393             it->startsample = ch->sample;
394             it->endsample = totalsamples-1;
395             float gain = gain_title, peak = peak_title;
396             if (ch->gain != 0) {
397                 gain = 64.82-ch->gain/256.0;
398             }
399             if (ch->peak != 0) {
400                 peak = pow (10, ch->peak / (20.0 * 256.0)) / (1<<15);
401             }
402             deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_ALBUMGAIN, gain_album);
403             deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_ALBUMPEAK, peak_album);
404             deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_TRACKGAIN, gain_title);
405             deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_TRACKPEAK, peak_title);
406             if (!prev) {
407                 meta = deadbeef->pl_item_alloc ();
408                 /*int apeerr = */deadbeef->junk_apev2_read (meta, fp);
409             }
410             else {
411                 prev->endsample = it->startsample-1;
412                 float dur = (prev->endsample - prev->startsample) / (float)si.sample_freq;
413                 deadbeef->plt_set_item_duration (plt, prev, dur);
414             }
415             if (i == nchapters - 1) {
416                 float dur = (it->endsample - it->startsample) / (float)si.sample_freq;
417                 deadbeef->plt_set_item_duration (plt, it, dur);
418             }
419             if (ch->tag_size > 0) {
420                 uint8_t *tag = ch->tag;
421                 deadbeef->junk_apev2_read_mem (it, ch->tag, ch->tag_size);
422                 if (meta) {
423                     deadbeef->pl_items_copy_junk (meta, it, it);
424                 }
425             }
426 
427             mpc_set_trk_properties (it, &si, fsize);
428 
429             deadbeef->pl_set_item_flags (it, deadbeef->pl_get_item_flags (it) | DDB_IS_SUBTRACK);
430             after = deadbeef->plt_insert_item (plt, after, it);
431             prev = it;
432             deadbeef->pl_item_unref (it);
433         }
434         mpc_demux_exit (demux);
435         demux = NULL;
436         deadbeef->fclose (fp);
437         if (meta) {
438             deadbeef->pl_item_unref (meta);
439         }
440         return after;
441     }
442 
443     DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, plugin.plugin.id);
444     deadbeef->pl_add_meta (it, ":FILETYPE", "MusePack");
445     deadbeef->plt_set_item_duration (plt, it, dur);
446 
447     /*int apeerr = */deadbeef->junk_apev2_read (it, fp);
448     deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_ALBUMGAIN, gain_album);
449     deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_ALBUMPEAK, peak_album);
450     deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_TRACKGAIN, gain_title);
451     deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_TRACKPEAK, peak_title);
452 
453     deadbeef->fclose (fp);
454 
455     deadbeef->pl_lock ();
456 
457     // embedded cue
458     const char *cuesheet = deadbeef->pl_find_meta (it, "cuesheet");
459     DB_playItem_t *cue = NULL;
460     if (cuesheet) {
461         cue = deadbeef->plt_insert_cue_from_buffer (plt, after, it, cuesheet, strlen (cuesheet), totalsamples, si.sample_freq);
462         if (cue) {
463             deadbeef->pl_item_unref (it);
464             deadbeef->pl_item_unref (cue);
465             deadbeef->pl_unlock ();
466             mpc_demux_exit (demux);
467             demux = NULL;
468             return cue;
469         }
470     }
471     deadbeef->pl_unlock ();
472 
473     mpc_set_trk_properties (it, &si, fsize);
474     cue  = deadbeef->plt_insert_cue (plt, after, it, totalsamples, si.sample_freq);
475     if (cue) {
476         deadbeef->pl_item_unref (it);
477         deadbeef->pl_item_unref (cue);
478         mpc_demux_exit (demux);
479         demux = NULL;
480 
481         return cue;
482     }
483 
484     deadbeef->pl_add_meta (it, "title", NULL);
485     after = deadbeef->plt_insert_item (plt, after, it);
486     deadbeef->pl_item_unref (it);
487 
488     mpc_demux_exit (demux);
489     demux = NULL;
490 
491     return after;
492 }
493 
musepack_read_metadata(DB_playItem_t * it)494 static int musepack_read_metadata (DB_playItem_t *it) {
495     deadbeef->pl_lock ();
496     DB_FILE *fp = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI"));
497     deadbeef->pl_unlock ();
498     if (!fp) {
499         return -1;
500     }
501     deadbeef->pl_delete_all_meta (it);
502     /*int apeerr = */deadbeef->junk_apev2_read (it, fp);
503     deadbeef->pl_add_meta (it, "title", NULL);
504     deadbeef->fclose (fp);
505     return 0;
506 }
507 
musepack_write_metadata(DB_playItem_t * it)508 static int musepack_write_metadata (DB_playItem_t *it) {
509     // get options
510     int strip_apev2 = deadbeef->conf_get_int ("ape.strip_apev2", 0);
511     int write_apev2 = deadbeef->conf_get_int ("ape.write_apev2", 1);
512 
513     uint32_t junk_flags = 0;
514     if (strip_apev2) {
515         junk_flags |= JUNK_STRIP_APEV2;
516     }
517     if (write_apev2) {
518         junk_flags |= JUNK_WRITE_APEV2;
519     }
520 
521     return deadbeef->junk_rewrite_tags (it, junk_flags, 4, NULL);
522 }
523 
524 
525 static int
musepack_start(void)526 musepack_start (void) {
527     return 0;
528 }
529 
530 static int
musepack_stop(void)531 musepack_stop (void) {
532     return 0;
533 }
534 
535 static const char * exts[] = { "mpc", "mpp", "mp+", NULL };
536 
537 // define plugin interface
538 static DB_decoder_t plugin = {
539     .plugin.api_vmajor = 1,
540     .plugin.api_vminor = 0,
541     .plugin.version_major = 1,
542     .plugin.version_minor = 0,
543     .plugin.type = DB_PLUGIN_DECODER,
544     .plugin.id = "musepack",
545     .plugin.name = "MusePack decoder",
546     .plugin.descr = "Musepack decoder using libmppdec",
547     .plugin.copyright =
548         "MusePack decoder plugin for DeaDBeeF Player\n"
549         "Copyright (C) 2009-2014 Alexey Yakovenko\n"
550         "Uses Musepack SV8 libs (r435), (C) 2005-2009, The Musepack Development Team\n"
551         "\n"
552         "This software is provided 'as-is', without any express or implied\n"
553         "warranty.  In no event will the authors be held liable for any damages\n"
554         "arising from the use of this software.\n"
555         "\n"
556         "Permission is granted to anyone to use this software for any purpose,\n"
557         "including commercial applications, and to alter it and redistribute it\n"
558         "freely, subject to the following restrictions:\n"
559         "\n"
560         "1. The origin of this software must not be misrepresented; you must not\n"
561         " claim that you wrote the original software. If you use this software\n"
562         " in a product, an acknowledgment in the product documentation would be\n"
563         " appreciated but is not required.\n"
564         "\n"
565         "2. Altered source versions must be plainly marked as such, and must not be\n"
566         " misrepresented as being the original software.\n"
567         "\n"
568         "3. This notice may not be removed or altered from any source distribution.\n"
569     ,
570     .plugin.website = "http://deadbeef.sf.net",
571     .plugin.start = musepack_start,
572     .plugin.stop = musepack_stop,
573     .open = musepack_open,
574     .init = musepack_init,
575     .free = musepack_free,
576     .read = musepack_read,
577     .seek = musepack_seek,
578     .seek_sample = musepack_seek_sample,
579     .insert = musepack_insert,
580     .read_metadata = musepack_read_metadata,
581     .write_metadata = musepack_write_metadata,
582     .exts = exts,
583 };
584 
585 DB_plugin_t *
musepack_load(DB_functions_t * api)586 musepack_load (DB_functions_t *api) {
587     deadbeef = api;
588     return DB_PLUGIN (&plugin);
589 }
590