⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 repeat.cpp

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 CPP
字号:
/**********************************************************************  Audacity: A Digital Audio Editor  Repeat.cpp  Dominic Mazzoni  Vaughan Johnson**********************************************************************/#include "Repeat.h"#include "../Audacity.h"#include "../WaveTrack.h"#include <wx/button.h>#include <wx/defs.h>#include <wx/intl.h>#include <wx/msgdlg.h>#include <wx/sizer.h>#include <wx/stattext.h>#include <wx/textctrl.h>#include <wx/validate.h>#include <wx/valtext.h>#include <math.h>EffectRepeat::EffectRepeat(){   repeatCount = 10;}wxString EffectRepeat::GetEffectDescription() {    // Note: This is useful only after values have been set.    return wxString::Format(_("Repeated %d times"), repeatCount);} bool EffectRepeat::PromptUser(){   //   // Figure out the maximum number of times the selection   // could be repeated without overflowing any track   //   int maxCount = -1;   TrackListIterator iter(mWaveTracks);   WaveTrack *track = (WaveTrack *) iter.First();   while (track) {      sampleCount trackLen =          (sampleCount)((track->GetEndTime() - track->GetStartTime()) *                        track->GetRate());      sampleCount selectionLen = (sampleCount)((mT1 - mT0) * track->GetRate());      int availSamples = 2147483647 - trackLen;      int count = availSamples / selectionLen;      if (maxCount == -1 || count < maxCount)         maxCount = count;      track = (WaveTrack *) iter.Next();   }      if (maxCount <= 1) {      wxMessageBox(_("Tracks are too long to repeat the selection."),                   _("Repeat"), wxOK | wxCENTRE, mParent);      return false;   }   RepeatDialog dlog(mParent, -1, _("Repeat"));   dlog.repeatCount = repeatCount;   dlog.selectionTimeSecs = mT1 - mT0;   dlog.maxCount = maxCount;   dlog.TransferDataToWindow();   dlog.CentreOnParent();   dlog.ShowModal();   if (!dlog.GetReturnCode())      return false;   repeatCount = dlog.repeatCount;   if (repeatCount > maxCount)      repeatCount = maxCount;   if (repeatCount < 1)      repeatCount = 1;   return true;}bool EffectRepeat::TransferParameters( Shuttle & shuttle ){     shuttle.TransferInt(wxT("Count"),repeatCount,1);   return true;}bool EffectRepeat::Process(){   TrackListIterator iter(mWaveTracks);   WaveTrack *track = (WaveTrack *) iter.First();   int count = 0;	double maxDestLen = 0.0; // used to change selection to original plus generated	double newDestLen = 0.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)         continue;      longSampleCount start = track->TimeToLongSamples(t0);      longSampleCount end = track->TimeToLongSamples(t1);      sampleCount len = (sampleCount)(end - start);      if (len <= 0)         continue;      //      // Create a track that contains 1 or more copies of the      // selection, cleverly arranged so that every BlockFile      // is within the minimum and maxmimum lengths of a normal      // BlockFile.  That allows us to repeat the same sequence      // of identical BlockFiles, saving lots of disk space.      //      sampleFormat format = track->GetSampleFormat();      WaveTrack *unitTrack = mFactory->NewWaveTrack(format);      WaveTrack *dest = mFactory->NewWaveTrack(format);      sampleCount maxBlockSize = unitTrack->GetMaxBlockSize();      sampleCount minBlockSize = maxBlockSize / 2;      samplePtr buffer = NewSamples(maxBlockSize, format);      int numCopies = 1;      int chunkSize = len;      int j;      while (chunkSize * numCopies < minBlockSize)         numCopies++;            if (chunkSize > maxBlockSize) {         j=2;         while(chunkSize/j >= maxBlockSize)            j++;         chunkSize = (chunkSize + (j-1)) / j;      }      sampleCount totalSamples = 0;      while(totalSamples < len * numCopies) {         sampleCount blockLen = chunkSize;         sampleCount blockStart = (totalSamples % len);         if (totalSamples + blockLen > len * numCopies)            blockLen = len * numCopies - totalSamples;         if (!track->Get(buffer, format, start+blockStart, blockLen)) {            delete unitTrack;            return false;         }         unitTrack->Append(buffer, format, blockLen);         if (numCopies == 1)            unitTrack->Flush();         totalSamples += blockLen;      }      if (numCopies != 1)         unitTrack->Flush();      //      // Repeat the unit track enough times, possible creating a few      // more than desired      //      int desiredCopies = repeatCount+1;      int desiredUnitTracks = (desiredCopies + (numCopies-1)) / numCopies;      for(j=0; j<desiredUnitTracks; j++)         dest->Paste(dest->GetEndTime(), unitTrack);      //      // If necessary, delete a few copies from the end      //      int actualCopies = desiredUnitTracks * numCopies;      if (actualCopies > desiredCopies) {         double oneLen = unitTrack->GetEndTime() / numCopies;         double clearLen = oneLen * (actualCopies - desiredCopies);			double oldDestLen = dest->GetEndTime();			newDestLen = oldDestLen - clearLen;         dest->Clear(newDestLen, oldDestLen);      } else {			newDestLen = dest->GetEndTime();		}		if (newDestLen > maxDestLen)			maxDestLen = newDestLen;      track->Clear(t0, t1);      track->Paste(t0, dest);      delete unitTrack;      delete dest;      track = (WaveTrack *) iter.Next();      count++;   }	mT1 = mT0 + maxDestLen; // Change selection to original plus generated.   return true;}//----------------------------------------------------------------------------// RepeatDialog//----------------------------------------------------------------------------#define ID_REPEAT_TEXT 7000BEGIN_EVENT_TABLE(RepeatDialog, wxDialog)   EVT_BUTTON(wxID_OK, RepeatDialog::OnOk)   EVT_BUTTON(wxID_CANCEL, RepeatDialog::OnCancel)   EVT_TEXT(ID_REPEAT_TEXT, RepeatDialog::OnRepeatTextChange)END_EVENT_TABLE()RepeatDialog::RepeatDialog(wxWindow *parent, wxWindowID id,                           const wxString &title):   wxDialog(parent, id, title){   wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);   wxStaticText *statText =      new wxStaticText(this, -1,                       _("Repeat by Dominic Mazzoni && Vaughan Johnson"));   mainSizer->Add(statText, 0, wxALIGN_CENTRE | wxALL, 5);   wxBoxSizer *hSizer = new wxBoxSizer(wxHORIZONTAL);   statText =      new wxStaticText(this, -1,                       _("Number of times to repeat: "));   hSizer->Add(statText, 0, wxALIGN_CENTRE | wxALL, 5);      mRepeatCount =      new wxTextCtrl(this, ID_REPEAT_TEXT, wxT("10"), wxDefaultPosition,                     wxSize(60, -1), 0,                     wxTextValidator(wxFILTER_NUMERIC));   hSizer->Add(mRepeatCount, 0, wxALL, 5);   mainSizer->Add(hSizer, 0, wxALIGN_CENTRE | wxALL, 5);   hSizer = new wxBoxSizer(wxHORIZONTAL);   mTotalTime =      new wxStaticText(this, -1, wxString(_("New selection length: ")) +                       wxT("XX minutes, XX seconds"));   hSizer->Add(mTotalTime, 1, wxALL | wxEXPAND, 5);   mainSizer->Add(hSizer, 0, wxALIGN_CENTRE | wxALL, 5);   hSizer = new wxBoxSizer(wxHORIZONTAL);   wxButton *cancel = new wxButton(this, wxID_CANCEL, _("Cancel"));   hSizer->Add(cancel, 0, wxALIGN_CENTRE|wxALL, 5);   wxButton *ok = new wxButton(this, wxID_OK, _("OK"));   ok->SetDefault();   ok->SetFocus();   hSizer->Add(ok, 0, wxALIGN_CENTRE|wxALL, 5);   mainSizer->Add(hSizer, 0, wxALIGN_CENTRE|wxALIGN_CENTER_VERTICAL|wxALL, 5);   SetAutoLayout(true);   SetSizer(mainSizer);   mainSizer->Fit(this);   mainSizer->SetSizeHints(this);}void RepeatDialog::OnRepeatTextChange(wxCommandEvent & event){   // We may even get called during the constructor.   // This test saves us from calling unsafe functions.   if( !IsShown() )      return;   TransferDataFromWindow();   DisplayNewTime();}void RepeatDialog::DisplayNewTime(){   int newTime = (int)(selectionTimeSecs * (repeatCount + 1));   wxString str;   str = _("New selection length: ");   if (newTime >= 120)      str += wxString::Format(_("%d minutes, %d seconds"),                              newTime/60, newTime%60);   else      str += wxString::Format(_("%d seconds"),                              newTime);   mTotalTime->SetLabel(str);}bool RepeatDialog::Validate(){   return TRUE;}bool RepeatDialog::TransferDataToWindow(){   mRepeatCount->SetValue(wxString::Format(wxT("%d"), repeatCount));   DisplayNewTime();   return true;}bool RepeatDialog::TransferDataFromWindow(){   long l;   mRepeatCount->GetValue().ToLong(&l);   repeatCount = l;   if (repeatCount < 1)      repeatCount = 1;   if (repeatCount > maxCount)      repeatCount = maxCount;   return true;}void RepeatDialog::OnOk(wxCommandEvent & event){   TransferDataFromWindow();      EndModal(true);}void RepeatDialog::OnCancel(wxCommandEvent & event){   EndModal(false);}// 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: 65c3dad7-00c2-48bf-a253-c973e626b9ac

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -