diff --git a/include/MidiAlsaSeq.h b/include/MidiAlsaSeq.h index 2b573422b..3860952e8 100644 --- a/include/MidiAlsaSeq.h +++ b/include/MidiAlsaSeq.h @@ -82,6 +82,9 @@ public: return m_writablePorts; } + // return name of port which specified MIDI event came from + virtual QString sourcePortName( const midiEvent & ) const; + // (un)subscribe given MidiPort to/from destination-port virtual void subscribeReadablePort( MidiPort * _port, const QString & _dest, diff --git a/include/MidiClient.h b/include/MidiClient.h index a53ada162..02cca11b6 100644 --- a/include/MidiClient.h +++ b/include/MidiClient.h @@ -77,6 +77,13 @@ public: return QStringList(); } + // return name of port which specified MIDI event came from + virtual QString sourcePortName( const midiEvent & ) const + { + return QString(); + } + + // (un)subscribe given MidiPort to/from destination-port virtual void subscribeReadablePort( MidiPort * _port, const QString & _dest, diff --git a/include/MidiPort.h b/include/MidiPort.h index 2ede0772b..8a6f0088a 100644 --- a/include/MidiPort.h +++ b/include/MidiPort.h @@ -115,9 +115,9 @@ public: } void subscribeReadablePort( const QString & _port, - bool _subscribe = TRUE ); + bool _subscribe = true ); void subscribeWritablePort( const QString & _port, - bool _subscribe = TRUE ); + bool _subscribe = true ); const Map & readablePorts() const { @@ -172,7 +172,6 @@ signals: void writablePortsChanged(); void modeChanged(); - } ; diff --git a/include/MidiWinMM.h b/include/MidiWinMM.h index feae6ddc6..51cccae71 100644 --- a/include/MidiWinMM.h +++ b/include/MidiWinMM.h @@ -77,6 +77,9 @@ public: } #endif + // return name of port which specified MIDI event came from + virtual QString sourcePortName( const midiEvent & ) const; + // (un)subscribe given MidiPort to/from destination-port virtual void subscribeReadablePort( MidiPort * _port, const QString & _dest, diff --git a/include/midi.h b/include/midi.h index 1db19d27d..5b994cf4b 100644 --- a/include/midi.h +++ b/include/midi.h @@ -95,21 +95,25 @@ struct midiEvent midiEvent( MidiEventTypes _type = MidiActiveSensing, Sint8 _channel = 0, Sint16 _param1 = 0, - Sint16 _param2 = 0 ) : + Sint16 _param2 = 0, + const void * _sourcePort = NULL ) : m_type( _type ), m_metaEvent( MidiMetaInvalid ), m_channel( _channel ), - m_sysExData( NULL ) + m_sysExData( NULL ), + m_sourcePort( _sourcePort ) { m_data.m_param[0] = _param1; m_data.m_param[1] = _param2; } + midiEvent( MidiEventTypes _type, const char * _sysex_data, int _data_len ) : m_type( _type ), m_metaEvent( MidiMetaInvalid ), m_channel( 0 ), - m_sysExData( _sysex_data ) + m_sysExData( _sysex_data ), + m_sourcePort( NULL ) { m_data.m_sysExDataLen = _data_len; } @@ -119,46 +123,52 @@ struct midiEvent m_metaEvent( _copy.m_metaEvent ), m_channel( _copy.m_channel ), m_data( _copy.m_data ), - m_sysExData( _copy.m_sysExData ) + m_sysExData( _copy.m_sysExData ), + m_sourcePort( _copy.m_sourcePort ) { } - inline int channel( void ) const + inline int channel() const { return m_channel; } - inline Sint16 key( void ) const + inline Sint16 key() const { return m_data.m_param[0]; } - inline Sint16 & key( void ) + inline Sint16 & key() { return m_data.m_param[0]; } - inline Sint16 velocity( void ) const + inline Sint16 velocity() const { return m_data.m_param[1]; } - inline Sint16 & velocity( void ) - { - return m_data.m_param[1]; - } - - inline Sint16 midiPanning( void ) const + inline Sint16 & velocity() { return m_data.m_param[1]; } - inline volume_t getVolume( void ) const + inline Sint16 midiPanning() const + { + return m_data.m_param[1]; + } + + inline volume_t getVolume() const { return (volume_t)( velocity() * 100 / MidiMaxVelocity ); } - - inline panning_t getPanning( void ) const + + inline const void * sourcePort() const + { + return m_sourcePort; + } + + inline panning_t getPanning() const { return (panning_t) ( PanningLeft + ( (float)( midiPanning() - MidiMinPanning ) ) / @@ -178,6 +188,7 @@ struct midiEvent } m_data; const char * m_sysExData; + const void * m_sourcePort; } ; diff --git a/src/core/midi/MidiAlsaSeq.cpp b/src/core/midi/MidiAlsaSeq.cpp index 5ba1651b2..3ce4d453a 100644 --- a/src/core/midi/MidiAlsaSeq.cpp +++ b/src/core/midi/MidiAlsaSeq.cpp @@ -50,6 +50,25 @@ static QString __portName( snd_seq_client_info_t * _cinfo, arg( snd_seq_port_info_get_name( _pinfo ) ); } +static QString __portName( snd_seq_t * _seq, const snd_seq_addr_t * _addr ) +{ + snd_seq_client_info_t * cinfo; + snd_seq_port_info_t * pinfo; + + snd_seq_client_info_malloc( &cinfo ); + snd_seq_port_info_malloc( &pinfo ); + + snd_seq_get_any_port_info( _seq, _addr->client, _addr->port, pinfo ); + snd_seq_get_any_client_info( _seq, _addr->client, cinfo ); + + const QString name = __portName( cinfo, pinfo ); + + snd_seq_client_info_free( cinfo ); + snd_seq_port_info_free( pinfo ); + + return name; +} + MidiAlsaSeq::MidiAlsaSeq() : @@ -320,6 +339,20 @@ void MidiAlsaSeq::removePort( MidiPort * _port ) +QString MidiAlsaSeq::sourcePortName( const midiEvent & _event ) const +{ + if( _event.sourcePort() ) + { + const snd_seq_addr_t * addr = + static_cast( _event.sourcePort() ); + return __portName( m_seqHandle, addr ); + } + return MidiClient::sourcePortName( _event ); +} + + + + void MidiAlsaSeq::subscribeReadablePort( MidiPort * _port, const QString & _dest, bool _subscribe ) @@ -441,13 +474,13 @@ void MidiAlsaSeq::run() // while event queue is not empty while( snd_seq_event_input_pending( m_seqHandle, true ) > 0 ) { - snd_seq_event_t * ev; if( snd_seq_event_input( m_seqHandle, &ev ) < 0 ) { break; } + snd_seq_addr_t * source = NULL; MidiPort * dest = NULL; for( int i = 0; i < m_portIDs.size(); ++i ) { @@ -455,6 +488,12 @@ void MidiAlsaSeq::run() { dest = m_portIDs.keys()[i]; } + if( ( m_portIDs.values()[i][1] != -1 && + m_portIDs.values()[i][1] == ev->source.port ) || + m_portIDs.values()[i][0] == ev->source.port ) + { + source = &ev->source; + } } if( dest == NULL ) @@ -469,7 +508,8 @@ void MidiAlsaSeq::run() ev->data.note.channel, ev->data.note.note - KeysPerOctave, - ev->data.note.velocity + ev->data.note.velocity, + source ), midiTime( ev->time.tick ) ); break; @@ -479,7 +519,8 @@ void MidiAlsaSeq::run() ev->data.note.channel, ev->data.note.note - KeysPerOctave, - ev->data.note.velocity + ev->data.note.velocity, + source ), midiTime( ev->time.tick) ); break; @@ -490,7 +531,8 @@ void MidiAlsaSeq::run() ev->data.note.channel, ev->data.note.note - KeysPerOctave, - ev->data.note.velocity + ev->data.note.velocity, + source ), midiTime() ); break; @@ -499,7 +541,7 @@ void MidiAlsaSeq::run() MidiControlChange, ev->data.control.channel, ev->data.control.param, - ev->data.control.value ), + ev->data.control.value, source ), midiTime() ); break; @@ -508,7 +550,7 @@ void MidiAlsaSeq::run() MidiProgramChange, ev->data.control.channel, ev->data.control.param, - ev->data.control.value ), + ev->data.control.value, source ), midiTime() ); break; @@ -517,15 +559,15 @@ void MidiAlsaSeq::run() MidiChannelPressure, ev->data.control.channel, ev->data.control.param, - ev->data.control.value ), + ev->data.control.value, source ), midiTime() ); break; case SND_SEQ_EVENT_PITCHBEND: dest->processInEvent( midiEvent( MidiPitchBend, ev->data.control.channel, - ev->data.control.value + 8192, - 0 ), midiTime() ); + ev->data.control.value + 8192, 0, source ), + midiTime() ); break; case SND_SEQ_EVENT_SENSING: diff --git a/src/core/midi/MidiWinMM.cpp b/src/core/midi/MidiWinMM.cpp index bb16b5b2b..2abb6a344 100644 --- a/src/core/midi/MidiWinMM.cpp +++ b/src/core/midi/MidiWinMM.cpp @@ -61,7 +61,7 @@ void MidiWinMM::processOutEvent( const midiEvent & _me, const midiTime & _time, const MidiPort * _port ) { - const DWORD short_msg = ( _me.m_type + _me.channel() ) + + const DWORD shortMsg = ( _me.m_type + _me.channel() ) + ( ( _me.m_data.m_param[0] & 0xff ) << 8 ) + ( ( _me.m_data.m_param[1] & 0xff ) << 16 ); @@ -85,7 +85,7 @@ void MidiWinMM::processOutEvent( const midiEvent & _me, { if( out_devs.contains( *it ) ) { - midiOutShortMsg( it.key(), short_msg ); + midiOutShortMsg( it.key(), shortMsg ); } } } @@ -137,6 +137,19 @@ void MidiWinMM::removePort( MidiPort * _port ) +QString MidiWinMM::sourcePortName( const midiEvent & _event ) const +{ + if( _event.sourcePort() ) + { + return m_inputDevices.value( *static_cast( + _event.sourcePort() ) ); + } + return MidiClient::sourcePortName( _event ); +} + + + + void MidiWinMM::subscribeReadablePort( MidiPort * _port, const QString & _dest, bool _subscribe ) @@ -219,25 +232,21 @@ void MidiWinMM::handleInputEvent( HMIDIIN _hm, DWORD _ev ) case MidiNoteOff: case MidiKeyPressure: ( *it )->processInEvent( - midiEvent( cmdtype, chan, - par1 - KeysPerOctave, - par2 & 0xff ), - midiTime() ); + midiEvent( cmdtype, chan, par1 - KeysPerOctave, + par2 & 0xff, &_hm ), midiTime() ); break; case MidiControlChange: case MidiProgramChange: case MidiChannelPressure: ( *it )->processInEvent( - midiEvent( cmdtype, chan, par1, - par2 & 0xff ), + midiEvent( cmdtype, chan, par1, par2 & 0xff, &_hm ), midiTime() ); break; case MidiPitchBend: ( *it )->processInEvent( - midiEvent( cmdtype, chan, - par1 + par2*128, 0 ), + midiEvent( cmdtype, chan, par1 + par2*128, 0, &_hm ), midiTime() ); break;