本文整理汇总了C++中WaveTrack::Clear方法的典型用法代码示例。如果您正苦于以下问题:C++ WaveTrack::Clear方法的具体用法?C++ WaveTrack::Clear怎么用?C++ WaveTrack::Clear使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类WaveTrack
的用法示例。
在下文中一共展示了WaveTrack::Clear方法的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的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: Process
bool EffectSilence::Process()
{
if (length <= 0.0)
length = sDefaultGenerateLen;
TrackListIterator iter(mWaveTracks);
WaveTrack *track = (WaveTrack *)iter.First();
while (track) {
WaveTrack *tmp = mFactory->NewWaveTrack(track->GetSampleFormat(), track->GetRate());
tmp->InsertSilence(0.0, length);
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;
}
示例4: Process
bool Generator::Process()
{
if (GetDuration() < 0.0)
return false;
// Set up mOutputTracks.
// This effect needs Track::All for sync-lock grouping.
this->CopyInputTracks(Track::All);
// Iterate over the tracks
bool bGoodResult = true;
int ntrack = 0;
TrackListIterator iter(mOutputTracks);
Track* t = iter.First();
while (t != NULL)
{
if (t->GetKind() == Track::Wave && t->GetSelected()) {
WaveTrack* track = (WaveTrack*)t;
bool editClipCanMove;
gPrefs->Read(wxT("/GUI/EditClipCanMove"), &editClipCanMove, true);
//if we can't move clips, and we're generating into an empty space,
//make sure there's room.
if (!editClipCanMove &&
track->IsEmpty(mT0, mT1+1.0/track->GetRate()) &&
!track->IsEmpty(mT0, mT0+GetDuration()-(mT1-mT0)-1.0/track->GetRate()))
{
wxMessageBox(
_("There is not enough room available to generate the audio"),
_("Error"), wxICON_STOP);
Failure();
return false;
}
if (GetDuration() > 0.0)
{
AudacityProject *p = GetActiveProject();
// Create a temporary track
std::unique_ptr<WaveTrack> tmp(
mFactory->NewWaveTrack(track->GetSampleFormat(),
track->GetRate())
);
BeforeTrack(*track);
BeforeGenerate();
// Fill it with data
if (!GenerateTrack(&*tmp, *track, ntrack))
bGoodResult = false;
else {
// Transfer the data from the temporary track to the actual one
tmp->Flush();
SetTimeWarper(new StepTimeWarper(mT0+GetDuration(), GetDuration()-(mT1-mT0)));
bGoodResult = track->ClearAndPaste(p->GetSel0(), p->GetSel1(), &*tmp, true,
false, GetTimeWarper());
}
if (!bGoodResult) {
Failure();
return false;
}
}
else
{
// If the duration is zero, there's no need to actually
// generate anything
track->Clear(mT0, mT1);
}
ntrack++;
}
else if (t->IsSyncLockSelected()) {
t->SyncLockAdjust(mT1, mT0 + GetDuration());
}
// Move on to the next track
t = iter.Next();
}
Success();
this->ReplaceProcessedTracks(bGoodResult);
mT1 = mT0 + GetDuration(); // Update selection.
return true;
}
示例5: Process
//------------------------- Processing methods -------------------------
bool EffectSineSweepGenerator::Process()
{
// taken `as is` from Audacity`s Generator.cpp to resolve
// a vc++ linking problem...
if (mDuration < 0.0)
return false;
BeforeGenerate();
// Set up mOutputTracks. This effect needs Track::All for grouping
this->CopyInputTracks(Track::All);
// Iterate over the tracks
bool bGoodResult = true;
int ntrack = 0;
TrackListIterator iter(mOutputTracks);
Track* t = iter.First();
while (t != NULL)
{
if (t->GetKind() == Track::Wave && t->GetSelected())
{
WaveTrack* track = (WaveTrack*)t;
bool editClipCanMove = true;
//gPrefs->Read(wxT("/GUI/EditClipCanMove"), &editClipCanMove, true);
//if we can't move clips, and we're generating into an empty space,
//make sure there's room.
if (!editClipCanMove &&
track->IsEmpty(mT0, mT1+1.0/track->GetRate()) &&
!track->IsEmpty(mT0, mT0+mDuration-(mT1-mT0)-1.0/track->GetRate()))
{
wxMessageBox(_("There is not enough room available to generate the audio"),
_("Error"), wxICON_STOP);
Failure();
return false;
}
if (mDuration > 0.0)
{
// Create a temporary track
WaveTrack *tmp = mFactory->NewWaveTrack(track->GetSampleFormat(),
track->GetRate());
//BeforeTrack(*track);
// Fill it with data
if (!GenerateTrack(tmp, *track, ntrack))
bGoodResult = false;
else
{
// Transfer the data from the temporary track to the actual one
tmp->Flush();
SetTimeWarper(new AFStepTimeWarper(mT0+mDuration, mDuration-(mT1-mT0)));
bGoodResult = track->ClearAndPaste(mT0, mT1, tmp, true,
false, GetTimeWarper());
delete tmp;
}
if (!bGoodResult)
{
Failure();
return false;
}
}
else
{
// If the duration is zero, there's no need to actually
// generate anything
track->Clear(mT0, mT1);
}
ntrack++;
}
else if (t->IsSyncLockSelected())
{
t->SyncLockAdjust(mT1, mT0 + mDuration);
}
// Move on to the next track
t = iter.Next();
}
Success();
this->ReplaceProcessedTracks(bGoodResult);
mT1 = mT0 + mDuration; // Update selection.
return true;
}
示例6: Process
//.........这里部分代码省略.........
buffer[tndx][truncIndex+fr] = ((mBlendFrameCount-fr)*buffer[tndx][truncIndex+fr] + fr*buffer[tndx][curOffset + fr]) / mBlendFrameCount;
}
// Append the 'keep' samples, if any
for ( ; fr < keep; fr++) {
buffer[tndx][truncIndex+fr] = buffer[tndx][curOffset + fr];
}
}
truncIndex += keep;
}
consecutiveSilentFrames = 0;
ignoringFrames = false;
truncToMinimum = false;
}
// Can get here either because > dbThreshold
// or silence duration isn't longer than allowed
for (tndx = 0; tndx < tcount; tndx++) {
buffer[tndx][truncIndex] = buffer[tndx][i];
}
truncIndex++;
}
// Update tracks if any samples were removed, now or before
if (outTrackOffset + truncIndex != index + limit) {
// Put updated sample back into output tracks.
tndx = 0;
t = (WaveTrack *) iterOut.First();
while (t) {
t->Set((samplePtr)buffer[tndx++], floatSample, outTrackOffset, truncIndex);
t = (WaveTrack *) iterOut.Next();
}
}
// If currently in a silent section, retain samples for the next pass
if(ignoringFrames) {
keep = consecutiveSilentFrames - truncInitialAllowedSilentSamples;
if(keep > (truncLongestAllowedSilentSamples+mBlendFrameCount))
keep = truncLongestAllowedSilentSamples+mBlendFrameCount;
for (tndx = 0; tndx < tcount; tndx++) {
for(fr = 0; fr < truncInitialAllowedSilentSamples; fr++) {
buffer[tndx][fr] = buffer[tndx][truncIndex-truncInitialAllowedSilentSamples+fr];
}
for(fr = 0; fr < keep; fr++) {
buffer[tndx][truncInitialAllowedSilentSamples+fr] = buffer[tndx][i-keep+fr];
}
}
// Update the output index, less what we are retaining for next time
outTrackOffset += truncIndex - truncInitialAllowedSilentSamples;
// Append the following buffer to the existing data
i = consecutiveSilentFrames = truncInitialAllowedSilentSamples + keep;
truncIndex = truncInitialAllowedSilentSamples;
} else {
// Maintain output index
outTrackOffset += truncIndex;
// Reset the buffer pointers to the beginning
i = 0;
truncIndex = 0;
consecutiveSilentFrames = 0;
}
// Update progress and bail if user cancelled
cancelled = TrackProgress(0, ((double)index / (double)end));
if (cancelled) {
break;
}
// Bump to next block
index += count;
}
AudacityProject *p = GetActiveProject();
if (!p)
return false;
// Remove stale data at end of output tracks.
if (!cancelled && (outTrackOffset < end)) {
t = (WaveTrack *) iterOut.First();
if( p->IsSticky() )
t->Clear(outTrackOffset / rate, t1, mOutputTracks);
else
while(t) {
t->Clear(outTrackOffset / rate, t1, mOutputTracks);
t = (WaveTrack *) iterOut.Next();
}
t1 = outTrackOffset / rate;
}
// Free buffers
for (tndx = 0; tndx < tcount; tndx++) {
delete [] buffer[tndx];
}
delete [] buffer;
mT0 = t0;
mT1 = t1;
this->ReplaceProcessedTracks(!cancelled);
return !cancelled;
}
示例7: 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;
}
示例8: OnRecord
void ControlToolBar::OnRecord(wxCommandEvent &evt)
{
if (gAudioIO->IsBusy()) {
mRecord->PopUp();
return;
}
AudacityProject *p = GetActiveProject();
if( evt.GetInt() == 1 ) // used when called by keyboard shortcut. Default (0) ignored.
mRecord->SetShift(true);
if( evt.GetInt() == 2 )
mRecord->SetShift(false);
SetRecord(true, mRecord->WasShiftDown());
if (p) {
TrackList *t = p->GetTracks();
TrackListIterator it(t);
if(it.First() == NULL)
mRecord->SetShift(false);
double t0 = p->GetSel0();
double t1 = p->GetSel1();
if (t1 == t0)
t1 = 1000000000.0; // record for a long, long time (tens of years)
/* TODO: set up stereo tracks if that is how the user has set up
* their preferences, and choose sample format based on prefs */
WaveTrackArray newRecordingTracks, playbackTracks;
#ifdef EXPERIMENTAL_MIDI_OUT
NoteTrackArray midiTracks;
#endif
bool duplex;
gPrefs->Read(wxT("/AudioIO/Duplex"), &duplex, true);
if(duplex){
playbackTracks = t->GetWaveTrackArray(false);
#ifdef EXPERIMENTAL_MIDI_OUT
midiTracks = t->GetNoteTrackArray(false);
#endif
}
else {
playbackTracks = WaveTrackArray();
#ifdef EXPERIMENTAL_MIDI_OUT
midiTracks = NoteTrackArray();
#endif
}
// If SHIFT key was down, the user wants append to tracks
int recordingChannels = 0;
bool shifted = mRecord->WasShiftDown();
if (shifted) {
bool sel = false;
double allt0 = t0;
// Find the maximum end time of selected and all wave tracks
// Find whether any tracks were selected. (If any are selected,
// record only into them; else if tracks exist, record into all.)
for (Track *tt = it.First(); tt; tt = it.Next()) {
if (tt->GetKind() == Track::Wave) {
WaveTrack *wt = static_cast<WaveTrack *>(tt);
if (wt->GetEndTime() > allt0) {
allt0 = wt->GetEndTime();
}
if (tt->GetSelected()) {
sel = true;
if (wt->GetEndTime() > t0) {
t0 = wt->GetEndTime();
}
}
}
}
// Use end time of all wave tracks if none selected
if (!sel) {
t0 = allt0;
}
// Pad selected/all wave tracks to make them all the same length
// Remove recording tracks from the list of tracks for duplex ("overdub")
// playback.
for (Track *tt = it.First(); tt; tt = it.Next()) {
if (tt->GetKind() == Track::Wave && (tt->GetSelected() || !sel)) {
WaveTrack *wt = static_cast<WaveTrack *>(tt);
if (duplex)
playbackTracks.Remove(wt);
t1 = wt->GetEndTime();
if (t1 < t0) {
WaveTrack *newTrack = p->GetTrackFactory()->NewWaveTrack();
newTrack->InsertSilence(0.0, t0 - t1);
newTrack->Flush();
wt->Clear(t1, t0);
bool bResult = wt->Paste(t1, newTrack);
wxASSERT(bResult); // TO DO: Actually handle this.
delete newTrack;
}
newRecordingTracks.Add(wt);
}
}
//.........这里部分代码省略.........
示例9: OnRecord
void ControlToolBar::OnRecord(wxCommandEvent &evt)
{
auto doubleClicked = mRecord->IsDoubleClicked();
mRecord->ClearDoubleClicked();
if (doubleClicked) {
// Display a fixed recording head while scrolling the waves continuously.
// If you overdub, you may want to anticipate some context in existing tracks,
// so center the head. If not, put it rightmost to display as much wave as we can.
const auto project = GetActiveProject();
bool duplex;
gPrefs->Read(wxT("/AudioIO/Duplex"), &duplex, true);
if (duplex) {
// See if there is really anything being overdubbed
if (gAudioIO->GetNumPlaybackChannels() == 0)
// No.
duplex = false;
}
using Mode = AudacityProject::PlaybackScroller::Mode;
project->GetPlaybackScroller().Activate(duplex ? Mode::Centered : Mode::Right);
return;
}
if (gAudioIO->IsBusy()) {
if (!CanStopAudioStream() || 0 == gAudioIO->GetNumCaptureChannels())
mRecord->PopUp();
else
mRecord->PushDown();
return;
}
AudacityProject *p = GetActiveProject();
if( evt.GetInt() == 1 ) // used when called by keyboard shortcut. Default (0) ignored.
mRecord->SetShift(true);
if( evt.GetInt() == 2 )
mRecord->SetShift(false);
SetRecord(true, mRecord->WasShiftDown());
if (p) {
TrackList *trackList = p->GetTracks();
TrackListIterator it(trackList);
if(it.First() == NULL)
mRecord->SetShift(false);
double t0 = p->GetSel0();
double t1 = p->GetSel1();
if (t1 == t0)
t1 = 1000000000.0; // record for a long, long time (tens of years)
/* TODO: set up stereo tracks if that is how the user has set up
* their preferences, and choose sample format based on prefs */
WaveTrackArray newRecordingTracks, playbackTracks;
#ifdef EXPERIMENTAL_MIDI_OUT
NoteTrackArray midiTracks;
#endif
bool duplex;
gPrefs->Read(wxT("/AudioIO/Duplex"), &duplex, true);
if(duplex){
playbackTracks = trackList->GetWaveTrackArray(false);
#ifdef EXPERIMENTAL_MIDI_OUT
midiTracks = trackList->GetNoteTrackArray(false);
#endif
}
else {
playbackTracks = WaveTrackArray();
#ifdef EXPERIMENTAL_MIDI_OUT
midiTracks = NoteTrackArray();
#endif
}
// If SHIFT key was down, the user wants append to tracks
int recordingChannels = 0;
TrackList tracksCopy{};
bool tracksCopied = false;
bool shifted = mRecord->WasShiftDown();
if (shifted) {
bool sel = false;
double allt0 = t0;
// Find the maximum end time of selected and all wave tracks
// Find whether any tracks were selected. (If any are selected,
// record only into them; else if tracks exist, record into all.)
for (Track *tt = it.First(); tt; tt = it.Next()) {
if (tt->GetKind() == Track::Wave) {
WaveTrack *wt = static_cast<WaveTrack *>(tt);
if (wt->GetEndTime() > allt0) {
allt0 = wt->GetEndTime();
}
if (tt->GetSelected()) {
sel = true;
if (wt->GetEndTime() > t0) {
t0 = wt->GetEndTime();
}
}
}
}
//.........这里部分代码省略.........
示例10: Process
//.........这里部分代码省略.........
// Look for silences in current block
for (sampleCount i = 0; i < limit; i++) {
// Is current frame in all tracks below threshold
bool below = true;
for (tndx = 0; tndx < tcount; tndx++) {
if (fabs(buffer[tndx][i]) >= truncDbSilenceThreshold) {
below = false;
break;
}
}
// Count frame if it's below threshold
if (below) {
consecutiveSilentFrames++;
// Ignore this frame (equivalent to cutting it)
// otherwise, keep sample to be part of allowed silence
if (consecutiveSilentFrames > truncLongestAllowedSilentSamples) {
ignoringFrames = true;
continue;
}
}
else {
if (ignoringFrames == true) {
sampleCount curOffset = i - rampInFrames;
truncIndex -= rampInFrames; // backup into ignored frames
for (tndx = 0; tndx < tcount; tndx++) {
sampleCount trunci = truncIndex;
for (int fr = 0; fr < rampInFrames; fr++) {
buffer[tndx][trunci++] = buffer[tndx][curOffset + fr];
}
if(((trunci - rampInFrames) - mBlendFrameCount) >= 0) {
BlendFrames(buffer[tndx], mBlendFrameCount,
((trunci - rampInFrames) - mBlendFrameCount),
((i - rampInFrames) - mBlendFrameCount));
}
}
truncIndex += rampInFrames;
}
consecutiveSilentFrames = 0;
ignoringFrames = false;
}
// Can get here either because > dbThreshold
// or silence duration isn't longer than allowed
for (tndx = 0; tndx < tcount; tndx++) {
buffer[tndx][truncIndex] = buffer[tndx][i];
}
truncIndex++;
}
// Update tracks if any samples were removed
if (truncIndex < limit) {
// Put updated sample back into output tracks.
tndx = 0;
t = (WaveTrack *) iterOut.First();
while (t) {
t->Set((samplePtr)buffer[tndx++], floatSample, outTrackOffset, truncIndex);
t = (WaveTrack *) iterOut.Next();
}
}
// Maintain output index
outTrackOffset += truncIndex;
// Update progress and bail if user cancelled
cancelled = TrackProgress(0, ((double)index / (double)end));
if (cancelled) {
break;
}
// Bump to next block
index += limit;
}
// Remove stale data at end of output tracks.
if (!cancelled && (outTrackOffset < end)) {
t = (WaveTrack *) iterOut.First();
while (t) {
t->Clear(outTrackOffset / rate, t1);
t = (WaveTrack *) iterOut.Next();
}
t1 = outTrackOffset / rate;
}
// Free buffers
for (tndx = 0; tndx < tcount; tndx++) {
delete [] buffer[tndx];
}
delete [] buffer;
mT0 = t0;
mT1 = t1;
this->ReplaceProcessedWaveTracks(!cancelled);
return !cancelled;
}
示例11: Process
//.........这里部分代码省略.........
for (rit = silences.rbegin(); rit != silences.rend(); ++rit) {
Region *r = *rit;
// Progress dialog and cancellation. Do additional cleanup before return.
if (TotalProgress(detectFrac + (1 - detectFrac) * whichReg / (double)silences.size()))
{
ReplaceProcessedTracks(false);
return false;
}
// Intersection may create regions smaller than allowed; ignore them.
// Allow one nanosecond extra for consistent results with exact milliseconds of allowed silence.
if ((r->end - r->start) < (mInitialAllowedSilence - 0.000000001))
continue;
// Find new silence length as requested
double inLength = r->end - r->start;
double outLength;
switch (mProcessIndex) {
case 0:
outLength = wxMin(mTruncLongestAllowedSilence, inLength);
break;
case 1:
outLength = mInitialAllowedSilence +
(inLength - mInitialAllowedSilence) * mSilenceCompressPercent / 100.0;
break;
default: // Not currently used.
outLength = wxMin(mInitialAllowedSilence +
(inLength - mInitialAllowedSilence) * mSilenceCompressPercent / 100.0,
mTruncLongestAllowedSilence);
}
double cutLen = inLength - outLength;
totalCutLen += cutLen;
TrackListIterator iterOut(mOutputTracks);
for (Track *t = iterOut.First(); t; t = iterOut.Next())
{
// Don't waste time past the end of a track
if (t->GetEndTime() < r->start)
continue;
if (t->GetKind() == Track::Wave && (
t->GetSelected() || t->IsSyncLockSelected()))
{
// In WaveTracks, clear with a cross-fade
WaveTrack *wt = (WaveTrack *)t;
sampleCount blendFrames = mBlendFrameCount;
double cutStart = (r->start + r->end - cutLen) / 2;
double cutEnd = cutStart + cutLen;
// Round start/end times to frame boundaries
cutStart = wt->LongSamplesToTime(wt->TimeToLongSamples(cutStart));
cutEnd = wt->LongSamplesToTime(wt->TimeToLongSamples(cutEnd));
// Make sure the cross-fade does not affect non-silent frames
if (wt->LongSamplesToTime(blendFrames) > inLength) {
blendFrames = wt->TimeToLongSamples(inLength);
}
// Perform cross-fade in memory
float *buf1 = new float[blendFrames];
float *buf2 = new float[blendFrames];
sampleCount t1 = wt->TimeToLongSamples(cutStart) - blendFrames / 2;
sampleCount t2 = wt->TimeToLongSamples(cutEnd) - blendFrames / 2;
wt->Get((samplePtr)buf1, floatSample, t1, blendFrames);
wt->Get((samplePtr)buf2, floatSample, t2, blendFrames);
for (sampleCount i = 0; i < blendFrames; ++i) {
buf1[i] = ((blendFrames-i) * buf1[i] + i * buf2[i]) /
(double)blendFrames;
}
// Perform the cut
wt->Clear(cutStart, cutEnd);
// Write cross-faded data
wt->Set((samplePtr)buf1, floatSample, t1, blendFrames);
delete [] buf1;
delete [] buf2;
}
else if (t->GetSelected() || t->IsSyncLockSelected())
{
// Non-wave tracks: just do a sync-lock adjust
double cutStart = (r->start + r->end - cutLen) / 2;
double cutEnd = cutStart + cutLen;
t->SyncLockAdjust(cutEnd, cutStart);
}
}
++whichReg;
}
mT1 -= totalCutLen;
ReplaceProcessedTracks(true);
return true;
}
示例12: Process
//.........这里部分代码省略.........
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;
} // finished the whole dtmf sequence
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/DtmfGen_SequenceDuration"), dtmfDuration);
gPrefs->Write(wxT("/CsPresets/DtmfGen_String"), dtmfString);
gPrefs->Write(wxT("/CsPresets/DtmfGen_DutyCycle"), dtmfDutyCycle);
// Update selection: this is not accurate if my calculations are wrong.
// To validate, once the effect is done, unselect, and select all, then
// see what the selection length is being reported (in sec,ms,samples)
mT1 = mT0 + dtmfDuration;
return true;
}
示例13: OnRecord
//.........这里部分代码省略.........
// Find the maximum end time of selected and all wave tracks
for (Track *tt = it.First(); tt; tt = it.Next()) {
if (tt->GetKind() == Track::Wave) {
wt = (WaveTrack *)tt;
if (wt->GetEndTime() > allt0) {
allt0 = wt->GetEndTime();
}
if (tt->GetSelected()) {
sel = true;
if (duplex)
playbackTracks.Remove(wt);
if (wt->GetEndTime() > t0) {
t0 = wt->GetEndTime();
}
}
}
}
// Use end time of all wave tracks if none selected
if (!sel) {
t0 = allt0;
}
// Pad selected/all wave tracks to make them all the same length
for (Track *tt = it.First(); tt; tt = it.Next()) {
if (tt->GetKind() == Track::Wave && (tt->GetSelected() || !sel)) {
wt = (WaveTrack *)tt;
t1 = wt->GetEndTime();
if (t1 < t0) {
WaveTrack *newTrack = p->GetTrackFactory()->NewWaveTrack();
newTrack->InsertSilence(0.0, t0 - t1);
newTrack->Flush();
wt->Clear(t1, t0);
wt->Paste(t1, newTrack);
delete newTrack;
}
newRecordingTracks.Add(wt);
}
}
t1 = 1000000000.0; // record for a long, long time (tens of years)
}
else {
recordingChannels = gPrefs->Read(wxT("/AudioIO/RecordChannels"), 2);
for (int c = 0; c < recordingChannels; c++) {
WaveTrack *newTrack = p->GetTrackFactory()->NewWaveTrack();
int initialheight = newTrack->GetHeight();
newTrack->SetOffset(t0);
if (recordingChannels <= 2) {
newTrack->SetHeight(initialheight/recordingChannels);
}
else {
newTrack->SetMinimized(true);
}
if (recordingChannels == 2) {
if (c == 0) {
newTrack->SetChannel(Track::LeftChannel);
newTrack->SetLinked(true);
}
else {
newTrack->SetChannel(Track::RightChannel);