added resampling with Sinc-interpolation in case LMMS processes with higher sample-rate than 96 KHz
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@920 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
@@ -1,3 +1,10 @@
|
||||
2008-04-14 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
|
||||
|
||||
* plugins/sf2_player/sf2_player.cpp:
|
||||
* plugins/sf2_player/sf2_player.h:
|
||||
added resampling with Sinc-interpolation in case LMMS processes with
|
||||
higher sample-rate than 96 KHz
|
||||
|
||||
2008-04-14 Paul Giblock <drfaygo/at/gmail/dot/com>
|
||||
|
||||
* plugins/sf2_player/sf2_player.cpp:
|
||||
|
||||
@@ -76,6 +76,7 @@ int (* sf2Instrument::s_origFree)( fluid_sfont_t * );
|
||||
|
||||
sf2Instrument::sf2Instrument( instrumentTrack * _instrument_track ) :
|
||||
instrument( _instrument_track, &sf2player_plugin_descriptor ),
|
||||
m_srcState( NULL ),
|
||||
m_fontId( 0 ),
|
||||
m_filename( "" ),
|
||||
m_bankNum( -1, -1, 999, 1, this ),
|
||||
@@ -126,6 +127,10 @@ sf2Instrument::~sf2Instrument()
|
||||
engine::getMixer()->removePlayHandles( getInstrumentTrack() );
|
||||
delete_fluid_synth( m_synth );
|
||||
delete_fluid_settings( m_settings );
|
||||
if( m_srcState != NULL )
|
||||
{
|
||||
src_delete( m_srcState );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -225,22 +230,44 @@ void sf2Instrument::updateSampleRate( void )
|
||||
fluid_settings_getnum( m_settings, "synth.sample-rate", &tempRate );
|
||||
m_internalSampleRate = static_cast<int>( tempRate );
|
||||
|
||||
if( m_filename != "" ) {
|
||||
// New synth
|
||||
fluid_synth_t * synth = new_fluid_synth( m_settings );
|
||||
|
||||
// Load sfont, should be in memory and increment refCount
|
||||
m_fontId = fluid_synth_sfload( synth, qPrintable( m_filename ), TRUE );
|
||||
|
||||
if( m_filename != "" )
|
||||
{
|
||||
// Now, delete the old one and replace
|
||||
m_synthMutex.lock();
|
||||
delete_fluid_synth( m_synth );
|
||||
m_synth = synth;
|
||||
|
||||
// New synth
|
||||
m_synth = new_fluid_synth( m_settings );
|
||||
|
||||
// Load sfont, should be in memory and increment refCount
|
||||
char * sf2Ascii = qstrdup( qPrintable( m_filename ) );
|
||||
m_fontId = fluid_synth_sfload( m_synth, sf2Ascii, TRUE );
|
||||
delete[] sf2Ascii;
|
||||
|
||||
// openFile( m_filename );
|
||||
m_synthMutex.unlock();
|
||||
|
||||
// synth program change (set bank and patch)
|
||||
updatePatch();
|
||||
}
|
||||
if( m_internalSampleRate < engine::getMixer()->sampleRate() )
|
||||
{
|
||||
m_synthMutex.lock();
|
||||
if( m_srcState != NULL )
|
||||
{
|
||||
src_delete( m_srcState );
|
||||
}
|
||||
int error;
|
||||
m_srcState = src_new( SRC_SINC_MEDIUM_QUALITY,
|
||||
DEFAULT_CHANNELS, &error );
|
||||
if( m_srcState == NULL || error )
|
||||
{
|
||||
printf( "error while creating SRC-data-"
|
||||
"structure in sf2Instrument::"
|
||||
"updateSampleRate()\n" );
|
||||
}
|
||||
m_synthMutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -292,8 +319,39 @@ void sf2Instrument::play( bool _try_parallelizing,
|
||||
// to account properly for accumulated error (i.e: using frames*internalRate/mixerRate
|
||||
// will not work unless the value is whole. Probably only a big deal for small period-sizes?
|
||||
|
||||
fluid_synth_write_float( m_synth, frames, _working_buffer, 0, 2,
|
||||
if( m_internalSampleRate < engine::getMixer()->sampleRate() &&
|
||||
m_srcState != NULL )
|
||||
{
|
||||
const fpp_t f = frames * m_internalSampleRate /
|
||||
engine::getMixer()->sampleRate();
|
||||
sampleFrame * tmp = new sampleFrame[f];
|
||||
fluid_synth_write_float( m_synth, f, tmp, 0, 2, tmp, 1, 2 );
|
||||
|
||||
SRC_DATA src_data;
|
||||
src_data.data_in = tmp[0];
|
||||
src_data.data_out = _working_buffer[0];
|
||||
src_data.input_frames = f;
|
||||
src_data.output_frames = frames;
|
||||
src_data.src_ratio = (float) frames / f;
|
||||
src_data.end_of_input = 0;
|
||||
int error = src_process( m_srcState, &src_data );
|
||||
delete[] tmp;
|
||||
if( error )
|
||||
{
|
||||
printf( "sf2Instrument: error while resampling: %s\n",
|
||||
src_strerror( error ) );
|
||||
}
|
||||
if( src_data.output_frames_gen > frames )
|
||||
{
|
||||
printf( "sf2Instrument: not enough frames: %ld / %d\n",
|
||||
src_data.output_frames_gen, frames );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fluid_synth_write_float( m_synth, frames, _working_buffer, 0, 2,
|
||||
_working_buffer, 1, 2 );
|
||||
}
|
||||
m_synthMutex.unlock();
|
||||
|
||||
getInstrumentTrack()->processAudioBuffer( _working_buffer, frames,
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "knob.h"
|
||||
#include "lcd_spinbox.h"
|
||||
#include "fluidsynth.h"
|
||||
#include "sample_buffer.h"
|
||||
|
||||
class sf2InstrumentView;
|
||||
class sf2Font;
|
||||
@@ -88,7 +89,9 @@ public slots:
|
||||
|
||||
private:
|
||||
static QMap<QString, sf2Font*> s_fonts;
|
||||
static int (* s_origFree)( fluid_sfont_t * );
|
||||
static int (* s_origFree)( fluid_sfont_t * );
|
||||
|
||||
SRC_STATE * m_srcState;
|
||||
|
||||
fluid_settings_t* m_settings;
|
||||
fluid_synth_t* m_synth;
|
||||
|
||||
Reference in New Issue
Block a user