diff --git a/ChangeLog b/ChangeLog index 35fb4d264..6aa352dfc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,34 @@ 2007-08-04 Tobias Doerffel + * 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()" diff --git a/include/note_play_handle.h b/include/note_play_handle.h index d33770d94..fa6e2d175 100644 --- a/include/note_play_handle.h +++ b/include/note_play_handle.h @@ -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( 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 diff --git a/include/play_handle.h b/include/play_handle.h index 3f7988e7f..a12a512b6 100644 --- a/include/play_handle.h +++ b/include/play_handle.h @@ -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; } ; diff --git a/src/core/mixer.cpp b/src/core/mixer.cpp index 8b8f75331..7ff439a56 100644 --- a/src/core/mixer.cpp +++ b/src/core/mixer.cpp @@ -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::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 ) ); diff --git a/src/core/note_play_handle.cpp b/src/core/note_play_handle.cpp index dca3c2346..d8e0ef377 100644 --- a/src/core/note_play_handle.cpp +++ b/src/core/note_play_handle.cpp @@ -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( 10, + m_releaseFramesToDo = tMax( 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 && diff --git a/src/tracks/instrument_track.cpp b/src/tracks/instrument_track.cpp index e7bff71bd..3823c3baa 100644 --- a/src/tracks/instrument_track.cpp +++ b/src/tracks/instrument_track.cpp @@ -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( _frames, + const fpp_t frames = tMin( _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; diff --git a/src/tracks/sample_track.cpp b/src/tracks/sample_track.cpp index d4793a302..19ecba2c3 100644 --- a/src/tracks/sample_track.cpp +++ b/src/tracks/sample_track.cpp @@ -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; } }