/********************************************************************** Audacity: A Digital Audio Editor Noise.cpp Dominic Mazzoni *******************************************************************//** \class EffectNoise \brief An Effect for the "Generator" menu to add white noise. *//*******************************************************************/ #include "Noise.h" #include "../Audacity.h" #include "../Project.h" #include "../Prefs.h" #include "../ShuttleGui.h" #include "../WaveTrack.h" #ifndef M_PI #define M_PI 3.14159265358979323846 /* pi */ #endif #define AMP_MIN 0 #define AMP_MAX 1 // // EffectNoise // bool EffectNoise::PromptUser() { wxArrayString noiseTypeList; noiseTypeList.Add(_("White")); noiseTypeList.Add(_("Pink")); noiseTypeList.Add(_("Brown")); NoiseDialog dlog(mParent, _("Noise Generator")); // dialog will be passed values from effect // Effect retrieves values from saved config // Dialog will take care of using them to initialize controls // If there is a selection, use that duration, otherwise use // value from saved config: this is useful is user wants to // replace selection with noise // if (mT1 > mT0) { noiseDuration = mT1 - mT0; dlog.nIsSelection = true; } else { gPrefs->Read(wxT("/CsPresets/NoiseGen_Duration"), &noiseDuration, 1L); dlog.nIsSelection = false; } gPrefs->Read(wxT("/CsPresets/NoiseGen_Type"), &noiseType, 0L); gPrefs->Read(wxT("/CsPresets/NoiseGen_Amp"), &noiseAmplitude, 1.0); // Initialize dialog locals dlog.nDuration = noiseDuration; dlog.nAmplitude = noiseAmplitude; dlog.nType = noiseType; dlog.nTypeList = &noiseTypeList; // start dialog dlog.Init(); dlog.TransferDataToWindow(); dlog.Fit(); dlog.ShowModal(); if (dlog.GetReturnCode() == wxID_CANCEL) return false; // if there was an OK, retrieve values noiseType = dlog.nType; noiseDuration = dlog.nDuration; noiseAmplitude = dlog.nAmplitude; return true; } bool EffectNoise::TransferParameters( Shuttle & shuttle ) { return true; } bool EffectNoise::MakeNoise(float *buffer, sampleCount len, float fs, float amplitude) { float white, buf0, buf1, buf2, buf3, buf4, buf5; float a0, b1, fc, y; sampleCount i; float div = ((float)RAND_MAX) / 2.0f; switch (noiseType) { default: case 0: // white for(i=0; iNewWaveTrack(track->GetSampleFormat(), track->GetRate()); numSamples = (longSampleCount)(noiseDuration * track->GetRate() + 0.5); longSampleCount i = 0; float *data = new float[tmp->GetMaxBlockSize()]; sampleCount block; while(i < numSamples) { block = tmp->GetBestBlockSize(i); if (block > (numSamples - i)) block = numSamples - i; MakeNoise(data, block, track->GetRate(), noiseAmplitude); tmp->Append((samplePtr)data, floatSample, block); i += block; } delete[] data; tmp->Flush(); track->Clear(mT0, mT1); track->Paste(mT0, tmp); delete tmp; //Iterate to the next track track = (WaveTrack *)iter.Next(); } /* save last used values save duration unless value was got from selection, so we save only when user explicitely setup a value */ if (mT1 == mT0) gPrefs->Write(wxT("/CsPresets/NoiseGen_Duration"), noiseDuration); gPrefs->Write(wxT("/CsPresets/NoiseGen_Type"), noiseType); gPrefs->Write(wxT("/CsPresets/NoiseGen_Amp"), noiseAmplitude); mT1 = mT0 + noiseDuration; // Update selection. return true; } //---------------------------------------------------------------------------- // NoiseDialog //---------------------------------------------------------------------------- #define FREQ_MIN 1 #define FREQ_MAX 20000 #define AMP_MIN 0 #define AMP_MAX 1 #define ID_NOISE_DURATION_TEXT 10001 BEGIN_EVENT_TABLE(NoiseDialog, EffectDialog) EVT_COMMAND(wxID_ANY, EVT_TIMETEXTCTRL_UPDATED, NoiseDialog::OnTimeCtrlUpdate) EVT_TEXT(ID_NOISE_DURATION_TEXT, NoiseDialog::OnNoiseDurationText) END_EVENT_TABLE() NoiseDialog::NoiseDialog(wxWindow * parent, const wxString & title): EffectDialog(parent, title, INSERT_EFFECT) { /* // already initialized in EffectNoise::PromptUser nDuration = noiseDuration; nAmplitude = noiseAmplitude; nType = noiseType; */ } void NoiseDialog::PopulateOrExchange( ShuttleGui & S ) { S.StartMultiColumn(2, wxCENTER); { S.AddFixedText(_("Noise duration"), false); mNoiseDurationT = new TimeTextCtrl(this, ID_NOISE_DURATION_TEXT, /* use this instead of "seconds" because if a selection is passed to the effect, I want it (nDuration) to be used as the duration, and with "seconds" this does not always work properly. For example, it rounds down to zero... */ TimeTextCtrl::GetBuiltinFormat(nIsSelection==true?(wxT("hh:mm:ss + samples")):(wxT("seconds"))), nDuration, 44100, wxDefaultPosition, wxDefaultSize, true); S.AddWindow(mNoiseDurationT); mNoiseDurationT->EnableMenu(); S.TieTextBox( _("Amplitude"), nAmplitude, 10); S.TieChoice( _("Noise type:"), nType, nTypeList); S.SetSizeHints(-1,-1); } S.EndMultiColumn(); } bool NoiseDialog::TransferDataToWindow() { // if you don't remove these, there will be a double // timetextctrl in the dialog. Don't know why... // // ShuttleGui S( this, eIsSettingToDialog ); // PopulateOrExchange( S ); mNoiseDurationT->SetTimeValue(nDuration); mNoiseDurationT->SetFocus(); mNoiseDurationT->Fit(); return true; } bool NoiseDialog::TransferDataFromWindow() { ShuttleGui S( this, eIsGettingFromDialog ); PopulateOrExchange( S ); nAmplitude = TrapDouble(nAmplitude, AMP_MIN, AMP_MAX); return true; } void NoiseDialog::OnNoiseDurationText(wxCommandEvent & event) { nDuration = mNoiseDurationT->GetTimeValue(); } void NoiseDialog::OnTimeCtrlUpdate(wxCommandEvent & event) { this->Fit(); } // 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: 0ca03dc2-c229-44b4-a6eb-1d5d04a3983c