diff --git a/ChangeLog b/ChangeLog index f3abfbdec..dac4dd6ef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2006-11-19 Tobias Doerffel + + * plugins/vst_base/lvsl_server.c: + proper handling of pitch-bend-events + + * plugins/vestige/vestige.h: + * plugins/vestige/vestige.cpp: + handle MIDI-events by forwarding them to VST-plugin + + * include/instrument.h: + * src/tracks/instrument_track.cpp: + if supported by according instrument, it now can handle all incoming + MIDI-events (except Noteon and Noteoff) + + * src/midi/midi_alsa_seq.cpp: + more complete implementation of MIDI-event-handling + 2006-11-15 Javier Serrano Polo * include/audio_alsa.h: diff --git a/TODO b/TODO index 2092b75ab..5dfca56db 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,4 @@ +- MIDI over Ethernet-support - lock m_instrument in instrumentTrack-class for not crashing when using m_instrument in notePlayHandle::supportsParallelizing() while instrument is being deleted or so - try to make vestige-plugin-dlls relative - do song-editor-tempo-connection to vst-plugin inside remoteVSTPlugin diff --git a/configure.in b/configure.in index 554f19c9c..06788adc7 100644 --- a/configure.in +++ b/configure.in @@ -2,8 +2,8 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.50) -AC_INIT(lmms, 0.2.1-svn20061115, lmms-devel/at/lists/dot/sf/dot/net) -AM_INIT_AUTOMAKE(lmms, 0.2.1-svn20061115) +AC_INIT(lmms, 0.2.1-svn20061119, lmms-devel/at/lists/dot/sf/dot/net) +AM_INIT_AUTOMAKE(lmms, 0.2.1-svn20061119) AM_CONFIG_HEADER(config.h) diff --git a/include/instrument.h b/include/instrument.h index 15d86f7b4..42e45409c 100644 --- a/include/instrument.h +++ b/include/instrument.h @@ -55,6 +55,7 @@ // forward-declarations class instrumentTrack; class notePlayHandle; +class midiEvent; class instrument : public QWidget, public plugin @@ -98,6 +99,14 @@ public: return( TRUE ); } + // sub-classes can re-implement this for receiving all incoming + // MIDI-events except NoteOn and NoteOff + inline virtual bool handleMidiEvent( const midiEvent & _me, + const midiTime & _time ) + { + return( FALSE ); + } + // instantiate instrument-plugin with given name or return NULL // on failure static instrument * FASTCALL instantiate( const QString & _plugin_name, diff --git a/plugins/vestige/vestige.cpp b/plugins/vestige/vestige.cpp index 59ae95a91..62a9e05cc 100644 --- a/plugins/vestige/vestige.cpp +++ b/plugins/vestige/vestige.cpp @@ -364,6 +364,21 @@ void vestigeInstrument::deleteNotePluginData( notePlayHandle * _n ) +bool vestigeInstrument::handleMidiEvent( const midiEvent & _me, + const midiTime & _time ) +{ + m_pluginMutex.lock(); + if( m_plugin != NULL ) + { + m_plugin->enqueueMidiEvent( _me, _time ); + } + m_pluginMutex.unlock(); + return( TRUE ); +} + + + + void vestigeInstrument::openPlugin( void ) { #ifdef QT4 diff --git a/plugins/vestige/vestige.h b/plugins/vestige/vestige.h index 82d96ed4e..4140f96fc 100644 --- a/plugins/vestige/vestige.h +++ b/plugins/vestige/vestige.h @@ -84,6 +84,9 @@ public: return( FALSE ); } + virtual bool handleMidiEvent( const midiEvent & _me, + const midiTime & _time ); + protected slots: void openPlugin( void ); diff --git a/plugins/vst_base/lvsl_server.c b/plugins/vst_base/lvsl_server.c index 778bdbbe4..5693ce78d 100644 --- a/plugins/vst_base/lvsl_server.c +++ b/plugins/vst_base/lvsl_server.c @@ -512,8 +512,18 @@ void VSTPlugin::enqueueMidiEvent( const midiEvent & _event, event.reserved1 = 0; event.reserved2 = 0; event.midiData[0] = _event.m_type + _event.m_channel; - event.midiData[1] = _event.key(); - event.midiData[2] = _event.velocity(); + switch( _event.m_type ) + { + case PITCH_BEND: + event.midiData[1] = _event.m_data.m_param[0] & 0x7f; + event.midiData[2] = _event.m_data.m_param[0] >> 7; + break; + // TODO: handle more special cases + default: + event.midiData[1] = _event.key(); + event.midiData[2] = _event.velocity(); + break; + } event.midiData[3] = 0; m_midiEvents.push_back( event ); } diff --git a/src/midi/midi_alsa_seq.cpp b/src/midi/midi_alsa_seq.cpp index e42d0fff2..948787678 100644 --- a/src/midi/midi_alsa_seq.cpp +++ b/src/midi/midi_alsa_seq.cpp @@ -192,10 +192,11 @@ void midiALSASeq::processOutEvent( const midiEvent & _me, _me.velocity() ); break; - case PITCH_BEND: - snd_seq_ev_set_pitchbend( &ev, + case CONTROL_CHANGE: + snd_seq_ev_set_controller( &ev, _port->outputChannel(), - _me.m_data.m_param[0] - 8192 ); + _me.m_data.m_param[0], + _me.m_data.m_param[1] ); break; case PROGRAM_CHANGE: @@ -210,6 +211,12 @@ void midiALSASeq::processOutEvent( const midiEvent & _me, _me.m_data.m_param[0] ); break; + case PITCH_BEND: + snd_seq_ev_set_pitchbend( &ev, + _port->outputChannel(), + _me.m_data.m_param[0] - 8192 ); + break; + default: printf( "ALSA-sequencer: unhandled output event %d\n", (int) _me.m_type ); @@ -519,6 +526,38 @@ void midiALSASeq::run( void ) ), midiTime() ); break; + case SND_SEQ_EVENT_CONTROLLER: + dest->processInEvent( midiEvent( CONTROL_CHANGE, + ev->data.control.channel, + ev->data.control.param, + ev->data.control.value ), + midiTime() ); + break; + + case SND_SEQ_EVENT_PGMCHANGE: + dest->processInEvent( midiEvent( PROGRAM_CHANGE, + ev->data.control.channel, + ev->data.control.param, + ev->data.control.value ), + midiTime() ); + break; + + case SND_SEQ_EVENT_CHANPRESS: + dest->processInEvent( midiEvent( + CHANNEL_PRESSURE, + ev->data.control.channel, + ev->data.control.param, + ev->data.control.value ), + midiTime() ); + break; + + case SND_SEQ_EVENT_PITCHBEND: + dest->processInEvent( midiEvent( PITCH_BEND, + ev->data.control.channel, + ev->data.control.value + 8192, + 0 ), midiTime() ); + break; + case SND_SEQ_EVENT_SENSING: case SND_SEQ_EVENT_CLOCK: break; diff --git a/src/tracks/instrument_track.cpp b/src/tracks/instrument_track.cpp index dd061589d..6a54be35a 100644 --- a/src/tracks/instrument_track.cpp +++ b/src/tracks/instrument_track.cpp @@ -683,13 +683,18 @@ void instrumentTrack::processInEvent( const midiEvent & _me, break; case KEY_PRESSURE: - if( m_notes[_me.key()] != NULL ) + if( !m_instrument->handleMidiEvent( _me, _time ) && + m_notes[_me.key()] != NULL ) { m_notes[_me.key()]->setVolume( _me.velocity() * 100 / 128 ); } break; + case PITCH_BEND: + m_instrument->handleMidiEvent( _me, _time ); + break; + /* case PITCH_BEND: if( m_pitchBendKnob != NULL ) { @@ -704,7 +709,7 @@ void instrumentTrack::processInEvent( const midiEvent & _me, break;*/ default: - printf( "channel-track: unhandled MIDI-event %d\n", + printf( "instrument-track: unhandled MIDI-event %d\n", _me.m_type ); break; }