00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00037
00038 #include "musepack/musepack.h"
00039 #include "musepack/internal.h"
00040
00041 static const char *
00042 Stringify(mpc_uint32_t profile)
00043 {
00044 static const char na[] = "n.a.";
00045 static const char *Names[] = {
00046 na, "'Unstable/Experimental'", na, na,
00047 na, "'quality 0'", "'quality 1'", "'Telephone'",
00048 "'Thumb'", "'Radio'", "'Standard'", "'Xtreme'",
00049 "'Insane'", "'BrainDead'", "'quality 9'", "'quality 10'"
00050 };
00051
00052 return profile >= sizeof(Names) / sizeof(*Names) ? na : Names[profile];
00053 }
00054
00055 void
00056 mpc_streaminfo_init(mpc_streaminfo * si)
00057 {
00058 memset(si, 0, sizeof(mpc_streaminfo));
00059 }
00060
00061
00062
00063 static mpc_int32_t
00064 streaminfo_read_header_sv8(mpc_streaminfo * si, mpc_reader * fp)
00065 {
00066 return 0;
00067 }
00068
00070 static mpc_int32_t
00071 streaminfo_read_header_sv7(mpc_streaminfo * si, mpc_uint32_t HeaderData[8])
00072 {
00073 const mpc_int32_t samplefreqs[4] = { 44100, 48000, 37800, 32000 };
00074
00075
00076 mpc_uint16_t Estimatedpeak_title = 0;
00077
00078 if (si->stream_version > 0x71) {
00079
00080 return 0;
00081 }
00082
00083
00084
00085
00086
00087
00088
00089
00090 si->bitrate = 0;
00091 si->frames = HeaderData[1];
00092 si->is = 0;
00093 si->ms = (HeaderData[2] >> 30) & 0x0001;
00094 si->max_band = (HeaderData[2] >> 24) & 0x003F;
00095 si->block_size = 1;
00096 si->profile = (HeaderData[2] << 8) >> 28;
00097 si->profile_name = Stringify(si->profile);
00098 si->sample_freq = samplefreqs[(HeaderData[2] >> 16) & 0x0003];
00099 Estimatedpeak_title = (mpc_uint16_t) (HeaderData[2] & 0xFFFF);
00100 si->gain_title = (mpc_uint16_t) ((HeaderData[3] >> 16) & 0xFFFF);
00101 si->peak_title = (mpc_uint16_t) (HeaderData[3] & 0xFFFF);
00102 si->gain_album = (mpc_uint16_t) ((HeaderData[4] >> 16) & 0xFFFF);
00103 si->peak_album = (mpc_uint16_t) (HeaderData[4] & 0xFFFF);
00104 si->is_true_gapless = (HeaderData[5] >> 31) & 0x0001;
00105 si->last_frame_samples = (HeaderData[5] >> 20) & 0x07FF;
00106 si->encoder_version = (HeaderData[6] >> 24) & 0x00FF;
00107
00108 if (si->encoder_version == 0) {
00109 sprintf(si->encoder, "Buschmann 1.7.0...9, Klemm 0.90...1.05");
00110 }
00111 else {
00112 switch (si->encoder_version % 10) {
00113 case 0:
00114 sprintf(si->encoder, "Release %u.%u", si->encoder_version / 100,
00115 si->encoder_version / 10 % 10);
00116 break;
00117 case 2:
00118 case 4:
00119 case 6:
00120 case 8:
00121 sprintf(si->encoder, "Beta %u.%02u", si->encoder_version / 100,
00122 si->encoder_version % 100);
00123 break;
00124 default:
00125 sprintf(si->encoder, "--Alpha-- %u.%02u",
00126 si->encoder_version / 100, si->encoder_version % 100);
00127 break;
00128 }
00129 }
00130
00131
00132
00133
00134
00135
00136
00137 si->channels = 2;
00138
00139 return ERROR_CODE_OK;
00140 }
00141
00142
00143 static mpc_int32_t
00144 streaminfo_read_header_sv6(mpc_streaminfo * si, mpc_uint32_t HeaderData[8])
00145 {
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 si->bitrate = (HeaderData[0] >> 23) & 0x01FF;
00156 si->is = (HeaderData[0] >> 22) & 0x0001;
00157 si->ms = (HeaderData[0] >> 21) & 0x0001;
00158 si->stream_version = (HeaderData[0] >> 11) & 0x03FF;
00159 si->max_band = (HeaderData[0] >> 6) & 0x001F;
00160 si->block_size = (HeaderData[0]) & 0x003F;
00161 si->profile = 0;
00162 si->profile_name = Stringify((mpc_uint32_t) (-1));
00163 if (si->stream_version >= 5)
00164 si->frames = HeaderData[1];
00165 else
00166 si->frames = (HeaderData[1] >> 16);
00167
00168 si->gain_title = 0;
00169 si->peak_title = 0;
00170 si->gain_album = 0;
00171 si->peak_album = 0;
00172
00173 si->last_frame_samples = 0;
00174 si->is_true_gapless = 0;
00175
00176 si->encoder_version = 0;
00177 si->encoder[0] = '\0';
00178
00179 if (si->stream_version == 7)
00180 return ERROR_CODE_SV7BETA;
00181 if (si->bitrate != 0)
00182 return ERROR_CODE_CBR;
00183 if (si->is != 0)
00184 return ERROR_CODE_IS;
00185 if (si->block_size != 1)
00186 return ERROR_CODE_BLOCKSIZE;
00187
00188 if (si->stream_version < 6)
00189 si->frames -= 1;
00190
00191 si->sample_freq = 44100;
00192 si->channels = 2;
00193
00194 if (si->stream_version < 4 || si->stream_version > 7)
00195 return ERROR_CODE_INVALIDSV;
00196
00197 return ERROR_CODE_OK;
00198 }
00199
00200
00201 mpc_int32_t
00202 mpc_streaminfo_read(mpc_streaminfo * si, mpc_reader * r)
00203 {
00204 mpc_uint32_t HeaderData[8];
00205 mpc_int32_t Error = 0;
00206
00207
00208 if ((si->header_position = JumpID3v2(r)) < 0) {
00209 return ERROR_CODE_FILE;
00210 }
00211
00212 if (!r->seek(r->data, si->header_position)) {
00213 return ERROR_CODE_FILE;
00214 }
00215 if (r->read(r->data, HeaderData, 8 * 4) != 8 * 4) {
00216 return ERROR_CODE_FILE;
00217 }
00218 if (!r->seek(r->data, si->header_position + 6 * 4)) {
00219 return ERROR_CODE_FILE;
00220 }
00221
00222 si->total_file_length = r->get_size(r->data);
00223 si->tag_offset = si->total_file_length;
00224 if (memcmp(HeaderData, "MP+", 3) == 0) {
00225 #ifndef MPC_LITTLE_ENDIAN
00226 mpc_uint32_t ptr;
00227 for (ptr = 0; ptr < 8; ptr++) {
00228 HeaderData[ptr] = swap32(HeaderData[ptr]);
00229 }
00230 #endif
00231 si->stream_version = HeaderData[0] >> 24;
00232
00233
00234 if ((si->stream_version & 15) >= 8) {
00235 Error = streaminfo_read_header_sv8(si, r);
00236 }
00237
00238 else if ((si->stream_version & 15) == 7) {
00239 Error = streaminfo_read_header_sv7(si, HeaderData);
00240 }
00241 }
00242 else {
00243
00244 Error = streaminfo_read_header_sv6(si, HeaderData);
00245 }
00246
00247
00248 si->pcm_samples = 1152 * si->frames - 576;
00249
00250 if (si->pcm_samples > 0) {
00251 si->average_bitrate =
00252 (si->tag_offset -
00253 si->header_position) * 8.0 * si->sample_freq / si->pcm_samples;
00254 }
00255 else {
00256 si->average_bitrate = 0;
00257 }
00258
00259 return Error;
00260 }
00261
00262 double
00263 mpc_streaminfo_get_length(mpc_streaminfo * si)
00264 {
00265 return (double)mpc_streaminfo_get_length_samples(si) /
00266 (double)si->sample_freq;
00267 }
00268
00269 mpc_int64_t
00270 mpc_streaminfo_get_length_samples(mpc_streaminfo * si)
00271 {
00272 mpc_int64_t samples = (mpc_int64_t) si->frames * MPC_FRAME_LENGTH;
00273 if (si->is_true_gapless) {
00274 samples -= (MPC_FRAME_LENGTH - si->last_frame_samples);
00275 }
00276 else {
00277 samples -= MPC_DECODER_SYNTH_DELAY;
00278 }
00279 return samples;
00280 }