// Note: this set of diffs compares files expanded with USE_MIDI and // EXPERIMENTAL_MIDI_OUT to the same file expanded with USE_MIDI, // EXPERIMENTAL_MIDI_OUT, and EXPERIMENTAL_SCOREALIGN. In all cases // here, "#include" was replaced with "$include" to thwart inclusion by the // preprocessor. Otherwise, the diffs would be over 100K lines and too hard to // understand. The goal here is to verify that all differences are related to // the implementation of SCOREALIGN. // The preprocessor reported some errors as before // (see diffs-no-EXP_MIDI_OUT-vs-EXP_MIDI_OUT.txt) *** w80/src/AudacityApp.cpp.moE 2010-11-28 16:58:38.000000000 -0500 --- w80/src/AudacityApp.cpp.saE 2010-11-28 16:58:38.000000000 -0500 *************** *** 65,70 **** --- 65,73 ---- $include "LoadModules.h" $include "import/Import.h" + + + $include "effects/ScoreAlignDialog.h" # 202 "w80/src/AudacityApp.cppni" DEFINE_EVENT_TYPE(EVT_OPEN_AUDIO_FILE); DEFINE_EVENT_TYPE(EVT_CAPTURE_KEYBOARD); // looks ok *************** *** 127,133 **** CloseContrastDialog(); ! CloseScreenshotTools(); --- 130,136 ---- CloseContrastDialog(); ! CloseScoreAlignDialog(); CloseScreenshotTools(); // looks ok *** w80/src/Menus.cpp.moE 2010-11-28 16:58:38.000000000 -0500 --- w80/src/Menus.cpp.saE 2010-11-28 16:58:38.000000000 -0500 *************** *** 82,88 **** $include "widgets/ErrorDialog.h" $include "CaptureEvents.h" ! # 120 "w80/src/Menus.cppni" enum { kAlignZero=0, kAlignCursor, --- 82,95 ---- $include "widgets/ErrorDialog.h" $include "CaptureEvents.h" ! ! ! $include "effects/ScoreAlignDialog.h" ! $include "audioreader.h" ! $include "scorealign.h" ! $include "scorealign-glue.h" ! ! enum { kAlignZero=0, kAlignCursor, // looks ok *************** *** 658,664 **** AudioIONotBusyFlag | TracksSelectedFlag); c->EndSubMenu(); ! # 719 "w80/src/Menus.cppni" c->AddSeparator(); --- 665,679 ---- AudioIONotBusyFlag | TracksSelectedFlag); c->EndSubMenu(); ! ! ! ! ! c->AddItem(wxT("ScoreAlign"), _("Synchronize MIDI with Audio"), new AudacityProjectCommandFunctor(this, &AudacityProject:: OnScoreAlign ), ! AudioIONotBusyFlag | NoteTracksSelectedFlag | WaveTracksSelectedFlag, ! AudioIONotBusyFlag | NoteTracksSelectedFlag | WaveTracksSelectedFlag); ! ! c->AddSeparator(); // looks ok *************** *** 4514,4520 **** { HandleAlign(index, true); } ! # 5215 "w80/src/Menus.cppni" void AudacityProject::OnNewWaveTrack() { WaveTrack *t = mTrackFactory->NewWaveTrack(mDefaultFormat, mRate); --- 4529,4771 ---- { HandleAlign(index, true); } ! # 4972 "w80/src/Menus.cppni" ! class ASAProgress : public SAProgress { ! private: ! float mTotalWork; ! float mFrames[2]; ! long mTotalCells; ! long mCellCount; ! long mPrevCellCount; ! ProgressDialog *mProgress; ! ! FILE *mTimeFile; ! wxDateTime mStartTime; ! long iterations; ! ! ! public: ! ASAProgress() { ! smoothing = false; ! mProgress = NULL; ! ! mTimeFile = fopen("timing-data.txt", "w"); ! ! } ! ~ASAProgress() { ! delete mProgress; ! ! fclose(mTimeFile); ! ! } ! virtual void set_phase(int i) { ! float work[2]; ! float work2, work3 = 0; ! SAProgress::set_phase(i); ! ! long ms = 0; ! wxDateTime now = wxDateTime::UNow(); ! fprintf(mTimeFile, "Phase %d begins at %s\n", ! i, now.FormatTime().c_str()); ! if (i != 0) ! ms = now.Subtract(mStartTime).GetMilliseconds().ToLong(); ! mStartTime = now; ! ! if (i == 0) { ! mCellCount = 0; ! for (int j = 0; j < 2; j++) { ! mFrames[j] = durations[j] / frame_period; ! } ! mTotalWork = 0; ! for (int j = 0; j < 2; j++) { ! work[j] = ! (is_audio[j] ? 0.004F : 0.0001F) * mFrames[j]; ! mTotalWork += work[j]; ! } ! mTotalCells = mFrames[0] * mFrames[1]; ! work2 = mTotalCells * 0.000002F; ! mTotalWork += work2; ! ! ! if (smoothing) { ! work3 = ! wxMax(mFrames[0], mFrames[1]) * 0.000001F * 40; ! mTotalWork += work3; ! } ! ! fprintf(mTimeFile, " mTotalWork (an estimate) = %g\n", mTotalWork); ! fprintf(mTimeFile, " work0 = %g, frames %g, is_audio %d\n", ! work[0], mFrames[0], is_audio[0]); ! fprintf(mTimeFile, " work1 = %g, frames %g, is_audio %d\n", ! work[1], mFrames[1], is_audio[1]); ! fprintf(mTimeFile, "work2 = %g, work3 = %g\n", work2, work3); ! ! mProgress = new ProgressDialog(_("Synchronize MIDI with Audio"), ! _("Synchronizing MIDI and Audio Tracks")); ! } else if (i < 3) { ! fprintf(mTimeFile, ! "Phase %d took %d ms for %g frames, coefficient = %g s/frame\n", ! i - 1, ms, mFrames[i - 1], (ms * 0.001) / mFrames[i - 1]); ! } else if (i == 3) { ! fprintf(mTimeFile, ! "Phase 2 took %d ms for %d cells, coefficient = %g s/cell\n", ! ms, mCellCount, (ms * 0.001) / mCellCount); ! } else if (i == 4) { ! fprintf(mTimeFile, "Phase 3 took %d ms for %d iterations on %g frames, coefficient = %g s per frame per iteration\n", ! ms, iterations, wxMax(mFrames[0], mFrames[1]), ! (ms * 0.001) / (wxMax(mFrames[0], mFrames[1]) * iterations)); ! } ! } ! virtual bool set_feature_progress(float s) { ! float work; ! if (phase == 0) { ! float f = s / frame_period; ! work = (is_audio[0] ? 0.004F : 0.0001F) * f; ! } else if (phase == 1) { ! float f = s / frame_period; ! work = (is_audio[0] ? 0.004F : 0.0001F) * mFrames[0] + ! (is_audio[1] ? 0.004F : 0.0001F) * f; ! } ! int updateResult = mProgress->Update(int(work), int(mTotalWork)); ! return (updateResult == eProgressSuccess); ! } ! virtual bool set_matrix_progress(int cells) { ! mCellCount += cells; ! float work = ! (is_audio[0] ? 0.004F : 0.0001F) * mFrames[0] + ! (is_audio[1] ? 0.004F : 0.0001F) * mFrames[1]; ! work += mCellCount * 0.000002F; ! int updateResult = mProgress->Update(int(work), int(mTotalWork)); ! return (updateResult == eProgressSuccess); ! } ! virtual bool set_smoothing_progress(int i) { ! iterations = i; ! float work = ! (is_audio[0] ? 0.004F : 0.0001F) * mFrames[0] + ! (is_audio[1] ? 0.004F : 0.0001F) * mFrames[1] + ! 0.000002F * mFrames[0] * mFrames[1]; ! work += i * wxMax(mFrames[0], mFrames[1]) * 0.000001F; ! int updateResult = mProgress->Update(int(work), int(mTotalWork)); ! return (updateResult == eProgressSuccess); ! } ! }; ! ! ! long mixer_process(void *mixer, float **buffer, long n) ! { ! Mixer *mix = (Mixer *) mixer; ! long frame_count = mix->Process(n); ! *buffer = (float *) mix->GetBuffer(); ! return frame_count; ! } ! ! void AudacityProject::OnScoreAlign() ! { ! TrackListIterator iter(mTracks); ! Track *t = iter.First(); ! int numWaveTracksSelected = 0; ! int numNoteTracksSelected = 0; ! int numOtherTracksSelected = 0; ! NoteTrack *nt; ! double endTime = 0.0; ! ! ! ! while (t) { ! if (t->GetSelected()) { ! if (t->GetKind() == Track::Wave) { ! numWaveTracksSelected++; ! WaveTrack *wt = (WaveTrack *) t; ! endTime = endTime > wt->GetEndTime() ? endTime : wt->GetEndTime(); ! } else if(t->GetKind() == Track::Note) { ! numNoteTracksSelected++; ! nt = (NoteTrack *) t; ! } else numOtherTracksSelected++; ! } ! t = iter.Next(); ! } ! ! if(numWaveTracksSelected == 0 || ! numNoteTracksSelected != 1 || ! numOtherTracksSelected != 0){ ! wxMessageBox(wxString::Format(wxT("Please select at least one audio track and one MIDI track."))); ! return; ! } ! ! ! ! ! ScoreAlignParams params; ! ScoreAlignDialog *dlog = new ScoreAlignDialog(NULL, params); ! CloseScoreAlignDialog(); ! ! if (params.mStatus != wxID_OK) return; ! ! ! PushState(_("Sync MIDI with Audio"), _("Sync MIDI with Audio")); ! ! ! if (nt->GetOffset() < 0) { ! ! nt->Clear(nt->GetOffset(), 0); ! } else if (nt->GetOffset() > 0) { ! nt->Shift(nt->GetOffset()); ! } ! nt->SetOffset(0); ! ! WaveTrack **waveTracks; ! mTracks->GetWaveTracks(true , ! &numWaveTracksSelected, &waveTracks); ! ! Mixer *mix = new Mixer(numWaveTracksSelected, ! waveTracks, ! mTracks->GetTimeTrack(), ! 0.0, ! endTime, ! 2, ! 44100, ! true, ! mRate, ! floatSample, ! true, ! NULL); ! delete [] waveTracks; ! ! ASAProgress *progress = new ASAProgress; ! # 5182 "w80/src/Menus.cppni" ! int result = scorealign((void *) mix, &mixer_process, ! 2 , 44100.0 , endTime, ! nt->GetSequence(), progress, params); ! ! ! ! ! delete progress; ! delete mix; ! ! if (result == SA_SUCCESS) { ! ! RedrawProject(); ! wxMessageBox(wxString::Format( ! _("Alignment completed: MIDI from %.2f to %.2f secs, Audio from %.2f to %.2f secs."), ! params.mMidiStart, params.mMidiEnd, ! params.mAudioStart, params.mAudioEnd)); ! } else if (result == SA_TOOSHORT) { ! wxMessageBox(wxString::Format( ! _("Alignment error: input too short: MIDI from %.2f to %.2f secs, Audio from %.2f to %.2f secs."), ! params.mMidiStart, params.mMidiEnd, ! params.mAudioStart, params.mAudioEnd)); ! } else if (result == SA_CANCEL) { ! GetActiveProject()->OnUndo(); ! return; ! } else { ! GetActiveProject()->OnUndo(); ! wxMessageBox(_("Internal error reported by alignment process.")); ! } ! } ! ! ! void AudacityProject::OnNewWaveTrack() { WaveTrack *t = mTrackFactory->NewWaveTrack(mDefaultFormat, mRate); // looks ok // Note: Most of the EXPERIMENTAL_SCOREALIGN changes are in libscorealign, // which should only be linked when EXPERIMENTAL_SCOREALIGN is defined. // The sources in this library are not actually hidden when // EXPERIMENTAL_SCOREALIGN is undefined, so it is up to the build system // or the linker to keep this code out unless EXPERIMENTAL_SCOREALIGN is // defined.