23 $ThisFileInfo[
'mpc'][
'header'] = array();
24 $thisfile_mpc_header = &$ThisFileInfo[
'mpc'][
'header'];
26 $ThisFileInfo[
'fileformat'] =
'mpc';
27 $ThisFileInfo[
'audio'][
'dataformat'] =
'mpc';
28 $ThisFileInfo[
'audio'][
'bitrate_mode'] =
'vbr';
29 $ThisFileInfo[
'audio'][
'channels'] = 2;
30 $ThisFileInfo[
'audio'][
'lossless'] =
false;
32 fseek($fd, $ThisFileInfo[
'avdataoffset'], SEEK_SET);
34 $thisfile_mpc_header[
'size'] = 28;
35 $MPCheaderData = fread($fd, $thisfile_mpc_header[
'size']);
38 if (substr($MPCheaderData, $offset, 3) ==
'MP+') {
41 $thisfile_mpc_header[
'raw'][
'preamble'] = substr($MPCheaderData, $offset, 3);
44 } elseif (preg_match(
'/^[\x00\x01\x10\x11\x40\x41\x50\x51\x80\x81\x90\x91\xC0\xC1\xD0\xD1][\x20-37][\x00\x20\x40\x60\x80\xA0\xC0\xE0]/s', substr($MPCheaderData, 0, 4))) {
47 $thisfile_mpc_header[
'size'] = 8;
50 $ThisFileInfo[
'avdataoffset'] += $thisfile_mpc_header[
'size'];
67 $thisfile_mpc_header[
'target_bitrate'] = (($HeaderDWORD[0] & 0xFF800000) >> 23);
68 $thisfile_mpc_header[
'intensity_stereo'] = (bool) (($HeaderDWORD[0] & 0x00400000) >> 22);
69 $thisfile_mpc_header[
'mid-side_stereo'] = (bool) (($HeaderDWORD[0] & 0x00200000) >> 21);
70 $thisfile_mpc_header[
'stream_major_version'] = ($HeaderDWORD[0] & 0x001FF800) >> 11;
71 $thisfile_mpc_header[
'stream_minor_version'] = 0;
72 $thisfile_mpc_header[
'max_band'] = ($HeaderDWORD[0] & 0x000007C0) >> 6;
73 $thisfile_mpc_header[
'block_size'] = ($HeaderDWORD[0] & 0x0000003F);
75 switch ($thisfile_mpc_header[
'stream_major_version']) {
77 $thisfile_mpc_header[
'frame_count'] = ($HeaderDWORD[1] >> 16);
82 $thisfile_mpc_header[
'frame_count'] = $HeaderDWORD[1];
86 $ThisFileInfo[
'error'] =
'Expecting 4, 5 or 6 in version field, found '.$thisfile_mpc_header[
'stream_major_version'].
' instead';
87 unset($ThisFileInfo[
'mpc']);
92 if (($thisfile_mpc_header[
'stream_major_version'] > 4) && ($thisfile_mpc_header[
'block_size'] != 1)) {
93 $ThisFileInfo[
'warning'][] =
'Block size expected to be 1, actual value found: '.$thisfile_mpc_header[
'block_size'];
96 $thisfile_mpc_header[
'sample_rate'] = 44100;
97 $ThisFileInfo[
'audio'][
'sample_rate'] = $thisfile_mpc_header[
'sample_rate'];
98 $thisfile_mpc_header[
'samples'] = $thisfile_mpc_header[
'frame_count'] * 1152 * $ThisFileInfo[
'audio'][
'channels'];
100 if ($thisfile_mpc_header[
'target_bitrate'] == 0) {
101 $ThisFileInfo[
'audio'][
'bitrate_mode'] =
'vbr';
103 $ThisFileInfo[
'audio'][
'bitrate_mode'] =
'cbr';
106 $ThisFileInfo[
'mpc'][
'bitrate'] = ($ThisFileInfo[
'avdataend'] - $ThisFileInfo[
'avdataoffset']) * 8 * 44100 / $thisfile_mpc_header[
'frame_count'] / 1152;
107 $ThisFileInfo[
'audio'][
'bitrate'] = $ThisFileInfo[
'mpc'][
'bitrate'];
108 $ThisFileInfo[
'audio'][
'encoder'] =
'SV'.$thisfile_mpc_header[
'stream_major_version'];
114 $ThisFileInfo[
'error'][] =
'Expecting "MP+" at offset '.$ThisFileInfo[
'avdataoffset'].
', found "'.substr($MPCheaderData, $offset, 3).
'"';
115 unset($ThisFileInfo[
'fileformat']);
116 unset($ThisFileInfo[
'mpc']);
124 $thisfile_mpc_header[
'stream_major_version'] = ($StreamVersionByte & 0x0F);
125 $thisfile_mpc_header[
'stream_minor_version'] = ($StreamVersionByte & 0xF0) >> 4;
129 switch ($thisfile_mpc_header[
'stream_major_version']) {
135 $ThisFileInfo[
'error'][] =
'Only Musepack SV7 supported';
141 $thisfile_mpc_header[
'intensity_stereo'] = (bool) (($FlagsDWORD1 & 0x80000000) >> 31);
142 $thisfile_mpc_header[
'mid_side_stereo'] = (bool) (($FlagsDWORD1 & 0x40000000) >> 30);
143 $thisfile_mpc_header[
'max_subband'] = ($FlagsDWORD1 & 0x3F000000) >> 24;
144 $thisfile_mpc_header[
'raw'][
'profile'] = ($FlagsDWORD1 & 0x00F00000) >> 20;
145 $thisfile_mpc_header[
'begin_loud'] = (bool) (($FlagsDWORD1 & 0x00080000) >> 19);
146 $thisfile_mpc_header[
'end_loud'] = (bool) (($FlagsDWORD1 & 0x00040000) >> 18);
147 $thisfile_mpc_header[
'raw'][
'sample_rate'] = ($FlagsDWORD1 & 0x00030000) >> 16;
148 $thisfile_mpc_header[
'max_level'] = ($FlagsDWORD1 & 0x0000FFFF);
162 $thisfile_mpc_header[
'true_gapless'] = (bool) (($FlagsDWORD2 & 0x80000000) >> 31);
163 $thisfile_mpc_header[
'last_frame_length'] = ($FlagsDWORD2 & 0x7FF00000) >> 20;
171 $thisfile_mpc_header[
'profile'] = $this->
MPCprofileNameLookup($thisfile_mpc_header[
'raw'][
'profile']);
172 $thisfile_mpc_header[
'sample_rate'] = $this->
MPCfrequencyLookup($thisfile_mpc_header[
'raw'][
'sample_rate']);
173 if ($thisfile_mpc_header[
'sample_rate'] == 0) {
174 $ThisFileInfo[
'error'][] =
'Corrupt MPC file: frequency == zero';
177 $ThisFileInfo[
'audio'][
'sample_rate'] = $thisfile_mpc_header[
'sample_rate'];
178 $thisfile_mpc_header[
'samples'] = ((($thisfile_mpc_header[
'frame_count'] - 1) * 1152) + $thisfile_mpc_header[
'last_frame_length']) * $ThisFileInfo[
'audio'][
'channels'];
180 $ThisFileInfo[
'playtime_seconds'] = ($thisfile_mpc_header[
'samples'] / $ThisFileInfo[
'audio'][
'channels']) / $ThisFileInfo[
'audio'][
'sample_rate'];
181 if ($ThisFileInfo[
'playtime_seconds'] == 0) {
182 $ThisFileInfo[
'error'][] =
'Corrupt MPC file: playtime_seconds == zero';
187 $ThisFileInfo[
'avdataoffset'] += $thisfile_mpc_header[
'size'];
189 $ThisFileInfo[
'audio'][
'bitrate'] = (($ThisFileInfo[
'avdataend'] - $ThisFileInfo[
'avdataoffset']) * 8) / $ThisFileInfo[
'playtime_seconds'];
191 $thisfile_mpc_header[
'title_peak'] = $thisfile_mpc_header[
'raw'][
'title_peak'];
192 $thisfile_mpc_header[
'title_peak_db'] = $this->
MPCpeakDBLookup($thisfile_mpc_header[
'title_peak']);
193 if ($thisfile_mpc_header[
'raw'][
'title_gain'] < 0) {
194 $thisfile_mpc_header[
'title_gain_db'] = (float) (32768 + $thisfile_mpc_header[
'raw'][
'title_gain']) / -100;
196 $thisfile_mpc_header[
'title_gain_db'] = (float) $thisfile_mpc_header[
'raw'][
'title_gain'] / 100;
199 $thisfile_mpc_header[
'album_peak'] = $thisfile_mpc_header[
'raw'][
'album_peak'];
200 $thisfile_mpc_header[
'album_peak_db'] = $this->
MPCpeakDBLookup($thisfile_mpc_header[
'album_peak']);
201 if ($thisfile_mpc_header[
'raw'][
'album_gain'] < 0) {
202 $thisfile_mpc_header[
'album_gain_db'] = (float) (32768 + $thisfile_mpc_header[
'raw'][
'album_gain']) / -100;
204 $thisfile_mpc_header[
'album_gain_db'] = (float) $thisfile_mpc_header[
'raw'][
'album_gain'] / 100;;
206 $thisfile_mpc_header[
'encoder_version'] = $this->
MPCencoderVersionLookup($thisfile_mpc_header[
'raw'][
'encoder_version']);
208 $ThisFileInfo[
'replay_gain'][
'track'][
'adjustment'] = $thisfile_mpc_header[
'title_gain_db'];
209 $ThisFileInfo[
'replay_gain'][
'album'][
'adjustment'] = $thisfile_mpc_header[
'album_gain_db'];
211 if ($thisfile_mpc_header[
'title_peak'] > 0) {
212 $ThisFileInfo[
'replay_gain'][
'track'][
'peak'] = $thisfile_mpc_header[
'title_peak'];
213 } elseif (round($thisfile_mpc_header[
'max_level'] * 1.18) > 0) {
214 $ThisFileInfo[
'replay_gain'][
'track'][
'peak'] =
getid3_lib::CastAsInt(round($thisfile_mpc_header[
'max_level'] * 1.18));
216 if ($thisfile_mpc_header[
'album_peak'] > 0) {
217 $ThisFileInfo[
'replay_gain'][
'album'][
'peak'] = $thisfile_mpc_header[
'album_peak'];
221 $ThisFileInfo[
'audio'][
'encoder'] = $thisfile_mpc_header[
'encoder_version'];
222 $ThisFileInfo[
'audio'][
'encoder_options'] = $thisfile_mpc_header[
'profile'];
228 static $MPCprofileNameLookup = array(
234 5 =>
'below Telephone (q = 0.0)',
235 6 =>
'below Telephone (q = 1.0)',
236 7 =>
'Telephone (q = 2.0)',
237 8 =>
'Thumb (q = 3.0)',
238 9 =>
'Radio (q = 4.0)',
239 10 =>
'Standard (q = 5.0)',
240 11 =>
'Extreme (q = 6.0)',
241 12 =>
'Insane (q = 7.0)',
242 13 =>
'BrainDead (q = 8.0)',
243 14 =>
'above BrainDead (q = 9.0)',
244 15 =>
'above BrainDead (q = 10.0)'
246 return (isset($MPCprofileNameLookup[$profileid]) ? $MPCprofileNameLookup[$profileid] :
'invalid');
250 static $MPCfrequencyLookup = array(
256 return (isset($MPCfrequencyLookup[$frequencyid]) ? $MPCfrequencyLookup[$frequencyid] :
'invalid');
261 return ((log10($intvalue) / log10(2)) - 15) * 6;
272 if ($encoderversion == 0) {
274 return 'Buschmann v1.7.0-v1.7.9 or Klemm v0.90-v1.05';
277 if (($encoderversion % 10) == 0) {
280 return number_format($encoderversion / 100, 2);
282 } elseif (($encoderversion % 2) == 0) {
285 return number_format($encoderversion / 100, 2).
' beta';
290 return number_format($encoderversion / 100, 2).
' alpha';