CDAFReader_MPC::~CDAFReader_MPC() { if(demux) { mpc_demux_exit(demux); demux = NULL; } }
~MPCReader() { if(demux) { mpc_demux_exit(demux); demux = NULL; } }
bool SFB::Audio::MusepackDecoder::_Close(CFErrorRef */*error*/) { if(mDemux) mpc_demux_exit(mDemux), mDemux = nullptr; mpc_reader_exit_stdio(&mReader); mBufferList.Deallocate(); return true; }
MPCReader(FILE *fp) { mpc_status err; fseek(fp, 0, SEEK_SET); demux = NULL; memset(&reader, 0, sizeof(reader)); memset(&si, 0, sizeof(si)); memset(MPCBuffer, 0, sizeof(MPCBuffer)); MPCBufferOffs = 0; MPCBufferIn = 0; if((err = mpc_reader_init_stdio_stream(&reader, fp)) < 0) { throw(MDFN_Error(0, _("Error initializing MusePack decoder!\n"))); } if(!(demux = mpc_demux_init(&reader))) { throw(0); } mpc_demux_get_info(demux, &si); if(si.channels != 2) { mpc_demux_exit(demux); demux = NULL; throw MDFN_Error(0, _("MusePack stream has wrong number of channels(%d); the correct number is 2."), si.channels); } if(si.sample_freq != 44100) { mpc_demux_exit(demux); demux = NULL; throw MDFN_Error(0, _("MusePack stream has wrong samplerate(%d Hz); the current samplerate is 44100 Hz."), si.sample_freq); } }
static void gst_musepackdec_dispose (GObject * obj) { GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (obj); g_free (musepackdec->r); musepackdec->r = NULL; if (musepackdec->d) { mpc_demux_exit (musepackdec->d); musepackdec->d = NULL; } G_OBJECT_CLASS (parent_class)->dispose (obj); }
CDAFReader_MPC::CDAFReader_MPC(Stream *fp) : fw(fp) { demux = NULL; memset(&si, 0, sizeof(si)); memset(MPCBuffer, 0, sizeof(MPCBuffer)); MPCBufferOffs = 0; MPCBufferIn = 0; memset(&reader, 0, sizeof(reader)); reader.read = impc_read; reader.seek = impc_seek; reader.tell = impc_tell; reader.get_size = impc_get_size; reader.canseek = impc_canseek; reader.data = (void*)fp; if(!(demux = mpc_demux_init(&reader))) { throw(0); } mpc_demux_get_info(demux, &si); if(si.channels != 2) { mpc_demux_exit(demux); demux = NULL; throw MDFN_Error(0, _("MusePack stream has wrong number of channels(%u); the correct number is 2."), si.channels); } if(si.sample_freq != 44100) { mpc_demux_exit(demux); demux = NULL; throw MDFN_Error(0, _("MusePack stream has wrong samplerate(%u Hz); the correct samplerate is 44100 Hz."), si.sample_freq); } }
static void gst_musepackdec_dispose (GObject * obj) { GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (obj); g_free (musepackdec->r); musepackdec->r = NULL; #ifdef MPC_IS_OLD_API g_free (musepackdec->d); musepackdec->d = NULL; #else if (musepackdec->d) { mpc_demux_exit (musepackdec->d); musepackdec->d = NULL; } #endif G_OBJECT_CLASS (parent_class)->dispose (obj); }
void xmms_mpc_destroy (xmms_xform_t *xform) { xmms_mpc_data_t *data; g_return_if_fail (xform); data = xmms_xform_private_data_get (xform); g_return_if_fail (data); #ifndef HAVE_MPCDEC_OLD if (data->demux) mpc_demux_exit (data->demux); #endif if (data->buffer) { g_string_free (data->buffer, TRUE); } g_free (data); }
bool SFB::Audio::MusepackDecoder::_Open(CFErrorRef *error) { UInt8 buf [PATH_MAX]; if(!CFURLGetFileSystemRepresentation(mInputSource->GetURL(), FALSE, buf, PATH_MAX)) return false; mReader.read = read_callback; mReader.seek = seek_callback; mReader.tell = tell_callback; mReader.get_size = get_size_callback; mReader.canseek = canseek_callback; mReader.data = this; mDemux = mpc_demux_init(&mReader); if(nullptr == mDemux) { if(error) { SFB::CFString description = CFCopyLocalizedString(CFSTR("The file “%@” is not a valid Musepack file."), ""); SFB::CFString failureReason = CFCopyLocalizedString(CFSTR("Not a Musepack file"), ""); SFB::CFString recoverySuggestion = CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), ""); *error = CreateErrorForURL(Decoder::ErrorDomain, Decoder::InputOutputError, description, mInputSource->GetURL(), failureReason, recoverySuggestion); } mpc_reader_exit_stdio(&mReader); return false; } // Get input file information mpc_streaminfo streaminfo; mpc_demux_get_info(mDemux, &streaminfo); mTotalFrames = mpc_streaminfo_get_length_samples(&streaminfo); // Canonical Core Audio format mFormat.mFormatID = kAudioFormatLinearPCM; mFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kAudioFormatFlagIsNonInterleaved; mFormat.mSampleRate = streaminfo.sample_freq; mFormat.mChannelsPerFrame = streaminfo.channels; mFormat.mBitsPerChannel = 8 * sizeof(float); mFormat.mBytesPerPacket = (mFormat.mBitsPerChannel / 8); mFormat.mFramesPerPacket = 1; mFormat.mBytesPerFrame = mFormat.mBytesPerPacket * mFormat.mFramesPerPacket; mFormat.mReserved = 0; // Set up the source format mSourceFormat.mFormatID = 'MUSE'; mSourceFormat.mSampleRate = streaminfo.sample_freq; mSourceFormat.mChannelsPerFrame = streaminfo.channels; mSourceFormat.mFramesPerPacket = (1 << streaminfo.block_pwr); // Setup the channel layout switch(streaminfo.channels) { case 1: mChannelLayout = ChannelLayout::ChannelLayoutWithTag(kAudioChannelLayoutTag_Mono); break; case 2: mChannelLayout = ChannelLayout::ChannelLayoutWithTag(kAudioChannelLayoutTag_Stereo); break; case 4: mChannelLayout = ChannelLayout::ChannelLayoutWithTag(kAudioChannelLayoutTag_Quadraphonic); break; } // Allocate the buffer list if(!mBufferList.Allocate(mFormat, MPC_FRAME_LENGTH)) { if(error) *error = CFErrorCreate(kCFAllocatorDefault, kCFErrorDomainPOSIX, ENOMEM, nullptr); mpc_demux_exit(mDemux), mDemux = nullptr; mpc_reader_exit_stdio(&mReader); return false; } for(UInt32 i = 0; i < mBufferList->mNumberBuffers; ++i) mBufferList->mBuffers[i].mDataByteSize = 0; return true; }
int main(int argc, char **argv) { MPC_SAMPLE_FORMAT album_max = 0; mpc_uint16_t album_gain; mpc_uint16_t album_peak; mpc_uint16_t * title_gain; mpc_uint16_t * title_peak; mpc_uint32_t * header_pos; int j; printf(About); if (argc < 2) { usage(argv[0]); return 0; } title_gain = malloc((sizeof(mpc_uint16_t) * 2 + sizeof(mpc_uint32_t)) * (argc - 1)); title_peak = title_gain + (argc - 1); header_pos = (mpc_uint32_t *) (title_peak + (argc - 1)); for (j = 1; j < argc; j++) { MPC_SAMPLE_FORMAT sample_buffer[MPC_DECODER_BUFFER_LENGTH]; MPC_SAMPLE_FORMAT title_max = 0, chap_max; mpc_uint16_t * chap_gain, * chap_peak; mpc_reader reader; mpc_demux* demux; mpc_streaminfo si; mpc_status err; int chap_nb, chap = 0; mpc_uint64_t cur_sample = 1, next_chap_sample = mpc_int64_max; err = mpc_reader_init_stdio(&reader, argv[j]); if (err < 0) return !MPC_STATUS_OK; demux = mpc_demux_init(&reader); if (!demux) return !MPC_STATUS_OK; mpc_demux_get_info(demux, &si); chap_nb = mpc_demux_chap_nb(demux); mpc_demux_seek_sample(demux, 0); if (chap_nb > 0) { mpc_chap_info * chap_info = mpc_demux_chap(demux, chap); next_chap_sample = chap_info->sample; chap_gain = malloc(sizeof(mpc_uint16_t) * 2 * chap_nb); chap_peak = chap_gain + chap_nb; } if (j == 1) gain_init_analysis ( si.sample_freq ); while (1) { mpc_frame_info frame; int i = 0; frame.buffer = sample_buffer; mpc_demux_decode(demux, &frame); if (frame.bits == -1) break; while (next_chap_sample < cur_sample + frame.samples) { int sample_nb = (int)(next_chap_sample - cur_sample); chap_max = _max(chap_max, analyze_get_max(sample_buffer + 2 * i, sample_nb)); if (chap == 0) // first samples are not in a chapter gain_get_chapter(); else { chap_gain[chap - 1] = (mpc_uint16_t) (gain_get_chapter() * 256); chap_peak[chap - 1] = (mpc_uint16_t) (log10(chap_max * (1 << 15)) * 20 * 256); } chap++; title_max = _max(title_max, chap_max); chap_max = 0; i += sample_nb; cur_sample = next_chap_sample; if (chap < chap_nb) { mpc_chap_info * chap_info = mpc_demux_chap(demux, chap); next_chap_sample = chap_info->sample; } else next_chap_sample = mpc_int64_max; } chap_max = _max(chap_max, analyze_get_max(sample_buffer + 2 * i, frame.samples - i)); cur_sample += frame.samples - i; } if (chap_nb > 0) { chap_gain[chap - 1] = (mpc_uint16_t) (gain_get_chapter() * 256); chap_peak[chap - 1] = (mpc_uint16_t) (log10(chap_max * (1 << 15)) * 20 * 256); write_chaps_gain(demux, argv[j], chap_gain, chap_peak); } title_max = _max(title_max, chap_max); album_max = _max(album_max, title_max); title_gain[j-1] = (mpc_uint16_t) (gain_get_title() * 256); title_peak[j-1] = (mpc_uint16_t) (log10(title_max * (1 << 15)) * 20 * 256); header_pos[j-1] = si.header_position + 4; mpc_demux_exit(demux); mpc_reader_exit_stdio(&reader); if (chap_nb > 0) free(chap_gain); } album_gain = (mpc_uint16_t) (gain_get_album() * 256); album_peak = (mpc_uint16_t) (log10(album_max * (1 << 15)) * 20 * 256); for (j = 0; j < argc - 1; j++) { unsigned char buffer[64]; mpc_bits_reader r; mpc_block b; mpc_uint64_t size; FILE * file; file = fopen( argv[j + 1], "r+b"); if (file == 0) { fprintf(stderr, "Can't open file \"%s\" for writing\n", argv[j + 1]); continue; } fseek(file, header_pos[j] - 4, SEEK_SET); fread(buffer, 1, 16, file); if (memcmp(buffer, "MPCK", 4) != 0) { fprintf(stderr, "Unsupported file format, not a sv8 file : %s\n", argv[j + 1]); fclose(file); continue; } r.buff = buffer + 4; r.count = 8; for(;;) { size = mpc_bits_get_block(&r, &b); if (mpc_check_key(b.key) != MPC_STATUS_OK) break; if (memcmp(b.key, "RG", 2) == 0) break; header_pos[j] += b.size + size; fseek(file, header_pos[j], SEEK_SET); fread(buffer, 1, 16, file); r.buff = buffer; r.count = 8; } if (memcmp(b.key, "RG", 2) != 0 || b.size < 9) { //check for the loop above having aborted without finding the packet we want to update fprintf(stderr, "Unsupported file format or corrupted file : %s\n", argv[j + 1]); fclose(file); continue; } header_pos[j] += size; buffer[size] = 1; // replaygain version buffer[size + 1] = title_gain[j] >> 8; buffer[size + 2] = title_gain[j] & 0xFF; buffer[size + 3] = title_peak[j] >> 8; buffer[size + 4] = title_peak[j] & 0xFF; buffer[size + 5] = album_gain >> 8; buffer[size + 6] = album_gain & 0xFF; buffer[size + 7] = album_peak >> 8; buffer[size + 8] = album_peak & 0xFF; fseek(file, header_pos[j], SEEK_SET); fwrite(buffer + size, 1, b.size, file); fclose(file); } free(title_gain); return 0; }
int main(int argc, char **argv) { mpc_reader reader; mpc_demux* demux; mpc_streaminfo si; mpc_encoder_t e; unsigned char buffer[16]; mpc_bits_reader r; mpc_block b; mpc_uint64_t size; mpc_status err; mpc_int64_t start_sample = 0, end_sample = 0; mpc_uint32_t beg_silence, start_block, block_num, i; int c; FILE * in_file; printf(About); while ((c = getopt(argc , argv, "s:e:")) != -1) { switch (c) { case 's': start_sample = atoll(optarg); break; case 'e': end_sample = atoll(optarg); break; } } if(argc - optind != 2) { usage(argv[0]); return 0; } err = mpc_reader_init_stdio(&reader, argv[optind]); if(err < 0) return !MPC_STATUS_OK; demux = mpc_demux_init(&reader); if(!demux) return !MPC_STATUS_OK; mpc_demux_get_info(demux, &si); if (si.stream_version < 8) { fprintf(stderr, "this file cannot be edited, please convert it first to sv8 using mpc2sv8\n"); exit(!MPC_STATUS_OK); } if (end_sample == 0) end_sample = si.samples; else end_sample += si.beg_silence; start_sample += si.beg_silence; if (start_sample < 0 || end_sample > si.samples || end_sample <= start_sample) { fprintf(stderr, "specified samples bounds out of stream bounds\n"); exit(!MPC_STATUS_OK); } beg_silence = start_sample % (MPC_FRAME_LENGTH << si.block_pwr); start_block = start_sample / (MPC_FRAME_LENGTH << si.block_pwr); block_num = (end_sample + (MPC_FRAME_LENGTH << si.block_pwr) - 1) / (MPC_FRAME_LENGTH << si.block_pwr) - start_block; end_sample -= start_block * (MPC_FRAME_LENGTH << si.block_pwr); mpc_encoder_init(&e, end_sample, si.block_pwr, 1); e.outputFile = fopen( argv[optind + 1], "rb" ); if ( e.outputFile != 0 ) { fprintf(stderr, "Error : output file \"%s\" already exists\n", argv[optind + 1]); exit(MPC_STATUS_FAIL); } e.outputFile = fopen( argv[optind + 1], "w+b" ); e.seek_ref = 0; writeMagic(&e); writeStreamInfo( &e, si.max_band, si.ms > 0, end_sample, beg_silence, si.sample_freq, si.channels); writeBlock(&e, "SH", MPC_TRUE, 0); writeGainInfo(&e, 0, 0, 0, 0); writeBlock(&e, "RG", MPC_FALSE, 0); in_file = fopen(argv[optind], "rb"); i = si.header_position + 4; fseek(in_file, i, SEEK_SET); fread(buffer, 1, 16, in_file); r.buff = buffer; r.count = 8; size = mpc_bits_get_block(&r, &b); while( memcmp(b.key, "AP", 2) != 0 ) { if ((err = mpc_check_key(b.key)) != MPC_STATUS_OK) { fprintf(stderr, "Error : invalid input stream\n"); goto error; } if (memcmp(b.key, "EI", 2) == 0) copy_data(in_file, i, e.outputFile, b.size + size); i += b.size + size; fseek(in_file, i, SEEK_SET); fread(buffer, 1, 16, in_file); r.buff = buffer; r.count = 8; size = mpc_bits_get_block(&r, &b); } e.seek_ptr = ftell(e.outputFile); writeBits (&e, 0, 16); writeBits (&e, 0, 24); // jump 40 bits for seek table pointer writeBlock(&e, "SO", MPC_FALSE, 0); // reserve space for seek offset while( start_block != 0 ) { if ((err = mpc_check_key(b.key)) != MPC_STATUS_OK) { fprintf(stderr, "Error : invalid input stream\n"); goto error; } if (memcmp(b.key, "AP", 2) == 0) start_block--; i += b.size + size; fseek(in_file, i, SEEK_SET); fread(buffer, 1, 16, in_file); r.buff = buffer; r.count = 8; size = mpc_bits_get_block(&r, &b); } while( block_num != 0 ) { if ((err = mpc_check_key(b.key)) != MPC_STATUS_OK) { fprintf(stderr, "Error : invalid input stream\n"); goto error; } if (memcmp(b.key, "AP", 2) == 0) { if ((e.block_cnt & ((1 << e.seek_pwr) - 1)) == 0) { e.seek_table[e.seek_pos] = ftell(e.outputFile); e.seek_pos++; } e.block_cnt++; copy_data(in_file, i, e.outputFile, b.size + size); block_num--; } i += b.size + size; fseek(in_file, i, SEEK_SET); fread(buffer, 1, 16, in_file); r.buff = buffer; r.count = 8; size = mpc_bits_get_block(&r, &b); } writeSeekTable(&e); writeBlock(&e, "ST", MPC_FALSE, 0); // write seek table block writeBlock(&e, "SE", MPC_FALSE, 0); // write end of stream block error: fclose ( e.outputFile ); fclose ( in_file ); mpc_demux_exit(demux); mpc_reader_exit_stdio(&reader); mpc_encoder_exit(&e); if (err != MPC_STATUS_OK) remove(argv[optind + 1]); return err; }