/* * Class: org_tritonus_midi_device_fluidsynth_FluidSynthesizer * Method: getMaxPolyphony * Signature: ()I */ JNIEXPORT jint JNICALL Java_org_tritonus_midi_device_fluidsynth_FluidSynthesizer_getMaxPolyphony (JNIEnv *env, jobject obj) { fluid_synth_t* synth = get_synth(env, obj); if (synth) { return fluid_synth_get_polyphony(synth); } else { return -1; } }
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(); }
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; } }