📄 exportmultiple.cpp
字号:
/********************************************************************** Audacity: A Digital Audio Editor ExportMultiple.cpp Dominic Mazzoni Presents a dialog box allowing the user to export multiple files either by exporting each track as a separate file, or by exporting each label as a separate file. 2004.06.23 added mp3 export using tompg.exe for multiple export, by ChackoN tested under w2k only**********************************************************************/#include "../Audacity.h"#include <wx/defs.h>#include <wx/button.h>#include <wx/checkbox.h>#include <wx/choice.h>#include <wx/dialog.h>#include <wx/dirdlg.h>#include <wx/event.h>#include <wx/intl.h>#include <wx/msgdlg.h>#include <wx/sizer.h>#include <wx/statbox.h>#include <wx/stattext.h>#include <wx/textctrl.h>#include <wx/radiobut.h>#include <wx/filedlg.h>#include "Export.h"#include "ExportPCM.h"#include "ExportMP3.h"#include "ExportOGG.h"#include "ExportCL.h"#include "../Internat.h"#include "../FileFormats.h"#include "../LabelTrack.h"#include "../Project.h"#include "../Prefs.h"#include "../Tags.h"enum { FormatID = 10001, DirID, ChooseID, LabelID, FirstID, FirstFileNameID, TrackID, ByNameID, ByNumberID, PrefixID, ForceMonoID, OverwriteID, ExplanationID};class ExportMultipleDialog : public wxDialog{ public: ExportMultipleDialog(wxWindow *parent, wxWindowID id); // input bool byLabelsAllowed; bool byTracksAllowed; // input and output wxString firstFileName; wxString prefix; // output int format; // PCM, MP3, Ogg wxString dir; bool forceMono; bool byLabels; // otherwise by tracks bool includeFirst; bool byName; // otherwise by number bool overwrite; void CopyDataToControls(); private: void EnableControls(); void OnFormat(wxCommandEvent& event); void OnChoose(wxCommandEvent& event); void OnLabel(wxCommandEvent& event); void OnFirst(wxCommandEvent& event); void OnFirstFileName(wxCommandEvent& event); void OnTrack(wxCommandEvent& event); // void OnByName(wxCommandEvent& event); void OnByNumber(wxCommandEvent& event); // void OnPrefix(wxCommandEvent& event); // void OnCancel(wxCommandEvent& event); void OnExport(wxCommandEvent& event); wxChoice *mFormat; wxTextCtrl *mDir; wxButton *mChoose; wxRadioButton *mLabel; wxCheckBox *mFirst; wxTextCtrl *mFirstFileName; wxRadioButton *mTrack; wxRadioButton *mByName; wxRadioButton *mByNumber; wxTextCtrl *mPrefix; wxTextCtrl *mExplanation; wxCheckBox *mForceMono; wxCheckBox *mOverwrite; wxButton *mCancel; wxButton *mExport; DECLARE_EVENT_TABLE()};int CountNumExportableTracks(TrackList *tracks){ int numTracks = 0; // Only count WaveTracks, and for linked pairs, only count the // second one of the pair TrackListIterator iter(tracks); Track *tr = iter.First(); while (tr) { if (tr->GetKind() == Track::Wave && tr->GetLinked()==false) numTracks++; tr = iter.Next(); } return numTracks;}int CountNumLabels(TrackList *tracks){ TrackListIterator iter(tracks); Track *tr = iter.First(); while (tr) { if (tr->GetKind() == Track::Label) { LabelTrack *labelTrack = (LabelTrack *)tr; return labelTrack->GetNumLabels(); } tr = iter.Next(); } return 0;}LabelTrack *GetLabelTrack(TrackList *tracks){ TrackListIterator iter(tracks); Track *tr = iter.First(); while (tr) { if (tr->GetKind() == Track::Label) return (LabelTrack *)tr; tr = iter.Next(); } return NULL;}bool *SaveSelected(TrackList *tracks){ int numTracks = CountNumExportableTracks(tracks); bool *saveSelected = new bool[numTracks]; int i = 0; TrackListIterator iter(tracks); Track *tr = iter.First(); while (tr) { if (tr->GetKind() == Track::Wave) { saveSelected[i++] = tr->GetSelected(); tr->SetSelected(false); if (tr->GetLinked()) { tr = iter.Next(); if (tr) tr->SetSelected(false); } } if (tr) tr = iter.Next(); } return saveSelected;}void RestoreSelected(TrackList *tracks, bool *saveSelected){ int i = 0; TrackListIterator iter(tracks); Track *tr = iter.First(); while (tr) { if (tr->GetKind() == Track::Wave) { tr->SetSelected(saveSelected[i]); if (tr->GetLinked()) { tr = iter.Next(); if (tr) tr->SetSelected(saveSelected[i]); } i++; } if (tr) tr = iter.Next(); } delete[] saveSelected;}wxString MakeFullPath(bool overwrite, wxString dir, wxString name, wxString extension){ wxString sep = wxFILE_SEP_PATH; if (overwrite) return dir+sep+name+extension; else { wxString fullPath = dir+sep+name+extension; int i = 2; while(::wxFileExists(fullPath)) { fullPath = dir+sep+ wxString::Format(wxT("%s-%d"), name.c_str(), i) + extension; i++; } return fullPath; }} wxString getMpgExePath(){ wxString mMpgExePath = gPrefs->Read(wxT("/MP3/MpgExePath"), wxT("")); if (mMpgExePath==wxT("") || !::wxFileExists(FILENAME(mMpgExePath))) { int action = wxMessageBox( _("Audacity needs to know the location of the TOMPG.EXE program.\nPlease download and save the freely available file in any convenient\nlocation such as the Plug-Ins subdir of Audacity and let Audacity\nknow about this path. Would you like to help Audacity locate the file now?"), _("Export needs TOMPG.EXE PATH"), wxYES_NO | wxICON_EXCLAMATION, 0); if (action == wxYES) { wxString question; question.Printf(_("Where is the mp3 encoder TOMPG.EXE located?")); mMpgExePath = wxFileSelector(question, wxT("."), // Path wxT("tompg"), // Name wxT(".exe"), // Extension wxT("Only tompg.exe|tompg.exe|*.exe|*.exe|All Files|*"), //type of files wxOPEN, 0); if (mMpgExePath == wxT("")) { //gPrefs->Write(wxT("/MP3/MpgExePath"), mMpgExePath); return wxT(""); } gPrefs->Write(wxT("/MP3/MpgExePath"), mMpgExePath); } else { //mMpgExePath = wxT(""); //gPrefs->Write(wxT("/MP3/MpgExePath"), mMpgExePath); return wxT(""); } } return mMpgExePath;} //getMpgExePath()static bool DoExport(AudacityProject *project, int format, wxString dir, bool stereo, wxString name, bool selectionOnly, double t0, double t1, bool overwrite, int trackNumber){ switch(format) { case 0: default: { int format = ReadExportFormatPref(); wxString extension = wxT(".") + sf_header_extension(format & SF_FORMAT_TYPEMASK); wxString fullPath = MakeFullPath(overwrite, dir, name, extension); return ExportPCM(project, stereo, fullPath, selectionOnly, t0, t1); } break; case 1: { Tags *tags = project->GetTags(); tags->SetTitle(name); tags->SetTrackNumber(trackNumber); wxString fullPath = MakeFullPath(overwrite, dir, name, wxT(".mp3")); return ExportMP3(project, stereo, fullPath, selectionOnly, t0, t1); } case 2: { wxString fullPath = MakeFullPath(overwrite, dir, name, wxT(".ogg")); return ExportOGG(project, stereo, fullPath, selectionOnly, t0, t1); } case 3: {//tompg. First make wav files, then call tompg.exe to convert wxString mp3OutputFile = MakeFullPath(overwrite,dir, name, wxT(".mp3")); long mpgBitrate = gPrefs->Read(wxT("/FileFormats/MP3Bitrate"), 128)/2; //mpg uses per channel rate 1/2 of total for stereo wxString mpgBitrateString = wxString::Format(wxT("%ld"), mpgBitrate); wxString mono = wxT(""); if (!stereo) mono = wxT(" -M3"); wxString mpgPath = getMpgExePath(); if (mpgPath != wxT("")){ //1. make temporary wav file int format = ReadExportFormatPref(); wxString extension = wxT(".") + sf_header_extension(format & SF_FORMAT_TYPEMASK) + wxT("_tmp"); wxString tmpWavOuput = MakeFullPath(overwrite, dir, name, extension); if (ExportPCM(project, stereo, tmpWavOuput, selectionOnly, t0, t1)){ //2. convert the wav to mp3 using tompg.exe wxString tompgCmd = wxT("\"") + mpgPath + wxT("\" ") + tmpWavOuput + wxT(" ") + mp3OutputFile + mono + wxT(" -B") + mpgBitrateString; wxBeginBusyCursor(); wxArrayString output, errors; int code = wxExecute(tompgCmd, output, errors); wxLogStatus(_T("command '%s' terminated with exit code %d."), tompgCmd.c_str(), code); #ifdef _UNICODE /* remove doesn't handle fn_Str() in Unicode build. May or may not actually work. */ remove(tmpWavOuput.mb_str()); //delete the tmp wav file #else // ANSI remove(tmpWavOuput.fn_str()); //delete the tmp wav file #endif // Unicode/ANSI wxEndBusyCursor(); return (code!=0); } else return false; } else return false; } }}void MakeNameUnique(wxArrayString otherNames, wxString &newName){ if (otherNames.Index(newName, false) >= 0) { int i=2; wxString orig = newName; do { newName.Printf(wxT("%s-%d"), orig.c_str(), i); i++; } while (otherNames.Index(newName, false) >= 0); }}bool ExportMultipleByTrack(AudacityProject *project, wxString dir, int format, bool byName, wxString prefix, bool overwrite, bool forceMono){ TrackList *tracks = project->GetTracks(); int numTracks = CountNumExportableTracks(tracks); bool *saveSelected = SaveSelected(tracks); TrackListIterator iter(tracks); Track *tr = iter.First(); Track *tr2 = NULL; double t0, t1; bool stereo; bool ok = true; int i=0; wxString name; wxArrayString otherNames; while (tr) { if (tr->GetKind() == Track::Wave) { tr->SetSelected(true); tr2 = NULL; if (tr->GetLinked()) { tr2 = iter.Next(); if (tr2) tr2->SetSelected(true); } t0 = ((WaveTrack *)tr)->GetStartTime(); t1 = ((WaveTrack *)tr)->GetEndTime(); if (tr2==NULL && ((WaveTrack *)tr)->GetChannel() == WaveTrack::MonoChannel && ((WaveTrack *)tr)->GetPan()==0.0) stereo = false; else stereo = true; if (format == 3 && forceMono) stereo = false; if (byName) { name = tr->GetName(); } else { if (numTracks > 9) name.Printf(wxT("%s-%02d"), prefix.c_str(), i+1); else name.Printf(wxT("%s-%d"), prefix.c_str(), i+1); } MakeNameUnique(otherNames, name); ok = DoExport(project, format, dir, stereo, name, true, t0, t1, overwrite, i+1); if (!ok) break; otherNames.Add(name); tr->SetSelected(false); if (tr2) { tr2->SetSelected(false); tr2 = NULL; } i++; if (tr) tr = iter.Next(); } } RestoreSelected(tracks, saveSelected); ::wxMessageBox(wxString::Format(_("Successfully exported %d files."), i), _("Export Multiple"), wxOK | wxCENTRE, project); return ok;}bool ExportMultipleByLabel(AudacityProject *project, wxString dir, int format, bool byName, wxString prefix, bool includeFirst, wxString firstFileName, bool overwrite, bool forceMono){ TrackList *tracks = project->GetTracks(); LabelTrack *labels = GetLabelTrack(tracks); if (!labels) return false; int numLabels = labels->GetNumLabels(); int numFiles = numLabels; int l = 0; if (includeFirst) { l--; numFiles++; } // Figure out if we're exporting stereo or mono
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -