static int8_t Midi_Receive(uint8_t *msg, uint32_t len) { uint8_t chan = msg[1] & 0xf; uint8_t msgtype = msg[1] & 0xf0; uint8_t b1 = msg[2]; uint8_t b2 = msg[3]; uint16_t b = ((b2 & 0x7f) << 7) | (b1 & 0x7f); switch (msgtype) { case 0x80: fluid_synth_noteoff(synth, chan, b1); break; case 0x90: fluid_synth_noteon(synth, chan, b1, b2); break; case 0xB0: fluid_synth_cc(synth, chan, b1, b2); break; case 0xC0: fluid_synth_program_change(synth, chan, b1); break; case 0xD0: fluid_synth_channel_pressure(synth, chan, b1); break; case 0xE0: fluid_synth_pitch_bend(synth, chan, b); break; default: break; } return 0; }
JNIEXPORT void JNICALL Java_org_herac_tuxguitar_player_impl_midiport_fluidsynth_MidiSynth_noteOn(JNIEnv* env, jobject ojb, jlong ptr, jint channel, jint note, jint velocity) { fluid_handle_t *handle = NULL; memcpy(&handle, &ptr, sizeof(handle)); if(handle != NULL && handle->synth != NULL){ fluid_synth_noteon(handle->synth, channel, note, velocity); } }
/* * Class: org_tritonus_midi_device_fluidsynth_FluidSynthesizer * Method: noteOn * Signature: (III)V */ JNIEXPORT void JNICALL Java_org_tritonus_midi_device_fluidsynth_FluidSynthesizer_noteOn (JNIEnv *env, jobject obj, jint channel, jint key, jint velocity) { fluid_synth_t* synth = get_synth(env, obj); if (synth) { fluid_synth_noteon(synth, channel, key, velocity); } }
int init(CSOUND *csound) { #pragma omp critical (critical_section_fluid_noteoff) { toa(iFluidSynth, fluidSynth); channel = (int) *iChannelNumber; key = (int) *iMidiKeyNumber; velocity = (int) *iVelocity; fluid_synth_noteon(fluidSynth, channel, key, velocity); } return OK; }
void soundfonts_note(t_soundfonts *instance, t_symbol *s, int argc, t_atom *argv) { if ((argc < 2) || (instance->synth == NULL)) { post("soundfonts error: need 2 values to play note (note, velocity pair)."); return; } float note = atom_getfloatarg(0, argc, argv); float velocity = atom_getfloatarg(1, argc, argv); if ( (note >= 0) && (note <= 127) && (velocity >= 0) && (velocity <= 127) ) { fluid_synth_noteon(instance->synth, 0, note, velocity); } }
bool ISynth::playNote(int channel, int pitch, int velo) { if (_busy) { // printf("fluid: playNote(): busy!\n"); return true; } if (velo) { int err = fluid_synth_noteon(_fluidsynth, channel, pitch, velo); if (err) { printf("ISynth: noteon error, channel %d pitch %d<%s>\n", channel, pitch, fluid_synth_error(_fluidsynth)); } } else fluid_synth_noteoff(_fluidsynth, channel, pitch); return false; }
int main(int argc, char** argv) { fluid_settings_t* settings; fluid_synth_t* synth; fluid_audio_driver_t* adriver1, *adriver2, *adriver3; int sfont_id; int i, key; /* Create the settings. */ settings = new_fluid_settings(); /* Change the settings if necessary*/ /* Create the synthesizer. */ synth = new_fluid_synth(settings); /* Create the audio driver. The synthesizer starts playing as soon as the driver is created. */ adriver1 = new_fluid_audio_driver(settings, synth); fluid_settings_setstr(settings, "audio.driver", "pulseaudio"); adriver2 = new_fluid_audio_driver(settings, synth); fluid_settings_setstr(settings, "audio.driver", "alsa"); adriver3 = new_fluid_audio_driver(settings, synth); /* Load a SoundFont and reset presets (so that new instruments * get used from the SoundFont) */ sfont_id = fluid_synth_sfload(synth, "/usr/share/soundfonts/SGM-V2.01.sf2", 1); /* Initialize the random number generator */ srand(time(NULL)); for (i = 0; i < 12; i++) { /* Generate a random key */ key = 60 + (int) (12.0f * rand() / (float) RAND_MAX); /* Play a note */ fluid_synth_noteon(synth, 0, key, 80); /* Sleep for 1 second */ sleep(1); /* Stop the note */ fluid_synth_noteoff(synth, 0, key); } /* Clean up */ delete_fluid_audio_driver(adriver1); delete_fluid_audio_driver(adriver2); delete_fluid_audio_driver(adriver3); delete_fluid_synth(synth); delete_fluid_settings(settings); return 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(); }
void fluidsynth_feed_midi (unsigned char *event_data, size_t event_length) { int channel = (event_data[0] & 0x0f); int type = (event_data[0] & 0xf0); switch (type) { case MIDI_NOTE_ON: { int velocity = ((int) (Denemo.project->movement->master_volume * event_data[2])); if (velocity > 0x7F) velocity = 0x7F; fluid_synth_noteon (synth, channel, event_data[1], velocity); } break; case MIDI_NOTE_OFF: fluid_synth_noteoff (synth, channel, event_data[1]); break; case MIDI_CONTROL_CHANGE: fluid_synth_cc (synth, channel, event_data[1], event_data[2]); break; case MIDI_PROGRAM_CHANGE: fluid_synth_program_change (synth, channel, event_data[1]); break; case MIDI_PITCH_BEND: fluid_synth_pitch_bend (synth, channel, event_data[1] + (event_data[2] << 7)); break; case SYS_EXCLUSIVE_MESSAGE1: //g_debug("length %d\n", event_length); fluid_synth_sysex (synth, (const char*) event_data + 1, event_length - 1, NULL, 0, NULL, FALSE); break; default: g_warning ("MIDI message type %x not handled", type); } }
int main(int argc, char** argv) { fluid_settings_t* settings; fluid_synth_t* synth = NULL; fluid_audio_driver_t* adriver = NULL; int err = 0; if (argc != 2) { fprintf(stderr, "Usage: fluidsynth_simple [soundfont]\n"); return 1; } /* Create the settings object. This example uses the default * values for the settings. */ settings = new_fluid_settings(); if (settings == NULL) { fprintf(stderr, "Failed to create the settings\n"); err = 2; goto cleanup; } /* Create the synthesizer */ synth = new_fluid_synth(settings); if (synth == NULL) { fprintf(stderr, "Failed to create the synthesizer\n"); err = 3; goto cleanup; } /* Load the soundfont */ if (fluid_synth_sfload(synth, argv[1], 1) == -1) { fprintf(stderr, "Failed to load the SoundFont\n"); err = 4; goto cleanup; } /* Create the audio driver. As soon as the audio driver is * created, the synthesizer can be played. */ adriver = new_fluid_audio_driver(settings, synth); if (adriver == NULL) { fprintf(stderr, "Failed to create the audio driver\n"); err = 5; goto cleanup; } /* Play a note */ fluid_synth_noteon(synth, 0, 60, 100); printf("Press \"Enter\" to stop: "); fgetc(stdin); printf("done\n"); cleanup: if (adriver) { delete_fluid_audio_driver(adriver); } if (synth) { delete_fluid_synth(synth); } if (settings) { delete_fluid_settings(settings); } return err; }
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; } }
static block_t *DecodeBlock (decoder_t *p_dec, block_t **pp_block) { block_t *p_block; decoder_sys_t *p_sys = p_dec->p_sys; block_t *p_out = NULL; if (pp_block == NULL) return NULL; p_block = *pp_block; if (p_block == NULL) return NULL; *pp_block = NULL; if (p_block->i_pts > VLC_TS_INVALID && !date_Get (&p_sys->end_date)) date_Set (&p_sys->end_date, p_block->i_pts); else if (p_block->i_pts < date_Get (&p_sys->end_date)) { msg_Warn (p_dec, "MIDI message in the past?"); goto drop; } if (p_block->i_buffer < 1) goto drop; uint8_t event = p_block->p_buffer[0]; uint8_t channel = p_block->p_buffer[0] & 0xf; event &= 0xF0; if (event == 0xF0) switch (channel) { case 0: if (p_block->p_buffer[p_block->i_buffer - 1] != 0xF7) { case 7: msg_Warn (p_dec, "fragmented SysEx not implemented"); goto drop; } fluid_synth_sysex (p_sys->synth, (char *)p_block->p_buffer + 1, p_block->i_buffer - 2, NULL, NULL, NULL, 0); break; case 0xF: fluid_synth_system_reset (p_sys->synth); break; } uint8_t p1 = (p_block->i_buffer > 1) ? (p_block->p_buffer[1] & 0x7f) : 0; uint8_t p2 = (p_block->i_buffer > 2) ? (p_block->p_buffer[2] & 0x7f) : 0; switch (event & 0xF0) { case 0x80: fluid_synth_noteoff (p_sys->synth, channel, p1); break; case 0x90: fluid_synth_noteon (p_sys->synth, channel, p1, p2); break; /*case 0xA0: note aftertouch not implemented */ case 0xB0: fluid_synth_cc (p_sys->synth, channel, p1, p2); break; case 0xC0: fluid_synth_program_change (p_sys->synth, channel, p1); break; case 0xD0: fluid_synth_channel_pressure (p_sys->synth, channel, p1); break; case 0xE0: fluid_synth_pitch_bend (p_sys->synth, channel, (p2 << 7) | p1); break; } unsigned samples = (p_block->i_pts - date_Get (&p_sys->end_date)) * 441 / 10000; if (samples == 0) goto drop; p_out = decoder_NewAudioBuffer (p_dec, samples); if (p_out == NULL) goto drop; p_out->i_pts = date_Get (&p_sys->end_date ); p_out->i_length = date_Increment (&p_sys->end_date, samples) - p_out->i_pts; fluid_synth_write_float (p_sys->synth, samples, p_out->p_buffer, 0, 2, p_out->p_buffer, 1, 2); drop: block_Release (p_block); return p_out; }
static void handle_buffer (GstFluidDec * fluiddec, GstBuffer * buffer) { GstMapInfo info; guint8 event; gst_buffer_map (buffer, &info, GST_MAP_READ); event = info.data[0]; switch (event & 0xf0) { case 0xf0: switch (event) { case 0xff: GST_DEBUG_OBJECT (fluiddec, "system reset"); fluid_synth_system_reset (fluiddec->synth); break; case 0xf0: case 0xf7: GST_DEBUG_OBJECT (fluiddec, "sysex 0x%02x", event); GST_MEMDUMP_OBJECT (fluiddec, "bytes ", info.data + 1, info.size - 1); fluid_synth_sysex (fluiddec->synth, (char *) info.data + 1, info.size - 1, NULL, NULL, NULL, 0); break; case 0xf9: GST_LOG_OBJECT (fluiddec, "midi tick"); break; default: GST_WARNING_OBJECT (fluiddec, "unhandled event 0x%02x", event); break; } break; default: { guint8 channel, p1, p2; channel = event & 0x0f; p1 = info.size > 1 ? info.data[1] & 0x7f : 0; p2 = info.size > 2 ? info.data[2] & 0x7f : 0; GST_DEBUG_OBJECT (fluiddec, "event 0x%02x channel %d, 0x%02x 0x%02x", event, channel, p1, p2); switch (event & 0xf0) { case 0x80: fluid_synth_noteoff (fluiddec->synth, channel, p1); break; case 0x90: fluid_synth_noteon (fluiddec->synth, channel, p1, p2); break; case 0xA0: /* aftertouch */ break; case 0xB0: fluid_synth_cc (fluiddec->synth, channel, p1, p2); break; case 0xC0: fluid_synth_program_change (fluiddec->synth, channel, p1); break; case 0xD0: fluid_synth_channel_pressure (fluiddec->synth, channel, p1); break; case 0xE0: fluid_synth_pitch_bend (fluiddec->synth, channel, (p2 << 7) | p1); break; default: break; } break; } } gst_buffer_unmap (buffer, &info); }
static aout_buffer_t *DecodeBlock (decoder_t *p_dec, block_t **pp_block) { block_t *p_block; decoder_sys_t *p_sys = p_dec->p_sys; aout_buffer_t *p_out = NULL; if (pp_block == NULL) return NULL; p_block = *pp_block; if (p_block == NULL) return NULL; *pp_block = NULL; if (p_block->i_pts && !date_Get (&p_sys->end_date)) date_Set (&p_sys->end_date, p_block->i_pts); else if (p_block->i_pts < date_Get (&p_sys->end_date)) { msg_Warn (p_dec, "MIDI message in the past?"); goto drop; } if (p_block->i_buffer < 1) goto drop; uint8_t channel = p_block->p_buffer[0] & 0xf; uint8_t p1 = (p_block->i_buffer > 1) ? (p_block->p_buffer[1] & 0x7f) : 0; uint8_t p2 = (p_block->i_buffer > 2) ? (p_block->p_buffer[2] & 0x7f) : 0; switch (p_block->p_buffer[0] & 0xf0) { case 0x80: fluid_synth_noteoff (p_sys->synth, channel, p1); break; case 0x90: fluid_synth_noteon (p_sys->synth, channel, p1, p2); break; case 0xB0: fluid_synth_cc (p_sys->synth, channel, p1, p2); break; case 0xC0: fluid_synth_program_change (p_sys->synth, channel, p1); break; case 0xE0: fluid_synth_pitch_bend (p_sys->synth, channel, (p1 << 7) | p2); break; } unsigned samples = (p_block->i_pts - date_Get (&p_sys->end_date)) * 441 / 10000; if (samples == 0) return NULL; p_out = decoder_NewAudioBuffer (p_dec, samples); if (p_out == NULL) goto drop; p_out->i_pts = date_Get (&p_sys->end_date ); p_out->i_length = date_Increment (&p_sys->end_date, samples) - p_out->i_pts; if (!p_sys->fixed) fluid_synth_write_float (p_sys->synth, samples, p_out->p_buffer, 0, 2, p_out->p_buffer, 1, 2); else fluid_synth_write_s16 (p_sys->synth, samples, (int16_t *)p_out->p_buffer, 0, 2, (int16_t *)p_out->p_buffer, 1, 2); drop: block_Release (p_block); return p_out; }
void note_on(seq_context_t *seq, uint32_t ch, uint32_t note, uint32_t vel) { fluid_synth_noteon(seq->f_synth, ch, note, vel); }
int kontrol(CSOUND *csound) { #pragma omp critical (critical_section_fluidopcodes) { midiStatus = 0xF0 & (int) *kMidiStatus; midiChannel = (int) *kMidiChannel; midiData1 = (int) *kMidiData1; midiData2 = (int) *kMidiData2; int result = -1; if (midiData2 != priorMidiData2 || midiData1 != priorMidiData1 || midiChannel != priorMidiChannel || midiStatus != priorMidiStatus) { switch (midiStatus) { case (int) 0x80: noteOff: result = fluid_synth_noteoff(fluidSynth, midiChannel, midiData1); if (printMsgs) csound->Message(csound, Str("result: %d \n Note off: c:%3d k:%3d\n"), result, midiChannel, midiData1); break; case (int) 0x90: if (!midiData2) { goto noteOff; } result = fluid_synth_noteon(fluidSynth, midiChannel, midiData1, midiData2); if (printMsgs) log(csound, "result: %d \nNote on: c:%3d k:%3d v:%3d\n",result, midiChannel, midiData1, midiData2); break; case (int) 0xA0: if (printMsgs) log(csound, "Key pressure (not handled): " "c:%3d k:%3d v:%3d\n", midiChannel, midiData1, midiData2); break; case (int) 0xB0: result = fluid_synth_cc(fluidSynth, midiChannel, midiData1, midiData2); if (printMsgs) log(csound, "Result: %d Control change: c:%3d c:%3d v:%3d\n",result, midiChannel, midiData1, midiData2); break; case (int) 0xC0: result = fluid_synth_program_change(fluidSynth, midiChannel, midiData1); if (printMsgs) log(csound, "Result: %d Program change: c:%3d p:%3d\n",result, midiChannel, midiData1); break; case (int) 0xD0: if (printMsgs) log(csound, "After touch (not handled): c:%3d v:%3d\n", midiChannel, midiData1); break; case (int) 0xE0: { int pbVal = midiData1 + (midiData2 << 7); fluid_synth_pitch_bend(fluidSynth, midiChannel, pbVal); if (printMsgs) log(csound, "Result: %d, Pitch bend: c:%d b:%d\n", result, midiChannel, pbVal); } break; case (int) 0xF0: if (printMsgs) log(csound, "System exclusive (not handled): " "c:%3d v1:%3d v2:%3d\n", midiChannel, midiData1, midiData2); break; } priorMidiStatus = midiStatus; priorMidiChannel = midiChannel; priorMidiData1 = midiData1; priorMidiData2 = midiData2; } } return OK; }
void ProcessMidi() { ALuint newtempo = 0; // Process more events std::vector<MidiTrack>::iterator i=Tracks.begin(), end=Tracks.end(); while(i != end) { if(i->Offset >= i->data.size() || i->SamplesLeft >= 1.) { i++; continue; } if(i->data.size() - i->Offset < 3) { i->Offset = i->data.size(); i++; continue; } ALubyte event = i->data[i->Offset++]; ALubyte parm1, parm2; if(!(event&0x80)) { event = i->LastEvent; i->Offset--; } if((event&MIDI_EVENT_MASK) != MIDI_SPECIAL) i->LastEvent = event; parm1 = i->data[i->Offset]; parm2 = i->data[i->Offset+1]; int channel = event&MIDI_CHANNEL_MASK; switch(event&MIDI_EVENT_MASK) { case MIDI_NOTEOFF: fluid_synth_noteoff(fluidSynth, channel, parm1); i->Offset += 2; break; case MIDI_NOTEON: fluid_synth_noteon(fluidSynth, channel, parm1, parm2); i->Offset += 2; break; case MIDI_POLYPRESS: i->Offset += 2; break; case MIDI_CTRLCHANGE: fluid_synth_cc(fluidSynth, channel, parm1, parm2); i->Offset += 2; break; case MIDI_PRGMCHANGE: fluid_synth_program_change(fluidSynth, channel, parm1); i->Offset += 1; break; case MIDI_CHANPRESS: fluid_synth_channel_pressure(fluidSynth, channel, parm1); i->Offset += 1; break; case MIDI_PITCHBEND: fluid_synth_pitch_bend(fluidSynth, channel, (parm1&0x7F) | ((parm2&0x7F)<<7)); i->Offset += 2; break; case MIDI_SPECIAL: switch(event) { case MIDI_SYSEX: { unsigned long len = i->ReadVarLen(); if(i->data.size() - i->Offset < len) { i->Offset = i->data.size(); break; } if(i->data[i->Offset+len-1] == MIDI_SYSEXEND) { char *data = reinterpret_cast<char*>(&i->data[i->Offset]); fluid_synth_sysex(fluidSynth, data, len-1, NULL, NULL, NULL, false); } i->Offset += len; break; } case MIDI_SYSEXEND: { unsigned long len = i->ReadVarLen(); if(i->data.size() - i->Offset < len) { i->Offset = i->data.size(); break; } i->Offset += len; break; } case MIDI_SONGPOS: i->Offset += 2; break; case MIDI_SONGSEL: i->Offset += 1; break; case MIDI_META: { ALubyte metatype = i->data[i->Offset++]; unsigned long val = i->ReadVarLen(); if(i->data.size() - i->Offset < val) { i->Offset = i->data.size(); break; } if(metatype == MIDI_META_EOT) { i->Offset = i->data.size(); break; } if(metatype == MIDI_META_TEMPO && val >= 3) { newtempo = (i->data[i->Offset] << 16) | (i->data[i->Offset+1] << 8) | (i->data[i->Offset+2]); } i->Offset += val; break; } default: /* The rest of the special events don't have any * data bytes */ break; } break; default: /* Shouldn't ever get to here */ break; } unsigned long val = i->ReadVarLen(); i->SamplesLeft += val * samplesPerTick; } if(newtempo) UpdateTempo(newtempo); }
/* Callback for midi events */ void fluid_seq_fluidsynth_callback(unsigned int time, fluid_event_t* evt, fluid_sequencer_t* seq, void* data) { fluid_synth_t* synth; fluid_seqbind_t* seqbind = (fluid_seqbind_t *) data; synth = seqbind->synth; switch (fluid_event_get_type(evt)) { case FLUID_SEQ_NOTEON: fluid_synth_noteon(synth, fluid_event_get_channel(evt), fluid_event_get_key(evt), fluid_event_get_velocity(evt)); break; case FLUID_SEQ_NOTEOFF: fluid_synth_noteoff(synth, fluid_event_get_channel(evt), fluid_event_get_key(evt)); break; case FLUID_SEQ_NOTE: { unsigned int dur; fluid_synth_noteon(synth, fluid_event_get_channel(evt), fluid_event_get_key(evt), fluid_event_get_velocity(evt)); dur = fluid_event_get_duration(evt); fluid_event_noteoff(evt, fluid_event_get_channel(evt), fluid_event_get_key(evt)); fluid_sequencer_send_at(seq, evt, dur, 0); } break; case FLUID_SEQ_ALLSOUNDSOFF: /* NYI */ break; case FLUID_SEQ_ALLNOTESOFF: fluid_synth_cc(synth, fluid_event_get_channel(evt), 0x7B, 0); break; case FLUID_SEQ_BANKSELECT: fluid_synth_bank_select(synth, fluid_event_get_channel(evt), fluid_event_get_bank(evt)); break; case FLUID_SEQ_PROGRAMCHANGE: fluid_synth_program_change(synth, fluid_event_get_channel(evt), fluid_event_get_program(evt)); break; case FLUID_SEQ_PROGRAMSELECT: fluid_synth_program_select(synth, fluid_event_get_channel(evt), fluid_event_get_sfont_id(evt), fluid_event_get_bank(evt), fluid_event_get_program(evt)); break; case FLUID_SEQ_ANYCONTROLCHANGE: /* nothing = only used by remove_events */ break; case FLUID_SEQ_PITCHBEND: fluid_synth_pitch_bend(synth, fluid_event_get_channel(evt), fluid_event_get_pitch(evt)); break; case FLUID_SEQ_PITCHWHHELSENS: fluid_synth_pitch_wheel_sens(synth, fluid_event_get_channel(evt), fluid_event_get_value(evt)); break; case FLUID_SEQ_CONTROLCHANGE: fluid_synth_cc(synth, fluid_event_get_channel(evt), fluid_event_get_control(evt), fluid_event_get_value(evt)); break; case FLUID_SEQ_MODULATION: { short ctrl = 0x01; // MODULATION_MSB fluid_synth_cc(synth, fluid_event_get_channel(evt), ctrl, fluid_event_get_value(evt)); } break; case FLUID_SEQ_SUSTAIN: { short ctrl = 0x40; // SUSTAIN_SWITCH fluid_synth_cc(synth, fluid_event_get_channel(evt), ctrl, fluid_event_get_value(evt)); } break; case FLUID_SEQ_PAN: { short ctrl = 0x0A; // PAN_MSB fluid_synth_cc(synth, fluid_event_get_channel(evt), ctrl, fluid_event_get_value(evt)); } break; case FLUID_SEQ_VOLUME: { short ctrl = 0x07; // VOLUME_MSB fluid_synth_cc(synth, fluid_event_get_channel(evt), ctrl, fluid_event_get_value(evt)); } break; case FLUID_SEQ_REVERBSEND: { short ctrl = 0x5B; // EFFECTS_DEPTH1 fluid_synth_cc(synth, fluid_event_get_channel(evt), ctrl, fluid_event_get_value(evt)); } break; case FLUID_SEQ_CHORUSSEND: { short ctrl = 0x5D; // EFFECTS_DEPTH3 fluid_synth_cc(synth, fluid_event_get_channel(evt), ctrl, fluid_event_get_value(evt)); } break; case FLUID_SEQ_CHANNELPRESSURE: { fluid_synth_channel_pressure(synth, fluid_event_get_channel(evt), fluid_event_get_value(evt)); } break; case FLUID_SEQ_SYSTEMRESET: { fluid_synth_system_reset(synth); } break; case FLUID_SEQ_UNREGISTERING: /* free ourselves */ { seqbind->client_id = -1; /* avoid recursive call to fluid_sequencer_unregister_client */ delete_fluid_seqbind(seqbind); } break; case FLUID_SEQ_TIMER: /* nothing in fluidsynth */ break; default: break; } }
static void FSynth_processQueue(FSynth *self, ALuint64 time) { EvtQueue *queue = &STATIC_CAST(MidiSynth, self)->EventQueue; while(queue->pos < queue->size && queue->events[queue->pos].time <= time) { const MidiEvent *evt = &queue->events[queue->pos]; if(evt->event == SYSEX_EVENT) { static const ALbyte gm2_on[] = { 0x7E, 0x7F, 0x09, 0x03 }; static const ALbyte gm2_off[] = { 0x7E, 0x7F, 0x09, 0x02 }; int handled = 0; fluid_synth_sysex(self->Synth, evt->param.sysex.data, evt->param.sysex.size, NULL, NULL, &handled, 0); if(!handled && evt->param.sysex.size >= (ALsizei)sizeof(gm2_on)) { if(memcmp(evt->param.sysex.data, gm2_on, sizeof(gm2_on)) == 0) self->ForceGM2BankSelect = AL_TRUE; else if(memcmp(evt->param.sysex.data, gm2_off, sizeof(gm2_off)) == 0) self->ForceGM2BankSelect = AL_FALSE; } } else switch((evt->event&0xF0)) { case AL_NOTEOFF_SOFT: fluid_synth_noteoff(self->Synth, (evt->event&0x0F), evt->param.val[0]); break; case AL_NOTEON_SOFT: fluid_synth_noteon(self->Synth, (evt->event&0x0F), evt->param.val[0], evt->param.val[1]); break; case AL_AFTERTOUCH_SOFT: break; case AL_CONTROLLERCHANGE_SOFT: if(self->ForceGM2BankSelect) { int chan = (evt->event&0x0F); if(evt->param.val[0] == 0) { if(evt->param.val[1] == 120 && (chan == 9 || chan == 10)) fluid_synth_set_channel_type(self->Synth, chan, CHANNEL_TYPE_DRUM); else if(evt->param.val[1] == 121) fluid_synth_set_channel_type(self->Synth, chan, CHANNEL_TYPE_MELODIC); break; } if(evt->param.val[0] == 32) { fluid_synth_bank_select(self->Synth, chan, evt->param.val[1]); break; } } fluid_synth_cc(self->Synth, (evt->event&0x0F), evt->param.val[0], evt->param.val[1]); break; case AL_PROGRAMCHANGE_SOFT: fluid_synth_program_change(self->Synth, (evt->event&0x0F), evt->param.val[0]); break; case AL_CHANNELPRESSURE_SOFT: fluid_synth_channel_pressure(self->Synth, (evt->event&0x0F), evt->param.val[0]); break; case AL_PITCHBEND_SOFT: fluid_synth_pitch_bend(self->Synth, (evt->event&0x0F), (evt->param.val[0]&0x7F) | ((evt->param.val[1]&0x7F)<<7)); break; } queue->pos++; } }
static int fluidsynth_midi_write(struct _midi_writer *self, unsigned char *buf, int len) { if (buf[0] == 0xf0) sciprintf("FluidSynth: Skipping sysex message.\n"); else if (len == 2) { guint8 command, channel; command = buf[0] & 0xf0; channel = buf[0] & 0x0f; switch(command) { case 0xc0: fluid_synth_program_change(synth, channel, buf[1]); break; default: printf("FluidSynth: MIDI command [%02x %02x] not supported\n", buf[0], buf[1]); } } else if (len == 3) { guint8 command, channel; command = buf[0] & 0xf0; channel = buf[0] & 0x0f; switch(command) { case 0x80: fluid_synth_noteoff(synth, channel, buf[1]); break; case 0x90: fluid_synth_noteon(synth, channel, buf[1], buf[2]); break; case 0xb0: switch (buf[1]) { case 0x06: /* Data Entry Slider - course */ if (rpn[channel] == 0) fluid_synth_pitch_wheel_sens(synth, channel, buf[2]); else sciprintf("FluidSynth: RPN %i not supported\n", rpn[channel]); case 0x64: /* Registered Parameter Number (RPN) - fine */ rpn[channel] &= ~0x7f; rpn[channel] |= buf[2] & 0x7f; break; case 0x65: /* Registered Parameter Number (RPN) - course */ rpn[channel] &= ~0x3f80; rpn[channel] |= (buf[2] & 0x7f) << 7; break; default: fluid_synth_cc(synth, channel, buf[1], buf[2]); } break; case 0xe0: fluid_synth_pitch_bend(synth, channel, (buf[2] << 7) | buf[1]); break; default: sciprintf("FluidSynth: MIDI command [%02x %02x %02x] not supported\n", buf[0], buf[1], buf[2]); } } else sciprintf("FluidSynth: Skipping invalid message of %i bytes.\n", len); return SFX_OK; }
void noteOn(int chan, int key, int vel) { fluid_synth_noteon(m_synth, chan, key, vel); }