本文整理汇总了C++中WaveTrack::Append方法的典型用法代码示例。如果您正苦于以下问题:C++ WaveTrack::Append方法的具体用法?C++ WaveTrack::Append怎么用?C++ WaveTrack::Append使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类WaveTrack
的用法示例。
在下文中一共展示了WaveTrack::Append方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: Process
bool EffectNoise::Process()
{
if (noiseDuration <= 0.0)
noiseDuration = sDefaultGenerateLen;
//Iterate over each track
TrackListIterator iter(mWaveTracks);
WaveTrack *track = (WaveTrack *)iter.First();
while (track) {
WaveTrack *tmp = mFactory->NewWaveTrack(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;
}
示例2: Process
bool EffectToneGen::Process()
{
if (length <= 0.0)
length = sDefaultGenerateLen;
//Iterate over each track
TrackListIterator iter(mWaveTracks);
WaveTrack *track = (WaveTrack *)iter.First();
while (track) {
mSample = 0;
WaveTrack *tmp = mFactory->NewWaveTrack(track->GetSampleFormat());
mCurRate = track->GetRate();
tmp->SetRate(mCurRate);
longSampleCount numSamples =
(longSampleCount)(length * mCurRate + 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;
MakeTone(data, block);
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();
}
mT1 = mT0 + length; // Update selection.
return true;
}
示例3: ProcessOne
// ProcessOne() takes a track, transforms it to bunch of buffer-blocks,
// and calls libsamplerate code on these blocks.
bool EffectChangeSpeed::ProcessOne(WaveTrack * track,
sampleCount start, sampleCount end)
{
if (track == NULL)
return false;
// initialization, per examples of Mixer::Mixer and
// EffectSoundTouch::ProcessOne
WaveTrack * outputTrack = mFactory->NewWaveTrack(track->GetSampleFormat(),
track->GetRate());
//Get the length of the selection (as double). len is
//used simple to calculate a progress meter, so it is easier
//to make it a double now than it is to do it later
double len = (double)(end - start);
// Initiate processing buffers, most likely shorter than
// the length of the selection being processed.
sampleCount inBufferSize = track->GetMaxBlockSize();
float * inBuffer = new float[inBufferSize];
sampleCount outBufferSize =
(sampleCount)((mFactor * inBufferSize) + 10);
float * outBuffer = new float[outBufferSize];
// Set up the resampling stuff for this track.
Resample resample(true, mFactor, mFactor);
//Go through the track one buffer at a time. samplePos counts which
//sample the current buffer starts at.
bool bResult = true;
sampleCount blockSize;
sampleCount samplePos = start;
while (samplePos < end) {
//Get a blockSize of samples (smaller than the size of the buffer)
blockSize = track->GetBestBlockSize(samplePos);
//Adjust the block size if it is the final block in the track
if (samplePos + blockSize > end)
blockSize = end - samplePos;
//Get the samples from the track and put them in the buffer
track->Get((samplePtr) inBuffer, floatSample, samplePos, blockSize);
int inUsed;
int outgen = resample.Process(mFactor,
inBuffer,
blockSize,
((samplePos + blockSize) >= end),
&inUsed,
outBuffer,
outBufferSize);
if (outgen < 0) {
bResult = false;
break;
}
if (outgen > 0)
outputTrack->Append((samplePtr)outBuffer, floatSample,
outgen);
// Increment samplePos
samplePos += inUsed;
// Update the Progress meter
if (TrackProgress(mCurTrackNum, (samplePos - start) / len)) {
bResult = false;
break;
}
}
// Flush the output WaveTrack (since it's buffered, too)
outputTrack->Flush();
// Clean up the buffers
delete [] inBuffer;
delete [] outBuffer;
// Take the output track and insert it in place of the original
// sample data
double newLength = outputTrack->GetEndTime();
if (bResult)
{
SetTimeWarper(new LinearTimeWarper(mCurT0, mCurT0, mCurT1, mCurT0 + newLength));
bResult = track->ClearAndPaste(mCurT0, mCurT1, outputTrack, true, false, GetTimeWarper());
}
if (newLength > mMaxNewLength)
mMaxNewLength = newLength;
// Delete the outputTrack now that its data is inserted in place
delete outputTrack;
return bResult;
}
示例4: QuickMix
//.........这里部分代码省略.........
WaveTrack *mixLeft = new WaveTrack(dirManager);
mixLeft->SetSampleFormat(format);
mixLeft->SetRate(rate);
mixLeft->SetChannel(VTrack::MonoChannel);
mixLeft->SetName(_("Mix"));
WaveTrack *mixRight = 0;
if (!mono) {
mixRight = new WaveTrack(dirManager);
mixRight->SetSampleFormat(format);
mixRight->SetRate(rate);
mixRight->SetName(_("Mix"));
mixLeft->SetChannel(VTrack::LeftChannel);
mixRight->SetChannel(VTrack::RightChannel);
mixLeft->SetLinked(true);
}
int maxBlockLen = mixLeft->GetIdealBlockSize();
double maxBlockTime = maxBlockLen / mixLeft->GetRate();
Mixer *mixer = new Mixer(mono ? 1 : 2, maxBlockLen, false,
rate, format);
wxProgressDialog *progress = NULL;
wxYield();
wxStartTimer();
wxBusyCursor busy;
double tt = 0.0;
while (tt < totalTime) {
double blockTime = maxBlockTime;
if (tt + blockTime > totalTime)
blockTime = totalTime - tt;
int blockLen = int (blockTime * mixLeft->GetRate());
mixer->Clear();
for (int i = 0; i < numWaves; i++) {
if (mono)
mixer->MixMono(waveArray[i], tt, tt + blockTime);
else {
switch (waveArray[i]->GetChannel()) {
case VTrack::LeftChannel:
mixer->MixLeft(waveArray[i], tt, tt + blockTime);
break;
case VTrack::RightChannel:
mixer->MixRight(waveArray[i], tt, tt + blockTime);
break;
case VTrack::MonoChannel:
mixer->MixMono(waveArray[i], tt, tt + blockTime);
break;
}
}
}
if (mono) {
samplePtr buffer = mixer->GetBuffer();
mixLeft->Append(buffer, format, blockLen);
} else {
samplePtr buffer;
buffer = mixer->GetBuffer(0);
mixLeft->Append(buffer, format, blockLen);
buffer = mixer->GetBuffer(1);
mixRight->Append(buffer, format, blockLen);
}
tt += blockTime;
if (!progress && wxGetElapsedTime(false) > 500) {
progress =
new wxProgressDialog(_("Quick Mix"), _("Mixing tracks"), 1000);
}
if (progress) {
int progressvalue = int (1000 * (tt / totalTime));
progress->Update(progressvalue);
}
}
tracks->Add(mixLeft);
if (!mono)
tracks->Add(mixRight);
delete progress;
int elapsedMS = wxGetElapsedTime();
double elapsedTime = elapsedMS * 0.001;
double maxTracks = totalTime / (elapsedTime / numWaves);
#ifdef __WXGTK__
printf(_(" Tracks: %d\n"), numWaves);
printf(_(" Mix length: %f sec\n"), totalTime);
printf(_("Elapsed time: %f sec\n"), elapsedTime);
printf(_("Max number of tracks to mix in real time: %f\n"), maxTracks);
#endif
delete waveArray;
delete mixer;
return true;
}
示例5: Process
bool EffectNoise::Process()
{
if (noiseDuration <= 0.0)
noiseDuration = sDefaultGenerateLen;
//Iterate over each track
int ntrack = 0;
this->CopyInputWaveTracks(); // Set up mOutputWaveTracks.
bool bGoodResult = true;
TrackListIterator iter(mOutputWaveTracks);
WaveTrack *track = (WaveTrack *)iter.First();
while (track) {
WaveTrack *tmp = mFactory->NewWaveTrack(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) && bGoodResult) {
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;
//Update the Progress meter
if (TrackProgress(ntrack, (double)i / numSamples))
bGoodResult = false;
}
delete[] data;
tmp->Flush();
track->Clear(mT0, mT1);
track->Paste(mT0, tmp);
delete tmp;
if (!bGoodResult)
break;
//Iterate to the next track
ntrack++;
track = (WaveTrack *)iter.Next();
}
if (bGoodResult)
{
/*
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.
}
this->ReplaceProcessedWaveTracks(bGoodResult);
return bGoodResult;
}
示例6: MixAndRender
bool MixAndRender(TrackList *tracks, TrackFactory *trackFactory,
double rate, sampleFormat format,
double startTime, double endTime,
WaveTrack **newLeft, WaveTrack **newRight)
{
// This function was formerly known as "Quick Mix". It takes one or
// more tracks as input; of all tracks that are selected, it mixes
// them together, applying any envelopes, amplitude gain, panning,
// and real-time effects in the process. The resulting pair of
// tracks (stereo) are "rendered" and have no effects, gain, panning,
// or envelopes.
WaveTrack **waveArray;
Track *t;
int numWaves = 0;
int numMono = 0;
bool mono = false;
int w;
TrackListIterator iter(tracks);
t = iter.First();
while (t) {
if (t->GetSelected() && t->GetKind() == Track::Wave) {
numWaves++;
float pan = ((WaveTrack*)t)->GetPan();
if (t->GetChannel() == Track::MonoChannel && pan == 0)
numMono++;
}
t = iter.Next();
}
if (numMono == numWaves)
mono = true;
double totalTime = 0.0;
waveArray = new WaveTrack *[numWaves];
w = 0;
t = iter.First();
while (t) {
if (t->GetSelected() && t->GetKind() == Track::Wave) {
waveArray[w++] = (WaveTrack *) t;
if (t->GetEndTime() > totalTime)
totalTime = t->GetEndTime();
}
t = iter.Next();
}
WaveTrack *mixLeft = trackFactory->NewWaveTrack(format, rate);
mixLeft->SetName(_("Mix"));
WaveTrack *mixRight = 0;
if (mono) {
mixLeft->SetChannel(Track::MonoChannel);
}
else {
mixRight = trackFactory->NewWaveTrack(format, rate);
mixRight->SetName(_("Mix"));
mixLeft->SetChannel(Track::LeftChannel);
mixRight->SetChannel(Track::RightChannel);
mixLeft->SetLinked(true);
mixRight->SetTeamed(true);
}
int maxBlockLen = mixLeft->GetIdealBlockSize();
if (startTime == endTime) {
startTime = 0.0;
endTime = totalTime;
}
Mixer *mixer = new Mixer(numWaves, waveArray, tracks->GetTimeTrack(),
startTime, endTime, mono ? 1 : 2, maxBlockLen, false,
rate, format);
wxYield();
GetActiveProject()->ProgressShow(_NoAcc("&Mix and Render"),
_("Mixing and rendering tracks"));
wxBusyCursor busy;
bool cancelling = false;
while(!cancelling) {
sampleCount blockLen = mixer->Process(maxBlockLen);
if (blockLen == 0)
break;
if (mono) {
samplePtr buffer = mixer->GetBuffer();
mixLeft->Append(buffer, format, blockLen);
}
else {
samplePtr buffer;
buffer = mixer->GetBuffer(0);
mixLeft->Append(buffer, format, blockLen);
buffer = mixer->GetBuffer(1);
mixRight->Append(buffer, format, blockLen);
}
int progressvalue = int (1000 * (mixer->MixGetCurrentTime() / totalTime));
//.........这里部分代码省略.........
示例7: ProcessOne
//ProcessOne() takes a track, transforms it to bunch of buffer-blocks,
//and executes ProcessSoundTouch on these blocks
bool EffectSoundTouch::ProcessOne(WaveTrack *track,
longSampleCount start, longSampleCount end)
{
WaveTrack *outputTrack;
longSampleCount s;
mSoundTouch->setSampleRate((unsigned int)(track->GetRate()+0.5));
outputTrack = mFactory->NewWaveTrack(track->GetSampleFormat());
//Get the length of the buffer (as double). len is
//used simple to calculate a progress meter, so it is easier
//to make it a double now than it is to do it later
double len = (double)(end - start);
//Initiate a processing buffer. This buffer will (most likely)
//be shorter than the length of the track being processed.
float *buffer = new float[track->GetMaxBlockSize()];
//Go through the track one buffer at a time. s counts which
//sample the current buffer starts at.
s = start;
while (s < end) {
//Get a block of samples (smaller than the size of the buffer)
sampleCount block = track->GetBestBlockSize(s);
//Adjust the block size if it is the final block in the track
if (s + block > end)
block = end - s;
//Get the samples from the track and put them in the buffer
track->Get((samplePtr) buffer, floatSample, s, block);
//Add samples to SoundTouch
mSoundTouch->putSamples(buffer, block);
//Get back samples from SoundTouch
unsigned int outputCount = mSoundTouch->numSamples();
if (outputCount > 0) {
float *buffer2 = new float[outputCount];
mSoundTouch->receiveSamples(buffer2, outputCount);
outputTrack->Append((samplePtr)buffer2, floatSample, outputCount);
delete[] buffer2;
}
//Increment s one blockfull of samples
s += block;
//Update the Progress meter
if (TrackProgress(mCurTrackNum, (s - start) / len))
return false;
}
// Tell SoundTouch to finish processing any remaining samples
mSoundTouch->flush();
unsigned int outputCount = mSoundTouch->numSamples();
if (outputCount > 0) {
float *buffer2 = new float[outputCount];
mSoundTouch->receiveSamples(buffer2, outputCount);
outputTrack->Append((samplePtr)buffer2, floatSample, outputCount);
delete[] buffer2;
}
// Flush the output WaveTrack (since it's buffered, too)
outputTrack->Flush();
// Clean up the buffer
delete[]buffer;
// Take the output track and insert it in place of the original
// sample data
track->Clear(mT0, mT1);
track->Paste(mT0, outputTrack);
double newLength = outputTrack->GetEndTime();
if (newLength > m_maxNewLength)
m_maxNewLength = newLength;
// Delete the outputTrack now that its data is inserted in place
delete outputTrack;
//Return true because the effect processing succeeded.
return true;
}
示例8: ProcessOne
//.........这里部分代码省略.........
(minDuration / track->GetRate()) + 0.05, // round up to 1/10 s.
floor(maxTimeRes * 10.0) / 10.0),
GetName(), wxOK | wxICON_EXCLAMATION);
}
else {
/* i18n-hint: 'Time Resolution' is the name of a control in the Paulstretch effect.*/
::wxMessageBox (wxString::Format(_("Unable to Preview.\n\n"
"For the current audio selection, the maximum\n"
"'Time Resolution' is %.1f seconds."),
floor(maxTimeRes * 10.0) / 10.0),
GetName(), wxOK | wxICON_EXCLAMATION);
}
}
else {
/* i18n-hint: 'Time Resolution' is the name of a control in the Paulstretch effect.*/
::wxMessageBox (wxString::Format(_("The 'Time Resolution' is too long for the selection.\n\n"
"Try increasing the audio selection to at least %.1f seconds,\n"
"or reducing the 'Time Resolution' to less than %.1f seconds."),
(minDuration / track->GetRate()) + 0.05, // round up to 1/10 s.
floor(maxTimeRes * 10.0) / 10.0),
GetName(), wxOK | wxICON_EXCLAMATION);
}
return false;
}
double adjust_amount=(double)len/((double)len-((double)stretch_buf_size*2.0));
amount=1.0+(amount-1.0)*adjust_amount;
WaveTrack * outputTrack = mFactory->NewWaveTrack(track->GetSampleFormat(),track->GetRate());
PaulStretch *stretch=new PaulStretch(amount,stretch_buf_size,track->GetRate());
sampleCount nget=stretch->get_nsamples_for_fill();
int bufsize=stretch->poolsize;
float *buffer0=new float[bufsize];
float *bufferptr0=buffer0;
sampleCount outs=0;
bool first_time=true;
int fade_len=100;
if (fade_len>(bufsize/2-1)) fade_len=bufsize/2-1;
float *fade_track_smps=new float[fade_len];
sampleCount s=0;
bool cancelled=false;
while (s<len){
track->Get((samplePtr)bufferptr0,floatSample,start+s,nget);
stretch->process(buffer0,nget);
if (first_time) {
stretch->process(buffer0,0);
};
outs+=stretch->out_bufsize;
s+=nget;
if (first_time){//blend the the start of the selection
track->Get((samplePtr)fade_track_smps,floatSample,start,fade_len);
first_time=false;
for (int i=0;i<fade_len;i++){
float fi=(float)i/(float)fade_len;
stretch->out_buf[i]=stretch->out_buf[i]*fi+(1.0-fi)*fade_track_smps[i];
};
};
if (s>=len){//blend the end of the selection
track->Get((samplePtr)fade_track_smps,floatSample,end-fade_len,fade_len);
for (int i=0;i<fade_len;i++){
float fi=(float)i/(float)fade_len;
int i2=bufsize/2-1-i;
stretch->out_buf[i2]=stretch->out_buf[i2]*fi+(1.0-fi)*fade_track_smps[fade_len-1-i];
};
};
outputTrack->Append((samplePtr)stretch->out_buf,floatSample,stretch->out_bufsize);
nget=stretch->get_nsamples();
if (TrackProgress(count, (s / (double) len))) {
cancelled=true;
break;
};
};
delete [] fade_track_smps;
outputTrack->Flush();
track->Clear(t0,t1);
bool success = track->Paste(t0,outputTrack);
if (!cancelled && success){
m_t1 = mT0 + outputTrack->GetEndTime();
}
delete stretch;
delete []buffer0;
delete outputTrack;
return !cancelled;
};
示例9: ProcessOne
bool EffectPaulstretch::ProcessOne(WaveTrack *track,double t0,double t1,int count){
int stretch_buf_size;//must be power of 2 (because Audacity's fft requires it)
if (time_resolution<0.001) time_resolution=0.001f;
{
float tmp=track->GetRate()*time_resolution*0.5;
tmp=log(tmp)/log(2.0);
tmp=pow(2.0,floor(tmp+0.5));
stretch_buf_size=(int)tmp;
};
if (stretch_buf_size<128) stretch_buf_size=128;
double amount=this->amount;
if (amount<1.0) amount=1.0;
sampleCount start = track->TimeToLongSamples(t0);
sampleCount end = track->TimeToLongSamples(t1);
sampleCount len = (sampleCount)(end - start);
m_t1=mT1;
if (len<=(stretch_buf_size*2+1)){//error because the selection is too short
/* i18n-hint: This is an effect error message, for the effect named Paulstretch.
* Time Resolution is a parameter of the effect, the translation should match
*/
::wxMessageBox(_("Error in Paulstretch:\nThe selection is too short.\n It must be much longer than the Time Resolution."));
return false;
};
double adjust_amount=(double)len/((double)len-((double)stretch_buf_size*2.0));
amount=1.0+(amount-1.0)*adjust_amount;
WaveTrack * outputTrack = mFactory->NewWaveTrack(track->GetSampleFormat(),track->GetRate());
PaulStretch *stretch=new PaulStretch(amount,stretch_buf_size,track->GetRate());
sampleCount nget=stretch->get_nsamples_for_fill();
int bufsize=stretch->poolsize;
float *buffer0=new float[bufsize];
float *bufferptr0=buffer0;
sampleCount outs=0;
bool first_time=true;
int fade_len=100;
if (fade_len>(bufsize/2-1)) fade_len=bufsize/2-1;
float *fade_track_smps=new float[fade_len];
sampleCount s=0;
bool cancelled=false;
while (s<len){
track->Get((samplePtr)bufferptr0,floatSample,start+s,nget);
stretch->process(buffer0,nget);
if (first_time) {
stretch->process(buffer0,0);
};
outs+=stretch->out_bufsize;
s+=nget;
if (first_time){//blend the the start of the selection
track->Get((samplePtr)fade_track_smps,floatSample,start,fade_len);
first_time=false;
for (int i=0;i<fade_len;i++){
float fi=(float)i/(float)fade_len;
stretch->out_buf[i]=stretch->out_buf[i]*fi+(1.0-fi)*fade_track_smps[i];
};
};
if (s>=len){//blend the end of the selection
track->Get((samplePtr)fade_track_smps,floatSample,end-fade_len,fade_len);
for (int i=0;i<fade_len;i++){
float fi=(float)i/(float)fade_len;
int i2=bufsize/2-1-i;
stretch->out_buf[i2]=stretch->out_buf[i2]*fi+(1.0-fi)*fade_track_smps[fade_len-1-i];
};
};
outputTrack->Append((samplePtr)stretch->out_buf,floatSample,stretch->out_bufsize);
nget=stretch->get_nsamples();
if (TrackProgress(count, (s / (double) len))) {
cancelled=true;
break;
};
};
delete [] fade_track_smps;
outputTrack->Flush();
track->Clear(t0,t1);
track->Paste(t0,outputTrack);
if (!cancelled){
double flen=t1-t0;
if (s>0) m_t1=t0+flen*(double)outs/(double)(s);
};
//.........这里部分代码省略.........
示例10: MixAndRender
//.........这里部分代码省略.........
mixLeft->SetName(usefulIter.First()->GetName()); /* set name of output track to be the same as the sole input track */
else
mixLeft->SetName(_("Mix"));
mixLeft->SetOffset(mixStartTime);
WaveTrack *mixRight = 0;
if (mono) {
mixLeft->SetChannel(Track::MonoChannel);
}
else {
mixRight = trackFactory->NewWaveTrack(format, rate);
if (oneinput) {
if (usefulIter.First()->GetLink() != NULL) // we have linked track
mixLeft->SetName(usefulIter.First()->GetLink()->GetName()); /* set name to match input track's right channel!*/
else
mixLeft->SetName(usefulIter.First()->GetName()); /* set name to that of sole input channel */
}
else
mixRight->SetName(_("Mix"));
mixLeft->SetChannel(Track::LeftChannel);
mixRight->SetChannel(Track::RightChannel);
mixRight->SetOffset(mixStartTime);
mixLeft->SetLinked(true);
}
int maxBlockLen = mixLeft->GetIdealBlockSize();
// If the caller didn't specify a time range, use the whole range in which
// any input track had clips in it.
if (startTime == endTime) {
startTime = mixStartTime;
endTime = mixEndTime;
}
Mixer *mixer = new Mixer(numWaves, waveArray,
Mixer::WarpOptions(tracks->GetTimeTrack()),
startTime, endTime, mono ? 1 : 2, maxBlockLen, false,
rate, format);
::wxSafeYield();
ProgressDialog *progress = new ProgressDialog(_("Mix and Render"),
_("Mixing and rendering tracks"));
int updateResult = eProgressSuccess;
while(updateResult == eProgressSuccess) {
sampleCount blockLen = mixer->Process(maxBlockLen);
if (blockLen == 0)
break;
if (mono) {
samplePtr buffer = mixer->GetBuffer();
mixLeft->Append(buffer, format, blockLen);
}
else {
samplePtr buffer;
buffer = mixer->GetBuffer(0);
mixLeft->Append(buffer, format, blockLen);
buffer = mixer->GetBuffer(1);
mixRight->Append(buffer, format, blockLen);
}
updateResult = progress->Update(mixer->MixGetCurrentTime() - startTime, endTime - startTime);
}
delete progress;
mixLeft->Flush();
if (!mono)
mixRight->Flush();
if (updateResult == eProgressCancelled || updateResult == eProgressFailed)
{
delete mixLeft;
if (!mono)
delete mixRight;
} else {
*newLeft = mixLeft;
if (!mono)
*newRight = mixRight;
#if 0
int elapsedMS = wxGetElapsedTime();
double elapsedTime = elapsedMS * 0.001;
double maxTracks = totalTime / (elapsedTime / numWaves);
// Note: these shouldn't be translated - they're for debugging
// and profiling only.
printf(" Tracks: %d\n", numWaves);
printf(" Mix length: %f sec\n", totalTime);
printf("Elapsed time: %f sec\n", elapsedTime);
printf("Max number of tracks to mix in real time: %f\n", maxTracks);
#endif
}
delete[] waveArray;
delete mixer;
return (updateResult == eProgressSuccess || updateResult == eProgressStopped);
}
示例11: Process
bool EffectDtmf::Process()
{
if (dtmfDuration <= 0.0)
return false;
//Iterate over each track
TrackListIterator iter(mWaveTracks);
WaveTrack *track = (WaveTrack *)iter.First();
while (track) {
// new tmp track, to fill with dtmf sequence
// we will build the track by adding a tone, then a silence, next tone, and so on...
WaveTrack *tmp = mFactory->NewWaveTrack(track->GetSampleFormat(), track->GetRate());
// all dtmf sequence durations in samples from seconds
numSamplesSequence = (longSampleCount)(dtmfDuration * track->GetRate() + 0.5);
numSamplesTone = (longSampleCount)(dtmfTone * track->GetRate() + 0.5);
numSamplesSilence = (longSampleCount)(dtmfSilence * track->GetRate() + 0.5);
// recalculate the sum, and spread the difference - due to approximations.
// Since diff should be in the order of "some" samples, a division (resulting in zero)
// is not sufficient, so we add the additional remaining samples in each tone/silence block,
// at least until available.
int diff = numSamplesSequence - (dtmfNTones*numSamplesTone) - (dtmfNTones-1)*numSamplesSilence;
if (diff>dtmfNTones) {
// in this case, both these values would change, so it makes sense to recalculate diff
// otherwise just keep the value we already have
// should always be the case that dtmfNTones>1, as if 0, we don't even start processing,
// and with 1 there is no difference to spread (no silence slot)...
wxASSERT(dtmfNTones > 1);
numSamplesTone += (diff/(dtmfNTones));
numSamplesSilence += (diff/(dtmfNTones-1));
diff = numSamplesSequence - (dtmfNTones*numSamplesTone) - (dtmfNTones-1)*numSamplesSilence;
}
// this var will be used as extra samples distributor
int extra=0;
longSampleCount i = 0;
longSampleCount j = 0;
int n=0; // pointer to string in dtmfString
sampleCount block;
bool isTone = true;
float *data = new float[tmp->GetMaxBlockSize()];
// for the whole dtmf sequence, we will be generating either tone or silence
// according to a bool value, and this might be done in small chunks of size
// 'block', as a single tone might sometimes be larger than the block
// tone and silence generally have different duration, thus two generation blocks
//
// Note: to overcome a 'clicking' noise introduced by the abrupt transition from/to
// silence, I added a fade in/out of 1/250th of a second (4ms). This can still be
// tweaked but gives excellent results at 44.1kHz: I haven't tried other freqs.
// A problem might be if the tone duration is very short (<10ms)... (?)
//
// One more problem is to deal with the approximations done when calculating the duration
// of both tone and silence: in some cases the final sum might not be same as the initial
// duration. So, to overcome this, we had a redistribution block up, and now we will spread
// the remaining samples in every bin in order to achieve the full duration: test case was
// to generate an 11 tone DTMF sequence, in 4 seconds, and with DutyCycle=75%: after generation
// you ended up with 3.999s or in other units: 3 seconds and 44097 samples.
//
while(i < numSamplesSequence) {
if (isTone)
// generate tone
{
// the statement takes care of extracting one sample from the diff bin and
// adding it into the tone block until depletion
extra=(diff-- > 0?1:0);
for(j=0; j < numSamplesTone+extra; j+=block) {
block = tmp->GetBestBlockSize(j);
if (block > (numSamplesTone+extra - j))
block = numSamplesTone+extra - j;
// generate the tone and append
MakeDtmfTone(data, block, track->GetRate(), dtmfString[n], j, numSamplesTone);
tmp->Append((samplePtr)data, floatSample, block);
}
i += numSamplesTone;
n++;
if(n>=dtmfNTones)break;
}
else
// generate silence
{
// the statement takes care of extracting one sample from the diff bin and
// adding it into the silence block until depletion
extra=(diff-- > 0?1:0);
for(j=0; j < numSamplesSilence+extra; j+=block) {
block = tmp->GetBestBlockSize(j);
if (block > (numSamplesSilence+extra - j))
block = numSamplesSilence+extra - j;
// generate silence and append
memset(data, 0, sizeof(float)*block);
tmp->Append((samplePtr)data, floatSample, block);
}
i += numSamplesSilence;
}
// flip flag
isTone=!isTone;
//.........这里部分代码省略.........