/********************************************************************** Audacity: A Digital Audio Editor ExportPCM.cpp Dominic Mazzoni **********************************************************************/ #include #include #include #include #include #include #include #include "sndfile.h" #include "../Audacity.h" #include "../FileFormats.h" #include "../Internat.h" #include "../LabelTrack.h" #include "../Mix.h" #include "../Prefs.h" #include "../Project.h" #include "../Track.h" #include "../WaveTrack.h" #include "ExportPCM.h" #ifdef __WXMAC__ #define __MOVIES__ /* Apple's Movies.h not compatible with Audacity */ /* #define __MACHELP__ */ #include # ifdef __UNIX__ # include # else # endif #endif bool ExportPCM(AudacityProject *project, bool stereo, wxString fName, bool selectionOnly, double t0, double t1) { double rate = project->GetRate(); wxWindow *parent = project; TrackList *tracks = project->GetTracks(); int sf_format = ReadExportFormatPref(); wxString formatStr; SF_INFO info; SNDFILE *sf = NULL; int err; formatStr = sf_header_name(sf_format & SF_FORMAT_TYPEMASK); // Use libsndfile to export file info.samplerate = (unsigned int)(rate + 0.5); info.frames = (unsigned int)((t1 - t0)*rate + 0.5); info.channels = stereo? 2: 1; info.format = sf_format; info.sections = 1; info.seekable = 0; // If we can't export exactly the format they requested, // try the default format for that header type... if (!sf_format_check(&info)) info.format = (info.format & SF_FORMAT_TYPEMASK); if (!sf_format_check(&info)) { wxMessageBox(_("Cannot export audio in this format.")); return false; } sf = sf_open((const char *)FILENAME(fName), SFM_WRITE, &info); if (!sf) { wxMessageBox(wxString::Format(_("Cannot export audio to %s"), (const char *)fName)); return false; } sampleFormat format; if (sf_subtype_more_than_16_bits(info.format)) format = floatSample; else format = int16Sample; int maxBlockLen = 44100 * 5; wxProgressDialog *progress = NULL; wxYield(); wxStartTimer(); wxBusyCursor busy; bool cancelling = false; int numWaveTracks; WaveTrack **waveTracks; tracks->GetWaveTracks(selectionOnly, &numWaveTracks, &waveTracks); Mixer *mixer = new Mixer(numWaveTracks, waveTracks, tracks->GetTimeTrack(), t0, t1, info.channels, maxBlockLen, true, rate, format); while(!cancelling) { sampleCount numSamples = mixer->Process(maxBlockLen); if (numSamples == 0) break; samplePtr mixed = mixer->GetBuffer(); if (format == int16Sample) sf_writef_short(sf, (short *)mixed, numSamples); else sf_writef_float(sf, (float *)mixed, numSamples); if (!progress && wxGetElapsedTime(false) > 500) { wxString message; if (selectionOnly) message = wxString:: Format(_("Exporting the selected audio as a %s file"), (const char *) formatStr); else message = wxString:: Format(_("Exporting the entire project as a %s file"), (const char *) formatStr); progress = new wxProgressDialog(_("Export"), message, 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; delete[] waveTracks; err = sf_close(sf); if (err) { char buffer[1000]; sf_error_str(sf, buffer, 1000); wxMessageBox(wxString::Format (_("Error (file may not have been written): %s"), buffer)); } #ifdef __WXMAC__ FSSpec spec; wxMacFilename2FSSpec(FILENAME(fName), &spec); FInfo finfo; if (FSpGetFInfo(&spec, &finfo) == noErr) { finfo.fdType = sf_header_mactype(sf_format & SF_FORMAT_TYPEMASK); finfo.fdCreator = AUDACITY_CREATOR; FSpSetFInfo(&spec, &finfo); } #endif if (progress) delete progress; return true; }