made rendering happen with one global working-buffer per thread - hopefully improves L1/L2-cache-efficiency

git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@890 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
Tobias Doerffel
2008-04-05 19:06:32 +00:00
parent 7f72593f06
commit c8c5382b35
38 changed files with 286 additions and 218 deletions

View File

@@ -49,14 +49,7 @@ instrument::~instrument()
void instrument::play( bool )
{
}
void instrument::playNote( notePlayHandle *, bool )
void instrument::play( bool, sampleFrame * )
{
}

View File

@@ -68,6 +68,39 @@
sample_rate_t SAMPLE_RATES[QUALITY_LEVELS] = { 44100, 88200 } ;
#define ALIGN_SIZE 64
void aligned_free( void * _buf )
{
if( _buf != NULL )
{
int *ptr2=(int *)_buf - 1;
_buf = (char *)_buf- *ptr2;
free(_buf);
}
}
void * aligned_malloc( int _bytes )
{
char *ptr,*ptr2,*aligned_ptr;
int align_mask = ALIGN_SIZE- 1;
ptr=(char *)malloc(_bytes +ALIGN_SIZE+ sizeof(int));
if(ptr==NULL) return(NULL);
ptr2 = ptr + sizeof(int);
aligned_ptr = ptr2 + (ALIGN_SIZE- ((size_t)ptr2 & align_mask));
ptr2 = aligned_ptr - sizeof(int);
*((int *)ptr2)=(int)(aligned_ptr - ptr);
return(aligned_ptr);
}
class mixerWorkerThread : public QThread
{
public:
@@ -146,6 +179,9 @@ public:
private:
virtual void run( void )
{
sampleFrame * working_buf = (sampleFrame *) aligned_malloc(
m_mixer->framesPerPeriod() *
sizeof( sampleFrame ) );
m_jobWait.acquire();
m_jobAccepted.acquire();
m_idle = TRUE;
@@ -167,7 +203,7 @@ private:
switch( it->type )
{
case PlayHandle:
it->playHandleJob->play();
it->playHandleJob->play( FALSE, working_buf );
break;
case AudioPortEffects:
{
@@ -196,6 +232,7 @@ private:
m_idle = TRUE;
m_sem->release();
}
aligned_free( working_buf );
}
mixer * m_mixer;
@@ -211,6 +248,7 @@ private:
mixer::mixer( void ) :
m_framesPerPeriod( DEFAULT_BUFFER_SIZE ),
m_workingBuf( NULL ),
m_readBuf( NULL ),
m_writeBuf( NULL ),
m_cpuLoad( 0 ),
@@ -249,10 +287,14 @@ mixer::mixer( void ) :
m_fifo = new fifo( 1 );
}
m_workingBuf = (sampleFrame*) aligned_malloc( m_framesPerPeriod *
sizeof( sampleFrame ) );
for( Uint8 i = 0; i < 3; i++ )
{
m_readBuf = new surroundSampleFrame[m_framesPerPeriod];
m_readBuf = (surroundSampleFrame*)
aligned_malloc( m_framesPerPeriod *
sizeof( surroundSampleFrame ) );
clearAudioBuffer( m_readBuf, m_framesPerPeriod );
m_bufferPool.push_back( m_readBuf );
}
@@ -287,8 +329,10 @@ mixer::~mixer()
for( Uint8 i = 0; i < 3; i++ )
{
delete[] m_bufferPool[i];
aligned_free( m_bufferPool[i] );
}
aligned_free( m_workingBuf );
}
@@ -435,7 +479,7 @@ const surroundSampleFrame * mixer::renderNextBuffer( void )
playHandle * n = m_playHandles[idx];
if( !n->done() && n->supportsParallelizing() )
{
n->play( TRUE );
n->play( TRUE, m_workingBuf );
par_hndls.push_back( n );
}
++idx;
@@ -489,7 +533,7 @@ if( COND_NPH )
if( !( *it )->done() )
{
( *it )->play();
( *it )->play( FALSE, m_workingBuf );
}
}
}

View File

@@ -157,7 +157,8 @@ notePlayHandle::~notePlayHandle()
void notePlayHandle::play( bool _try_parallelizing )
void notePlayHandle::play( bool _try_parallelizing,
sampleFrame * _working_buffer )
{
if( m_muted == TRUE )
{
@@ -177,7 +178,8 @@ void notePlayHandle::play( bool _try_parallelizing )
if( framesLeft() > 0 )
{
// play note!
m_instrumentTrack->playNote( this, _try_parallelizing );
m_instrumentTrack->playNote( this, _try_parallelizing,
_working_buffer );
}
if( m_released == TRUE )
@@ -238,7 +240,7 @@ void notePlayHandle::play( bool _try_parallelizing )
for( notePlayHandleVector::iterator it = m_subNotes.begin();
it != m_subNotes.end(); )
{
( *it )->play( _try_parallelizing );
( *it )->play( _try_parallelizing, _working_buffer );
if( ( *it )->done() )
{
delete *it;

View File

@@ -161,9 +161,10 @@ presetPreviewPlayHandle::~presetPreviewPlayHandle()
void presetPreviewPlayHandle::play( bool _try_parallelizing )
void presetPreviewPlayHandle::play( bool _try_parallelizing,
sampleFrame * _working_buffer )
{
m_previewNote->play( _try_parallelizing );
m_previewNote->play( _try_parallelizing, _working_buffer );
}

View File

@@ -116,7 +116,8 @@ samplePlayHandle::~samplePlayHandle()
void samplePlayHandle::play( bool /* _try_parallelizing */ )
void samplePlayHandle::play( bool /* _try_parallelizing */,
sampleFrame * _working_buffer )
{
//play( 0, _try_parallelizing );
if( framesDone() >= totalFrames() )
@@ -128,14 +129,11 @@ void samplePlayHandle::play( bool /* _try_parallelizing */ )
if( !( m_track && m_track->muted() )
&& !( m_bbTrack && m_bbTrack->muted() ) )
{
sampleFrame * buf = new sampleFrame[frames];
stereoVolumeVector v = { { m_volumeModel->value(),
m_volumeModel->value() } };
m_sampleBuffer->play( buf, &m_state, frames );
engine::getMixer()->bufferToPort( buf, frames, offset(), v,
m_audioPort );
delete[] buf;
m_sampleBuffer->play( _working_buffer, &m_state, frames );
engine::getMixer()->bufferToPort( _working_buffer, frames,
offset(), v, m_audioPort );
}
m_frame += frames;

View File

@@ -338,7 +338,8 @@ void instrumentTrack::processOutEvent( const midiEvent & _me,
void instrumentTrack::playNote( notePlayHandle * _n, bool _try_parallelizing )
void instrumentTrack::playNote( notePlayHandle * _n, bool _try_parallelizing,
sampleFrame * _working_buffer )
{
// arpeggio- and chord-widget has to do its work -> adding sub-notes
// for chords/arpeggios
@@ -400,7 +401,8 @@ void instrumentTrack::playNote( notePlayHandle * _n, bool _try_parallelizing )
}
}
// all is done, so now lets play the note!
m_instrument->playNote( _n, _try_parallelizing );
m_instrument->playNote( _n, _try_parallelizing,
_working_buffer );
}
}