Пример #1
0
void sf2Instrument::noteOn( SF2PluginData * n )
{
	m_synthMutex.lock();

	// get list of current voice IDs so we can easily spot the new
	// voice after the fluid_synth_noteon() call
	const int poly = fluid_synth_get_polyphony( m_synth );
	fluid_voice_t * voices[poly];
	unsigned int id[poly];
	fluid_synth_get_voicelist( m_synth, voices, poly, -1 );
	for( int i = 0; i < poly; ++i )
	{
		id[i] = 0;
	}
	for( int i = 0; i < poly && voices[i]; ++i )
	{
		id[i] = fluid_voice_get_id( voices[i] );
	}

	fluid_synth_noteon( m_synth, m_channel, n->midiNote, n->lastVelocity );

	// get new voice and save it
	fluid_synth_get_voicelist( m_synth, voices, poly, -1 );
	for( int i = 0; i < poly && voices[i]; ++i )
	{
		const unsigned int newID = fluid_voice_get_id( voices[i] );
		if( id[i] != newID || newID == 0 )
		{
			n->fluidVoice = voices[i];
			break;
		}
	}

	m_synthMutex.unlock();

	m_notesRunningMutex.lock();
	++m_notesRunning[ n->midiNote ];
	m_notesRunningMutex.unlock();
}
Пример #2
0
void sf2Instrument::playNote( NotePlayHandle * _n, sampleFrame * )
{
	const float LOG440 = 2.643452676f;

	const f_cnt_t tfp = _n->totalFramesPlayed();

	int midiNote = (int)floor( 12.0 * ( log2( _n->unpitchedFrequency() ) - LOG440 ) - 4.0 );

	// out of range?
	if( midiNote <= 0 || midiNote >= 128 )
	{
		return;
	}

	if( tfp == 0 )
	{
		SF2PluginData * pluginData = new SF2PluginData;
		pluginData->midiNote = midiNote;
		pluginData->lastPanning = -1;
		pluginData->lastVelocity = 127;
		pluginData->fluidVoice = NULL;

		_n->m_pluginData = pluginData;

		m_synthMutex.lock();

		// get list of current voice IDs so we can easily spot the new
		// voice after the fluid_synth_noteon() call
		const int poly = fluid_synth_get_polyphony( m_synth );
		fluid_voice_t * voices[poly];
		unsigned int id[poly];
		fluid_synth_get_voicelist( m_synth, voices, poly, -1 );
		for( int i = 0; i < poly; ++i )
		{
			id[i] = 0;
		}
		for( int i = 0; i < poly && voices[i]; ++i )
		{
			id[i] = fluid_voice_get_id( voices[i] );
		}

		const int baseVelocity = instrumentTrack()->midiPort()->baseVelocity();

		fluid_synth_noteon( m_synth, m_channel, midiNote, _n->midiVelocity( baseVelocity ) );

		// get new voice and save it
		fluid_synth_get_voicelist( m_synth, voices, poly, -1 );
		for( int i = 0; i < poly && voices[i]; ++i )
		{
			const unsigned int newID = fluid_voice_get_id( voices[i] );
			if( id[i] != newID || newID == 0 )
			{
				pluginData->fluidVoice = voices[i];
				break;
			}
		}

		m_synthMutex.unlock();

		m_notesRunningMutex.lock();
		++m_notesRunning[midiNote];
		m_notesRunningMutex.unlock();
	}

	SF2PluginData * pluginData = static_cast<SF2PluginData *>(
							_n->m_pluginData );
#ifdef SOMEONE_FIXED_PER_NOTE_PANNING
	if( pluginData->fluidVoice &&
			pluginData->lastPanning != _n->getPanning() )
	{
		const float pan = -500 +
			  ( (float)( _n->getPanning() - PanningLeft ) ) /
			  ( (float)( PanningRight - PanningLeft ) ) * 1000;

		m_synthMutex.lock();
		fluid_voice_gen_set( pluginData->fluidVoice, GEN_PAN, pan );
		fluid_voice_update_param( pluginData->fluidVoice, GEN_PAN );
		m_synthMutex.unlock();

		pluginData->lastPanning = _n->getPanning();
	}
#endif

	const float currentVelocity = _n->volumeLevel( tfp ) * instrumentTrack()->midiPort()->baseVelocity();
	if( pluginData->fluidVoice &&
			pluginData->lastVelocity != currentVelocity )
	{
		m_synthMutex.lock();
		fluid_voice_gen_set( pluginData->fluidVoice, GEN_VELOCITY, currentVelocity );
		fluid_voice_update_param( pluginData->fluidVoice, GEN_VELOCITY );
		// make sure, FluidSynth modulates our changed GEN_VELOCITY via internal
		// attenuation modulator, so changes take effect (7=Volume CC)
		fluid_synth_cc( m_synth, m_channel, 7, 127 );
		m_synthMutex.unlock();

		pluginData->lastVelocity = currentVelocity;
	}
}