1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 Thom Johansen
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
27 #include "metadata_common.h"
29 #include "replaygain.h"
31 bool get_musepack_metadata(int fd
, struct mp3entry
*id3
)
33 const int32_t sfreqs_sv7
[4] = { 44100, 48000, 37800, 32000 };
38 if (!skip_id3v2(fd
, id3
))
40 if (read(fd
, header
, 4*8) != 4*8) return false;
41 /* Musepack files are little endian, might need swapping */
42 for (i
= 1; i
< 8; i
++)
43 header
[i
] = letoh32(header
[i
]);
44 if (!memcmp(header
, "MP+", 3)) { /* Compare to sig "MP+" */
45 unsigned int streamversion
;
47 header
[0] = letoh32(header
[0]);
48 streamversion
= (header
[0] >> 24) & 15;
49 if (streamversion
>= 8) {
50 return false; /* SV8 or higher don't exist yet, so no support */
51 } else if (streamversion
== 7) {
52 unsigned int gapless
= (header
[5] >> 31) & 0x0001;
53 unsigned int last_frame_samples
= (header
[5] >> 20) & 0x07ff;
54 int track_gain
, album_gain
;
57 id3
->frequency
= sfreqs_sv7
[(header
[2] >> 16) & 0x0003];
58 samples
= (uint64_t)header
[1]*1152; /* 1152 is mpc frame size */
60 samples
-= 1152 - last_frame_samples
;
62 samples
-= 481; /* Musepack subband synth filter delay */
64 /* Extract ReplayGain data from header */
65 track_gain
= (int16_t)((header
[3] >> 16) & 0xffff);
66 id3
->track_gain
= get_replaygain_int(track_gain
);
67 id3
->track_peak
= ((uint16_t)(header
[3] & 0xffff)) << 9;
69 album_gain
= (int16_t)((header
[4] >> 16) & 0xffff);
70 id3
->album_gain
= get_replaygain_int(album_gain
);
71 id3
->album_peak
= ((uint16_t)(header
[4] & 0xffff)) << 9;
73 /* Write replaygain values to strings for use in id3 screen. We use
74 the XING header as buffer space since Musepack files shouldn't
75 need to use it in any other way */
76 id3
->track_gain_string
= (char *)id3
->toc
;
77 bufused
= snprintf(id3
->track_gain_string
, 45,
78 "%d.%d dB", track_gain
/100, abs(track_gain
)%100);
79 id3
->album_gain_string
= (char *)id3
->toc
+ bufused
+ 1;
80 bufused
= snprintf(id3
->album_gain_string
, 45,
81 "%d.%d dB", album_gain
/100, abs(album_gain
)%100);
84 header
[0] = letoh32(header
[0]);
85 unsigned int streamversion
= (header
[0] >> 11) & 0x03FF;
86 if (streamversion
!= 4 && streamversion
!= 5 && streamversion
!= 6)
88 id3
->frequency
= 44100;
94 if (streamversion
>= 5)
95 samples
= (uint64_t)header
[1]*1152; // 32 bit
97 samples
= (uint64_t)(header
[1] >> 16)*1152; // 16 bit
100 if (streamversion
< 6)
105 /* Estimate bitrate, we should probably subtract the various header sizes
106 here for super-accurate results */
107 id3
->length
= ((int64_t) samples
* 1000) / id3
->frequency
;
109 if (id3
->length
<= 0)
111 logf("mpc length invalid!");
115 id3
->filesize
= filesize(fd
);
116 id3
->bitrate
= id3
->filesize
* 8 / id3
->length
;