📄 exportmp3.cpp
字号:
return _("Audacity does not export MP3 files directly, but instead uses the\nfreely available LAME library to handle MP3 file encoding. You must\nobtain lame_enc.dll separately, by downloading the LAME MP3 encoder,and then locate this file for Audacity. You only need to do this once.\n\nWould you like to locate lame_enc.dll now?"); } bool LoadLibrary() { wxLogNull logNo; if (wxFileExists(FILENAME(mLibPath))) { if(lame_enc_lib.IsLoaded()) { lame_enc_lib.Unload(); } if(!lame_enc_lib.Load(FILENAME(mLibPath))) { return false; } } else return false; beInitStream = (BEINITSTREAM)lame_enc_lib.GetSymbol(wxT("beInitStream")); beEncodeChunk = (BEENCODECHUNK)lame_enc_lib.GetSymbol(wxT("beEncodeChunk")); beDeinitStream = (BEDEINITSTREAM)lame_enc_lib.GetSymbol(wxT("beDeinitStream")); beCloseStream = (BECLOSESTREAM)lame_enc_lib.GetSymbol(wxT("beCloseStream")); beVersion = (BEVERSION)lame_enc_lib.GetSymbol(wxT("beVersion")); if(!beInitStream || !beEncodeChunk || !beDeinitStream || !beCloseStream || !beVersion) return false; beVersion(&mVersion); mLibraryLoaded = true; return true; } bool ValidLibraryLoaded() { return mLibraryLoaded; } wxString GetLibraryVersion() { BE_VERSION ver; if(!mLibraryLoaded) return wxT(""); beVersion(&ver); return wxString::Format(wxT("LAME v%d.%d"), ver.byMajorVersion, ver.byMinorVersion); } int InitializeStream(int channels, int sampleRate) { if(!mLibraryLoaded) return -1; //int modes[] = { 0, BE_MP3_MODE_MONO, BE_MP3_MODE_STEREO }; //mConf.format.LHV1.dwSampleRate = sampleRate; //mConf.format.LHV1.nMode = modes[channels]; int modes[] = { 0, BE_MP3_MODE_MONO, BE_MP3_MODE_STEREO }; mConf.format.mp3.byMode = modes[channels]; mConf.format.mp3.dwSampleRate = sampleRate; mConf.format.mp3.wBitrate = mDefaultRate; beInitStream(&mConf, &mInSampleNum, &mOutBufferSize, &mStreamHandle); mEncoding = true; if(channels == 2) { mStereo = true; return(mInSampleNum / 2); /* convert samples_total into samples_per_channel */ } else { mStereo = false; return (mInSampleNum); } } int GetOutBufferSize() { if (!mEncoding) return -1; return mOutBufferSize; } int EncodeBuffer(short int inbuffer[], unsigned char outbuffer[]) { if(!mEncoding) return -1; unsigned long bytes; beEncodeChunk(mStreamHandle, mInSampleNum, inbuffer, outbuffer, &bytes); return bytes; } int EncodeRemainder(short int inbuffer[], int nSamples, unsigned char outbuffer[]) { if(!mEncoding) return -1; unsigned long bytes; beEncodeChunk(mStreamHandle, nSamples, inbuffer, outbuffer, &bytes); return bytes; } int EncodeBufferMono(short int inbuffer[], unsigned char outbuffer[]) { return EncodeBuffer(inbuffer, outbuffer); } int EncodeRemainderMono(short int inbuffer[], int nSamples, unsigned char outbuffer[]) { return EncodeRemainder(inbuffer, nSamples, outbuffer); } int FinishStream(unsigned char outbuffer[]) { if(!mEncoding) return -1; unsigned long bytes; beDeinitStream(mStreamHandle, outbuffer, &bytes); beCloseStream(mStreamHandle); mEncoding = false; return bytes; } void CancelEncoding() { beCloseStream(mStreamHandle); } int GetQualityVariance() { return -1; } int GetConfigurationCaps() { return MP3CONFIG_BITRATE; } void SetBitrate(int rate) { mDefaultRate = rate; } int GetBitrate() { return mDefaultRate; } void SetQuality(int quality) { } int GetQuality() { return -1; }};MP3Exporter *gMP3Exporter = NULL;MP3Exporter *GetMP3Exporter(){ if (!gMP3Exporter) gMP3Exporter = new BladeEncExporter(); return gMP3Exporter;}void ReleaseMP3Exporter(){ if( gMP3Exporter ) delete gMP3Exporter; gMP3Exporter = NULL;}#endif class MP3ExporterCleanup{public: MP3ExporterCleanup(){}; ~MP3ExporterCleanup(){ ReleaseMP3Exporter();}};// Create instance of this cleanup class purely to clean up // the exporter.// No one will reference this variable, but when the program// exits it will clean up any allocated MP3 exporter.MP3ExporterCleanup gMP3ExporterCleanup;bool ExportMP3(AudacityProject *project, bool stereo, wxString fName, bool selectionOnly, double t0, double t1){ double rate = project->GetRate(); wxWindow *parent = project; TrackList *tracks = project->GetTracks(); wxLogNull logNo; /* temporarily disable wxWindows error messages */ bool success = GetMP3Exporter()->FindLibrary(parent); if (!success) return false; success = GetMP3Exporter()->LoadLibrary(); if (!success) { wxMessageBox(_("Could not open MP3 encoding library!")); gPrefs->Write(wxT("/MP3/MP3LibPath"), wxString(wxT(""))); return false; } if(!GetMP3Exporter()->ValidLibraryLoaded()) { wxMessageBox(_("Not a valid or supported MP3 encoding library!")); gPrefs->Write(wxT("/MP3/MP3LibPath"), wxString(wxT(""))); return false; } /* Open file for writing */ wxFFile outFile(FILENAME(fName).c_str(), wxT("wb")); if (!outFile.IsOpened()) { wxMessageBox(_("Unable to open target file for writing")); return false; } /* Put ID3 tags at beginning of file */ /*lda Check ShowId3Dialog flag for CleanSpeech */ bool showId3Dialog = project->GetShowId3Dialog(); Tags *tags = project->GetTags(); bool emptyTags = tags->IsEmpty(); if (showId3Dialog && emptyTags) { if (!tags->ShowEditDialog(project, _("Edit the ID3 tags for the MP3 file"))) { return false; // used selected "cancel" } } char *id3buffer = NULL; int id3len; bool endOfFile; id3len = tags->ExportID3(&id3buffer, &endOfFile); if (!endOfFile) outFile.Write(id3buffer, id3len); /* Export MP3 using DLL */ long bitrate = gPrefs->Read(wxT("/FileFormats/MP3Bitrate"), 128); GetMP3Exporter()->SetBitrate(bitrate); sampleCount inSamples = GetMP3Exporter()->InitializeStream(stereo ? 2 : 1, int(rate + 0.5)); wxProgressDialog *progress = NULL; wxYield(); wxStartTimer(); wxBusyCursor busy; bool cancelling = false; long bytes; int bufferSize = GetMP3Exporter()->GetOutBufferSize(); unsigned char *buffer = new unsigned char[bufferSize]; wxASSERT(buffer); int numWaveTracks; WaveTrack **waveTracks; tracks->GetWaveTracks(selectionOnly, &numWaveTracks, &waveTracks); Mixer *mixer = new Mixer(numWaveTracks, waveTracks, tracks->GetTimeTrack(), t0, t1, stereo? 2: 1, inSamples, true, rate, int16Sample); while(!cancelling) { sampleCount blockLen = mixer->Process(inSamples); if (blockLen == 0) break; short *mixed = (short *)mixer->GetBuffer(); if(blockLen < inSamples) { if (stereo) bytes = GetMP3Exporter()->EncodeRemainder(mixed, blockLen , buffer); else bytes = GetMP3Exporter()->EncodeRemainderMono(mixed, blockLen , buffer); } else { if (stereo) bytes = GetMP3Exporter()->EncodeBuffer(mixed, buffer); else bytes = GetMP3Exporter()->EncodeBufferMono(mixed, buffer); } outFile.Write(buffer, bytes); if (!progress && wxGetElapsedTime(false) > 500) { wxString title; wxFileName newFileName(fName); wxString justName = newFileName.GetName(); if (selectionOnly) title = wxString::Format(_("Exporting selected audio at %d kbps"), bitrate); else { title = wxString::Format(_("Exporting entire file at %d kbps"), bitrate); } progress = new wxProgressDialog(title, justName, 1000, parent, wxPD_CAN_ABORT | wxPD_REMAINING_TIME | wxPD_AUTO_HIDE); } if (progress) { int progressvalue = int (1000 * ((mixer->MixGetCurrentTime()-t0) / (t1-t0))); cancelling = !progress->Update(progressvalue); } } delete mixer; bytes = GetMP3Exporter()->FinishStream(buffer); if (bytes) outFile.Write(buffer, bytes); /* Write ID3 tag if it was supposed to be at the end of the file */ if (endOfFile) outFile.Write(id3buffer, id3len); free(id3buffer); /* Close file */ outFile.Close(); /* MacOS: set the file type/creator so that the OS knows it's an MP3 file which was created by Audacity */ #ifdef __WXMAC__ FSSpec spec; wxMacFilename2FSSpec(FILENAME(fName), &spec); FInfo finfo; if (FSpGetFInfo(&spec, &finfo) == noErr) { finfo.fdType = 'MP3 '; finfo.fdCreator = AUDACITY_CREATOR; FSpSetFInfo(&spec, &finfo); }#endif if (progress) delete progress; delete[]buffer; return true;}// Indentation settings for Vim and Emacs and unique identifier for Arch, a// version control system. Please do not modify past this point.//// Local Variables:// c-basic-offset: 3// indent-tabs-mode: nil// End://// vim: et sts=3 sw=3// arch-tag: c6af56b1-37fa-4d95-b982-0a24b3a49c00
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -