rewrote management of MIDI-ports and MIDI-port subscriptions - now it's central and easy to use

git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@1087 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
Tobias Doerffel
2008-06-07 21:20:35 +00:00
parent 4c4596f9f4
commit 231bef1349
25 changed files with 677 additions and 1053 deletions

View File

@@ -1,3 +1,32 @@
2008-06-07 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
* include/controller_connection_dialog.h:
* include/instrument_midi_io_view.h:
* include/instrument_track.h:
* include/midi_alsa_raw.h:
* include/midi_alsa_seq.h:
* include/midi_client.h:
* include/midi_controller.h:
* include/midi_io_model.h:
* include/midi_oss.h:
* include/midi_port.h:
* include/midi_port_menu.h:
* src/core/note_play_handle.cpp:
* src/core/preset_preview_play_handle.cpp:
* src/core/song.cpp:
* src/core/midi/midi_client.cpp:
* src/core/midi/midi_controller.cpp:
* src/core/midi/midi_port.cpp:
* src/core/midi/midi_io_model.cpp:
* src/core/midi/midi_alsa_seq.cpp:
* src/gui/piano_roll.cpp:
* src/gui/controller_connection_dialog.cpp:
* src/gui/widgets/instrument_midi_io_view.cpp:
* src/tracks/instrument_track.cpp:
* Makefile.am:
rewrote management of MIDI-ports and MIDI-port subscriptions - now
it's central and easy to use
2008-06-06 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
* include/note.h:

View File

@@ -113,8 +113,6 @@ lmms_MOC = \
./group_box.moc \
./instrument_functions.moc \
./instrument_function_views.moc \
./instrument_midi_io.moc \
./instrument_midi_io_view.moc \
./instrument_sound_shaping.moc \
./instrument_sound_shaping_view.moc \
./kmultitabbar.moc \
@@ -125,14 +123,15 @@ lmms_MOC = \
./led_checkbox.moc \
./lfo_controller.moc \
./main_window.moc \
./meter_model.moc \
./midi_alsa_seq.moc \
./midi_controller.moc \
./midi_port.moc \
./midi_port_menu.moc \
./mixer.moc \
./mv_base.moc \
./name_label.moc \
./nstate_button.moc \
./meter_model.moc \
./midi_alsa_seq.moc \
./midi_controller.moc \
./instrument_midi_io.moc \
./pattern.moc \
./piano_roll.moc \
./piano.moc \
@@ -218,7 +217,6 @@ lmms_SOURCES = \
$(srcdir)/src/core/import_filter.cpp \
$(srcdir)/src/core/instrument.cpp \
$(srcdir)/src/core/instrument_functions.cpp \
$(srcdir)/src/core/instrument_midi_io.cpp \
$(srcdir)/src/core/journalling_object.cpp \
$(srcdir)/src/core/ladspa_2_lmms.cpp \
$(srcdir)/src/core/ladspa_manager.cpp \
@@ -261,7 +259,7 @@ lmms_SOURCES = \
$(srcdir)/src/core/midi/midi_alsa_raw.cpp \
$(srcdir)/src/core/midi/midi_alsa_seq.cpp \
$(srcdir)/src/core/midi/midi_client.cpp \
$(srcdir)/src/core/midi/midi_controller.cpp \
$(srcdir)/src/core/midi/midi_controller.cpp \
$(srcdir)/src/core/midi/midi_mapper.cpp \
$(srcdir)/src/core/midi/midi_oss.cpp \
$(srcdir)/src/core/midi/midi_port.cpp \
@@ -310,6 +308,7 @@ lmms_SOURCES = \
$(srcdir)/src/gui/widgets/lcd_spinbox.cpp \
$(srcdir)/src/gui/widgets/led_checkbox.cpp \
$(srcdir)/src/gui/widgets/meter_dialog.cpp \
$(srcdir)/src/gui/widgets/midi_port_menu.cpp \
$(srcdir)/src/gui/widgets/name_label.cpp \
$(srcdir)/src/gui/widgets/nstate_button.cpp \
$(srcdir)/src/gui/widgets/pixmap_button.cpp \
@@ -414,10 +413,11 @@ lmms_SOURCES = \
$(srcdir)/include/midi.h \
$(srcdir)/include/midi_alsa_raw.h \
$(srcdir)/include/midi_client.h \
$(srcdir)/include/midi_controller.h \
$(srcdir)/include/midi_controller.h \
$(srcdir)/include/midi_event_processor.h \
$(srcdir)/include/midi_oss.h \
$(srcdir)/include/midi_port.h \
$(srcdir)/include/midi_port_menu.h \
$(srcdir)/include/midi_time.h \
$(srcdir)/include/clipboard.h \
$(srcdir)/include/types.h \
@@ -449,7 +449,6 @@ lmms_SOURCES = \
$(srcdir)/include/dummy_instrument.h \
$(srcdir)/include/instrument_play_handle.h \
$(srcdir)/include/string_pair_drag.h \
$(srcdir)/include/instrument_midi_io.h \
$(srcdir)/include/instrument_midi_io_view.h \
$(srcdir)/include/audio_port.h \
$(srcdir)/include/tool.h \
@@ -491,7 +490,7 @@ lmms_SOURCES = \
$(srcdir)/include/ladspa_control_view.h \
$(srcdir)/include/ladspa_base.h \
$(srcdir)/include/controller.h \
$(srcdir)/include/controller_connection.h \
$(srcdir)/include/controller_connection.h \
$(srcdir)/include/controller_rack_view.h \
$(srcdir)/include/controller_view.h \
$(srcdir)/include/controller_dialog.h \

View File

@@ -38,11 +38,12 @@
class QLineEdit;
class QListView;
class QScrollArea;
class autoDetectMidiController;
class comboBox;
class groupBox;
class lcdSpinBox;
class ledCheckBox;
class comboBox;
class autoDetectMidiController;
class midiPortMenu;
@@ -69,16 +70,13 @@ public slots:
protected slots:
void midiValueChanged( void );
void activatedReadablePort( QAction * _item );
void updateReadablePortsMenu( void );
private:
groupBox * m_midiGroupBox;
lcdSpinBox * m_midiChannelSpinBox;
lcdSpinBox * m_midiControllerSpinBox;
ledCheckBox * m_midiAutoDetectCheckBox;
QMenu * m_readablePorts;
midiPortMenu * m_readablePorts;
boolModel m_midiAutoDetect;
groupBox * m_userGroupBox;

View File

@@ -32,30 +32,21 @@
#include "mv_base.h"
class QMenu;
class QAction;
class tabWidget;
class ledCheckBox;
class lcdSpinBox;
class midiPortMenu;
class instrumentMidiIOView : public QWidget, public modelView
{
Q_OBJECT
public:
instrumentMidiIOView( QWidget * _parent );
instrumentMidiIOView( midiPortMenu * _readable_ports_menu,
midiPortMenu * _writable_ports_menu,
QWidget * _parent );
virtual ~instrumentMidiIOView();
protected slots:
void activatedReadablePort( QAction * _item );
void activatedWriteablePort( QAction * _item );
void updateReadablePortsMenu( void );
void updateWriteablePortsMenu( void );
private:
virtual void modelChanged( void );
@@ -67,12 +58,6 @@ private:
ledCheckBox * m_defaultVelocityInCheckBox;
ledCheckBox * m_defaultVelocityOutCheckBox;
QMenu * m_readablePorts;
QMenu * m_writeablePorts;
friend class instrumentTrackWindow;
} ;

View File

@@ -32,10 +32,10 @@
#include "audio_port.h"
#include "automatable_model.h"
#include "instrument_functions.h"
#include "instrument_midi_io.h"
#include "instrument_sound_shaping.h"
#include "lcd_spinbox.h"
#include "midi_event_processor.h"
#include "midi_port.h"
#include "mixer.h"
#include "piano.h"
#include "effect_chain.h"
@@ -51,10 +51,10 @@ class effectRackView;
class instrumentSoundShapingView;
class fadeButton;
class instrument;
class instrumentMidiIOView;
class instrumentTrackButton;
class instrumentTrackWindow;
class midiPort;
class instrumentMidiIOView;
class midiPortMenu;
class notePlayHandle;
class pluginView;
class presetPreviewPlayHandle;
@@ -167,8 +167,8 @@ protected slots:
private:
midiPort * m_midiPort;
audioPort m_audioPort;
midiPort m_midiPort;
notePlayHandle * m_notes[NumKeys];
@@ -186,7 +186,6 @@ private:
instrumentSoundShaping m_soundShaping;
arpeggiator m_arpeggiator;
chordCreator m_chordCreator;
instrumentMidiIO m_midiIO;
piano m_piano;
@@ -234,6 +233,10 @@ private slots:
void updateName( void );
void midiInSelected( void );
void midiOutSelected( void );
void midiConfigChanged( void );
private:
instrumentTrackWindow * m_window;
@@ -246,6 +249,11 @@ private:
instrumentTrackButton * m_tswInstrumentTrackButton;
QMenu * m_tswMidiMenu;
midiPortMenu * m_readablePortsMenu;
midiPortMenu * m_writablePortsMenu;
QAction * m_midiInputAction;
QAction * m_midiOutputAction;
friend class instrumentTrackButton;
@@ -292,10 +300,6 @@ public slots:
void updateName( void );
void updateInstrumentView( void );
void midiInSelected( void );
void midiOutSelected( void );
void midiConfigChanged( bool );
protected:
// capture close-events for toggling instrument-track-button
@@ -339,9 +343,6 @@ private:
// test-piano at the bottom of every instrument-settings-window
pianoView * m_pianoView;
QAction * m_midiInputAction;
QAction * m_midiOutputAction;
friend class instrumentTrackButton;
friend class instrumentView;

View File

@@ -78,7 +78,7 @@ public:
protected:
virtual void FASTCALL sendByte( const Uint8 _c );
virtual void sendByte( const Uint8 _c );
virtual void run( void );

View File

@@ -70,14 +70,14 @@ public:
virtual void FASTCALL processOutEvent( const midiEvent & _me,
virtual void processOutEvent( const midiEvent & _me,
const midiTime & _time,
const midiPort * _port );
virtual void FASTCALL applyPortMode( midiPort * _port );
virtual void FASTCALL applyPortName( midiPort * _port );
virtual void applyPortMode( midiPort * _port );
virtual void applyPortName( midiPort * _port );
virtual void FASTCALL removePort( midiPort * _port );
virtual void removePort( midiPort * _port );
// list seq-ports from ALSA
@@ -94,10 +94,10 @@ public:
// (un)subscribe given midiPort to/from destination-port
virtual void subscribeReadablePort( midiPort * _port,
const QString & _dest,
bool _unsubscribe = FALSE );
bool _subscribe = TRUE );
virtual void subscribeWriteablePort( midiPort * _port,
const QString & _dest,
bool _unsubscribe = FALSE );
bool _subscribe = TRUE );
virtual void connectRPChanged( QObject * _receiver,
const char * _member )
{

View File

@@ -1,7 +1,7 @@
/*
* midi_client.h - base-class for MIDI-clients like ALSA-sequencer-client
*
* Copyright (c) 2005-2007 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2005-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -46,24 +46,19 @@ public:
virtual ~midiClient();
// to be implemented by sub-classes
virtual void FASTCALL processOutEvent( const midiEvent & _me,
virtual void processOutEvent( const midiEvent & _me,
const midiTime & _time,
const midiPort * _port ) = 0;
// inheriting classes can re-implement this for being able to update
// their internal port-structures etc.
virtual void FASTCALL applyPortMode( midiPort * _port );
virtual void FASTCALL applyPortName( midiPort * _port );
virtual void applyPortMode( midiPort * _port );
virtual void applyPortName( midiPort * _port );
// inheriting classes can re-implement this although it's actually not
// neccessary, because they can catch port-mode-changes and do their
// stuff as soon as port-mode changes from DUMMY to something else
// re-implemented methods HAVE to call addPort() of base-class!!
virtual midiPort * FASTCALL addPort( midiEventProcessor * _mep,
const QString & _name );
virtual void addPort( midiPort * _port );
// re-implemented methods HAVE to call removePort() of base-class!!
virtual void FASTCALL removePort( midiPort * _port );
virtual void removePort( midiPort * _port );
// returns whether client works with raw-MIDI, only needs to be
@@ -80,10 +75,10 @@ public:
// (un)subscribe given midiPort to/from destination-port
virtual void subscribeReadablePort( midiPort * _port,
const QString & _dest,
bool _unsubscribe = FALSE );
bool _subscribe = TRUE );
virtual void subscribeWriteablePort( midiPort * _port,
const QString & _dest,
bool _unsubscribe = FALSE );
bool _subscribe = TRUE );
// qobject-derived classes can use this for make a slot being
// connected to signal of non-raw-MIDI-client if port-lists change
@@ -152,22 +147,22 @@ public:
protected:
// generic raw-MIDI-parser which generates appropriate MIDI-events
void FASTCALL parseData( const Uint8 _c );
void parseData( const Uint8 _c );
// to be implemented by actual client-implementation
virtual void FASTCALL sendByte( const Uint8 _c ) = 0;
virtual void sendByte( const Uint8 _c ) = 0;
private:
// this does MIDI-event-process
void processParsedEvent();
virtual void FASTCALL processOutEvent( const midiEvent & _me,
virtual void processOutEvent( const midiEvent & _me,
const midiTime & _time,
const midiPort * _port );
// small helper function returning length of a certain event - this
// is neccessary for parsing raw-MIDI-data
static Uint8 FASTCALL eventLength( const Uint8 _event );
static Uint8 eventLength( const Uint8 _event );
// data being used for parsing

View File

@@ -26,13 +26,11 @@
#define _MIDI_CONTROLLER_H
#include <QtGui/QWidget>
#include <QtCore/QMap>
#include "mv_base.h"
#include "automatable_model.h"
#include "controller.h"
#include "controller_dialog.h"
#include "midi_event_processor.h"
#include "midi_port.h"
class midiPort;
@@ -42,18 +40,16 @@ class midiController : public controller, public midiEventProcessor
{
Q_OBJECT
public:
typedef QMap<QString, bool> midiPortMap;
midiController( model * _parent );
virtual ~midiController();
#warning TODO: use displayName-property!
virtual QString publicName() const
{
return "MIDI Controller";
}
virtual void processInEvent( const midiEvent & _me,
const midiTime & _time,
bool _lock = TRUE );
@@ -68,45 +64,29 @@ public:
virtual void loadSettings( const QDomElement & _this );
virtual QString nodeName( void ) const;
virtual intModel * midiChannelModel( void )
{
return &m_midiChannel;
}
virtual intModel * midiControllerModel( void )
{
return &m_midiController;
}
virtual midiPort * getMidiPort( void )
{
return m_midiPort;
}
// Used by controllerConnectionDialog to copy
virtual void setReadablePorts( const midiPortMap & _map );
void subscribeReadablePorts( const midiPort::map & _map );
public slots:
virtual controllerDialog * createDialog( QWidget * _parent );
void updateMidiPort( void );
void updateReadablePorts( void );
void updateName( void );
protected:
// The internal per-controller get-value function
virtual float value( int _offset );
intModel m_midiChannel;
intModel m_midiController;
midiPort * m_midiPort;
midiPortMap m_readablePorts;
midiPort m_midiPort;
float m_lastValue;
friend class controllerConnectionDialog;
};
friend class autoDetectMidiController;
} ;
#endif

View File

@@ -1,100 +0,0 @@
/*
* instrument_midi_io.h - class instrumentMidiIO
*
* Copyright (c) 2005-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#ifndef _INSTRUMENT_MIDI_IO_H
#define _INSTRUMENT_MIDI_IO_H
#include <QtCore/QList>
#include <QtCore/QPair>
#include "automatable_model.h"
class instrumentTrack;
class midiPort;
class instrumentMidiIO : public model, public journallingObject
{
Q_OBJECT
public:
typedef QPair<QString, bool> descriptiveMidiPort;
typedef QList<descriptiveMidiPort> midiPortMap;
instrumentMidiIO( instrumentTrack * _instrument_track,
midiPort * _port );
virtual ~instrumentMidiIO();
virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent );
virtual void loadSettings( const QDomElement & _this );
virtual QString nodeName( void ) const
{
return( "midi" );
}
signals:
void readablePortsChanged( void );
void writeablePortsChanged( void );
public slots:
void updateMidiPortMode( void );
protected slots:
void updateInputChannel( void );
void updateOutputChannel( void );
void updateDefaultVelIn( void );
void updateDefaultVelOut( void );
void updateReadablePorts( void );
void updateWriteablePorts( void );
void activatedReadablePort( const descriptiveMidiPort & _port );
void activatedWriteablePort( const descriptiveMidiPort & _port );
private:
instrumentTrack * m_instrumentTrack;
midiPort * m_midiPort;
intModel m_inputChannelModel;
intModel m_outputChannelModel;
boolModel m_receiveEnabledModel;
boolModel m_sendEnabledModel;
boolModel m_defaultVelocityInEnabledModel;
boolModel m_defaultVelocityOutEnabledModel;
midiPortMap m_readablePorts;
midiPortMap m_writeablePorts;
friend class instrumentMidiIOView;
} ;
#endif

View File

@@ -71,7 +71,7 @@ public:
protected:
virtual void FASTCALL sendByte( const Uint8 _c );
virtual void sendByte( const Uint8 _c );
virtual void run( void );

View File

@@ -2,7 +2,7 @@
* midi_port.h - abstraction of MIDI-ports which are part of LMMS's MIDI-
* sequencing system
*
* Copyright (c) 2005-2007 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2005-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -28,14 +28,11 @@
#define _MIDI_PORT_H
#include <QtCore/QString>
#include <QtCore/QList>
#include <QtCore/QPair>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "types.h"
#include "midi.h"
#include "automatable_model.h"
class midiClient;
@@ -44,9 +41,22 @@ class midiTime;
// class for abstraction of MIDI-port
class midiPort
class midiPort : public model, public serializingObject
{
Q_OBJECT
mapPropertyFromModel(int,inputChannel,setInputChannel,
m_inputChannelModel);
mapPropertyFromModel(int,outputChannel,setOutputChannel,
m_outputChannelModel);
mapPropertyFromModel(int,inputController,setInputController,
m_inputControllerModel);
mapPropertyFromModel(int,outputController,setOutputController,
m_outputControllerModel);
mapPropertyFromModel(bool,isReadable,setReadable,m_readableModel);
mapPropertyFromModel(bool,isWritable,setWritable,m_writableModel);
public:
typedef QMap<QString, bool> map;
enum Modes
{
Disabled, // don't route any MIDI-events (default)
@@ -55,71 +65,105 @@ public:
Duplex // both directions
} ;
midiPort( midiClient * _mc, midiEventProcessor * _mep,
const QString & _name, Modes _mode = Disabled );
~midiPort();
midiPort( const QString & _name,
midiClient * _mc,
midiEventProcessor * _mep,
model * _parent = NULL,
track * _track = NULL,
Modes _mode = Disabled );
virtual ~midiPort();
inline const QString & name( void ) const
{
return( m_name );
}
void FASTCALL setName( const QString & _name );
void setName( const QString & _name );
inline Modes mode( void ) const
{
return( m_mode );
}
void FASTCALL setMode( Modes _mode );
inline Sint8 inputChannel( void ) const
{
return( m_inputChannel );
}
inline void setInputChannel( Sint8 _chnl )
{
m_inputChannel = _chnl;
}
void setMode( Modes _mode );
inline void enableDefaultVelocityForInEvents( const bool _on )
{
m_defaultVelocityForInEventsEnabled = _on;
}
inline Sint8 outputChannel( void ) const
{
return( m_outputChannel );
}
inline void setOutputChannel( Sint8 _chnl )
{
m_outputChannel = _chnl;
m_defaultVelocityInEnabledModel.setValue( _on );
}
inline void enableDefaultVelocityForOutEvents( const bool _on )
{
m_defaultVelocityForOutEventsEnabled = _on;
m_defaultVelocityOutEnabledModel.setValue( _on );
}
void processInEvent( const midiEvent & _me, const midiTime & _time );
void processOutEvent( const midiEvent & _me, const midiTime & _time );
void FASTCALL processInEvent( const midiEvent & _me,
const midiTime & _time );
void FASTCALL processOutEvent( const midiEvent & _me,
const midiTime & _time );
virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent );
virtual void loadSettings( const QDomElement & _this );
virtual QString nodeName( void ) const
{
return( "midiport" );
}
void subscribeReadablePort( const QString & _port,
bool _subscribe = TRUE );
void subscribeWriteablePort( const QString & _port,
bool _subscribe = TRUE );
const map & readablePorts( void ) const
{
return( m_readablePorts );
}
const map & writablePorts( void ) const
{
return( m_writablePorts );
}
signals:
void readablePortsChanged( void );
void writeablePortsChanged( void );
void modeChanged( void );
public slots:
void updateMidiPortMode( void );
private slots:
void updateReadablePorts( void );
void updateWriteablePorts( void );
private:
midiClient * m_midiClient;
midiEventProcessor * m_midiEventProcessor;
QString m_name;
QString m_name; // TODO: replace with model-name-property!
Modes m_mode;
Sint8 m_inputChannel;
Sint8 m_outputChannel;
bool m_defaultVelocityForInEventsEnabled;
bool m_defaultVelocityForOutEventsEnabled;
intModel m_inputChannelModel;
intModel m_outputChannelModel;
intModel m_inputControllerModel;
intModel m_outputControllerModel;
boolModel m_readableModel;
boolModel m_writableModel;
boolModel m_defaultVelocityInEnabledModel;
boolModel m_defaultVelocityOutEnabledModel;
map m_readablePorts;
map m_writablePorts;
friend class controllerConnectionDialog;
friend class instrumentMidiIOView;
} ;

60
include/midi_port_menu.h Normal file
View File

@@ -0,0 +1,60 @@
/*
* midi_port_menu.h - a menu for subscribing a midiPort to several external
* MIDI ports
*
* Copyright (c) 2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#ifndef _MIDI_PORT_MENU_H
#define _MIDI_PORT_MENU_H
#include <QtGui/QMenu>
#include "mv_base.h"
#include "midi_port.h"
class QAction;
class midiPortMenu : public QMenu, public modelView
{
Q_OBJECT
public:
midiPortMenu( midiPort::Modes _mode );
virtual ~midiPortMenu();
protected slots:
void activatedPort( QAction * _item );
void updatePorts( void );
private:
virtual void modelChanged( void );
midiPort::Modes m_mode;
} ;
#endif

View File

@@ -323,7 +323,7 @@ void midiALSASeq::removePort( midiPort * _port )
void midiALSASeq::subscribeReadablePort( midiPort * _port,
const QString & _dest,
bool _unsubscribe )
bool _subscribe )
{
if( m_portIDs.contains( _port ) == FALSE ||
( _port->mode() != midiPort::Input &&
@@ -346,13 +346,13 @@ void midiALSASeq::subscribeReadablePort( midiPort * _port,
snd_seq_port_subscribe_malloc( &subs );
snd_seq_port_subscribe_set_sender( subs, &sender );
snd_seq_port_subscribe_set_dest( subs, dest );
if( _unsubscribe )
if( _subscribe )
{
snd_seq_unsubscribe_port( m_seqHandle, subs );
snd_seq_subscribe_port( m_seqHandle, subs );
}
else
{
snd_seq_subscribe_port( m_seqHandle, subs );
snd_seq_unsubscribe_port( m_seqHandle, subs );
}
snd_seq_port_subscribe_free( subs );
snd_seq_port_info_free( port_info );
@@ -363,7 +363,7 @@ void midiALSASeq::subscribeReadablePort( midiPort * _port,
void midiALSASeq::subscribeWriteablePort( midiPort * _port,
const QString & _dest,
bool _unsubscribe )
bool _subscribe )
{
if( m_portIDs.contains( _port ) == FALSE ||
( _port->mode() != midiPort::Output &&
@@ -389,13 +389,13 @@ void midiALSASeq::subscribeWriteablePort( midiPort * _port,
snd_seq_port_subscribe_malloc( &subs );
snd_seq_port_subscribe_set_sender( subs, sender );
snd_seq_port_subscribe_set_dest( subs, &dest );
if( _unsubscribe )
if( _subscribe )
{
snd_seq_unsubscribe_port( m_seqHandle, subs );
snd_seq_subscribe_port( m_seqHandle, subs );
}
else
{
snd_seq_subscribe_port( m_seqHandle, subs );
snd_seq_unsubscribe_port( m_seqHandle, subs );
}
snd_seq_port_subscribe_free( subs );
snd_seq_port_info_free( port_info );

View File

@@ -64,12 +64,9 @@ void midiClient::applyPortName( midiPort * )
midiPort * midiClient::addPort( midiEventProcessor * _mep,
const QString & _name )
void midiClient::addPort( midiPort * _port )
{
midiPort * port = new midiPort( this, _mep, _name );
m_midiPorts.push_back( port );
return( port );
m_midiPorts.push_back( _port );
}
@@ -82,7 +79,6 @@ void midiClient::removePort( midiPort * _port )
_port );
if( it != m_midiPorts.end() )
{
delete *it;
m_midiPorts.erase( it );
}
}

View File

@@ -34,7 +34,6 @@
#include "engine.h"
#include "mixer.h"
#include "midi_client.h"
#include "midi_port.h"
#include "midi_controller.h"
@@ -42,34 +41,19 @@
midiController::midiController( model * _parent ) :
controller( MidiController, _parent ),
midiEventProcessor(),
m_midiChannel( 0, 0, MIDI_CHANNEL_COUNT, this ),
m_midiController( 0, 0, MIDI_CONTROLLER_COUNT, this ),
m_midiPort( engine::getMixer()->getMIDIClient()->addPort(
this, tr( "unnamed_midi_controller" ) ) ),
m_midiPort( tr( "unnamed_midi_controller" ),
engine::getMixer()->getMIDIClient(), this,
this, NULL, midiPort::Input ),
m_lastValue( 0.0f )
{
m_midiPort->setMode( midiPort::Input );
midiClient * mc = engine::getMixer()->getMIDIClient();
if( mc->isRaw() == FALSE )
{
updateReadablePorts();
}
connect( &m_midiChannel, SIGNAL( dataChanged() ),
this, SLOT( updateMidiPort() ) );
connect( &m_midiController, SIGNAL( dataChanged() ),
this, SLOT( updateMidiPort() ) );
connect( &m_midiPort, SIGNAL( modeChanged() ),
this, SLOT( updateName() ) );
}
midiController::~midiController()
{
m_midiChannel.disconnect( this );
m_midiController.disconnect( this );
engine::getMixer()->getMIDIClient()->removePort( m_midiPort );
}
@@ -83,12 +67,11 @@ float midiController::value( int _offset )
void midiController::updateMidiPort( void )
void midiController::updateName( void )
{
m_midiPort->setInputChannel( m_midiChannel.value() - 1 );
setName( QString("MIDI ch%1 ctrl%2").
arg( m_midiChannel.value() ).
arg( m_midiController.value() ) );
arg( m_midiPort.inputChannel() ).
arg( m_midiPort.inputController() ) );
}
@@ -105,9 +88,9 @@ void midiController::processInEvent( const midiEvent & _me,
bytes = _me.m_data.m_bytes;
controllerNum = _me.m_data.m_bytes[0] & 0x7F;
if( m_midiController.value() == controllerNum + 1 &&
( m_midiChannel.value() == _me.m_channel + 1 ||
m_midiChannel.value() == 0 ) )
if( m_midiPort.inputController() == controllerNum + 1 &&
( m_midiPort.inputChannel() == _me.m_channel + 1 ||
m_midiPort.inputChannel() == 0 ) )
{
Uint8 val = _me.m_data.m_bytes[2] & 0x7F;
m_lastValue = (float)( val ) / 127.0f;
@@ -124,43 +107,13 @@ void midiController::processInEvent( const midiEvent & _me,
void midiController::setReadablePorts( const midiPortMap & _map )
void midiController::subscribeReadablePorts( const midiPort::map & _map )
{
m_readablePorts.clear();
for( midiPortMap::const_iterator it = _map.constBegin();
it != _map.constEnd(); ++it )
for( midiPort::map::const_iterator it = _map.constBegin();
it != _map.constEnd(); ++it )
{
engine::getMixer()->getMIDIClient()->subscribeReadablePort(
m_midiPort, it.key(), !( *it ) );
m_midiPort.subscribeReadablePort( it.key(), *it );
}
m_readablePorts = _map;
}
void midiController::updateReadablePorts( void )
{
// first save all selected ports
QStringList selected_ports;
for( midiPortMap::const_iterator i = m_readablePorts.constBegin();
i != m_readablePorts.constEnd(); ++i )
{
selected_ports.push_back( i.key() );
++i;
}
m_readablePorts.clear();
const QStringList & wp = engine::getMixer()->getMIDIClient()->
readablePorts();
// now insert new ports and restore selections
for( QStringList::const_iterator it = wp.begin(); it != wp.end(); ++it )
{
m_readablePorts[ *it ] = ( selected_ports.indexOf( *it ) != -1 );
}
//emit readablePortsChanged();
}
@@ -169,28 +122,8 @@ void midiController::updateReadablePorts( void )
void midiController::saveSettings( QDomDocument & _doc, QDomElement & _this )
{
controller::saveSettings( _doc, _this );
m_midiPort.saveSettings( _doc, _this );
m_midiChannel.saveSettings( _doc, _this, "channel" );
m_midiController.saveSettings( _doc, _this, "controller" );
if( m_readablePorts.size() )
{
QString rp;
for( midiPortMap::const_iterator it = m_readablePorts.constBegin();
it != m_readablePorts.constEnd(); ++it )
{
if( *it )
{
rp += it.key() + ",";
}
}
// cut off comma
if( rp.length() > 0 )
{
rp.truncate( rp.length() - 1 );
}
_this.setAttribute( "inports", rp );
}
}
@@ -200,28 +133,9 @@ void midiController::loadSettings( const QDomElement & _this )
{
controller::loadSettings( _this );
m_midiChannel.loadSettings( _this, "channel" );
m_midiController.loadSettings( _this, "controller" );
m_midiPort.loadSettings( _this );
midiClient * mc = engine::getMixer()->getMIDIClient();
if( mc->isRaw() == FALSE )
{
//updateReadablePorts();
QStringList rp = _this.attribute( "inports" ).split( ',' );
for( midiPortMap::iterator it = m_readablePorts.begin();
it != m_readablePorts.end(); ++it )
{
if( rp.indexOf( it.key() ) != -1 )
{
*it = TRUE;
engine::getMixer()->getMIDIClient()->subscribeReadablePort(
m_midiPort, it.key(), !( *it ) );
}
}
}
updateMidiPort();
updateName();
}

View File

@@ -1,374 +0,0 @@
#ifndef SINGLE_SOURCE_COMPILE
/*
* instrument_midi_io.cpp - class instrumentMidiIO
*
* Copyright (c) 2005-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#include <Qt/QtXml>
#include "instrument_midi_io.h"
#include "engine.h"
#include "instrument_track.h"
#include "midi_client.h"
#include "midi_port.h"
#include "song.h"
instrumentMidiIO::instrumentMidiIO( instrumentTrack * _instrument_track,
midiPort * _port ) :
model( _instrument_track ),
m_instrumentTrack( _instrument_track ),
m_midiPort( _port ),
m_inputChannelModel( m_midiPort->inputChannel() + 1,
0, MIDI_CHANNEL_COUNT, this ),
m_outputChannelModel( m_midiPort->outputChannel() + 1,
1, MIDI_CHANNEL_COUNT, this ),
m_receiveEnabledModel( FALSE, this ),
m_sendEnabledModel( FALSE, this ),
m_defaultVelocityInEnabledModel( FALSE, this ),
m_defaultVelocityOutEnabledModel( FALSE, this )
{
m_inputChannelModel.setTrack( m_instrumentTrack );
m_outputChannelModel.setTrack( m_instrumentTrack );
m_receiveEnabledModel.setTrack( m_instrumentTrack );
m_defaultVelocityInEnabledModel.setTrack( m_instrumentTrack );
m_sendEnabledModel.setTrack( m_instrumentTrack );
m_defaultVelocityOutEnabledModel.setTrack( m_instrumentTrack );
connect( &m_inputChannelModel, SIGNAL( dataChanged() ),
this, SLOT( updateInputChannel() ) );
connect( &m_outputChannelModel, SIGNAL( dataChanged() ),
this, SLOT( updateOutputChannel() ) );
connect( &m_receiveEnabledModel, SIGNAL( dataChanged() ),
this, SLOT( updateMidiPortMode() ) );
connect( &m_defaultVelocityInEnabledModel, SIGNAL( dataChanged() ),
this, SLOT( updateDefaultVelIn() ) );
connect( &m_sendEnabledModel, SIGNAL( dataChanged() ),
this, SLOT( updateMidiPortMode() ) );
connect( &m_defaultVelocityOutEnabledModel, SIGNAL( dataChanged() ),
this, SLOT( updateDefaultVelOut() ) );
updateInputChannel();
updateOutputChannel();
const midiPort::Modes m = m_midiPort->mode();
m_receiveEnabledModel.setValue( m == midiPort::Input ||
m == midiPort::Duplex );
m_sendEnabledModel.setValue( m == midiPort::Output ||
m == midiPort::Duplex );
// when using with non-raw-clients we can provide buttons showing
// our port-menus when being clicked
midiClient * mc = engine::getMixer()->getMIDIClient();
if( mc->isRaw() == FALSE )
{
updateReadablePorts();
updateWriteablePorts();
// we want to get informed about port-changes!
mc->connectRPChanged( this, SLOT( updateReadablePorts() ) );
mc->connectWPChanged( this, SLOT( updateWriteablePorts() ) );
}
}
instrumentMidiIO::~instrumentMidiIO()
{
}
void instrumentMidiIO::saveSettings( QDomDocument & _doc, QDomElement & _this )
{
m_inputChannelModel.saveSettings( _doc, _this, "inputchannel" );
m_outputChannelModel.saveSettings( _doc, _this, "outputchannel" );
m_receiveEnabledModel.saveSettings( _doc, _this, "receive" );
m_sendEnabledModel.saveSettings( _doc, _this, "send" );
m_defaultVelocityInEnabledModel.saveSettings( _doc, _this, "defvelin" );
m_defaultVelocityOutEnabledModel.saveSettings( _doc, _this,
"defvelout" );
if( m_receiveEnabledModel.value() == TRUE )
{
QString rp;
for( midiPortMap::iterator it = m_readablePorts.begin();
it != m_readablePorts.end(); ++it )
{
if( it->second )
{
rp += it->first + ",";
}
}
// cut off comma
if( rp.length() > 0 )
{
rp.truncate( rp.length() - 1 );
}
_this.setAttribute( "inports", rp );
}
if( m_sendEnabledModel.value() == TRUE )
{
QString wp;
for( midiPortMap::iterator it = m_writeablePorts.begin();
it != m_writeablePorts.end(); ++it )
{
if( it->second )
{
wp += it->first + ",";
}
}
// cut off comma
if( wp.length() > 0 )
{
wp.truncate( wp.length() - 1 );
}
_this.setAttribute( "outports", wp );
}
}
void instrumentMidiIO::loadSettings( const QDomElement & _this )
{
m_inputChannelModel.loadSettings( _this, "inputchannel" );
m_outputChannelModel.loadSettings( _this, "outputchannel" );
m_receiveEnabledModel.loadSettings( _this, "receive" );
m_sendEnabledModel.loadSettings( _this, "send" );
m_defaultVelocityInEnabledModel.loadSettings( _this, "defvelin" );
m_defaultVelocityOutEnabledModel.loadSettings( _this, "defvelout" );
// restore connections
if( m_receiveEnabledModel.value() == TRUE )
{
QStringList rp = _this.attribute( "inports" ).split( ',' );
for( midiPortMap::iterator it = m_readablePorts.begin();
it != m_readablePorts.end(); ++it )
{
if( it->second != ( rp.indexOf( it->first ) != -1 ) )
{
it->second = TRUE;
activatedReadablePort( *it );
}
}
}
if( m_sendEnabledModel.value() == TRUE )
{
QStringList wp = _this.attribute( "outports" ).split( ',' );
for( midiPortMap::iterator it = m_writeablePorts.begin();
it != m_writeablePorts.end(); ++it )
{
if( it->second != ( wp.indexOf( it->first ) != -1 ) )
{
it->second = TRUE;
activatedWriteablePort( *it );
}
}
}
}
void instrumentMidiIO::updateInputChannel( void )
{
m_midiPort->setInputChannel( m_inputChannelModel.value() - 1 );
engine::getSong()->setModified();
}
void instrumentMidiIO::updateOutputChannel( void )
{
m_midiPort->setOutputChannel( m_outputChannelModel.value() - 1 );
engine::getSong()->setModified();
}
void instrumentMidiIO::updateDefaultVelIn( void )
{
m_midiPort->enableDefaultVelocityForInEvents(
m_defaultVelocityInEnabledModel.value() );
}
void instrumentMidiIO::updateDefaultVelOut( void )
{
m_midiPort->enableDefaultVelocityForOutEvents(
m_defaultVelocityOutEnabledModel.value() );
}
void instrumentMidiIO::updateMidiPortMode( void )
{
// this small lookup-table makes everything easier
static const midiPort::Modes modeTable[2][2] =
{
{ midiPort::Disabled, midiPort::Output },
{ midiPort::Input, midiPort::Duplex }
} ;
m_midiPort->setMode( modeTable[m_receiveEnabledModel.value()]
[m_sendEnabledModel.value()] );
// check whether we have to dis-check items in connection-menu
if( m_receiveEnabledModel.value() == FALSE )
{
for( midiPortMap::iterator it = m_readablePorts.begin();
it != m_readablePorts.end(); ++it )
{
if( it->second == TRUE )
{
it->second = FALSE;
activatedReadablePort( *it );
}
}
}
if( m_sendEnabledModel.value() == FALSE )
{
for( midiPortMap::iterator it = m_writeablePorts.begin();
it != m_writeablePorts.end(); ++it )
{
if( it->second == TRUE )
{
it->second = FALSE;
activatedWriteablePort( *it );
}
}
}
engine::getSong()->setModified();
}
void instrumentMidiIO::updateReadablePorts( void )
{
// first save all selected ports
QStringList selected_ports;
for( midiPortMap::iterator it = m_readablePorts.begin();
it != m_readablePorts.end(); ++it )
{
if( it->second == TRUE )
{
selected_ports.push_back( it->first );
}
}
m_readablePorts.clear();
const QStringList & wp = engine::getMixer()->getMIDIClient()->
readablePorts();
// now insert new ports and restore selections
for( QStringList::const_iterator it = wp.begin(); it != wp.end(); ++it )
{
m_readablePorts.push_back( qMakePair( *it,
selected_ports.indexOf( *it ) != -1 ) );
}
emit readablePortsChanged();
}
void instrumentMidiIO::updateWriteablePorts( void )
{
// first save all selected ports
QStringList selected_ports;
for( midiPortMap::iterator it = m_writeablePorts.begin();
it != m_writeablePorts.end(); ++it )
{
if( it->second == TRUE )
{
selected_ports.push_back( it->first );
}
}
m_writeablePorts.clear();
const QStringList & wp = engine::getMixer()->getMIDIClient()->
writeablePorts();
// now insert new ports and restore selections
for( QStringList::const_iterator it = wp.begin(); it != wp.end(); ++it )
{
m_writeablePorts.push_back( qMakePair( *it,
selected_ports.indexOf( *it ) != -1 ) );
}
emit writeablePortsChanged();
}
void instrumentMidiIO::activatedReadablePort(
const descriptiveMidiPort & _port )
{
// make sure, MIDI-port is configured for input
if( _port.second == TRUE &&
m_midiPort->mode() != midiPort::Input &&
m_midiPort->mode() != midiPort::Duplex )
{
m_receiveEnabledModel.setValue( TRUE );
}
engine::getMixer()->getMIDIClient()->subscribeReadablePort( m_midiPort,
_port.first, !_port.second );
}
void instrumentMidiIO::activatedWriteablePort(
const descriptiveMidiPort & _port )
{
// make sure, MIDI-port is configured for output
if( _port.second == TRUE &&
m_midiPort->mode() != midiPort::Output &&
m_midiPort->mode() != midiPort::Duplex )
{
m_sendEnabledModel.setValue( TRUE );
}
engine::getMixer()->getMIDIClient()->subscribeWriteablePort( m_midiPort,
_port.first, !_port.second );
}
#include "instrument_midi_io.moc"
#endif

View File

@@ -26,23 +26,62 @@
*/
#include <Qt/QtXml>
#include "midi_port.h"
#include "midi_client.h"
#include "volume.h"
#include "song.h"
midiPort::midiPort( midiClient * _mc, midiEventProcessor * _mep,
const QString & _name, Modes _mode ) :
midiPort::midiPort( const QString & _name, midiClient * _mc,
midiEventProcessor * _mep, model * _parent,
track * _track, Modes _mode ) :
model( _parent ),
m_midiClient( _mc ),
m_midiEventProcessor( _mep ),
m_name( _name ),
m_mode( _mode ),
m_inputChannel( -1 ),
m_outputChannel( -1 ),
m_defaultVelocityForInEventsEnabled( FALSE ),
m_defaultVelocityForOutEventsEnabled( FALSE )
m_inputChannelModel( 0, 0, MIDI_CHANNEL_COUNT, this ),
m_outputChannelModel( 1, 1, MIDI_CHANNEL_COUNT, this ),
m_inputControllerModel( 0, 0, MIDI_CONTROLLER_COUNT, this ),
m_outputControllerModel( 0, 0, MIDI_CONTROLLER_COUNT, this ),
m_readableModel( FALSE, this ),
m_writableModel( FALSE, this ),
m_defaultVelocityInEnabledModel( FALSE, this ),
m_defaultVelocityOutEnabledModel( FALSE, this )
{
m_midiClient->addPort( this );
m_inputChannelModel.setTrack( _track );
m_outputChannelModel.setTrack( _track );
m_defaultVelocityInEnabledModel.setTrack( _track );
m_defaultVelocityOutEnabledModel.setTrack( _track );
m_readableModel.setValue( m_mode == Input || m_mode == Duplex );
m_writableModel.setValue( m_mode == Output || m_mode == Duplex );
connect( &m_readableModel, SIGNAL( dataChanged() ),
this, SLOT( updateMidiPortMode() ) );
connect( &m_writableModel, SIGNAL( dataChanged() ),
this, SLOT( updateMidiPortMode() ) );
// when using with non-raw-clients we can provide buttons showing
// our port-menus when being clicked
if( m_midiClient->isRaw() == FALSE )
{
updateReadablePorts();
updateWriteablePorts();
// we want to get informed about port-changes!
m_midiClient->connectRPChanged( this,
SLOT( updateReadablePorts() ) );
m_midiClient->connectWPChanged( this,
SLOT( updateWriteablePorts() ) );
}
updateMidiPortMode();
}
@@ -50,6 +89,7 @@ midiPort::midiPort( midiClient * _mc, midiEventProcessor * _mep,
midiPort::~midiPort()
{
m_midiClient->removePort( this );
}
@@ -77,10 +117,10 @@ void midiPort::processInEvent( const midiEvent & _me, const midiTime & _time )
{
// mask event
if( ( mode() == Input || mode() == Duplex ) &&
( inputChannel() == _me.m_channel || inputChannel() == -1 ) )
( inputChannel()-1 == _me.m_channel || inputChannel() == 0 ) )
{
midiEvent ev = _me;
if( m_defaultVelocityForInEventsEnabled == TRUE &&
if( m_defaultVelocityInEnabledModel.value() == TRUE &&
_me.velocity() > 0 )
{
ev.velocity() = DefaultVolume;
@@ -96,10 +136,10 @@ void midiPort::processOutEvent( const midiEvent & _me, const midiTime & _time )
{
// mask event
if( ( mode() == Output || mode() == Duplex ) &&
( outputChannel() == _me.m_channel && outputChannel() != -1 ) )
( outputChannel()-1 == _me.m_channel && outputChannel() != 0 ) )
{
midiEvent ev = _me;
if( m_defaultVelocityForOutEventsEnabled == TRUE &&
if( m_defaultVelocityOutEnabledModel.value() == TRUE &&
_me.velocity() > 0 )
{
ev.velocity() = DefaultVolume;
@@ -110,4 +150,231 @@ void midiPort::processOutEvent( const midiEvent & _me, const midiTime & _time )
void midiPort::saveSettings( QDomDocument & _doc, QDomElement & _this )
{
m_inputChannelModel.saveSettings( _doc, _this, "inputchannel" );
m_outputChannelModel.saveSettings( _doc, _this, "outputchannel" );
m_inputControllerModel.saveSettings( _doc, _this, "inputcontroller" );
m_outputControllerModel.saveSettings( _doc, _this, "outputcontroller" );
m_readableModel.saveSettings( _doc, _this, "readable" );
m_writableModel.saveSettings( _doc, _this, "writable" );
m_defaultVelocityInEnabledModel.saveSettings( _doc, _this, "defvelin" );
m_defaultVelocityOutEnabledModel.saveSettings( _doc, _this,
"defvelout" );
if( m_readableModel.value() == TRUE )
{
QString rp;
for( midiPort::map::iterator it = m_readablePorts.begin();
it != m_readablePorts.end(); ++it )
{
if( it.value() )
{
rp += it.key() + ",";
}
}
// cut off comma
if( rp.length() > 0 )
{
rp.truncate( rp.length() - 1 );
}
_this.setAttribute( "inports", rp );
}
if( m_writableModel.value() == TRUE )
{
QString wp;
for( map::const_iterator it = m_writablePorts.begin();
it != m_writablePorts.end(); ++it )
{
if( it.value() )
{
wp += it.key() + ",";
}
}
// cut off comma
if( wp.length() > 0 )
{
wp.truncate( wp.length() - 1 );
}
_this.setAttribute( "outports", wp );
}
}
void midiPort::loadSettings( const QDomElement & _this )
{
m_inputChannelModel.loadSettings( _this, "inputchannel" );
m_outputChannelModel.loadSettings( _this, "outputchannel" );
m_inputControllerModel.loadSettings( _this, "inputcontroller" );
m_outputControllerModel.loadSettings( _this, "outputcontroller" );
m_readableModel.loadSettings( _this, "readable" );
m_writableModel.loadSettings( _this, "writable" );
m_defaultVelocityInEnabledModel.loadSettings( _this, "defvelin" );
m_defaultVelocityOutEnabledModel.loadSettings( _this, "defvelout" );
// restore connections
if( m_readableModel.value() == TRUE )
{
QStringList rp = _this.attribute( "inports" ).split( ',' );
for( map::const_iterator it = m_readablePorts.begin();
it != m_readablePorts.end(); ++it )
{
if( it.value() != ( rp.indexOf( it.key() ) != -1 ) )
{
subscribeReadablePort( it.key() );
}
}
}
if( m_writableModel.value() == TRUE )
{
QStringList wp = _this.attribute( "outports" ).split( ',' );
for( map::const_iterator it = m_writablePorts.begin();
it != m_writablePorts.end(); ++it )
{
if( it.value() != ( wp.indexOf( it.key() ) != -1 ) )
{
subscribeReadablePort( it.key() );
}
}
}
}
void midiPort::updateMidiPortMode( void )
{
// this small lookup-table makes everything easier
static const Modes modeTable[2][2] =
{
{ Disabled, Output },
{ Input, Duplex }
} ;
setMode( modeTable[m_readableModel.value()][m_writableModel.value()] );
// check whether we have to dis-check items in connection-menu
if( m_readableModel.value() == FALSE )
{
for( map::const_iterator it = m_readablePorts.begin();
it != m_readablePorts.end(); ++it )
{
if( it.value() == TRUE )
{
subscribeReadablePort( it.key(), FALSE );
}
}
}
if( m_writableModel.value() == FALSE )
{
for( map::const_iterator it = m_writablePorts.begin();
it != m_writablePorts.end(); ++it )
{
if( it.value() == TRUE )
{
subscribeWriteablePort( it.key(), FALSE );
}
}
}
emit readablePortsChanged();
emit writeablePortsChanged();
emit modeChanged();
engine::getSong()->setModified();
}
void midiPort::updateReadablePorts( void )
{
// first save all selected ports
QStringList selected_ports;
for( midiPort::map::iterator it = m_readablePorts.begin();
it != m_readablePorts.end(); ++it )
{
if( it.value() == TRUE )
{
selected_ports.push_back( it.key() );
}
}
m_readablePorts.clear();
const QStringList & wp = engine::getMixer()->getMIDIClient()->
readablePorts();
// now insert new ports and restore selections
for( QStringList::const_iterator it = wp.begin(); it != wp.end(); ++it )
{
m_readablePorts[*it] = ( selected_ports.indexOf( *it ) != -1 );
}
emit readablePortsChanged();
}
void midiPort::updateWriteablePorts( void )
{
// first save all selected ports
QStringList selected_ports;
for( midiPort::map::iterator it = m_writablePorts.begin();
it != m_writablePorts.end(); ++it )
{
if( it.value() == TRUE )
{
selected_ports.push_back( it.key() );
}
}
m_writablePorts.clear();
const QStringList & wp = engine::getMixer()->getMIDIClient()->
writeablePorts();
// now insert new ports and restore selections
for( QStringList::const_iterator it = wp.begin(); it != wp.end(); ++it )
{
m_writablePorts[*it] = ( selected_ports.indexOf( *it ) != -1 );
}
emit writeablePortsChanged();
}
void midiPort::subscribeReadablePort( const QString & _port, bool _subscribe )
{
m_readablePorts[_port] = _subscribe;
// make sure, MIDI-port is configured for input
if( _subscribe == TRUE && mode() != Input && mode() != Duplex )
{
m_readableModel.setValue( TRUE );
}
m_midiClient->subscribeReadablePort( this, _port, _subscribe );
}
void midiPort::subscribeWriteablePort( const QString & _port, bool _subscribe )
{
m_writablePorts[_port] = _subscribe;
// make sure, MIDI-port is configured for output
if( _subscribe == TRUE && mode() != Output && mode() != Duplex )
{
m_writableModel.setValue( TRUE );
}
m_midiClient->subscribeWriteablePort( this, _port, _subscribe );
}
#include "midi_port.moc"
#endif

View File

@@ -105,7 +105,7 @@ notePlayHandle::notePlayHandle( instrumentTrack * _it,
setFrames( _frames );
// send MIDI-note-on-event
m_instrumentTrack->processOutEvent( midiEvent( NOTE_ON,
m_instrumentTrack->m_midiPort->outputChannel(),
m_instrumentTrack->m_midiPort.outputChannel(),
key(),
tLimit<Uint16>(
(Uint16) ( ( getVolume() / 100.0f ) *
@@ -303,7 +303,7 @@ void notePlayHandle::noteOff( const f_cnt_t _s )
m_instrumentTrack->m_soundShaping.releaseFrames() );
// send MIDI-note-off-event
m_instrumentTrack->processOutEvent( midiEvent( NOTE_OFF,
m_instrumentTrack->m_midiPort->outputChannel(),
m_instrumentTrack->m_midiPort.outputChannel(),
key(), 0 ),
midiTime::fromFrames( m_framesBeforeRelease,
engine::framesPerTick() ) );

View File

@@ -126,7 +126,7 @@ presetPreviewPlayHandle::presetPreviewPlayHandle(
// make sure, our preset-preview-track does not appear in any MIDI-
// devices list, so just disable receiving/sending MIDI-events at all
s_previewTC->previewInstrumentTrack()->m_midiPort->setMode(
s_previewTC->previewInstrumentTrack()->m_midiPort.setMode(
midiPort::Disabled );
// create note-play-handle for it

View File

@@ -117,6 +117,8 @@ song::song( void ) :
/* connect( &m_masterPitchModel, SIGNAL( dataChanged() ),
this, SLOT( masterPitchChanged() ) );*/
qRegisterMetaType<note>( "note" );
}

View File

@@ -39,7 +39,7 @@
#include "group_box.h"
#include "midi_controller.h"
#include "midi_client.h"
#include "midi_port.h"
#include "midi_port_menu.h"
#include "midi.h"
#include "song.h"
#include "tool_button.h"
@@ -55,7 +55,7 @@ public:
m_detectedMidiChannel( 0 ),
m_detectedMidiController( 0 )
{
updateMidiPort();
updateName();
}
@@ -68,8 +68,8 @@ public:
const midiTime & _time, bool _lock )
{
if( _me.m_type == CONTROL_CHANGE &&
( m_midiChannel.value() == _me.m_channel + 1 ||
m_midiChannel.value() == 0 ) )
( m_midiPort.inputChannel() == _me.m_channel + 1 ||
m_midiPort.inputChannel() == 0 ) )
{
m_detectedMidiChannel = _me.m_channel + 1;
m_detectedMidiController = ( _me.m_data.m_bytes[0] & 0x7F ) + 1;
@@ -87,9 +87,9 @@ public:
midiController * copyToMidiController( model * _parent )
{
midiController * c = new midiController( _parent );
c->midiChannelModel()->setValue( m_midiChannel.value() );
c->midiControllerModel()->setValue( m_midiController.value() );
c->setReadablePorts( m_readablePorts );
c->m_midiPort.setInputChannel( m_midiPort.inputChannel() );
c->m_midiPort.setInputController( m_midiPort.inputController() );
c->subscribeReadablePorts( m_midiPort.readablePorts() );
return c;
}
@@ -97,16 +97,16 @@ public:
void useDetected( void )
{
m_midiChannel.setValue( m_detectedMidiChannel );
m_midiController.setValue( m_detectedMidiController );
m_midiPort.setInputChannel( m_detectedMidiChannel );
m_midiPort.setInputController( m_detectedMidiController );
}
public slots:
void reset( void )
{
m_midiChannel.setValue( 0 );
m_midiController.setValue( 0 );
m_midiPort.setInputChannel( 0 );
m_midiPort.setInputController( 0 );
}
};
@@ -162,14 +162,9 @@ controllerConnectionDialog::controllerConnectionDialog( QWidget * _parent,
// when using with non-raw-clients we can provide buttons showing
// our port-menus when being clicked
midiClient * mc = engine::getMixer()->getMIDIClient();
if( mc->isRaw() == FALSE )
if( !engine::getMixer()->getMIDIClient()->isRaw() )
{
m_readablePorts = new QMenu( this );
m_readablePorts->setFont( pointSize<9>(
m_readablePorts->font() ) );
connect( m_readablePorts, SIGNAL( triggered( QAction * ) ),
this, SLOT( activatedReadablePort( QAction * ) ) );
m_readablePorts = new midiPortMenu( midiPort::Input );
toolButton * rp_btn = new toolButton( m_midiGroupBox );
rp_btn->setText( tr( "MIDI-devices to receive "
@@ -251,13 +246,11 @@ controllerConnectionDialog::controllerConnectionDialog( QWidget * _parent,
midiController * cont =
(midiController*)( cc->getController() );
m_midiChannelSpinBox->model()->setValue(
cont->midiChannelModel()->value() );
cont->m_midiPort.inputChannel() );
m_midiControllerSpinBox->model()->setValue(
cont->midiControllerModel()->value() );
cont->m_midiPort.inputController() );
// update menuupdateReadablePortsMenu
m_midiController->setReadablePorts( static_cast<midiController*>( cc->getController() )->m_readablePorts );
updateReadablePortsMenu();
m_midiController->subscribeReadablePorts( static_cast<midiController*>( cc->getController() )->m_midiPort.readablePorts() );
}
else
{
@@ -307,13 +300,13 @@ void controllerConnectionDialog::selectController( void )
if( m_targetModel->getTrack() &&
!m_targetModel->getTrack()->displayName().isEmpty() )
{
mc->getMidiPort()->setName( QString( "%1 (%2)" ).
mc->m_midiPort.setName( QString( "%1 (%2)" ).
arg( m_targetModel->getTrack()->displayName() ).
arg( m_targetModel->displayName() ) );
}
else
{
mc->getMidiPort()->setName( m_targetModel->displayName() );
mc->m_midiPort.setName( m_targetModel->displayName() );
}
m_controller = mc;
}
@@ -348,15 +341,14 @@ void controllerConnectionDialog::midiToggled( void )
{
m_midiController = new autoDetectMidiController( engine::getSong() );
m_midiChannelSpinBox->setModel(
m_midiController->midiChannelModel() );
&m_midiController->m_midiPort.m_inputChannelModel );
m_midiControllerSpinBox->setModel(
m_midiController->midiControllerModel() );
&m_midiController->m_midiPort.m_inputControllerModel );
m_readablePorts->setModel( &m_midiController->m_midiPort );
connect( m_midiController, SIGNAL( valueChanged() ),
this, SLOT( midiValueChanged() ) );
updateReadablePortsMenu();
}
}
else
@@ -410,39 +402,6 @@ void controllerConnectionDialog::midiValueChanged( void )
void controllerConnectionDialog::activatedReadablePort( QAction * _item )
{
// make sure, MIDI-port is configured for input
if( _item->isChecked() == TRUE &&
m_midiController->m_midiPort->mode() != midiPort::Input &&
m_midiController->m_midiPort->mode() != midiPort::Duplex )
{
//mio->m_receiveEnabledModel.setValue( TRUE );
}
engine::getMixer()->getMIDIClient()->subscribeReadablePort(
m_midiController->m_midiPort, _item->text(), !_item->isChecked() );
m_midiController->m_readablePorts[_item->text()] = _item->isChecked();
}
void controllerConnectionDialog::updateReadablePortsMenu( void )
{
if( m_readablePorts )
{
m_readablePorts->clear();
for( midiController::midiPortMap::const_iterator it =
m_midiController->m_readablePorts.begin();
it != m_midiController->m_readablePorts.end(); ++it )
{
QAction * a = m_readablePorts->addAction( it.key() );
a->setCheckable( TRUE );
a->setChecked( *it );
}
}
}
#include "controller_connection_dialog.moc"
#endif

View File

@@ -515,7 +515,7 @@ void pianoRoll::setCurrentPattern( pattern * _new_pattern )
// of start-notes and so on...)
resizeEvent( NULL );
// remove all connections to other channel-tracks
// remove all connections to other instrument-tracks
disconnect( this, SLOT( recordNote( const note & ) ) );
// and now connect to noteDone()-signal of channel so that

View File

@@ -30,13 +30,9 @@
#include "instrument_midi_io_view.h"
#include "instrument_midi_io.h"
#include "midi_port_menu.h"
#include "embed.h"
#include "engine.h"
#include "gui_templates.h"
#include "midi_client.h"
#include "midi_port.h"
#include "mixer.h"
#include "led_checkbox.h"
#include "lcd_spinbox.h"
#include "tab_widget.h"
@@ -44,11 +40,12 @@
instrumentMidiIOView::instrumentMidiIOView( QWidget * _parent ) :
instrumentMidiIOView::instrumentMidiIOView(
midiPortMenu * _readable_ports_menu,
midiPortMenu * _writable_ports_menu,
QWidget * _parent ) :
QWidget( _parent ),
modelView( NULL ),
m_readablePorts( NULL ),
m_writeablePorts( NULL )
modelView( NULL )
{
m_setupTabWidget = new tabWidget( tr( "MIDI-SETUP FOR THIS CHANNEL" ),
this );
@@ -101,38 +98,24 @@ instrumentMidiIOView::instrumentMidiIOView( QWidget * _parent ) :
m_defaultVelocityOutCheckBox->move( 28, 164 );
// when using with non-raw-clients we can provide buttons showing
// our port-menus when being clicked
midiClient * mc = engine::getMixer()->getMIDIClient();
if( mc->isRaw() == FALSE )
if( _readable_ports_menu != NULL )
{
m_readablePorts = new QMenu( m_setupTabWidget );
m_readablePorts->setFont( pointSize<9>(
m_readablePorts->font() ) );
connect( m_readablePorts, SIGNAL( triggered( QAction * ) ),
this, SLOT( activatedReadablePort( QAction * ) ) );
m_writeablePorts = new QMenu( m_setupTabWidget );
m_writeablePorts->setFont( pointSize<9>(
m_writeablePorts->font() ) );
connect( m_writeablePorts, SIGNAL( triggered( QAction * ) ),
this, SLOT( activatedWriteablePort( QAction * ) ) );
QToolButton * rp_btn = new QToolButton( m_setupTabWidget );
rp_btn->setText( tr( "MIDI-devices to receive "
"MIDI-events from" ) );
rp_btn->setIcon( embed::getIconPixmap( "midi_in" ) );
rp_btn->setGeometry( 186, 34, 40, 40 );
rp_btn->setMenu( m_readablePorts );
rp_btn->setMenu( _readable_ports_menu );
rp_btn->setPopupMode( QToolButton::InstantPopup );
}
if( _writable_ports_menu != NULL )
{
QToolButton * wp_btn = new QToolButton( m_setupTabWidget );
wp_btn->setText( tr( "MIDI-devices to send MIDI-events "
"to" ) );
wp_btn->setIcon( embed::getIconPixmap( "midi_out" ) );
wp_btn->setGeometry( 186, 114, 40, 40 );
wp_btn->setMenu( m_writeablePorts );
wp_btn->setMenu( _writable_ports_menu );
wp_btn->setPopupMode( QToolButton::InstantPopup );
}
}
@@ -149,101 +132,16 @@ instrumentMidiIOView::~instrumentMidiIOView()
void instrumentMidiIOView::modelChanged( void )
{
instrumentMidiIO * mio = castModel<instrumentMidiIO>();
m_inputChannelSpinBox->setModel( &mio->m_inputChannelModel );
m_outputChannelSpinBox->setModel( &mio->m_outputChannelModel );
m_receiveCheckBox->setModel( &mio->m_receiveEnabledModel );
midiPort * mp = castModel<midiPort>();
m_inputChannelSpinBox->setModel( &mp->m_inputChannelModel );
m_outputChannelSpinBox->setModel( &mp->m_outputChannelModel );
m_receiveCheckBox->setModel( &mp->m_readableModel );
m_defaultVelocityInCheckBox->setModel(
&mio->m_defaultVelocityInEnabledModel );
m_sendCheckBox->setModel( &mio->m_sendEnabledModel );
&mp->m_defaultVelocityInEnabledModel );
m_sendCheckBox->setModel( &mp->m_writableModel );
m_defaultVelocityOutCheckBox->setModel(
&mio->m_defaultVelocityOutEnabledModel );
connect( mio, SIGNAL( readablePortsChanged() ),
this, SLOT( updateReadablePortsMenu() ) );
connect( mio, SIGNAL( writeablePortsChanged() ),
this, SLOT( updateWriteablePortsMenu() ) );
updateReadablePortsMenu();
updateWriteablePortsMenu();
&mp->m_defaultVelocityOutEnabledModel );
}
void instrumentMidiIOView::activatedReadablePort( QAction * _item )
{
instrumentMidiIO * mio = castModel<instrumentMidiIO>();
// make sure, MIDI-port is configured for input
if( _item->isChecked() == TRUE &&
mio->m_midiPort->mode() != midiPort::Input &&
mio->m_midiPort->mode() != midiPort::Duplex )
{
mio->m_receiveEnabledModel.setValue( TRUE );
}
engine::getMixer()->getMIDIClient()->subscribeReadablePort(
mio->m_midiPort, _item->text(), !_item->isChecked() );
}
void instrumentMidiIOView::activatedWriteablePort( QAction * _item )
{
instrumentMidiIO * mio = castModel<instrumentMidiIO>();
// make sure, MIDI-port is configured for output
if( _item->isChecked() == TRUE &&
mio->m_midiPort->mode() != midiPort::Output &&
mio->m_midiPort->mode() != midiPort::Duplex )
{
mio->m_sendEnabledModel.setValue( TRUE );
}
engine::getMixer()->getMIDIClient()->subscribeWriteablePort(
mio->m_midiPort, _item->text(), !_item->isChecked() );
}
void instrumentMidiIOView::updateReadablePortsMenu( void )
{
instrumentMidiIO * mio = castModel<instrumentMidiIO>();
if( m_readablePorts )
{
m_readablePorts->clear();
for( instrumentMidiIO::midiPortMap::const_iterator it =
mio->m_readablePorts.begin();
it != mio->m_readablePorts.end(); ++it )
{
QAction * a = m_readablePorts->addAction( it->first );
a->setCheckable( TRUE );
a->setChecked( it->second );
}
}
}
void instrumentMidiIOView::updateWriteablePortsMenu( void )
{
instrumentMidiIO * mio = castModel<instrumentMidiIO>();
if( m_writeablePorts )
{
m_writeablePorts->clear();
for( instrumentMidiIO::midiPortMap::const_iterator it =
mio->m_writeablePorts.begin();
it != mio->m_writeablePorts.end(); ++it )
{
QAction * a = m_writeablePorts->addAction( it->first );
a->setCheckable( TRUE );
a->setChecked( it->second );
}
}
}
#include "instrument_midi_io_view.moc"
#endif

View File

@@ -63,9 +63,8 @@
#include "led_checkbox.h"
#include "main_window.h"
#include "midi_client.h"
#include "midi_port.h"
#include "midi_port_menu.h"
#include "fx_mixer.h"
#include "instrument_midi_io.h"
#include "mmp.h"
#include "note_play_handle.h"
#include "pattern.h"
@@ -104,19 +103,20 @@ const int INSTRUMENT_WINDOW_CACHE_SIZE = 8;
instrumentTrack::instrumentTrack( trackContainer * _tc ) :
track( InstrumentTrack, _tc ),
midiEventProcessor(),
m_midiPort( engine::getMixer()->getMIDIClient()->addPort( this,
tr( "unnamed_channel" ) ) ),
m_audioPort( tr( "unnamed_channel" ), this ),
m_audioPort( tr( "unnamed_track" ), this ),
m_midiPort( tr( "unnamed_track" ), engine::getMixer()->getMIDIClient(),
this, this, this ),
m_notes(),
m_baseNoteModel( 0, 0, KeysPerOctave * NumOctaves - 1, this ),
m_volumeModel( DefaultVolume, MinVolume, MaxVolume, 1.0f, this, tr( "Volume" ) ),
m_panningModel( DefaultPanning, PanningLeft, PanningRight, 1.0f, this, tr( "Panning" ) ),
m_volumeModel( DefaultVolume, MinVolume, MaxVolume, 1.0f, this,
tr( "Volume" ) ),
m_panningModel( DefaultPanning, PanningLeft, PanningRight, 1.0f,
this, tr( "Panning" ) ),
m_effectChannelModel( 0, 0, NumFxChannels, this ),
m_instrument( NULL ),
m_soundShaping( this ),
m_arpeggiator( this ),
m_chordCreator( this ),
m_midiIO( this, m_midiPort ),
m_piano( this )
{
m_baseNoteModel.setTrack( this );
@@ -145,7 +145,6 @@ instrumentTrack::instrumentTrack( trackContainer * _tc ) :
instrumentTrack::~instrumentTrack()
{
engine::getMixer()->removePlayHandles( this );
engine::getMixer()->getMIDIClient()->removePort( m_midiPort );
delete m_instrument;
}
@@ -339,7 +338,7 @@ void instrumentTrack::processOutEvent( const midiEvent & _me,
break;
}
// if appropriate, midi-port does futher routing
m_midiPort->processOutEvent( _me, _time );
m_midiPort.processOutEvent( _me, _time );
}
@@ -466,7 +465,7 @@ void instrumentTrack::setName( const QString & _new_name )
}
track::setName( _new_name );
m_midiPort->setName( name() );
m_midiPort.setName( name() );
m_audioPort.setName( name() );
emit nameChanged();
@@ -675,7 +674,7 @@ void instrumentTrack::saveTrackSpecificSettings( QDomDocument & _doc,
m_soundShaping.saveState( _doc, _this );
m_chordCreator.saveState( _doc, _this );
m_arpeggiator.saveState( _doc, _this );
m_midiIO.saveState( _doc, _this );
m_midiPort.saveState( _doc, _this );
m_audioPort.getEffects()->saveState( _doc, _this );
if( getHook() )
{
@@ -743,9 +742,9 @@ void instrumentTrack::loadTrackSpecificSettings( const QDomElement & _this )
{
m_arpeggiator.restoreState( node.toElement() );
}
else if( m_midiIO.nodeName() == node.nodeName() )
else if( m_midiPort.nodeName() == node.nodeName() )
{
m_midiIO.restoreState( node.toElement() );
m_midiPort.restoreState( node.toElement() );
}
else if( m_audioPort.getEffects()->nodeName() ==
node.nodeName() )
@@ -830,7 +829,9 @@ QQueue<instrumentTrackWindow *> instrumentTrackView::s_windows;
instrumentTrackView::instrumentTrackView( instrumentTrack * _it,
trackContainerView * _tcv ) :
trackView( _it, _tcv ),
m_window( NULL )
m_window( NULL ),
m_readablePortsMenu( NULL ),
m_writablePortsMenu( NULL )
{
setAcceptDrops( TRUE );
setFixedHeight( 32 );
@@ -854,6 +855,32 @@ instrumentTrackView::instrumentTrackView( instrumentTrack * _it,
m_tswMidiMenu = new QMenu( tsw_midi );
tsw_midi->setMenu( m_tswMidiMenu );
// sequenced MIDI?
if( !engine::getMixer()->getMIDIClient()->isRaw() )
{
m_readablePortsMenu = new midiPortMenu( midiPort::Input );
m_writablePortsMenu = new midiPortMenu( midiPort::Output );
m_readablePortsMenu->setModel( &_it->m_midiPort );
m_writablePortsMenu->setModel( &_it->m_midiPort );
m_midiInputAction = m_tswMidiMenu->addMenu(
m_readablePortsMenu );
m_midiOutputAction = m_tswMidiMenu->addMenu(
m_writablePortsMenu );
}
else
{
m_midiInputAction = m_tswMidiMenu->addAction( "" );
connect( m_midiInputAction, SIGNAL( changed() ), this,
SLOT( midiInSelected() ) );
m_midiOutputAction = m_tswMidiMenu->addAction( "" );
connect( m_midiOutputAction, SIGNAL( changed() ), this,
SLOT( midiOutSelected() ) );
connect( &_it->m_midiPort, SIGNAL( modeChanged() ),
this, SLOT( midiConfigChanged() ) );
}
m_midiInputAction->setText( tr( "MIDI input" ) );
m_midiOutputAction->setText( tr( "MIDI output" ) );
m_tswActivityIndicator = new fadeButton( QColor( 96, 96, 96 ),
QColor( 255, 204, 0 ),
@@ -871,41 +898,6 @@ instrumentTrackView::instrumentTrackView( instrumentTrack * _it,
m_tswInstrumentTrackButton->setGeometry( 64, 2, 144, 28 );
m_tswInstrumentTrackButton->show();
/* if( m_midiWidget->m_readablePorts )
{
m_midiInputAction = m_tswMidiMenu->addMenu(
m_midiWidget->m_readablePorts );
}
else
{
m_midiInputAction = m_tswMidiMenu->addAction( "" );
connect( m_midiInputAction, SIGNAL( changed() ), this,
SLOT( midiInSelected() ) );
}
if( m_midiWidget->m_writeablePorts )
{
m_midiOutputAction = m_tswMidiMenu->addMenu(
m_midiWidget->m_writeablePorts );
}
else
{
m_midiOutputAction = m_tswMidiMenu->addAction( "" );
connect( m_midiOutputAction, SIGNAL( changed() ), this,
SLOT( midiOutSelected() ) );
}
m_midiInputAction->setText( tr( "MIDI input" ) );
m_midiOutputAction->setText( tr( "MIDI output" ) );
if( m_midiWidget->m_readablePorts == NULL ||
m_midiWidget->m_writeablePorts == NULL )
{
connect( m_midiWidget->m_sendCheckBox,
SIGNAL( toggled( bool ) ),
this, SLOT( midiConfigChanged( bool ) ) );
connect( m_midiWidget->m_receiveCheckBox,
SIGNAL( toggled( bool ) ),
this, SLOT( midiConfigChanged( bool ) ) );
}*/
setModel( _it );
connect( m_tswInstrumentTrackButton, SIGNAL( toggled( bool ) ),
@@ -1029,6 +1021,36 @@ void instrumentTrackView::updateName( void )
void instrumentTrackView::midiInSelected( void )
{
m_midiInputAction->setChecked( !m_midiInputAction->isChecked() );
model()->m_midiPort.setReadable( m_midiInputAction->isChecked() );
}
void instrumentTrackView::midiOutSelected( void )
{
m_midiOutputAction->setChecked( !m_midiOutputAction->isChecked() );
model()->m_midiPort.setWritable( m_midiOutputAction->isChecked() );
}
void instrumentTrackView::midiConfigChanged( void )
{
m_midiInputAction->setChecked( model()->m_midiPort.isReadable() );
m_midiOutputAction->setChecked( model()->m_midiPort.isWritable() );
}
class fxLineLcdSpinBox : public lcdSpinBox
{
public:
@@ -1052,9 +1074,7 @@ instrumentTrackWindow::instrumentTrackWindow( instrumentTrackView * _itv ) :
modelView( NULL ),
m_track( _itv->model() ),
m_itv( _itv ),
m_instrumentView( NULL ),
m_midiInputAction( NULL ),
m_midiOutputAction( NULL )
m_instrumentView( NULL )
{
setAcceptDrops( TRUE );
@@ -1130,7 +1150,9 @@ instrumentTrackWindow::instrumentTrackWindow( instrumentTrackView * _itv ) :
instrument_functions );
m_arpView= new arpeggiatorView( &m_track->m_arpeggiator,
instrument_functions );
m_midiView = new instrumentMidiIOView( m_tabWidget );
m_midiView = new instrumentMidiIOView( m_itv->m_readablePortsMenu,
m_itv->m_writablePortsMenu,
m_tabWidget );
m_effectView = new effectRackView( m_track->m_audioPort.getEffects(),
m_tabWidget );
m_tabWidget->addTab( m_ssView, tr( "ENV/LFO" ), 1 );
@@ -1146,40 +1168,6 @@ instrumentTrackWindow::instrumentTrackWindow( instrumentTrackView * _itv ) :
vlayout->addWidget( m_tabWidget );
vlayout->addWidget( m_pianoView );
if( m_midiView->m_readablePorts )
{
m_midiInputAction = m_itv->m_tswMidiMenu->addMenu(
m_midiView->m_readablePorts );
}
else
{
m_midiInputAction = m_itv->m_tswMidiMenu->addAction( "" );
connect( m_midiInputAction, SIGNAL( changed() ), this,
SLOT( midiInSelected() ) );
}
if( m_midiView->m_writeablePorts )
{
m_midiOutputAction = m_itv->m_tswMidiMenu->addMenu(
m_midiView->m_writeablePorts );
}
else
{
m_midiOutputAction = m_itv->m_tswMidiMenu->addAction( "" );
connect( m_midiOutputAction, SIGNAL( changed() ), this,
SLOT( midiOutSelected() ) );
}
m_midiInputAction->setText( tr( "MIDI input" ) );
m_midiOutputAction->setText( tr( "MIDI output" ) );
if( m_midiView->m_readablePorts == NULL ||
m_midiView->m_writeablePorts == NULL )
{
connect( m_midiView->m_sendCheckBox,
SIGNAL( toggled( bool ) ),
this, SLOT( midiConfigChanged( bool ) ) );
connect( m_midiView->m_receiveCheckBox,
SIGNAL( toggled( bool ) ),
this, SLOT( midiConfigChanged( bool ) ) );
}
setModel( _itv->model() );
@@ -1241,9 +1229,18 @@ void instrumentTrackWindow::modelChanged( void )
m_ssView->setModel( &m_track->m_soundShaping );
m_chordView->setModel( &m_track->m_chordCreator );
m_arpView->setModel( &m_track->m_arpeggiator );
m_midiView->setModel( &m_track->m_midiIO );
m_midiView->setModel( &m_track->m_midiPort );
m_effectView->setModel( m_track->m_audioPort.getEffects() );
updateName();
if( m_itv->m_readablePortsMenu != NULL )
{
m_itv->m_readablePortsMenu->setModel( &m_track->m_midiPort );
}
if( m_itv->m_writablePortsMenu != NULL )
{
m_itv->m_writablePortsMenu->setModel( &m_track->m_midiPort );
}
}
@@ -1435,32 +1432,6 @@ void instrumentTrackWindow::loadSettings( const QDomElement & _this )
void instrumentTrackWindow::midiInSelected( void )
{
m_midiInputAction->setChecked( !m_midiInputAction->isChecked() );
m_midiView->m_receiveCheckBox->setChecked(
m_midiInputAction->isChecked() );
}
void instrumentTrackWindow::midiOutSelected( void )
{
m_midiOutputAction->setChecked( !m_midiOutputAction->isChecked() );
m_midiView->m_sendCheckBox->setChecked(
m_midiOutputAction->isChecked() );
}
void instrumentTrackWindow::midiConfigChanged( bool )
{
m_midiInputAction->setChecked(
m_midiView->m_receiveCheckBox->model()->value() );
m_midiOutputAction->setChecked(
m_midiView->m_sendCheckBox->model()->value() );
}