Update of /cvsroot/audacity/audacity-src/src/effects
In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv19825/src/effects
Added Files:
SBSMSEffect.cpp SBSMSEffect.h TimeScale.cpp TimeScale.h
Log Message:
Added sbsms and a sliding time scale/pitch shift effect. Modified
configuration for unix/win build to include sbsms.
--- NEW FILE: TimeScale.h ---
/**********************************************************************
Audacity: A Digital Audio Editor
TimeScale.h
Clayton Otey
**********************************************************************/
#include "../Audacity.h"
#if USE_SBSMS
#ifndef __AUDACITY_EFFECT_TIMESCALE__
#define __AUDACITY_EFFECT_TIMESCALE__
#include "SBSMSEffect.h"
#include <wx/intl.h>
#include <wx/dialog.h>
#include <wx/slider.h>
class wxString;
class wxTextCtrl;
class EffectTimeScale : public EffectSBSMS {
public:
EffectTimeScale();
virtual wxString GetEffectName() {
return wxString(_("Sliding Time Scale/Pitch Shift..."));
}
virtual std::set<wxString> GetEffectCategories() {
std::set<wxString> result;
result.insert(wxT("http://audacityteam.org/namespace#PitchAndTempo"));
return result;
}
virtual wxString GetEffectIdentifier() {
return wxString(wxT("TimeScale"));
}
virtual wxString GetEffectAction() {
return wxString(_("Changing Tempo/Pitch"));
}
// Useful only after PromptUser values have been set.
virtual wxString GetEffectDescription();
virtual bool Init();
virtual bool PromptUser();
virtual bool TransferParameters( Shuttle & shuttle );
virtual bool Process();
private:
double m_RateStart;
double m_RateEnd;
double m_HalfStepsStart;
double m_HalfStepsEnd;
double m_CentsStart;
double m_CentsEnd;
int m_Quality;
bool m_PreAnalyze;
friend class TimeScaleDialog;
};
//----------------------------------------------------------------------------
// TimeScaleDialog
//----------------------------------------------------------------------------
class TimeScaleDialog:public EffectDialog {
public:
TimeScaleDialog(EffectTimeScale * effect,
wxWindow * parent);
void PopulateOrExchange(ShuttleGui & S);
bool TransferDataToWindow();
bool TransferDataFromWindow();
private:
// handlers
void OnText_RateStart(wxCommandEvent & event);
void OnText_RateEnd(wxCommandEvent & event);
void OnText_HalfStepsStart(wxCommandEvent & event);
void OnText_HalfStepsEnd(wxCommandEvent & event);
void OnText_CentsStart(wxCommandEvent & event);
void OnText_CentsEnd(wxCommandEvent & event);
void OnSlider_RateStart(wxCommandEvent & event);
void OnSlider_RateEnd(wxCommandEvent & event);
void OnSlider_Quality(wxCommandEvent & event);
void OnCheckBox_PreAnalyze(wxCommandEvent & event);
// helper fns
void Update_Text_RateStart();
void Update_Text_RateEnd();
void Update_Text_HalfStepsStart();
void Update_Text_HalfStepsEnd();
void Update_Text_CentsStart();
void Update_Text_CentsEnd();
void Update_Slider_RateStart();
void Update_Slider_RateEnd();
void Update_Slider_Quality();
void Update_CheckBox_PreAnalyze();
private:
EffectTimeScale *mEffect;
bool m_bLoopDetect;
// controls
wxTextCtrl *m_pTextCtrl_RateStart;
wxSlider *m_pSlider_RateStart;
wxTextCtrl *m_pTextCtrl_RateEnd;
wxSlider *m_pSlider_RateEnd;
wxTextCtrl *m_pTextCtrl_HalfStepsStart;
wxTextCtrl *m_pTextCtrl_HalfStepsEnd;
wxTextCtrl *m_pTextCtrl_CentsStart;
wxTextCtrl *m_pTextCtrl_CentsEnd;
wxSlider *m_pSlider_Quality;
wxCheckBox *m_pCheckBox_PreAnalyze;
public:
double m_RateStart;
double m_RateEnd;
double m_HalfStepsStart;
double m_HalfStepsEnd;
double m_CentsStart;
double m_CentsEnd;
int m_Quality;
bool m_PreAnalyze;
private:
DECLARE_EVENT_TABLE()
};
#endif // __AUDACITY_EFFECT_TIMESCALE
#endif // USE_SBSMS
--- NEW FILE: SBSMSEffect.cpp ---
/**********************************************************************
Audacity: A Digital Audio Editor
SBSMSEffect.cpp
Clayton Otey
This abstract class contains all of the common code for an
effect that uses SBSMS to do its processing (TimeScale)
**********************************************************************/
#include "../Audacity.h"
#if USE_SBSMS
#include <math.h>
#include "SBSMSEffect.h"
#include "../WaveTrack.h"
#include "../Project.h"
struct resampleBuf {
audio *buf;
double ratio;
sampleCount samplesIn;
sampleCount block;
sampleCount offset;
sampleCount end;
float *leftBuffer;
float *rightBuffer;
WaveTrack *leftTrack;
WaveTrack *rightTrack;
};
long samplesCB(audio *chdata, long numFrames, void *userData)
{
sbsmsInfo *si = (sbsmsInfo*) userData;
long n_read = si->rs->read(chdata, numFrames);
return n_read;
}
real stretchCB(long nProcessed, void *userData)
{
sbsmsInfo *si = (sbsmsInfo*) userData;
real t0 = (real)nProcessed/(real)si->samplesToProcess;
real stretch = si->stretch0 + (si->stretch1-si->stretch0)*t0;
return stretch;
}
real ratioCB(long nProcessed, void *userData)
{
sbsmsInfo *si = (sbsmsInfo*) userData;
real t0 = (real)nProcessed/(real)si->samplesToProcess;
real stretch = si->stretch0 + (si->stretch1-si->stretch0)*t0;
real t1;
if(stretch == si->stretch0)
t1 = 1.0/stretch;
else
t1 = log(stretch/si->stretch0)/(stretch-si->stretch0);
real ratio = si->ratio0 +
(si->ratio1-si->ratio0)*t1*(real)nProcessed/(real)si->samplesToGenerate;
return ratio;
}
void EffectSBSMS :: setParameters(double rateStart, double rateEnd, double
pitchStart, double pitchEnd, int quality, bool bPreAnalyze)
{
this->rateStart = rateStart;
this->rateEnd = rateEnd;
this->pitchStart = pitchStart;
this->pitchEnd = pitchEnd;
this->quality = quality;
this->bPreAnalyze = bPreAnalyze;
}
bool EffectSBSMS :: bInit = FALSE;
long resampleCB(void *cb_data, sbsms_resample_frame *data)
{
resampleBuf *r = (resampleBuf*) cb_data;
long blockSize = r->leftTrack->GetBestBlockSize(r->offset);
//Adjust the block size if it is the final block in the track
if (r->offset + blockSize > r->end)
blockSize = r->end - r->offset;
// Get the samples from the tracks and put them in the buffers.
r->leftTrack->Get((samplePtr)(r->leftBuffer), floatSample, r->offset,
blockSize);
r->rightTrack->Get((samplePtr)(r->rightBuffer), floatSample, r->offset,
blockSize);
// convert to sbsms audio format
for(int i=0; i<blockSize; i++) {
r->buf[i][0] = r->leftBuffer[i];
r->buf[i][1] = r->rightBuffer[i];
}
r->offset += blockSize;
r->samplesIn += blockSize;
data->in = r->buf;
data->size = blockSize;
data->ratio = r->ratio;
return blockSize;
}
bool EffectSBSMS::Process()
{
if(!bInit) {
sbsms_init(4096);
bInit = TRUE;
}
bool bGoodResult = true;
//Iterate over each track
this->CopyInputWaveTracks(); // Set up mOutputWaveTracks.
TrackListIterator iter(mOutputWaveTracks);
WaveTrack* leftTrack = (WaveTrack*)(iter.First());
mCurTrackNum = 0;
while (leftTrack != NULL) {
//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;
sampleCount end;
start = leftTrack->TimeToLongSamples(mCurT0);
end = leftTrack->TimeToLongSamples(mCurT1);
WaveTrack* rightTrack = NULL;
if (leftTrack->GetLinked()) {
double t;
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);
mCurTrackNum++; // Increment for rightTrack, too.
}
// SBSMS has a fixed sample rate - we just convert to its sample rate and
then convert back
float srIn = leftTrack->GetRate();
float srSBSMS = 44100.0;
// the resampler needs a callback to supply its samples
resampleBuf rb;
rb.samplesIn = 0;
sampleCount maxBlockSize = leftTrack->GetMaxBlockSize();
rb.block = maxBlockSize;
rb.buf = (audio*)calloc(rb.block,sizeof(audio));
rb.leftTrack = leftTrack;
rb.rightTrack = rightTrack?rightTrack:leftTrack;
rb.leftBuffer = (float*)calloc(maxBlockSize,sizeof(float));
rb.rightBuffer = (float*)calloc(maxBlockSize,sizeof(float));
rb.offset = start;
rb.end = end;
rb.ratio = srSBSMS/srIn;
Resampler *resampler = new Resampler(resampleCB, &rb);
// Samples in selection
sampleCount samplesIn = end-start;
// Samples for SBSMS to process after resampling
sampleCount samplesToProcess = (sampleCount)
((real)samplesIn*(srSBSMS/srIn));
// Samples in output after resampling back
real stretch2;
if(rateStart == rateEnd)
stretch2 = 1.0/rateStart;
else
stretch2 = 1.0/(rateEnd-rateStart)*log(rateEnd/rateStart);
sampleCount samplesToGenerate = (sampleCount) ((real)samplesToProcess *
stretch2);
sampleCount samplesOut = (sampleCount) ((real)samplesIn * stretch2);
sbsmsInfo si;
si.rs = resampler;
si.samplesToProcess = samplesToProcess;
si.samplesToGenerate = samplesToGenerate;
si.stretch0 = rateStart;
si.stretch1 = rateEnd;
si.ratio0 = pitchStart;
si.ratio1 = pitchEnd;
sbsms *sbsmser =
sbsms_create(&samplesCB,&stretchCB,&ratioCB,rightTrack?2:1,quality,bPreAnalyze,true);
pitcher *pitch = pitch_create(sbsmser,&si,srIn/srSBSMS);
WaveTrack* outputLeftTrack =
mFactory->NewWaveTrack(leftTrack->GetSampleFormat(),
leftTrack->GetRate());
WaveTrack* outputRightTrack =
rightTrack?mFactory->NewWaveTrack(rightTrack->GetSampleFormat(),
rightTrack->GetRate()):NULL;
sampleCount blockSize = SBSMS_FRAME_SIZE[quality];
audio *outBuf = (audio*)calloc(blockSize,sizeof(audio));
float *outputLeftBuffer = (float*)calloc(blockSize*2,sizeof(float));
float *outputRightBuffer =
rightTrack?(float*)calloc(blockSize*2,sizeof(float)):NULL;
long pos = 0;
long outputCount = -1;
while(pos<samplesOut && outputCount) {
long frames;
if(pos+blockSize>samplesOut) {
frames = samplesOut - pos;
} else {
frames = blockSize;
}
outputCount = pitch_process(outBuf, frames, pitch);
for(int i = 0; i < outputCount; i++) {
outputLeftBuffer[i] = outBuf[i][0];
if(rightTrack) outputRightBuffer[i] = outBuf[i][1];
}
pos += outputCount;
outputLeftTrack->Append((samplePtr)outputLeftBuffer, floatSample,
outputCount);
if(rightTrack) outputRightTrack->Append((samplePtr)outputRightBuffer,
floatSample, outputCount);
double frac = (double)pos/(double)samplesOut;
int nWhichTrack = mCurTrackNum;
if(rightTrack) {
nWhichTrack = 2*(mCurTrackNum/2);
if (frac < 0.5)
frac *= 2.0; // Show twice as far for each track, because we're
doing 2 at once.
else {
nWhichTrack++;
frac -= 0.5;
frac *= 2.0; // Show twice as far for each track, because we're
doing 2 at once.
}
}
if (TrackProgress(nWhichTrack, frac))
return false;
}
outputLeftTrack->Flush();
if(rightTrack) outputRightTrack->Flush();
leftTrack->HandleClear(mCurT0, mCurT1, false, false);
leftTrack->HandlePaste(mCurT0, outputLeftTrack);
if(rightTrack) {
rightTrack->HandleClear(mCurT0, mCurT1, false, false);
rightTrack->HandlePaste(mCurT0, outputRightTrack);
}
delete outputLeftTrack;
if(rightTrack) delete outputRightTrack;
free(outputLeftBuffer);
if(rightTrack) free(outputRightBuffer);
free(outBuf);
free(rb.leftBuffer);
free(rb.rightBuffer);
free(rb.buf);
delete resampler;
sbsms_destroy(sbsmser);
pitch_destroy(pitch);
}
//Iterate to the next track
leftTrack = (WaveTrack*)(iter.Next());
mCurTrackNum++;
}
this->ReplaceProcessedWaveTracks(bGoodResult);
return bGoodResult;
}
#endif
--- NEW FILE: SBSMSEffect.h ---
/**********************************************************************
Audacity: A Digital Audio Editor
SBSMSEffect.h
ClaytonOtey
This abstract class contains all of the common code for an
effect that uses SBSMS to do its processing (TimeScale)
**********************************************************************/
#if USE_SBSMS
#ifndef __AUDACITY_EFFECT_SBSMS__
#define __AUDACITY_EFFECT_SBSMS__
#include "Effect.h"
// Soundtouch defines these as well, so get rid of them before including
#undef PACKAGE_NAME
#undef PACKAGE_STRING
#undef PACKAGE_TARNAME
#undef PACKAGE_VERSION
#undef PACKAGE_BUGREPORT
#include "sbsms.h"
class WaveTrack;
class EffectSBSMS : public Effect {
public:
static bool bInit;
virtual bool Process();
void setParameters(double rateStart, double rateEnd, double pitchStart,
double pitchEnd, int quality, bool bPreAnalyze);
private:
double rateStart, rateEnd, pitchStart, pitchEnd;
int quality;
bool bPreAnalyze;
int mCurTrackNum;
double mCurT0;
double mCurT1;
};
#endif
#endif
--- NEW FILE: TimeScale.cpp ---
/**********************************************************************
Audacity: A Digital Audio Editor
TimeScale.cpp
Clayton Otey
*******************************************************************//**
\class EffectTimeScale
\brief An EffectTimeScale does high quality sliding time scaling/pitch shifting
*//****************************************************************//**
\class TimeScaleDialog
\brief Dialog used with EffectTimeScale
*//*******************************************************************/
#include "../Audacity.h" // for USE_SBSMS
#if USE_SBSMS
#include "TimeScale.h"
#include "../ShuttleGui.h"
#include <math.h>
#include <wx/sizer.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>
#include <wx/checkbox.h>
#include <wx/valtext.h>
//
// EffectTimeScale
//
EffectTimeScale::EffectTimeScale()
{
m_RateStart = 0;
m_RateEnd = 0;
m_HalfStepsStart = 0;
m_HalfStepsEnd = 0;
m_CentsStart = 0;
m_CentsEnd = 0;
m_Quality = 0;
}
wxString EffectTimeScale::GetEffectDescription() {
// Note: This is useful only after change amount has been set.
return wxString::Format(_("Applied effect: %s"),
this->GetEffectName().c_str());
}
bool EffectTimeScale::Init()
{
return true;
}
bool EffectTimeScale::PromptUser()
{
TimeScaleDialog dlog(this, mParent);
dlog.m_RateStart = m_RateStart;
dlog.m_RateEnd = m_RateEnd;
dlog.m_HalfStepsStart = m_HalfStepsStart;
dlog.m_HalfStepsEnd = m_HalfStepsEnd;
dlog.m_CentsStart = m_CentsStart;
dlog.m_CentsEnd = m_CentsEnd;
dlog.m_Quality = m_Quality;
// Don't need to call TransferDataToWindow, although other
// Audacity dialogs (from which I derived this one) do it, because
// ShowModal calls stuff that eventually calls wxWindowBase::OnInitDialog,
// which calls dlog.TransferDataToWindow();
dlog.CentreOnParent();
dlog.ShowModal();
if (dlog.GetReturnCode() == wxID_CANCEL)
return false;
m_RateStart = dlog.m_RateStart;
m_RateEnd = dlog.m_RateEnd;
m_HalfStepsStart = dlog.m_HalfStepsStart;
m_HalfStepsEnd = dlog.m_HalfStepsEnd;
m_CentsStart = dlog.m_CentsStart;
m_CentsEnd = dlog.m_CentsEnd;
m_Quality = dlog.m_Quality;
return true;
}
bool EffectTimeScale::TransferParameters( Shuttle & shuttle )
{
shuttle.TransferDouble(wxT("RateStart"),m_RateStart,0.0);
shuttle.TransferDouble(wxT("RateEnd"),m_RateEnd,0.0);
shuttle.TransferDouble(wxT("HalfStepsStart"),m_HalfStepsStart,0.0);
shuttle.TransferDouble(wxT("HalfStepsEnd"),m_HalfStepsEnd,0.0);
shuttle.TransferDouble(wxT("CentsStart"),m_CentsStart,0.0);
shuttle.TransferDouble(wxT("CentsEnd"),m_CentsEnd,0.0);
shuttle.TransferInt(wxT("Quality"),m_Quality,0);
return true;
}
bool EffectTimeScale::Process()
{
double pitchStart = pow(2.0,-(m_HalfStepsStart+0.01*m_CentsStart)/12.0);
double pitchEnd = pow(2.0,-(m_HalfStepsEnd+0.01*m_CentsEnd)/12.0);
double rateStart = (100.0+m_RateStart)/100.0;
double rateEnd = (100.0+m_RateEnd)/100.0;
int quality = m_Quality + 1;
this->EffectSBSMS::setParameters(rateStart,rateEnd,pitchStart,pitchEnd,quality,m_PreAnalyze);
return this->EffectSBSMS::Process();
}
//----------------------------------------------------------------------------
// TimeScaleDialog
//----------------------------------------------------------------------------
#define RATE_MAX 150
#define RATE_DEFAULT 0
#define RATE_MIN -80
#define HALFSTEPS_MIN -12
#define HALFSTEPS_MAX 12
#define CENTS_MIN -50
#define CENTS_MAX 50
#define ID_TEXT_RATE_START 10001
#define ID_TEXT_RATE_END 10002
#define ID_TEXT_HALFSTEPS_START 10003
#define ID_TEXT_HALFSTEPS_END 10004
#define ID_TEXT_CENTS_START 10005
#define ID_TEXT_CENTS_END 10006
#define ID_SLIDER_RATE_START 10007
#define ID_SLIDER_RATE_END 10008
#define ID_SLIDER_QUALITY 10009
#define ID_CHECKBOX_PREANALYZE 10010
// event table for TimeScaleDialog
BEGIN_EVENT_TABLE(TimeScaleDialog, EffectDialog)
EVT_TEXT(ID_TEXT_RATE_START, TimeScaleDialog::OnText_RateStart)
EVT_TEXT(ID_TEXT_RATE_END, TimeScaleDialog::OnText_RateEnd)
EVT_TEXT(ID_TEXT_HALFSTEPS_START, TimeScaleDialog::OnText_HalfStepsStart)
EVT_TEXT(ID_TEXT_HALFSTEPS_END, TimeScaleDialog::OnText_HalfStepsEnd)
EVT_TEXT(ID_TEXT_CENTS_START, TimeScaleDialog::OnText_CentsStart)
EVT_TEXT(ID_TEXT_CENTS_END, TimeScaleDialog::OnText_CentsEnd)
EVT_SLIDER(ID_SLIDER_RATE_START, TimeScaleDialog::OnSlider_RateStart)
EVT_SLIDER(ID_SLIDER_RATE_END, TimeScaleDialog::OnSlider_RateEnd)
EVT_SLIDER(ID_SLIDER_QUALITY, TimeScaleDialog::OnSlider_Quality)
EVT_CHECKBOX(ID_CHECKBOX_PREANALYZE, TimeScaleDialog::OnCheckBox_PreAnalyze)
END_EVENT_TABLE()
TimeScaleDialog::TimeScaleDialog(EffectTimeScale *effect, wxWindow *parent)
: EffectDialog(parent, _("Time Scale"), PROCESS_EFFECT),
mEffect(effect)
{
m_bLoopDetect = false;
// NULL out these control members because there are some cases where the
// event table handlers get called during this method, and those handlers
that
// can cause trouble check for NULL.
m_pTextCtrl_RateStart = NULL;
m_pTextCtrl_RateEnd = NULL;
m_pSlider_RateStart = NULL;
m_pSlider_RateEnd = NULL;
m_pTextCtrl_HalfStepsStart = NULL;
m_pTextCtrl_HalfStepsEnd = NULL;
m_pTextCtrl_CentsStart = NULL;
m_pTextCtrl_CentsEnd = NULL;
m_pSlider_Quality = NULL;
m_pCheckBox_PreAnalyze = NULL;
// effect parameters
m_RateStart = 0;
m_RateEnd = 0;
m_HalfStepsStart = 0;
m_HalfStepsEnd = 0;
m_CentsStart = 0;
m_CentsEnd = 0;
m_Quality = 0;
m_PreAnalyze = false;
Init();
}
void TimeScaleDialog::PopulateOrExchange(ShuttleGui & S)
{
wxTextValidator nullvld(wxFILTER_INCLUDE_CHAR_LIST);
wxTextValidator numvld(wxFILTER_NUMERIC);
S.SetBorder(10);
S.StartHorizontalLay(wxCENTER, false);
{
S.AddTitle(_("Sliding Time Scale/Pitch Shift") +
wxString(wxT("\n\n")) +
_("by Clayton Otey") +
wxString(wxT("\n")) +
_("using SBSMS, by Clayton Otey"));
}
S.EndHorizontalLay();
S.SetBorder(5);
// Rate Text
S.StartMultiColumn(2, wxCENTER);
{
m_pTextCtrl_RateStart = S.Id(ID_TEXT_RATE_START)
.AddTextBox(_("Start Rate Change (%):"), wxT(""), 12);
m_pTextCtrl_RateStart->SetValidator(numvld);
m_pTextCtrl_RateEnd = S.Id(ID_TEXT_RATE_END)
.AddTextBox(_("End Rate Change (%):"), wxT(""), 12);
m_pTextCtrl_RateEnd->SetValidator(numvld);
}
S.EndMultiColumn();
// Rate Slider
S.StartHorizontalLay(wxEXPAND);
{
S.SetStyle(wxSL_HORIZONTAL);
m_pSlider_RateStart = S.Id(ID_SLIDER_RATE_START)
.AddSlider(wxT(""), (int)RATE_DEFAULT, (int)RATE_MAX, (int)RATE_MIN);
m_pSlider_RateStart->SetName(_("Start Rate Change (%)"));
}
S.EndHorizontalLay();
S.StartHorizontalLay(wxEXPAND);
{
S.SetStyle(wxSL_HORIZONTAL);
m_pSlider_RateEnd = S.Id(ID_SLIDER_RATE_END)
.AddSlider(wxT(""), (int)RATE_DEFAULT, (int)RATE_MAX, (int)RATE_MIN);
m_pSlider_RateEnd->SetName(_("End Rate Change (%)"));
}
S.EndHorizontalLay();
// HalfStep Text
S.StartMultiColumn(2, wxCENTER);
{
m_pTextCtrl_HalfStepsStart = S.Id(ID_TEXT_HALFSTEPS_START)
.AddTextBox(_("Initial Pitch Shift (half steps) [-12:12]:"), wxT(""),
12);
m_pTextCtrl_HalfStepsStart->SetValidator(numvld);
m_pTextCtrl_HalfStepsEnd = S.Id(ID_TEXT_HALFSTEPS_END)
.AddTextBox(_("Final Pitch Shift (half steps) [-12:12]:"), wxT(""),
12);
m_pTextCtrl_HalfStepsEnd->SetValidator(numvld);
}
S.EndMultiColumn();
// Cents Text
S.StartMultiColumn(2, wxCENTER);
{
m_pTextCtrl_CentsStart = S.Id(ID_TEXT_CENTS_START)
.AddTextBox(_("Initial Pitch Shift (cents) [-50:50]:"), wxT(""), 12);
m_pTextCtrl_CentsStart->SetValidator(numvld);
m_pTextCtrl_CentsEnd = S.Id(ID_TEXT_CENTS_END)
.AddTextBox(_("Final Pitch Shift (cents) [-50:50]:"), wxT(""), 12);
m_pTextCtrl_CentsEnd->SetValidator(numvld);
}
S.EndMultiColumn();
S.AddFixedText(_("Quality"),false);
// Quality Slider
S.StartHorizontalLay(wxEXPAND);
{
S.SetStyle(wxSL_HORIZONTAL);
m_pSlider_Quality = S.Id(ID_SLIDER_QUALITY)
.AddSlider(wxT(""), 0, 1, -1);
m_pSlider_Quality->SetName(_("Quality"));
}
m_pCheckBox_PreAnalyze = S.Id(ID_CHECKBOX_PREANALYZE)
.AddCheckBox(wxT("Dynamic Transient Sharpening"), wxT("Dynamic Transient
Sharpening"));
S.EndHorizontalLay();
return;
}
bool TimeScaleDialog::TransferDataToWindow()
{
m_bLoopDetect = true;
this->Update_Text_RateStart();
this->Update_Slider_RateStart();
this->Update_Text_RateEnd();
this->Update_Slider_RateEnd();
this->Update_Text_HalfStepsStart();
this->Update_Text_HalfStepsEnd();
this->Update_Text_CentsStart();
this->Update_Text_CentsEnd();
this->Update_Slider_Quality();
this->Update_CheckBox_PreAnalyze();
m_bLoopDetect = false;
return true;
}
bool TimeScaleDialog::TransferDataFromWindow()
{
wxString str;
if (m_pTextCtrl_RateStart) {
str = m_pTextCtrl_RateStart->GetValue();
double newValue = 0;
str.ToDouble(&newValue);
m_RateStart = newValue;
}
if (m_pTextCtrl_RateEnd) {
str = m_pTextCtrl_RateEnd->GetValue();
double newValue = 0;
str.ToDouble(&newValue);
m_RateEnd = newValue;
}
if (m_pTextCtrl_HalfStepsStart) {
str = m_pTextCtrl_HalfStepsStart->GetValue();
double newValue = 0;
str.ToDouble(&newValue);
m_HalfStepsStart = newValue;
}
if (m_pTextCtrl_HalfStepsEnd) {
str = m_pTextCtrl_HalfStepsEnd->GetValue();
double newValue = 0;
str.ToDouble(&newValue);
m_HalfStepsEnd = newValue;
}
if (m_pTextCtrl_CentsStart) {
str = m_pTextCtrl_CentsStart->GetValue();
double newValue = 0;
str.ToDouble(&newValue);
m_CentsStart = newValue;
}
if (m_pTextCtrl_CentsEnd) {
str = m_pTextCtrl_CentsEnd->GetValue();
double newValue = 0;
str.ToDouble(&newValue);
m_CentsEnd = newValue;
}
if (m_pSlider_Quality) {
m_Quality = m_pSlider_Quality->GetValue();
}
if(m_pCheckBox_PreAnalyze) {
m_PreAnalyze = m_pCheckBox_PreAnalyze->GetValue();
}
return true;
}
// handler implementations for TimeScaleDialog
void TimeScaleDialog::OnText_RateStart(wxCommandEvent & event)
{
if (m_bLoopDetect)
return;
if (m_pTextCtrl_RateStart) {
wxString str = m_pTextCtrl_RateStart->GetValue();
double newValue = 0;
str.ToDouble(&newValue);
m_RateStart = newValue;
m_bLoopDetect = true;
this->Update_Slider_RateStart();
m_bLoopDetect = false;
FindWindow(wxID_OK)->Enable(m_RateStart >= -80.0 && m_RateStart <= 300.0);
}
}
void TimeScaleDialog::OnText_RateEnd(wxCommandEvent & event)
{
if (m_bLoopDetect)
return;
if (m_pTextCtrl_RateEnd) {
wxString str = m_pTextCtrl_RateEnd->GetValue();
double newValue = 0;
str.ToDouble(&newValue);
m_RateEnd = newValue;
m_bLoopDetect = true;
this->Update_Slider_RateEnd();
m_bLoopDetect = false;
FindWindow(wxID_OK)->Enable(m_RateEnd >= -80.0 && m_RateEnd <= 300.0);
}
}
void TimeScaleDialog::OnSlider_RateStart(wxCommandEvent & event)
{
if (m_bLoopDetect)
return;
if (m_pSlider_RateStart) {
m_RateStart = (double)(m_pSlider_RateStart->GetValue());
m_bLoopDetect = true;
this->Update_Text_RateStart();
m_bLoopDetect = false;
}
}
void TimeScaleDialog::OnSlider_RateEnd(wxCommandEvent & event)
{
if (m_bLoopDetect)
return;
if (m_pSlider_RateEnd) {
m_RateEnd = (double)(m_pSlider_RateEnd->GetValue());
m_bLoopDetect = true;
this->Update_Text_RateEnd();
m_bLoopDetect = false;
}
}
void TimeScaleDialog::OnText_HalfStepsStart(wxCommandEvent & event)
{
if (m_pTextCtrl_HalfStepsStart) {
wxString str = m_pTextCtrl_HalfStepsStart->GetValue();
double newValue = 0;
str.ToDouble(&newValue);
m_HalfStepsStart = newValue;
FindWindow(wxID_OK)->Enable(m_HalfStepsStart >= -12 && m_HalfStepsStart
<=12);
}
}
void TimeScaleDialog::OnText_HalfStepsEnd(wxCommandEvent & event)
{
if (m_pTextCtrl_HalfStepsEnd) {
wxString str = m_pTextCtrl_HalfStepsEnd->GetValue();
double newValue = 0;
str.ToDouble(&newValue);
m_HalfStepsEnd = newValue;
FindWindow(wxID_OK)->Enable(m_HalfStepsEnd >= -12 && m_HalfStepsEnd <=12);
}
}
void TimeScaleDialog::OnText_CentsStart(wxCommandEvent & event)
{
if (m_pTextCtrl_CentsStart) {
wxString str = m_pTextCtrl_CentsStart->GetValue();
double newValue = 0;
str.ToDouble(&newValue);
m_CentsStart = newValue;
FindWindow(wxID_OK)->Enable(m_CentsStart >= -50 && m_CentsStart <=50);
}
}
void TimeScaleDialog::OnText_CentsEnd(wxCommandEvent & event)
{
if (m_pTextCtrl_CentsEnd) {
wxString str = m_pTextCtrl_CentsEnd->GetValue();
double newValue = 0;
str.ToDouble(&newValue);
m_CentsEnd = newValue;
FindWindow(wxID_OK)->Enable(m_CentsEnd >= -50 && m_CentsEnd <=50);
}
}
void TimeScaleDialog::OnSlider_Quality(wxCommandEvent & event)
{
if (m_pSlider_Quality) {
m_Quality = (m_pSlider_Quality->GetValue());
}
}
void TimeScaleDialog::OnCheckBox_PreAnalyze(wxCommandEvent & event)
{
if (m_pCheckBox_PreAnalyze) {
m_PreAnalyze = m_pCheckBox_PreAnalyze->GetValue();
}
}
void TimeScaleDialog::Update_Text_RateStart()
{
if (m_pTextCtrl_RateStart) {
wxString str;
str.Printf(wxT("%.3f"), m_RateStart);
m_pTextCtrl_RateStart->SetValue(str);
}
}
void TimeScaleDialog::Update_Text_RateEnd()
{
if (m_pTextCtrl_RateEnd) {
wxString str;
str.Printf(wxT("%.3f"), m_RateEnd);
m_pTextCtrl_RateEnd->SetValue(str);
}
}
void TimeScaleDialog::Update_Slider_RateStart()
{
if (m_pSlider_RateStart) {
m_pSlider_RateStart->SetValue((int)(m_RateStart + 0.5));
}
}
void TimeScaleDialog::Update_Slider_RateEnd()
{
if (m_pSlider_RateEnd) {
m_pSlider_RateEnd->SetValue((int)(m_RateEnd + 0.5));
}
}
void TimeScaleDialog::Update_Text_HalfStepsStart()
{
if (m_pTextCtrl_HalfStepsStart) {
wxString str;
str.Printf(wxT("%.3f"), m_HalfStepsStart);
m_pTextCtrl_HalfStepsStart->SetValue(str);
}
}
void TimeScaleDialog::Update_Text_HalfStepsEnd()
{
if (m_pTextCtrl_HalfStepsEnd) {
wxString str;
str.Printf(wxT("%.3f"), m_HalfStepsEnd);
m_pTextCtrl_HalfStepsEnd->SetValue(str);
}
}
void TimeScaleDialog::Update_Text_CentsStart()
{
if (m_pTextCtrl_CentsStart) {
wxString str;
str.Printf(wxT("%.3f"), m_CentsStart);
m_pTextCtrl_CentsStart->SetValue(str);
}
}
void TimeScaleDialog::Update_Text_CentsEnd()
{
if (m_pTextCtrl_CentsEnd) {
wxString str;
str.Printf(wxT("%.3f"), m_CentsEnd);
m_pTextCtrl_CentsEnd->SetValue(str);
}
}
void TimeScaleDialog::Update_Slider_Quality()
{
if (m_pSlider_Quality) {
m_pSlider_Quality->SetValue(m_Quality);
}
}
void TimeScaleDialog::Update_CheckBox_PreAnalyze()
{
if (m_pCheckBox_PreAnalyze) {
m_pCheckBox_PreAnalyze->SetValue(m_PreAnalyze);
}
}
#endif
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Audacity-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/audacity-cvs