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);
	}
}
예제 #4
0
    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;
    }
예제 #5
0
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);
        
    }
}
예제 #6
0
파일: fluid.cpp 프로젝트: AndreeeCZ/muse
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;
}
예제 #8
0
파일: sf2_player.cpp 프로젝트: Lukas-W/lmms
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();
}
예제 #9
0
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;
}
예제 #11
0
파일: sf2_player.cpp 프로젝트: AHudon/lmms
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;
	}
}
예제 #12
0
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;
}
예제 #13
0
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);
}
예제 #14
0
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;
}
예제 #15
0
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);
}
예제 #16
0
    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;
    }
예제 #17
0
    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);
    }
예제 #18
0
/* 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;
	}
}
예제 #19
0
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++;
    }
}
예제 #20
0
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;
}
예제 #21
0
 void noteOn(int chan, int key, int vel)
 {
     fluid_synth_noteon(m_synth, chan, key, vel);
 }