bool EffectPhaser::Process() { TrackListIterator iter(mWaveTracks); VTrack *t = iter.First(); int count = 0; while(t) { sampleCount start, len; GetSamples((WaveTrack *)t, &start, &len); bool success = ProcessOne(count, (WaveTrack *)t, start, len, startphase); if (!success) return false; if (t->linked) { // In a stereo pair, the "other" half should be 180 degrees out of phase t = iter.Next(); count++; GetSamples((WaveTrack *)t, &start, &len); success = ProcessOne(count, (WaveTrack *)t, start, len, startphase + M_PI); if (!success) return false; } t = iter.Next(); count++; } return true; }
bool EffectEqualization::Process() { TrackListIterator iter(mWaveTracks); WaveTrack *track = (WaveTrack *) iter.First(); int count = 0; while (track) { double trackStart = track->GetStartTime(); double trackEnd = track->GetEndTime(); double t0 = mT0 < trackStart? trackStart: mT0; double t1 = mT1 > trackEnd? trackEnd: mT1; if (t1 > t0) { longSampleCount start = track->TimeToLongSamples(t0); longSampleCount end = track->TimeToLongSamples(t1); sampleCount len = (sampleCount)(end - start); if (!ProcessOne(count, track, start, len)) return false; } track = (WaveTrack *) iter.Next(); count++; } return true; }
bool EffectPaulstretch::Process() { CopyInputTracks(); SelectedTrackListOfKindIterator iter(Track::Wave, mOutputTracks.get()); WaveTrack *track = (WaveTrack *) iter.First(); m_t1=mT1; int count=0; while (track) { double trackStart = track->GetStartTime(); double trackEnd = track->GetEndTime(); double t0 = mT0 < trackStart? trackStart: mT0; double t1 = mT1 > trackEnd? trackEnd: mT1; if (t1 > t0) { if (!ProcessOne(track, t0,t1,count)) return false; } track = (WaveTrack *) iter.Next(); count++; } mT1=m_t1; ReplaceProcessedTracks(true); return true; }
bool EffectClickRemoval::Process() { this->CopyInputTracks(); // Set up mOutputTracks. bool bGoodResult = true; SelectedTrackListOfKindIterator iter(Track::Wave, mOutputTracks); WaveTrack *track = (WaveTrack *) iter.First(); int count = 0; while (track) { double trackStart = track->GetStartTime(); double trackEnd = track->GetEndTime(); double t0 = mT0 < trackStart? trackStart: mT0; double t1 = mT1 > trackEnd? trackEnd: mT1; if (t1 > t0) { sampleCount start = track->TimeToLongSamples(t0); sampleCount end = track->TimeToLongSamples(t1); sampleCount len = (sampleCount)(end - start); if (!ProcessOne(count, track, start, len)) { bGoodResult = false; break; } } track = (WaveTrack *) iter.Next(); count++; } this->ReplaceProcessedTracks(bGoodResult); return bGoodResult; }
bool EffectNoiseRemoval::Process() { if (!mDoProfile && !mHasProfile) CleanSpeechMayReadNoisegate(); // If we still don't have a profile we have a problem. // This should only happen in CleanSpeech. if(!mDoProfile && !mHasProfile) { wxMessageBox( _("Attempt to run Noise Removal without a noise profile.\n")); return false; } Initialize(); // This same code will both remove noise and profile it, // depending on 'mDoProfile' this->CopyInputWaveTracks(); // Set up mOutputWaveTracks. bool bGoodResult = true; TrackListIterator iter(mOutputWaveTracks); WaveTrack *track = (WaveTrack *) iter.First(); int count = 0; while (track) { double trackStart = track->GetStartTime(); double trackEnd = track->GetEndTime(); double t0 = mT0 < trackStart? trackStart: mT0; double t1 = mT1 > trackEnd? trackEnd: mT1; if (t1 > t0) { sampleCount start = track->TimeToLongSamples(t0); sampleCount end = track->TimeToLongSamples(t1); sampleCount len = (sampleCount)(end - start); if (!ProcessOne(count, track, start, len)) { Cleanup(); bGoodResult = false; break; } } track = (WaveTrack *) iter.Next(); count++; } if (bGoodResult && mDoProfile) { CleanSpeechMayWriteNoiseGate(); mHasProfile = true; mDoProfile = false; } if (bGoodResult) Cleanup(); this->ReplaceProcessedWaveTracks(bGoodResult); return bGoodResult; }
bool EffectFindClipping::Process() { LabelTrack *l = NULL; Track *original = NULL; TrackListOfKindIterator iter(Track::Label, mTracks); for (Track *t = iter.First(); t; t = iter.Next()) { if (t->GetName() == wxT("Clipping")) { l = (LabelTrack *) t; // copy LabelTrack here, so it can be undone on cancel l->Copy(l->GetStartTime(), l->GetEndTime(), &original); original->SetOffset(l->GetStartTime()); original->SetName(wxT("Clipping")); break; } } if (!l) { l = mFactory->NewLabelTrack(); l->SetName(_("Clipping")); mTracks->Add((Track *) l); } int count = 0; // JC: Only process selected tracks. SelectedTrackListOfKindIterator waves(Track::Wave, mTracks); WaveTrack *t = (WaveTrack *) waves.First(); while (t) { double trackStart = t->GetStartTime(); double trackEnd = t->GetEndTime(); double t0 = mT0 < trackStart ? trackStart : mT0; double t1 = mT1 > trackEnd ? trackEnd : mT1; if (t1 > t0) { sampleCount start = t->TimeToLongSamples(t0); sampleCount end = t->TimeToLongSamples(t1); sampleCount len = (sampleCount)(end - start); if (!ProcessOne(l, count, t, start, len)) { //put it back how it was mTracks->Remove((Track *) l); if(original) { mTracks->Add((Track *) original); } return false; } } count++; t = (WaveTrack *) waves.Next(); } return true; }
bool EffectSoundTouch::Process() { // Assumes that mSoundTouch has already been initialized // by the subclass for subclass-specific parameters. //Iterate over each track TrackListIterator iter(mWaveTracks); WaveTrack* leftTrack = (WaveTrack*)(iter.First()); WaveTrack* rightTrack = NULL; mCurTrackNum = 0; m_maxNewLength = 0.0; while (leftTrack) { //Get start and end times from track double trackStart = leftTrack->GetStartTime(); double trackEnd = leftTrack->GetEndTime(); //Set the current bounds to whichever left marker is //greater and whichever right marker is less: mCurT0 = mT0 < trackStart? trackStart: mT0; mCurT1 = mT1 > trackEnd? trackEnd: mT1; // Process only if the right marker is to the right of the left marker if (mCurT1 > mCurT0) { //Transform the marker timepoints to samples longSampleCount start = leftTrack->TimeToLongSamples(mCurT0); longSampleCount end = leftTrack->TimeToLongSamples(mCurT1); rightTrack = NULL; if (leftTrack->GetLinked()) { rightTrack = (WaveTrack*)(iter.Next()); mSoundTouch->setChannels(2); if (!ProcessStereo(leftTrack, rightTrack, start, end)) return false; mCurTrackNum++; // Increment for rightTrack, too. } else { mSoundTouch->setChannels(1); //ProcessOne() (implemented below) processes a single track if (!ProcessOne(leftTrack, start, end)) return false; } } //Iterate to the next track leftTrack = (WaveTrack*)(iter.Next()); mCurTrackNum++; } delete mSoundTouch; mSoundTouch = NULL; mT1 = mT0 + m_maxNewLength; // Update selection. return true; }
bool EffectPopClickRemoval::Process() { TrackListIterator iter(mWaveTracks); WaveTrack *track = (WaveTrack *) iter.First(); int count = 0; while (track) { double trackStart = track->GetStartTime(); double trackEnd = track->GetEndTime(); double t0 = mT0 < trackStart? trackStart: mT0; double t1 = mT1 > trackEnd? trackEnd: mT1; double deltat = t1 - t0; double tpre; double pretime; double rate = track->GetRate(); int max_matrix_size = 1500; pretime = 3*deltat; if (pretime * rate > max_matrix_size) pretime = max_matrix_size / rate; tpre = t0 - pretime; tpre = tpre < trackStart? trackStart: tpre; tpre = tpre > t0? t0: tpre; if (t1 - t0 > 1) { ::wxMessageBox(_("Cannot remove a pop or click longer than " "one second.")); } else if (t1 > t0) { if ((t0 - tpre) * rate < 20) ::wxMessageBox(_("Cannot remove a pop or click at the very " "beginning of a track.")); else { longSampleCount pre = track->TimeToLongSamples(tpre); longSampleCount start = track->TimeToLongSamples(t0); longSampleCount end = track->TimeToLongSamples(t1); sampleCount preLen = (sampleCount)(start - pre); sampleCount postLen = (sampleCount)(end - start); if (!ProcessOne(count, track, pre, preLen, postLen)) return false; } } track = (WaveTrack *) iter.Next(); count++; } return true; }
bool EffectChangeSpeed::Process() { // Similar to EffectSoundTouch::Process() //Iterate over each track this->CopyInputWaveTracks(); // Set up m_pOutputWaveTracks. bool bGoodResult = true; TrackListIterator iter(m_pOutputWaveTracks); WaveTrack* pOutWaveTrack = (WaveTrack*)(iter.First()); mCurTrackNum = 0; m_maxNewLength = 0.0; while (pOutWaveTrack != NULL) { //Get start and end times from track mCurT0 = pOutWaveTrack->GetStartTime(); mCurT1 = pOutWaveTrack->GetEndTime(); //Set the current bounds to whichever left marker is //greater and whichever right marker is less: mCurT0 = wxMax(mT0, mCurT0); mCurT1 = wxMin(mT1, mCurT1); // Process only if the right marker is to the right of the left marker if (mCurT1 > mCurT0) { //Transform the marker timepoints to samples longSampleCount start = pOutWaveTrack->TimeToLongSamples(mCurT0); longSampleCount end = pOutWaveTrack->TimeToLongSamples(mCurT1); //ProcessOne() (implemented below) processes a single track if (!ProcessOne(pOutWaveTrack, start, end)) { bGoodResult = false; break; } } //Iterate to the next track pOutWaveTrack = (WaveTrack*)(iter.Next()); mCurTrackNum++; } this->ReplaceProcessedWaveTracks(bGoodResult); // mT1 = mT0 + m_maxNewLength; // Update selection. return bGoodResult; }
bool EffectSimpleMono::Process() { //Iterate over each track this->CopyInputWaveTracks(); // Set up mOutputWaveTracks. bool bGoodResult = true; TrackListIterator iter(mOutputWaveTracks); WaveTrack* pOutWaveTrack = (WaveTrack*)(iter.First()); mCurTrackNum = 0; while (pOutWaveTrack != NULL) { //Get start and end times from track double trackStart = pOutWaveTrack->GetStartTime(); double trackEnd = pOutWaveTrack->GetEndTime(); //Set the current bounds to whichever left marker is //greater and whichever right marker is less: mCurT0 = mT0 < trackStart? trackStart: mT0; mCurT1 = mT1 > trackEnd? trackEnd: mT1; // Process only if the right marker is to the right of the left marker if (mCurT1 > mCurT0) { //Transform the marker timepoints to samples longSampleCount start = pOutWaveTrack->TimeToLongSamples(mCurT0); longSampleCount end = pOutWaveTrack->TimeToLongSamples(mCurT1); //Get the track rate and samples mCurRate = pOutWaveTrack->GetRate(); mCurChannel = pOutWaveTrack->GetChannel(); //NewTrackSimpleMono() will returns true by default //ProcessOne() processes a single track if (!NewTrackSimpleMono() || !ProcessOne(pOutWaveTrack, start, end)) { bGoodResult = false; break; } } //Iterate to the next track pOutWaveTrack = (WaveTrack*)(iter.Next()); mCurTrackNum++; } this->ReplaceProcessedWaveTracks(bGoodResult); return bGoodResult; }
bool EffectTwoPassSimpleMono::ProcessPass() { //Iterate over each track SelectedTrackListOfKindIterator iter(Track::Wave, mOutputTracks); WaveTrack *track = (WaveTrack *) iter.First(); mCurTrackNum = 0; while (track) { //Get start and end times from track double trackStart = track->GetStartTime(); double trackEnd = track->GetEndTime(); //Set the current bounds to whichever left marker is //greater and whichever right marker is less: mCurT0 = mT0 < trackStart? trackStart: mT0; mCurT1 = mT1 > trackEnd? trackEnd: mT1; // Process only if the right marker is to the right of the left marker if (mCurT1 > mCurT0) { //Transform the marker timepoints to samples sampleCount start = track->TimeToLongSamples(mCurT0); sampleCount end = track->TimeToLongSamples(mCurT1); //Get the track rate and samples mCurRate = track->GetRate(); mCurChannel = track->GetChannel(); //NewTrackPass1/2() returns true by default bool ret; if (mPass == 0) ret = NewTrackPass1(); else ret = NewTrackPass2(); if (!ret) return false; //ProcessOne() (implemented below) processes a single track if (!ProcessOne(track, start, end)) return false; } //Iterate to the next track track = (WaveTrack *) iter.Next(); mCurTrackNum++; } return true; }
bool EffectSoundTouch::Process() { //Assumes that mSoundTouch has already been initialized //by the subclass //Iterate over each track TrackListIterator iter(mWaveTracks); WaveTrack *track = (WaveTrack *) iter.First(); mCurTrackNum = 0; m_maxNewLength = 0.0; while (track) { //Get start and end times from track double trackStart = track->GetStartTime(); double trackEnd = track->GetEndTime(); //Set the current bounds to whichever left marker is //greater and whichever right marker is less: mCurT0 = mT0 < trackStart? trackStart: mT0; mCurT1 = mT1 > trackEnd? trackEnd: mT1; // Process only if the right marker is to the right of the left marker if (mCurT1 > mCurT0) { //Transform the marker timepoints to samples longSampleCount start = track->TimeToLongSamples(mCurT0); longSampleCount end = track->TimeToLongSamples(mCurT1); //Get the track rate and samples mCurRate = track->GetRate(); mCurChannel = track->GetChannel(); //ProcessOne() (implemented below) processes a single track if (!ProcessOne(track, start, end)) return false; } //Iterate to the next track track = (WaveTrack *) iter.Next(); mCurTrackNum++; } delete mSoundTouch; mSoundTouch = NULL; mT1 = mT0 + m_maxNewLength; // Update selection. return true; }
bool EffectNoiseRemoval::Process() { if (doProfile) { for(int i=0; i<windowSize; i++) { sum[i] = float(0.0); sumsq[i] = float(0.0); profileCount[i] = 0; } } TrackListIterator iter(mWaveTracks); WaveTrack *track = (WaveTrack *) iter.First(); int count = 0; while (track) { double trackStart = track->GetStartTime(); double trackEnd = track->GetEndTime(); double t0 = mT0 < trackStart? trackStart: mT0; double t1 = mT1 > trackEnd? trackEnd: mT1; if (t1 > t0) { longSampleCount start = track->TimeToLongSamples(t0); longSampleCount end = track->TimeToLongSamples(t1); sampleCount len = (sampleCount)(end - start); if (!ProcessOne(count, track, start, len)) return false; } track = (WaveTrack *) iter.Next(); count++; } if (doProfile) { for(int i=0; i<=windowSize/2; i++) { //float stddev = sqrt(sumsq[i] - (sum[i]*sum[i])/profileCount[i]) // / profileCount[i]; noiseGate[i] = sum[i] / profileCount[i]; // average } hasProfile = true; } return true; }
void xrMerge() { // clear marks to "false" used.assign (g_nodes.size(),false); // rmark.assign(g_nodes.size(),false); // iterate on nodes u32 group_id = 0; u32 start_time = timeGetTime(); for (u32 Size=16; Size>2; Size/=2) { Msg("Pass size: %d",Size); for (u32 i=0; i<g_nodes.size(); i++) { if (!used[i]) { // analyze vertex& Start = g_nodes[i]; int px,pz; px = iFloor(Start.Pos.x/g_params.fPatchSize+EPS_L); pz = iFloor(Start.Pos.z/g_params.fPatchSize+EPS_L); if (px%Size!=0 || pz%Size!=0) continue; if (QuadFit(i,Size)) CreatePN(group_id); } Progress(float(i)/float(g_nodes.size())); } } for (u32 i=0; i<g_nodes.size(); i++) { if (!used[i]) { // analyze ProcessOne (i,8); CreatePN (group_id); } Progress(float(i)/float(g_nodes.size())); } Msg("Optimization ratio: %2.1f%%\n", 100.f*float(group_id)/float(g_nodes.size()) ); Msg("%d / %d\n%d seconds elapsed.", group_id,g_nodes.size(), (timeGetTime()-start_time)/1000); }
bool EffectNoiseRemoval::Process() { Initialize(); // This same code will both remove noise and profile it, // depending on 'mDoProfile' this->CopyInputTracks(); // Set up mOutputTracks. bool bGoodResult = true; SelectedTrackListOfKindIterator iter(Track::Wave, mOutputTracks); WaveTrack *track = (WaveTrack *) iter.First(); int count = 0; while (track) { double trackStart = track->GetStartTime(); double trackEnd = track->GetEndTime(); double t0 = mT0 < trackStart? trackStart: mT0; double t1 = mT1 > trackEnd? trackEnd: mT1; if (t1 > t0) { sampleCount start = track->TimeToLongSamples(t0); sampleCount end = track->TimeToLongSamples(t1); sampleCount len = (sampleCount)(end - start); if (!ProcessOne(count, track, start, len)) { Cleanup(); bGoodResult = false; break; } } track = (WaveTrack *) iter.Next(); count++; } if (bGoodResult && mDoProfile) { mHasProfile = true; mDoProfile = false; } if (bGoodResult) Cleanup(); this->ReplaceProcessedTracks(bGoodResult); return bGoodResult; }
bool EffectFilter::Process() { TrackListIterator iter(mWaveTracks); VTrack *t = iter.First(); int count = 0; while(t) { sampleCount start, len; GetSamples((WaveTrack *)t, &start, &len); bool success = ProcessOne(count, (WaveTrack *)t, start, len); if (!success) return false; t = iter.Next(); count++; } return true; }
bool EffectChangeSpeed::Process() { // Similar to EffectSoundTouch::Process() //Iterate over each track TrackListIterator iter(mWaveTracks); WaveTrack *track = (WaveTrack *) iter.First(); mCurTrackNum = 0; m_maxNewLength = 0.0; double curT0; double curT1; while (track) { //Get start and end times from track double trackStart = track->GetStartTime(); double trackEnd = track->GetEndTime(); //Set the current bounds to whichever left marker is //greater and whichever right marker is less: curT0 = mT0 < trackStart? trackStart: mT0; curT1 = mT1 > trackEnd? trackEnd: mT1; // Process only if the right marker is to the right of the left marker if (curT1 > curT0) { //Transform the marker timepoints to samples longSampleCount start = track->TimeToLongSamples(curT0); longSampleCount end = track->TimeToLongSamples(curT1); //ProcessOne() (implemented below) processes a single track if (!ProcessOne(track, start, end)) return false; } //Iterate to the next track track = (WaveTrack *) iter.Next(); mCurTrackNum++; } mT1 = mT0 + m_maxNewLength; // Update selection. return true; }
bool EffectNoiseRemoval::Process() { if (doProfile) { for(int i=0; i<windowSize; i++) { sum[i] = 0.0; sumsq[i] = 0.0; profileCount[i] = 0; } } TrackListIterator iter(mWaveTracks); VTrack *t = iter.First(); int count = 0; while(t) { sampleCount start, len; GetSamples((WaveTrack *)t, &start, &len); bool success = ProcessOne(count, (WaveTrack *)t, start, len); if (!success) return false; t = iter.Next(); count++; } if (doProfile) { for(int i=0; i<=windowSize/2; i++) { float avg = sum[i] / profileCount[i]; float stddev = sqrt(sumsq[i] - (sum[i]*sum[i])/profileCount[i]) / profileCount[i]; noiseGate[i] = avg; } hasProfile = true; } return true; }
bool EffectStereoToMono::Process() { // Do not use mWaveTracks here. We will possibly delete tracks, // so we must use the "real" tracklist. TrackListIterator iter(mTracks); mLeftTrack = (WaveTrack *)iter.First(); bool refreshIter = false; while (mLeftTrack) { if (mLeftTrack->GetKind() == Track::Wave && mLeftTrack->GetSelected() && mLeftTrack->GetLinked()) { mRightTrack = (WaveTrack *)iter.Next(); mLeftTrackLen = mLeftTrack->TimeToLongSamples(mLeftTrack->GetEndTime()); mRightTrackLen = mRightTrack->TimeToLongSamples(mRightTrack->GetEndTime()); long diff = abs((long)mRightTrackLen - (long)mLeftTrackLen); if ((diff <= 2) && (mLeftTrack->GetRate() == mRightTrack->GetRate())) { ProcessOne(); // The right channel has been deleted, so we must restart from the beginning refreshIter = true; } } if (refreshIter) { mLeftTrack = (WaveTrack *)iter.First(); refreshIter = false; } else { mLeftTrack = (WaveTrack *)iter.Next(); } } return true; }
static void ProcessAll(ZipArchiveHandle zah) { MaybeShowHeader(); // libziparchive iteration order doesn't match the central directory. // We could sort, but that would cost extra and wouldn't match either. void* cookie; int err = StartIteration(zah, &cookie); if (err != 0) { error(1, 0, "couldn't iterate %s: %s", archive_name, ErrorCodeString(err)); } ZipEntry entry; ZipString string; while ((err = Next(cookie, &entry, &string)) >= 0) { std::string name(string.name, string.name + string.name_length); if (ShouldInclude(name)) ProcessOne(zah, entry, name); } if (err < -1) error(1, 0, "failed iterating %s: %s", archive_name, ErrorCodeString(err)); EndIteration(cookie); MaybeShowFooter(); }
bool EffectNormalize::Process() { if (mGain == false && mDC == false) return true; float ratio; if( mGain ) ratio = pow(10.0,TrapDouble(mLevel, // same value used for all tracks NORMALIZE_DB_MIN, NORMALIZE_DB_MAX)/20.0); else ratio = 1.0; //Iterate over each track this->CopyInputTracks(); // Set up mOutputTracks. bool bGoodResult = true; SelectedTrackListOfKindIterator iter(Track::Wave, mOutputTracks); WaveTrack *track = (WaveTrack *) iter.First(); WaveTrack *prevTrack; prevTrack = track; mCurTrackNum = 0; wxString topMsg; if(mDC & mGain) topMsg = _("Removing DC offset and Normalizing...\n"); else if(mDC & !mGain) topMsg = _("Removing DC offset...\n"); else if(!mDC & mGain) topMsg = _("Normalizing without removing DC offset...\n"); else if(!mDC & !mGain) topMsg = wxT("Not doing anything)...\n"); // shouldn't get here while (track) { //Get start and end times from track double trackStart = track->GetStartTime(); double trackEnd = track->GetEndTime(); //Set the current bounds to whichever left marker is //greater and whichever right marker is less: mCurT0 = mT0 < trackStart? trackStart: mT0; mCurT1 = mT1 > trackEnd? trackEnd: mT1; // Process only if the right marker is to the right of the left marker if (mCurT1 > mCurT0) { wxString msg; wxString trackName = track->GetName(); if(!track->GetLinked() || mStereoInd) msg = topMsg + _("Analyzing: ") + trackName; else msg = topMsg + _("Analyzing first track of stereo pair: ") + trackName; AnalyseTrack(track, msg); // sets mOffset and offset-adjusted mMin and mMax if(!track->GetLinked() || mStereoInd) { // mono or 'stereo tracks independently' float extent = wxMax(fabs(mMax), fabs(mMin)); if( (extent > 0) && mGain ) mMult = ratio / extent; else mMult = 1.0; msg = topMsg + _("Processing: ") + trackName; if(track->GetLinked() || prevTrack->GetLinked()) // only get here if there is a linked track but we are processing independently msg = topMsg + _("Processing stereo channels independently: ") + trackName; if (!ProcessOne(track, msg)) { bGoodResult = false; break; } } else { // we have a linked stereo track // so we need to find it's min, max and offset // as they are needed to calc the multiplier for both tracks float offset1 = mOffset; // remember ones from first track float min1 = mMin; float max1 = mMax; track = (WaveTrack *) iter.Next(); // get the next one mCurTrackNum++; // keeps progress bar correct msg = topMsg + _("Analyzing second track of stereo pair: ") + trackName; AnalyseTrack(track, msg); // sets mOffset and offset-adjusted mMin and mMax float offset2 = mOffset; // ones for second track float min2 = mMin; float max2 = mMax; float extent = wxMax(fabs(min1), fabs(max1)); extent = wxMax(extent, fabs(min2)); extent = wxMax(extent, fabs(max2)); if( (extent > 0) && mGain ) mMult = ratio / extent; // we need to use this for both linked tracks else mMult = 1.0; mOffset = offset1; track = (WaveTrack *) iter.Prev(); // go back to the first linked one mCurTrackNum--; // keeps progress bar correct msg = topMsg + _("Processing first track of stereo pair: ") + trackName; if (!ProcessOne(track, msg)) { bGoodResult = false; break; } mOffset = offset2; track = (WaveTrack *) iter.Next(); // go to the second linked one mCurTrackNum++; // keeps progress bar correct msg = topMsg + _("Processing second track of stereo pair: ") + trackName; if (!ProcessOne(track, msg)) { bGoodResult = false; break; } } } //Iterate to the next track prevTrack = track; track = (WaveTrack *) iter.Next(); mCurTrackNum++; } this->ReplaceProcessedTracks(bGoodResult); return bGoodResult; }
bool EffectChangeSpeed::Process() { // Similar to EffectSoundTouch::Process() // Iterate over each track. // Track::All is needed because this effect needs to introduce // silence in the sync-lock group tracks to keep sync this->CopyInputTracks(Track::All); // Set up mOutputTracks. bool bGoodResult = true; TrackListIterator iter(mOutputTracks); Track* t; mCurTrackNum = 0; mMaxNewLength = 0.0; mFactor = 100.0 / (100.0 + mPercentChange); t = iter.First(); while (t != NULL) { if (t->GetKind() == Track::Label) { if (t->GetSelected() || t->IsSyncLockSelected()) { if (!ProcessLabelTrack(t)) { bGoodResult = false; break; } } } else if (t->GetKind() == Track::Wave && t->GetSelected()) { WaveTrack *pOutWaveTrack = (WaveTrack*)t; //Get start and end times from track mCurT0 = pOutWaveTrack->GetStartTime(); mCurT1 = pOutWaveTrack->GetEndTime(); //Set the current bounds to whichever left marker is //greater and whichever right marker is less: mCurT0 = wxMax(mT0, mCurT0); mCurT1 = wxMin(mT1, mCurT1); // Process only if the right marker is to the right of the left marker if (mCurT1 > mCurT0) { //Transform the marker timepoints to samples sampleCount start = pOutWaveTrack->TimeToLongSamples(mCurT0); sampleCount end = pOutWaveTrack->TimeToLongSamples(mCurT1); //ProcessOne() (implemented below) processes a single track if (!ProcessOne(pOutWaveTrack, start, end)) { bGoodResult = false; break; } } mCurTrackNum++; } else if (t->IsSyncLockSelected()) { t->SyncLockAdjust(mT1, mT0 + (mT1 - mT0) * mFactor); } //Iterate to the next track t=iter.Next(); } if (bGoodResult) ReplaceProcessedTracks(bGoodResult); mT1 = mT0 + mMaxNewLength; // Update selection. return bGoodResult; }
bool EffectNoiseRemoval::Process() { // If we are creating a profile, we don't care whether we have // one already. We just prepare the counters. if (mDoProfile) { for(int i=0; i<windowSize; i++) { sum[i] = float(0.0); sumsq[i] = float(0.0); profileCount[i] = 0; } } else { // We need a profile. if( !mHasProfile ) { CleanSpeechMayReadNoisegate(); } // If we still don't have a profile we have a problem. if( !mHasProfile) { wxMessageBox( _("Attempt to run Noise Removal without a noise profile\n.") ); return false; } } // This same code will both remove noise and // profile it, depending on 'mDoProfile' TrackListIterator iter(mWaveTracks); WaveTrack *track = (WaveTrack *) iter.First(); int count = 0; while (track) { double trackStart = track->GetStartTime(); double trackEnd = track->GetEndTime(); double t0 = mT0 < trackStart? trackStart: mT0; double t1 = mT1 > trackEnd? trackEnd: mT1; if (t1 > t0) { longSampleCount start = track->TimeToLongSamples(t0); longSampleCount end = track->TimeToLongSamples(t1); sampleCount len = (sampleCount)(end - start); if (!ProcessOne(count, track, start, len)){ return false; } } track = (WaveTrack *) iter.Next(); count++; } if (mDoProfile) { for(int i=0; i<=windowSize/2; i++) { //float stddev = sqrt(sumsq[i] - (sum[i]*sum[i])/profileCount[i]) // / profileCount[i]; mNoiseGate[i] = sum[i] / profileCount[i]; // average } CleanSpeechMayWriteNoiseGate(); mHasProfile = true; mDoProfile = false; } return true; }
bool EffectNormalize::Process() { bool wasLinked = false; // set when a track has a linked (stereo) track if (mGain == false && mDC == false) return true; //Iterate over each track this->CopyInputTracks(); // Set up mOutputTracks. bool bGoodResult = true; SelectedTrackListOfKindIterator iter(Track::Wave, mOutputTracks); WaveTrack *track = (WaveTrack *) iter.First(); mCurTrackNum = 0; while (track) { //Get start and end times from track double trackStart = track->GetStartTime(); double trackEnd = track->GetEndTime(); //Set the current bounds to whichever left marker is //greater and whichever right marker is less: mCurT0 = mT0 < trackStart? trackStart: mT0; mCurT1 = mT1 > trackEnd? trackEnd: mT1; // Process only if the right marker is to the right of the left marker if (mCurT1 > mCurT0) { //Transform the marker timepoints to samples sampleCount start = track->TimeToLongSamples(mCurT0); sampleCount end = track->TimeToLongSamples(mCurT1); //Get the track rate and samples mCurRate = track->GetRate(); mCurChannel = track->GetChannel(); if(mStereoInd) // do stereo tracks independently (the easy way) track->GetMinMax(&mMin, &mMax, mCurT0, mCurT1); else { if(!wasLinked) // new mono track or first of a stereo pair { track->GetMinMax(&mMin, &mMax, mCurT0, mCurT1); if(track->GetLinked()) { wasLinked = true; // so we use these values for the next (linked) track track = (WaveTrack *) iter.Next(); // get the next one for the max/min float min, max; track->GetMinMax(&min, &max, mCurT0, mCurT1); mMin = min < mMin ? min : mMin; mMax = max > mMax ? max : mMax; track = (WaveTrack *) iter.Prev(); // back to the one we are on } } else wasLinked = false; // second of the stereo pair, next one is mono or first } //ProcessOne() (implemented below) processes a single track if (!ProcessOne(track, start, end)) { bGoodResult = false; break; } } //Iterate to the next track track = (WaveTrack *) iter.Next(); mCurTrackNum++; } this->ReplaceProcessedTracks(bGoodResult); return bGoodResult; }
bool EffectRepair::Process() { //v This may be too much copying for EffectRepair. To support Cancel, may be able to copy much less. // But for now, Cancel isn't supported without this. this->CopyInputTracks(); // Set up mOutputTracks. //v This may be too much copying for EffectRepair. bool bGoodResult = true; SelectedTrackListOfKindIterator iter(Track::Wave, mOutputTracks.get()); WaveTrack *track = (WaveTrack *) iter.First(); int count = 0; while (track) { const double trackStart = track->GetStartTime(); const double repair_t0 = std::max(mT0, trackStart); const double trackEnd = track->GetEndTime(); const double repair_t1 = std::min(mT1, trackEnd); const double repair_deltat = repair_t1 - repair_t0; if (repair_deltat > 0) { // selection is within track audio const auto repair0 = track->TimeToLongSamples(repair_t0); const auto repair1 = track->TimeToLongSamples(repair_t1); const auto repairLen = repair1 - repair0; if (repairLen > 128) { ::Effect::MessageBox(_("The Repair effect is intended to be used on very short sections of damaged audio (up to 128 samples).\n\nZoom in and select a tiny fraction of a second to repair.")); bGoodResult = false; break; } const double rate = track->GetRate(); const double spacing = std::max(repair_deltat * 2, 128. / rate); const double t0 = std::max(repair_t0 - spacing, trackStart); const double t1 = std::min(repair_t1 + spacing, trackEnd); const auto s0 = track->TimeToLongSamples(t0); const auto s1 = track->TimeToLongSamples(t1); // The difference is at most 2 * 128: const auto repairStart = (repair0 - s0).as_size_t(); const auto len = s1 - s0; if (s0 == repair0 && s1 == repair1) { ::Effect::MessageBox(_("Repair works by using audio data outside the selection region.\n\nPlease select a region that has audio touching at least one side of it.\n\nThe more surrounding audio, the better it performs.")); /// The Repair effect needs some data to go on.\n\nPlease select an area to repair with some audio on at least one side (the more the better).")); bGoodResult = false; break; } if (!ProcessOne(count, track, s0, // len is at most 5 * 128. len.as_size_t(), repairStart, // repairLen is at most 128. repairLen.as_size_t() )) { bGoodResult = false; break; } } track = (WaveTrack *) iter.Next(); count++; } this->ReplaceProcessedTracks(bGoodResult); return bGoodResult; }
bool EffectNyquist::Process() { bool success = true; if (mExternal) { mProgress->Hide(); } // We must copy all the tracks, because Paste needs label tracks to ensure // correct sync-lock group behavior when the timeline is affected; then we just want // to operate on the selected wave tracks this->CopyInputTracks(Track::All); SelectedTrackListOfKindIterator iter(Track::Wave, mOutputTracks); mCurTrack[0] = (WaveTrack *) iter.First(); mOutputTime = mT1 - mT0; mCount = 0; mProgressIn = 0; mProgressOut = 0; mProgressTot = 0; mScale = (GetEffectFlags() & PROCESS_EFFECT ? 0.5 : 1.0) / GetNumWaveGroups(); mStop = false; mBreak = false; mCont = false; mDebugOutput = ""; // Keep track of whether the current track is first selected in its sync-lock group // (we have no idea what the length of the returned audio will be, so we have // to handle sync-lock group behavior the "old" way). mFirstInGroup = true; Track *gtLast = NULL; while (mCurTrack[0]) { mCurNumChannels = 1; if (mT1 >= mT0) { if (mCurTrack[0]->GetLinked()) { mCurNumChannels = 2; mCurTrack[1] = (WaveTrack *)iter.Next(); if (mCurTrack[1]->GetRate() != mCurTrack[0]->GetRate()) { wxMessageBox(_("Sorry, cannot apply effect on stereo tracks where the tracks don't match."), wxT("Nyquist"), wxOK | wxCENTRE, mParent); success = false; goto finish; } mCurStart[1] = mCurTrack[1]->TimeToLongSamples(mT0); } // Check whether we're in the same group as the last selected track SyncLockedTracksIterator gIter(mOutputTracks); Track *gt = gIter.First(mCurTrack[0]); mFirstInGroup = !gtLast || (gtLast != gt); gtLast = gt; mCurStart[0] = mCurTrack[0]->TimeToLongSamples(mT0); sampleCount end = mCurTrack[0]->TimeToLongSamples(mT1); mCurLen = (sampleCount)(end - mCurStart[0]); mProgressIn = 0.0; mProgressOut = 0.0; // libnyquist breaks except in LC_NUMERIC=="C". // // Note that we must set the locale to "C" even before calling // nyx_init() because otherwise some effects will not work! // // MB: setlocale is not thread-safe. Should use uselocale() // if available, or fix libnyquist to be locale-independent. char *prevlocale = setlocale(LC_NUMERIC, NULL); setlocale(LC_NUMERIC, "C"); nyx_init(); nyx_set_os_callback(StaticOSCallback, (void *)this); nyx_capture_output(StaticOutputCallback, (void *)this); success = ProcessOne(); nyx_capture_output(NULL, (void *)NULL); nyx_set_os_callback(NULL, (void *)NULL); nyx_cleanup(); // Reset previous locale setlocale(LC_NUMERIC, prevlocale); if (!success) { goto finish; } mProgressTot += mProgressIn + mProgressOut; } mCurTrack[0] = (WaveTrack *) iter.Next(); mCount += mCurNumChannels; } mT1 = mT0 + mOutputTime; finish: if (mDebug && !mExternal) { NyquistOutputDialog dlog(mParent, -1, _("Nyquist"), _("Nyquist Output: "), NyquistToWxString(mDebugOutput.c_str())); dlog.CentreOnParent(); dlog.ShowModal(); } this->ReplaceProcessedTracks(success); //mDebug = false; return success; }
bool EffectSoundTouch::Process() { // Assumes that mSoundTouch has already been initialized // by the subclass for subclass-specific parameters. The // time warper should also be set. // Check if this effect will alter the selection length; if so, we need // to operate on sync-lock selected tracks. bool mustSync = true; if (mT1 == GetTimeWarper()->Warp(mT1)) { mustSync = false; } //Iterate over each track // Needs Track::All for sync-lock grouping. this->CopyInputTracks(Track::All); bool bGoodResult = true; TrackListIterator iter(mOutputTracks); Track* t; mCurTrackNum = 0; m_maxNewLength = 0.0; t = iter.First(); while (t != NULL) { if (t->GetKind() == Track::Label && (t->GetSelected() || (mustSync && t->IsSyncLockSelected())) ) { if (!ProcessLabelTrack(t)) { bGoodResult = false; break; } } #ifdef USE_MIDI else if (t->GetKind() == Track::Note && (t->GetSelected() || (mustSync && t->IsSyncLockSelected()))) { if (!ProcessNoteTrack(t)) { bGoodResult = false; break; } } #endif else if (t->GetKind() == Track::Wave && t->GetSelected()) { WaveTrack* leftTrack = (WaveTrack*)t; //Get start and end times from track mCurT0 = leftTrack->GetStartTime(); mCurT1 = leftTrack->GetEndTime(); //Set the current bounds to whichever left marker is //greater and whichever right marker is less mCurT0 = wxMax(mT0, mCurT0); mCurT1 = wxMin(mT1, mCurT1); // Process only if the right marker is to the right of the left marker if (mCurT1 > mCurT0) { sampleCount start, end; if (leftTrack->GetLinked()) { double t; WaveTrack* rightTrack = (WaveTrack*)(iter.Next()); //Adjust bounds by the right tracks markers t = rightTrack->GetStartTime(); t = wxMax(mT0, t); mCurT0 = wxMin(mCurT0, t); t = rightTrack->GetEndTime(); t = wxMin(mT1, t); mCurT1 = wxMax(mCurT1, t); //Transform the marker timepoints to samples start = leftTrack->TimeToLongSamples(mCurT0); end = leftTrack->TimeToLongSamples(mCurT1); //Inform soundtouch there's 2 channels mSoundTouch->setChannels(2); //ProcessStereo() (implemented below) processes a stereo track if (!ProcessStereo(leftTrack, rightTrack, start, end)) { bGoodResult = false; break; } mCurTrackNum++; // Increment for rightTrack, too. } else { //Transform the marker timepoints to samples start = leftTrack->TimeToLongSamples(mCurT0); end = leftTrack->TimeToLongSamples(mCurT1); //Inform soundtouch there's a single channel mSoundTouch->setChannels(1); //ProcessOne() (implemented below) processes a single track if (!ProcessOne(leftTrack, start, end)) { bGoodResult = false; break; } } } mCurTrackNum++; } else if (mustSync && t->IsSyncLockSelected()) { t->SyncLockAdjust(mT1, GetTimeWarper()->Warp(mT1)); } //Iterate to the next track t = iter.Next(); } if (bGoodResult) ReplaceProcessedTracks(bGoodResult); delete mSoundTouch; mSoundTouch = NULL; // mT0 = mCurT0; // mT1 = mCurT0 + m_maxNewLength; // Update selection. return bGoodResult; }
bool EffectChangeSpeed::Process() { // Similar to EffectSoundTouch::Process() //Iterate over each track this->CopyInputWaveTracks(); // Set up mOutputWaveTracks. bool bGoodResult = true; TrackListIterator iter(mOutputWaveTracks); WaveTrack* pOutWaveTrack = (WaveTrack*)(iter.First()); mCurTrackNum = 0; m_maxNewLength = 0.0; //Get start and end times from track mCurT0 = pOutWaveTrack->GetStartTime(); mCurT1 = pOutWaveTrack->GetEndTime(); //Set the current bounds to whichever left marker is //greater and whichever right marker is less: mCurT0 = wxMax(mT0, mCurT0); mCurT1 = wxMin(mT1, mCurT1); double len = pOutWaveTrack->GetEndTime() - pOutWaveTrack->GetStartTime(); while (pOutWaveTrack != NULL) { //Get start and end times from track mCurT0 = pOutWaveTrack->GetStartTime(); mCurT1 = pOutWaveTrack->GetEndTime(); //Set the current bounds to whichever left marker is //greater and whichever right marker is less: mCurT0 = wxMax(mT0, mCurT0); mCurT1 = wxMin(mT1, mCurT1); // Process only if the right marker is to the right of the left marker if (mCurT1 > mCurT0) { //Transform the marker timepoints to samples sampleCount start = pOutWaveTrack->TimeToLongSamples(mCurT0); sampleCount end = pOutWaveTrack->TimeToLongSamples(mCurT1); //ProcessOne() (implemented below) processes a single track if (!ProcessOne(pOutWaveTrack, start, end)) { bGoodResult = false; break; } } //Iterate to the next track pOutWaveTrack = (WaveTrack*)(iter.Next()); mCurTrackNum++; } this->ReplaceProcessedWaveTracks(bGoodResult); #ifdef EXPERIMENTAL_FULL_LINKING AudacityProject *p = (AudacityProject*)mParent; if( p && p->IsSticky() ){ pOutWaveTrack = (WaveTrack*)(iter.First()); double newLen = pOutWaveTrack->GetEndTime() - pOutWaveTrack->GetStartTime(); double timeAdded = newLen-len; double sel = mCurT1-mCurT0; double percent = (sel/(timeAdded+sel))*100 - 100; if ( !(HandleGroupChangeSpeed(percent, mCurT0, mCurT1)) ) bGoodResult = false; } #endif // mT1 = mT0 + m_maxNewLength; // Update selection. return bGoodResult; }
bool EffectStereoToMono::Process() { // Do not use mWaveTracks here. We will possibly delete tracks, // so we must use the "real" tracklist. this->CopyInputTracks(); // Set up mOutputTracks. bool bGoodResult = true; SelectedTrackListOfKindIterator iter(Track::Wave, mOutputTracks); mLeftTrack = (WaveTrack *)iter.First(); bool refreshIter = false; if(mLeftTrack) { // create a new WaveTrack to hold all of the output AudacityProject *p = GetActiveProject(); mOutTrack = p->GetTrackFactory()->NewWaveTrack(floatSample, mLeftTrack->GetRate()); } int count = 0; while (mLeftTrack) { if (mLeftTrack->GetKind() == Track::Wave && mLeftTrack->GetSelected() && mLeftTrack->GetLinked()) { mRightTrack = (WaveTrack *)iter.Next(); if ((mLeftTrack->GetRate() == mRightTrack->GetRate())) { sampleCount leftTrackStart = mLeftTrack->TimeToLongSamples(mLeftTrack->GetStartTime()); sampleCount rightTrackStart = mRightTrack->TimeToLongSamples(mRightTrack->GetStartTime()); mStart = wxMin(leftTrackStart, rightTrackStart); sampleCount leftTrackEnd = mLeftTrack->TimeToLongSamples(mLeftTrack->GetEndTime()); sampleCount rightTrackEnd = mRightTrack->TimeToLongSamples(mRightTrack->GetEndTime()); mEnd = wxMax(leftTrackEnd, rightTrackEnd); bGoodResult = ProcessOne(count); if (!bGoodResult) break; mOutTrack->Clear(mOutTrack->GetStartTime(), mOutTrack->GetEndTime()); // The right channel has been deleted, so we must restart from the beginning refreshIter = true; } } if (refreshIter) { mLeftTrack = (WaveTrack *)iter.First(); refreshIter = false; } else { mLeftTrack = (WaveTrack *)iter.Next(); } count++; } if(mOutTrack) delete mOutTrack; this->ReplaceProcessedTracks(bGoodResult); return bGoodResult; }
bool EffectRepair::Process() { //v This may be too much copying for EffectRepair. To support Cancel, may be able to copy much less. // But for now, Cancel isn't supported without this. this->CopyInputTracks(); // Set up mOutputTracks. //v This may be too much copying for EffectRepair. bool bGoodResult = true; SelectedTrackListOfKindIterator iter(Track::Wave, mOutputTracks); WaveTrack *track = (WaveTrack *) iter.First(); int count = 0; while (track) { double trackStart = track->GetStartTime(); double trackEnd = track->GetEndTime(); double repair_t0 = mT0; double repair_t1 = mT1; repair_t0 = (repair_t0 < trackStart? trackStart: repair_t0); repair_t1 = (repair_t1 > trackEnd? trackEnd: repair_t1); if (repair_t0 < repair_t1) { // selection is within track audio double rate = track->GetRate(); double repair_deltat = repair_t1 - repair_t0; double spacing = repair_deltat * 2; if (spacing < 128. / rate) spacing = 128. / rate; double t0 = repair_t0 - spacing; double t1 = repair_t1 + spacing; t0 = t0 < trackStart? trackStart: t0; t1 = t1 > trackEnd? trackEnd: t1; repair_t0 = (repair_t0 < t0? t0: repair_t0); repair_t1 = (repair_t1 > t1? t1: repair_t1); sampleCount s0 = track->TimeToLongSamples(t0); sampleCount repair0 = track->TimeToLongSamples(repair_t0); sampleCount repair1 = track->TimeToLongSamples(repair_t1); sampleCount s1 = track->TimeToLongSamples(t1); sampleCount repairStart = (sampleCount)(repair0 - s0); sampleCount repairLen = (sampleCount)(repair1 - repair0); sampleCount len = (sampleCount)(s1 - s0); if (repairLen > 128) { ::wxMessageBox(_("The Repair effect is intended to be used on very short sections of damaged audio (up to 128 samples).\n\nZoom in and select a tiny fraction of a second to repair.")); bGoodResult = false; break; } if (s0 == repair0 && s1 == repair1) { ::wxMessageBox(_("Repair works by using audio data outside the selection region.\n\nPlease select a region that has audio touching at least one side of it.\n\nThe more surrounding audio, the better it performs.")); /// The Repair effect needs some data to go on.\n\nPlease select an area to repair with some audio on at least one side (the more the better).")); bGoodResult = false; break; } if (!ProcessOne(count, track, s0, len, repairStart, repairLen)) { bGoodResult = false; break; } } track = (WaveTrack *) iter.Next(); count++; } this->ReplaceProcessedTracks(bGoodResult); return bGoodResult; }