introduced offset-property in playHandles-base-class, re-ordered mixing-procedure, improved handling of monophonic instruments

git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@504 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
Tobias Doerffel
2007-08-04 01:21:35 +00:00
parent b95fa0aab8
commit 6243edf1ec
7 changed files with 181 additions and 129 deletions

View File

@@ -1,5 +1,34 @@
2007-08-04 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
* src/tracks/instrument_track.cpp:
- do not simply pass-through _frames-parameter, use
notePlayHandle::framesLeftForCurrentPeriod() if possible
- disabled basic envelopes for the time being
- better handling of monophonic instruments
- do not play new notePlayHandles directly, set offset instead and let
mixer manage the rest
* src/tracks/sample_track.cpp:
do not play new samplePlayHandles directly, set offset instead and let
mixer manage the rest
* include/note_play_handle.h:
- removed framesAhead-property - now replaced by offset-property of
base-class
- introduced methods framesLeft() and framesLeftForCurrentPeriod() -
proper usage of them in plugins etc. fixes more clicks/pops especially
in monophonic instruments (LB302!)
* src/core/mixer.cpp:
call songEditor::processNextBuffer() *before* playing all play-handles
* src/core/mixer.cpp:
* include/mixer.h:
extended clearAudioBuffer()-methods by offset
* include/play_handle.h:
added offset-property
* include/mixer.h:
* most other files:
renamed "framesPerAudioBuffer()" to "framesPerPeriod()"

View File

@@ -48,8 +48,8 @@ public:
void * m_pluginData;
basicFilters<> * m_filter;
notePlayHandle( instrumentTrack * _chnl_trk,
const f_cnt_t _frames_ahead,
notePlayHandle( instrumentTrack * _instrument_track,
const f_cnt_t _offset,
const f_cnt_t _frames, const note & _n,
notePlayHandle * _parent = NULL,
const bool _arp_note = FALSE );
@@ -67,8 +67,8 @@ public:
virtual inline bool done( void ) const
{
return( ( m_released && m_framesBeforeRelease == 0 &&
m_releaseFramesDone >= m_releaseFramesToDo ) );
return( m_released && framesLeft() == 0 );/* ( m_released && m_framesBeforeRelease == 0 &&
m_releaseFramesDone >= m_releaseFramesToDo ) );*/
}
bool willFinishThisPeriod( void ) const
@@ -78,16 +78,16 @@ public:
f_cnt_t rfd = m_releaseFramesDone;
if( m_released == TRUE )
{
f_cnt_t todo = engine::getMixer()->framesPerAudioBuffer();
f_cnt_t todo = engine::getMixer()->framesPerPeriod();
if( arpBaseNote() == TRUE )
{
rftd = rfd + 2 *
engine::getMixer()->framesPerAudioBuffer();
engine::getMixer()->framesPerPeriod();
}
if( fbr )
{
if( fbr <=
engine::getMixer()->framesPerAudioBuffer() )
engine::getMixer()->framesPerPeriod() )
{
todo -= fbr;
fbr = 0;
@@ -96,7 +96,7 @@ public:
{
todo = 0;
fbr -=
engine::getMixer()->framesPerAudioBuffer();
engine::getMixer()->framesPerPeriod();
}
}
if( todo && rfd < rftd )
@@ -120,6 +120,15 @@ public:
return( ( m_released && fbr == 0 && rfd >= rftd ) );
}
f_cnt_t framesLeft( void ) const;
inline f_cnt_t framesLeftForCurrentPeriod( void ) const
{
return( tMin<f_cnt_t>( framesLeft(),
engine::getMixer()->framesPerPeriod() ) );
}
virtual bool isFromTrack( const track * _track ) const;
@@ -138,13 +147,6 @@ public:
f_cnt_t actualReleaseFramesToDo( void ) const;
// returns how many samples this note is aligned ahead, i.e.
// at which position it is inserted in the according buffer
inline f_cnt_t framesAhead( void ) const
{
return ( m_framesAhead );
}
// returns total numbers of frames to play
inline f_cnt_t frames( void ) const
{
@@ -292,8 +294,6 @@ private:
instrumentTrack * m_instrumentTrack; // needed for calling
// instrumentTrack::playNote
f_cnt_t m_frames; // total frames to play
f_cnt_t m_framesAhead; // numbers of frames ahead in buffer
// to mix in
f_cnt_t m_totalFramesPlayed; // total frame-counter - used for
// figuring out whether a whole note
// has been played

View File

@@ -43,6 +43,7 @@
#endif
#include "types.h"
class track;
@@ -58,8 +59,9 @@ public:
PresetPreviewHandle
} ;
playHandle( const types _type ) :
m_type( _type )
playHandle( const types _type, f_cnt_t _offset = 0 ) :
m_type( _type ),
m_offset( _offset )
{
}
@@ -75,6 +77,19 @@ public:
virtual void play( bool _try_parallelizing = FALSE ) = 0;
virtual bool done( void ) const = 0;
// returns how many frames this play-handle is aligned ahead, i.e.
// at which position it is inserted in the according buffer
inline f_cnt_t offset( void ) const
{
return ( m_offset );
}
inline void setOffset( f_cnt_t _offset )
{
m_offset = _offset;
}
virtual bool isFromTrack( const track * _track ) const = 0;
virtual bool supportsParallelizing( void ) const
@@ -89,6 +104,7 @@ public:
private:
types m_type;
f_cnt_t m_offset;
} ;

View File

@@ -62,7 +62,7 @@ sample_rate_t SAMPLE_RATES[QUALITY_LEVELS] = { 44100, 88200 } ;
mixer::mixer( void ) :
m_framesPerAudioBuffer( DEFAULT_BUFFER_SIZE ),
m_framesPerPeriod( DEFAULT_BUFFER_SIZE ),
m_readBuf( NULL ),
m_writeBuf( NULL ),
m_cpuLoad( 0 ),
@@ -80,14 +80,14 @@ mixer::mixer( void ) :
if( configManager::inst()->value( "mixer", "framesperaudiobuffer"
).toInt() >= 32 )
{
m_framesPerAudioBuffer = configManager::inst()->value( "mixer",
m_framesPerPeriod = configManager::inst()->value( "mixer",
"framesperaudiobuffer" ).toInt();
if( m_framesPerAudioBuffer > DEFAULT_BUFFER_SIZE )
if( m_framesPerPeriod > DEFAULT_BUFFER_SIZE )
{
m_fifo = new fifo( m_framesPerAudioBuffer
m_fifo = new fifo( m_framesPerPeriod
/ DEFAULT_BUFFER_SIZE );
m_framesPerAudioBuffer = DEFAULT_BUFFER_SIZE;
m_framesPerPeriod = DEFAULT_BUFFER_SIZE;
}
else
{
@@ -98,7 +98,7 @@ mixer::mixer( void ) :
{
configManager::inst()->setValue( "mixer",
"framesperaudiobuffer",
QString::number( m_framesPerAudioBuffer ) );
QString::number( m_framesPerPeriod ) );
m_fifo = new fifo( 1 );
}
@@ -111,9 +111,9 @@ mixer::mixer( void ) :
for( Uint8 i = 0; i < 3; i++ )
{
m_readBuf = new surroundSampleFrame[m_framesPerAudioBuffer];
m_readBuf = new surroundSampleFrame[m_framesPerPeriod];
clearAudioBuffer( m_readBuf, m_framesPerAudioBuffer );
clearAudioBuffer( m_readBuf, m_framesPerPeriod );
m_bufferPool.push_back( m_readBuf );
}
@@ -202,7 +202,7 @@ void mixer::setClipScaling( bool _state )
for( ch_cnt_t chnl=0; chnl < m_audioDev->channels(); ++chnl )
{
m_clipped[chnl] = FALSE;
m_halfStart[chnl] = m_framesPerAudioBuffer;
m_halfStart[chnl] = m_framesPerPeriod;
m_maxClip[chnl] = 1.0f;
m_previousSample[chnl] = 0.0;
m_newBuffer[chnl] = FALSE;
@@ -213,7 +213,7 @@ void mixer::setClipScaling( bool _state )
for( Uint8 i = 0; i < 3; i++ )
{
m_readBuf = m_bufferPool[i];
clearAudioBuffer( m_readBuf, m_framesPerAudioBuffer );
clearAudioBuffer( m_readBuf, m_framesPerPeriod );
}
}
else
@@ -233,7 +233,6 @@ void mixer::setClipScaling( bool _state )
const surroundSampleFrame * mixer::renderNextBuffer( void )
{
microTimer timer;
static songEditor::playPos last_metro_pos = -1;
songEditor::playPos p = engine::getSongEditor()->getPlayPos(
@@ -288,10 +287,12 @@ const surroundSampleFrame * mixer::renderNextBuffer( void )
m_readBuf = m_bufferPool[m_readBuffer];
// clear last audio-buffer
clearAudioBuffer( m_writeBuf, m_framesPerAudioBuffer );
clearAudioBuffer( m_writeBuf, m_framesPerPeriod );
// if( criticalXRuns() == FALSE )
{
engine::getSongEditor()->processNextBuffer();
lockPlayHandles();
csize idx = 0;
if( m_parallelizingLevel > 1 )
@@ -366,8 +367,6 @@ const surroundSampleFrame * mixer::renderNextBuffer( void )
}
unlockPlayHandles();
engine::getSongEditor()->processNextBuffer();
bool more_effects = FALSE;
for( vvector<audioPort *>::iterator it = m_audioPorts.begin();
it != m_audioPorts.end(); ++it )
@@ -384,7 +383,7 @@ const surroundSampleFrame * mixer::renderNextBuffer( void )
}
emit nextAudioBuffer( m_readBuf, m_framesPerAudioBuffer );
emit nextAudioBuffer( m_readBuf, m_framesPerPeriod );
unlock();
@@ -392,7 +391,7 @@ const surroundSampleFrame * mixer::renderNextBuffer( void )
envelopeAndLFOWidget::triggerLFO();
const float new_cpu_load = timer.elapsed() / 10000.0f * sampleRate() /
m_framesPerAudioBuffer;
m_framesPerPeriod;
m_cpuLoad = tLimit( (int) ( new_cpu_load * 0.1f + m_cpuLoad * 0.9f ), 0,
100 );
@@ -425,34 +424,36 @@ void mixer::clear( void )
void FASTCALL mixer::clearAudioBuffer( sampleFrame * _ab,
const f_cnt_t _frames )
const f_cnt_t _frames,
const f_cnt_t _offset )
{
memset( _ab, 0, sizeof( *_ab ) * _frames );
memset( _ab+_offset, 0, sizeof( *_ab ) * _frames );
}
#ifndef DISABLE_SURROUND
void FASTCALL mixer::clearAudioBuffer( surroundSampleFrame * _ab,
const f_cnt_t _frames )
const f_cnt_t _frames,
const f_cnt_t _offset )
{
memset( _ab, 0, sizeof( *_ab ) * _frames );
memset( _ab+_offset, 0, sizeof( *_ab ) * _frames );
}
#endif
void FASTCALL mixer::bufferToPort( const sampleFrame * _buf,
const fpab_t _frames,
const f_cnt_t _frames_ahead,
const fpp_t _frames,
const f_cnt_t _offset,
const volumeVector & _volume_vector,
audioPort * _port )
{
const fpab_t start_frame = _frames_ahead % m_framesPerAudioBuffer;
fpab_t end_frame = start_frame + _frames;
const fpab_t loop1_frame = tMin( end_frame, m_framesPerAudioBuffer );
const fpp_t start_frame = _offset % m_framesPerPeriod;
fpp_t end_frame = start_frame + _frames;
const fpp_t loop1_frame = tMin( end_frame, m_framesPerPeriod );
for( fpab_t frame = start_frame; frame < loop1_frame; ++frame )
for( fpp_t frame = start_frame; frame < loop1_frame; ++frame )
{
for( ch_cnt_t chnl = 0; chnl < m_audioDev->channels(); ++chnl )
{
@@ -463,12 +464,12 @@ void FASTCALL mixer::bufferToPort( const sampleFrame * _buf,
}
}
if( end_frame > m_framesPerAudioBuffer )
if( end_frame > m_framesPerPeriod )
{
fpab_t frames_done = m_framesPerAudioBuffer - start_frame;
end_frame = tMin( end_frame -= m_framesPerAudioBuffer,
m_framesPerAudioBuffer );
for( fpab_t frame = 0; frame < end_frame; ++frame )
fpp_t frames_done = m_framesPerPeriod - start_frame;
end_frame = tMin( end_frame -= m_framesPerPeriod,
m_framesPerPeriod );
for( fpp_t frame = 0; frame < end_frame; ++frame )
{
for( ch_cnt_t chnl = 0; chnl < m_audioDev->channels();
++chnl )
@@ -741,7 +742,7 @@ void mixer::processBuffer( const surroundSampleFrame * _buf,
}
}
for( fpab_t frame = 0; frame < m_framesPerAudioBuffer; ++frame )
for( fpp_t frame = 0; frame < m_framesPerPeriod; ++frame )
{
for( ch_cnt_t chnl = 0; chnl < m_audioDev->channels(); ++chnl )
{
@@ -758,7 +759,7 @@ void mixer::processBuffer( const surroundSampleFrame * _buf,
void FASTCALL mixer::scaleClip( fpab_t _frame, ch_cnt_t _chnl )
void FASTCALL mixer::scaleClip( fpp_t _frame, ch_cnt_t _chnl )
{
// Check for zero crossing
if( ( m_writeBuf[_frame][_chnl] >=0 &&
@@ -772,15 +773,15 @@ void FASTCALL mixer::scaleClip( fpab_t _frame, ch_cnt_t _chnl )
{
if( m_newBuffer[_chnl] )
{
for( fpab_t i = m_halfStart[_chnl];
i < m_framesPerAudioBuffer;
for( fpp_t i = m_halfStart[_chnl];
i < m_framesPerPeriod;
i++ )
{
m_bufferPool[m_analBuffer][i][_chnl] /=
m_maxClip[_chnl];
}
for( fpab_t i = 0;
for( fpp_t i = 0;
i < _frame;
i++ )
{
@@ -790,7 +791,7 @@ void FASTCALL mixer::scaleClip( fpab_t _frame, ch_cnt_t _chnl )
}
else
{
for( fpab_t i = m_halfStart[_chnl];
for( fpp_t i = m_halfStart[_chnl];
i < _frame;
i++ )
{
@@ -848,7 +849,7 @@ void mixer::fifoWriter::run( void )
{
while( m_writing )
{
fpab_t frames = m_mixer->framesPerAudioBuffer();
fpp_t frames = m_mixer->framesPerPeriod();
surroundSampleFrame * buffer = new surroundSampleFrame[frames];
const surroundSampleFrame * b = m_mixer->renderNextBuffer();
memcpy( buffer, b, frames * sizeof( surroundSampleFrame ) );

View File

@@ -61,19 +61,18 @@ inline void notePlayHandle::baseDetuning::setLevel( int _level )
notePlayHandle::notePlayHandle( instrumentTrack * _it,
const f_cnt_t _frames_ahead,
const f_cnt_t _offset,
const f_cnt_t _frames,
const note & _n,
notePlayHandle * _parent,
const bool _arp_note ) :
playHandle( NotePlayHandle ),
playHandle( NotePlayHandle, _offset ),
note( _n.length(), _n.pos(), _n.tone(), _n.octave(),
_n.getVolume(), _n.getPanning(), _n.detuning() ),
m_pluginData( NULL ),
m_filter( NULL ),
m_instrumentTrack( _it ),
m_frames( 0 ),
m_framesAhead( _frames_ahead ),
m_totalFramesPlayed( 0 ),
m_framesBeforeRelease( 0 ),
m_releaseFramesToDo( 0 ),
@@ -120,7 +119,7 @@ notePlayHandle::notePlayHandle( instrumentTrack * _it,
(Uint16) ( ( getVolume() / 100.0f ) *
( m_instrumentTrack->getVolume() / 100.0f ) *
127 ), 0, 127 ) ),
midiTime::fromFrames( m_framesAhead,
midiTime::fromFrames( offset(),
engine::framesPerTact64th() ) );
}
@@ -166,7 +165,7 @@ void notePlayHandle::play( bool _try_parallelizing )
}
if( m_released == FALSE &&
m_totalFramesPlayed + engine::getMixer()->framesPerAudioBuffer()
m_totalFramesPlayed + engine::getMixer()->framesPerPeriod()
>= m_frames )
{
noteOff( m_frames - m_totalFramesPlayed );
@@ -177,7 +176,7 @@ void notePlayHandle::play( bool _try_parallelizing )
if( m_released == TRUE )
{
f_cnt_t todo = engine::getMixer()->framesPerAudioBuffer();
f_cnt_t todo = engine::getMixer()->framesPerPeriod();
// if this note is base-note for arpeggio, always set
// m_releaseFramesToDo to bigger value than m_releaseFramesDone
// because we do not allow notePlayHandle::done() to be true
@@ -186,7 +185,7 @@ void notePlayHandle::play( bool _try_parallelizing )
if( arpBaseNote() == TRUE )
{
m_releaseFramesToDo = m_releaseFramesDone + 2 *
engine::getMixer()->framesPerAudioBuffer();
engine::getMixer()->framesPerPeriod();
}
// look whether we have frames left to be done before release
if( m_framesBeforeRelease )
@@ -194,7 +193,7 @@ void notePlayHandle::play( bool _try_parallelizing )
// yes, then look whether these samples can be played
// within one audio-buffer
if( m_framesBeforeRelease <=
engine::getMixer()->framesPerAudioBuffer() )
engine::getMixer()->framesPerPeriod() )
{
// yes, then we did less releaseFramesDone
todo -= m_framesBeforeRelease;
@@ -207,7 +206,7 @@ void notePlayHandle::play( bool _try_parallelizing )
// release-phase yet)
todo = 0;
m_framesBeforeRelease -=
engine::getMixer()->framesPerAudioBuffer();
engine::getMixer()->framesPerPeriod();
}
}
// look whether we're in release-phase
@@ -255,7 +254,27 @@ void notePlayHandle::play( bool _try_parallelizing )
}
// update internal data
m_totalFramesPlayed += engine::getMixer()->framesPerAudioBuffer();
m_totalFramesPlayed += engine::getMixer()->framesPerPeriod();
}
f_cnt_t notePlayHandle::framesLeft( void ) const
{
const instrument * i = ( m_instrumentTrack != NULL ) ?
m_instrumentTrack->getInstrument() : NULL;
f_cnt_t rftd = ( i != NULL && i->isMonophonic() ) ?
0 : m_releaseFramesToDo;
if( m_released && rftd == 0 )
{
return( m_framesBeforeRelease );
}
else if( m_released && m_releaseFramesToDo >= m_releaseFramesDone )
{
return( m_releaseFramesToDo - m_releaseFramesDone );
}
return( m_frames+rftd-m_totalFramesPlayed );
}
@@ -280,7 +299,7 @@ void notePlayHandle::noteOff( const f_cnt_t _s )
// then set some variables indicating release-state
m_framesBeforeRelease = _s;
m_releaseFramesToDo = tMax<f_cnt_t>( 10,
m_releaseFramesToDo = tMax<f_cnt_t>( 0, // 10,
m_instrumentTrack->m_envWidget->releaseFrames() );
// send MIDI-note-off-event
m_instrumentTrack->processOutEvent( midiEvent( NOTE_OFF,
@@ -398,7 +417,7 @@ bool notePlayHandle::operator==( const notePlayHandle & _nph ) const
getPanning() == _nph.getPanning() &&
m_instrumentTrack == _nph.m_instrumentTrack &&
m_frames == _nph.m_frames &&
m_framesAhead == _nph.m_framesAhead &&
offset() == _nph.offset() &&
m_totalFramesPlayed == _nph.m_totalFramesPlayed &&
m_released == _nph.m_released &&
m_baseNote == _nph.m_baseNote &&

View File

@@ -541,7 +541,7 @@ f_cnt_t instrumentTrack::beatLen( notePlayHandle * _n ) const
void instrumentTrack::processAudioBuffer( sampleFrame * _buf,
const fpab_t _frames,
const fpp_t _frames,
notePlayHandle * _n )
{
// we must not play the sound if this instrumentTrack is muted...
@@ -560,14 +560,14 @@ void instrumentTrack::processAudioBuffer( sampleFrame * _buf,
{
m_envWidget->processAudioBuffer( _buf, _frames, _n );
v_scale *= ( (float) _n->getVolume() / DEFAULT_VOLUME );
const fpab_t ENV_FRAMES = 10;
/* const fpp_t ENV_FRAMES = 10;
if( _n->totalFramesPlayed() == 0 )
{
// very basic envelope for not having clicks at the
// beginning
const fpab_t frames = tMin<fpab_t>( _frames,
const fpp_t frames = tMin<fpp_t>( _frames,
ENV_FRAMES );
for( fpab_t i = 0; i < frames; ++i )
for( fpp_t i = 0; i < frames; ++i )
{
for( ch_cnt_t ch = 0; ch < DEFAULT_CHANNELS;
++ch )
@@ -581,7 +581,7 @@ void instrumentTrack::processAudioBuffer( sampleFrame * _buf,
if( _n->willFinishThisPeriod() )
{
// then do a soft fade-out at the end to avoid clicks
for( fpab_t i = ( _frames >= ENV_FRAMES ) ?
for( fpp_t i = ( _frames >= ENV_FRAMES ) ?
_frames - ENV_FRAMES : 0;
i < _frames; ++i )
{
@@ -592,14 +592,13 @@ void instrumentTrack::processAudioBuffer( sampleFrame * _buf,
ENV_FRAMES;
}
}
}
}*/
}
volumeVector v = m_surroundArea->getVolumeVector( v_scale );
engine::getMixer()->bufferToPort( _buf, _frames,
( _n != NULL ) ? _n->framesAhead() : 0, v,
m_audioPort );
engine::getMixer()->bufferToPort( _buf,
( _n != NULL ) ? _n->framesLeftForCurrentPeriod() : _frames,
( _n != NULL ) ? _n->offset() : 0, v, m_audioPort );
}
@@ -768,11 +767,33 @@ void instrumentTrack::playNote( notePlayHandle * _n, bool _try_parallelizing )
}
}
if( *youngest_note != _n &&
!( *youngest_note )->arpBaseNote() )
!( *youngest_note )->arpBaseNote() &&
!_n->released() )
{
processInEvent( midiEvent( NOTE_OFF, 0,
_n->key(), 0 ), midiTime() );
return;
if( ( *youngest_note )->offset() >
_n->offset() )
{
_n->noteOff( ( *youngest_note )->
offset() -
_n->offset() );
}
else
{
// for the case the youngest
// note has an offset smaller
// then the current note we
// already played everything
// in last period and have
// to clear it
_n->noteOff();
engine::getMixer()->clearAudioBuffer( m_audioPort->firstBuffer(),
engine::getMixer()->framesPerPeriod() );
engine::getMixer()->clearAudioBuffer( m_audioPort->secondBuffer(),
engine::getMixer()->framesPerPeriod() );
return;
}
}
}
}
@@ -942,8 +963,8 @@ int instrumentTrack::masterKey( notePlayHandle * _n ) const
bool FASTCALL instrumentTrack::play( const midiTime & _start,
const fpab_t _frames,
const f_cnt_t _frame_base,
const fpp_t _frames,
const f_cnt_t _offset,
Sint16 _tco_num )
{
float frames_per_tact64th = engine::framesPerTact64th();
@@ -1007,19 +1028,9 @@ bool FASTCALL instrumentTrack::play( const midiTime & _start,
samplePlayHandle * handle = new samplePlayHandle( p );
handle->setBBTrack( bb_track );
handle->play( _frame_base );
// could we play all within current number of frames per
// audio-buffer?
if( handle->done() )
{
// throw it away...
delete handle;
}
else
{
// send it to the mixer
engine::getMixer()->addPlayHandle( handle );
}
handle->setOffset( _offset );
// send it to the mixer
engine::getMixer()->addPlayHandle( handle );
played_a_note = TRUE;
continue;
}
@@ -1068,42 +1079,28 @@ bool FASTCALL instrumentTrack::play( const midiTime & _start,
cur_note->getVolume() *
128 / 100 ),
midiTime::fromFrames(
_frame_base,
_offset,
frames_per_tact64th ) );
processOutEvent( midiEvent( NOTE_OFF,
m_midiPort->outputChannel(),
cur_note->key(), 0 ),
midiTime::fromFrames(
_frame_base +
_offset+
note_frames,
frames_per_tact64th ) );
*/
notePlayHandle * note_play_handle =
new notePlayHandle( this,
_frame_base,
new notePlayHandle( this, _offset,
note_frames,
*cur_note );
note_play_handle->setBBTrack( bb_track );
#if SINGERBOT_SUPPORT
note_play_handle->setPatternIndex( note_idx );
#endif
note_play_handle->play( FALSE );
// could we play all within current number of
// frames per audio-buffer?
if( note_play_handle->done() == FALSE )
{
// no, then insert it into
// play-handle-vector of mixer
engine::getMixer()->addPlayHandle(
engine::getMixer()->addPlayHandle(
note_play_handle );
}
else
{
// otherwise just throw it away...
delete note_play_handle;
}
played_a_note = TRUE;
#if SINGERBOT_SUPPORT
++note_idx;

View File

@@ -418,8 +418,8 @@ track::trackTypes sampleTrack::type( void ) const
bool FASTCALL sampleTrack::play( const midiTime & _start,
const fpab_t _frames,
const f_cnt_t _frame_base,
const fpp_t _frames,
const f_cnt_t _offset,
Sint16 /*_tco_num*/ )
{
sendMidiTime( _start );
@@ -443,19 +443,9 @@ bool FASTCALL sampleTrack::play( const midiTime & _start,
handle->setVolume( m_volumeKnob->value() );
//TODO: do we need sample tracks in BB editor?
// handle->setBBTrack( bb_track );
handle->play( _frame_base );
// could we play all within current number of frames per
// audio-buffer?
if( handle->done() )
{
// throw it away...
delete handle;
}
else
{
// send it to the mixer
engine::getMixer()->addPlayHandle( handle );
}
handle->setOffset( _offset );
// send it to the mixer
engine::getMixer()->addPlayHandle( handle );
played_a_note = TRUE;
}
}