summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2008-02-19 01:31:24 +0000
committerDavid Robillard <d@drobilla.net>2008-02-19 01:31:24 +0000
commitb79d5bfad3473f54ab24c0b7852fc4bfc9d9ebb0 (patch)
tree93374d44e9b7264cc790802eb3389f7a94ac781e
parent466500fdaf25b57ba7c99ffe7a78364212be8e40 (diff)
'Channel safe' MIDI:
Resolve note on/off pairs in MidiModel. Add channel field to Parameter (for associating a channel with a CC list). Add channel selector to 'add controller automation' dialog. Write out note and CC MIDI events with proper channel. git-svn-id: svn://localhost/ardour2/branches/3.0@3085 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/add_midi_cc_track_dialog.cc40
-rw-r--r--gtk2_ardour/add_midi_cc_track_dialog.h2
-rw-r--r--libs/ardour/SConscript1
-rw-r--r--libs/ardour/ardour/note.h2
-rw-r--r--libs/ardour/ardour/parameter.h80
-rw-r--r--libs/ardour/midi_model.cc10
-rw-r--r--libs/ardour/note.cc8
7 files changed, 52 insertions, 91 deletions
diff --git a/gtk2_ardour/add_midi_cc_track_dialog.cc b/gtk2_ardour/add_midi_cc_track_dialog.cc
index e1a3a89bd6..fcd3ebbe40 100644
--- a/gtk2_ardour/add_midi_cc_track_dialog.cc
+++ b/gtk2_ardour/add_midi_cc_track_dialog.cc
@@ -36,40 +36,50 @@ using namespace PBD;
using namespace ARDOUR;
AddMidiCCTrackDialog::AddMidiCCTrackDialog ()
- : Dialog (_("ardour: add midi controller track")),
- _cc_num_adjustment (1, 0, 127, 1, 10),
- _cc_num_spinner (_cc_num_adjustment)
+ : Dialog (_("ardour: add midi controller track"))
+ , _chan_adjustment (1, 1, 16, 8)
+ , _chan_spinner (_chan_adjustment)
+ , _cc_num_adjustment (1, 0, 127, 1, 10)
+ , _cc_num_spinner (_cc_num_adjustment)
{
set_name ("AddMidiCCTrackDialog");
set_wmclass (X_("ardour_add_track_bus"), "Ardour");
set_position (Gtk::WIN_POS_MOUSE);
set_resizable (false);
-
+ _chan_spinner.set_name ("AddMidiCCTrackDialogSpinner");
_cc_num_spinner.set_name ("AddMidiCCTrackDialogSpinner");
- HBox *hbox = manage (new HBox());
- Label *label = manage(new Label("Controller Number: "));
-
- hbox->pack_start(*label, true, true, 4);
- hbox->pack_start(_cc_num_spinner, false, false, 4);
-
- get_vbox()->pack_start(*hbox, true, true, 4);
+ HBox *chan_box = manage (new HBox());
+ Label *chan_label = manage(new Label("Channel: "));
+ chan_box->pack_start(*chan_label, true, true, 4);
+ chan_box->pack_start(_chan_spinner, false, false, 4);
+ get_vbox()->pack_start(*chan_box, true, true, 4);
+
+ HBox* num_box = manage (new HBox());
+ Label *num_label = manage(new Label("Controller: "));
+ num_box->pack_start(*num_label, true, true, 4);
+ num_box->pack_start(_cc_num_spinner, false, false, 4);
+ get_vbox()->pack_start(*num_box, true, true, 4);
add_button (Stock::CANCEL, RESPONSE_CANCEL);
add_button (Stock::ADD, RESPONSE_ACCEPT);
-
+
+ _chan_spinner.show();
+ chan_box->show();
+ chan_label->show();
_cc_num_spinner.show();
- hbox->show();
- label->show();
+ num_box->show();
+ num_label->show();
}
ARDOUR::Parameter
AddMidiCCTrackDialog::parameter ()
{
+ int chan = _chan_spinner.get_value_as_int() - 1;
int cc_num = _cc_num_spinner.get_value_as_int();
- return Parameter(MidiCCAutomation, cc_num);
+ return Parameter(MidiCCAutomation, cc_num, chan);
}
diff --git a/gtk2_ardour/add_midi_cc_track_dialog.h b/gtk2_ardour/add_midi_cc_track_dialog.h
index f1ca24990f..d3124044fe 100644
--- a/gtk2_ardour/add_midi_cc_track_dialog.h
+++ b/gtk2_ardour/add_midi_cc_track_dialog.h
@@ -37,6 +37,8 @@ class AddMidiCCTrackDialog : public Gtk::Dialog
ARDOUR::Parameter parameter ();
private:
+ Gtk::Adjustment _chan_adjustment;
+ Gtk::SpinButton _chan_spinner;
Gtk::Adjustment _cc_num_adjustment;
Gtk::SpinButton _cc_num_spinner;
};
diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript
index 942905c341..b8a003cb08 100644
--- a/libs/ardour/SConscript
+++ b/libs/ardour/SConscript
@@ -95,6 +95,7 @@ mtc_slave.cc
named_selection.cc
note.cc
panner.cc
+parameter.cc
pcm_utils.cc
playlist.cc
playlist_factory.cc
diff --git a/libs/ardour/ardour/note.h b/libs/ardour/ardour/note.h
index d88ecd05b0..ea598573e8 100644
--- a/libs/ardour/ardour/note.h
+++ b/libs/ardour/ardour/note.h
@@ -34,7 +34,7 @@ namespace ARDOUR {
*/
class Note {
public:
- Note(double time=0, double dur=0, uint8_t note=0, uint8_t vel=0x40);
+ Note(uint8_t chan=0, double time=0, double dur=0, uint8_t note=0, uint8_t vel=0x40);
Note(const Note& copy);
const Note& operator=(const Note& copy);
diff --git a/libs/ardour/ardour/parameter.h b/libs/ardour/ardour/parameter.h
index d56124ee53..92fa672e22 100644
--- a/libs/ardour/ardour/parameter.h
+++ b/libs/ardour/ardour/parameter.h
@@ -48,85 +48,32 @@ namespace ARDOUR {
class Parameter
{
public:
- inline Parameter(AutomationType type = NullAutomation, uint32_t id=0) : _type(type), _id(id) {}
+ Parameter(AutomationType type = NullAutomation, uint32_t id=0, uint8_t channel=0)
+ : _type(type), _id(id), _channel(channel)
+ {}
- /** Construct an Parameter from a string returned from Parameter::to_string
- * (AutomationList automation-id property)
- */
- Parameter(const std::string& str) : _type(NullAutomation), _id(0) {
- if (str == "gain") {
- _type = GainAutomation;
- } else if (str == "solo") {
- _type = SoloAutomation;
- } else if (str == "mute") {
- _type = MuteAutomation;
- } else if (str == "fadein") {
- _type = FadeInAutomation;
- } else if (str == "fadeout") {
- _type = FadeOutAutomation;
- } else if (str == "envelope") {
- _type = EnvelopeAutomation;
- } else if (str == "pan") {
- _type = PanAutomation;
- } else if (str.length() > 4 && str.substr(0, 4) == "pan-") {
- _type = PanAutomation;
- _id = atoi(str.c_str()+4);
- } else if (str.length() > 10 && str.substr(0, 10) == "parameter-") {
- _type = PluginAutomation;
- _id = atoi(str.c_str()+10);
- } else if (str.length() > 7 && str.substr(0, 7) == "midicc-") {
- _type = MidiCCAutomation;
- _id = atoi(str.c_str()+7);
- } else {
- PBD::warning << "Unknown Parameter '" << str << "'" << endmsg;
- }
- }
+ Parameter(const std::string& str);
- inline AutomationType type() const { return _type; }
- inline uint32_t id() const { return _id; }
+ inline AutomationType type() const { return _type; }
+ inline uint32_t id() const { return _id; }
+ inline uint8_t channel() const { return _channel; }
- inline bool operator==(const Parameter& id) const
- { return (_type == id._type && _id == id._id); }
+ inline bool operator==(const Parameter& id) const {
+ return (_type == id._type && _id == id._id);
+ }
- /** Arbitrary but fixed ordering, so we're comparable (usable in std::map) */
+ /** Arbitrary but fixed ordering (for use in e.g. std::map) */
inline bool operator<(const Parameter& id) const {
#ifndef NDEBUG
if (_type == NullAutomation)
PBD::warning << "Uninitialized Parameter compared." << endmsg;
#endif
- return (_type < id._type || _id < id._id);
+ return (_channel < id._channel || _type < id._type || _id < id._id);
}
inline operator bool() const { return (_type != 0); }
- /** Unique string representation, suitable as an XML property value.
- * e.g. <AutomationList automation-id="whatthisreturns">
- */
- inline std::string to_string() const {
- if (_type == GainAutomation) {
- return "gain";
- } else if (_type == PanAutomation) {
- return string_compose("pan-%1", _id);
- } else if (_type == SoloAutomation) {
- return "solo";
- } else if (_type == MuteAutomation) {
- return "mute";
- } else if (_type == FadeInAutomation) {
- return "fadein";
- } else if (_type == FadeOutAutomation) {
- return "fadeout";
- } else if (_type == EnvelopeAutomation) {
- return "envelope";
- } else if (_type == PluginAutomation) {
- return string_compose("parameter-%1", _id);
- } else if (_type == MidiCCAutomation) {
- return string_compose("midicc-%1", _id);
- } else {
- assert(false);
- PBD::warning << "Uninitialized Parameter to_string() called." << endmsg;
- return "";
- }
- }
+ std::string to_string() const;
/* The below properties are only used for CC right now, but unchanging properties
* of parameters (rather than changing parameters of automation lists themselves)
@@ -154,6 +101,7 @@ private:
// default copy constructor is ok
AutomationType _type;
uint32_t _id;
+ uint8_t _channel;
};
diff --git a/libs/ardour/midi_model.cc b/libs/ardour/midi_model.cc
index b2c7369edd..00fcd44021 100644
--- a/libs/ardour/midi_model.cc
+++ b/libs/ardour/midi_model.cc
@@ -304,9 +304,10 @@ MidiModel::control_to_midi_event(MidiEvent& ev, const MidiControlIterator& iter)
ev.set_buffer((Byte*)malloc(3), true);
assert(iter.first);
+ assert(iter.first->parameter().channel() < 16);
assert(iter.first->parameter().id() <= INT8_MAX);
assert(iter.second.second <= INT8_MAX);
- ev.buffer()[0] = MIDI_CMD_CONTROL;
+ ev.buffer()[0] = MIDI_CMD_CONTROL + iter.first->parameter().channel();
ev.buffer()[1] = (Byte)iter.first->parameter().id();
ev.buffer()[2] = (Byte)iter.second.second;
ev.time() = iter.second.first; // x
@@ -412,7 +413,7 @@ MidiModel::append_note_on_unlocked(uint8_t chan, double time, uint8_t note_num,
assert(chan < 16);
assert(_writing);
- _notes.push_back(boost::shared_ptr<Note>(new Note(time, 0, note_num, velocity)));
+ _notes.push_back(boost::shared_ptr<Note>(new Note(chan, time, 0, note_num, velocity)));
if (_note_mode == Sustained) {
//cerr << "MM Sustained: Appending active note on " << (unsigned)(uint8_t)note_num << endl;
_write_notes[chan].push_back(_notes.size() - 1);
@@ -471,10 +472,7 @@ MidiModel::append_cc_unlocked(uint8_t chan, double time, uint8_t number, uint8_t
assert(chan < 16);
assert(_writing);
- if (chan != 0) // FIXME
- cerr << "WARNING: CC on non-0 channel, channel information lost!" << endl;
-
- Parameter param(MidiCCAutomation, number);
+ Parameter param(MidiCCAutomation, number, chan);
boost::shared_ptr<AutomationControl> control = Automatable::control(param, true);
control->list()->fast_simple_add(time, (double)value);
diff --git a/libs/ardour/note.cc b/libs/ardour/note.cc
index 1cd691c3d7..27f50e4092 100644
--- a/libs/ardour/note.cc
+++ b/libs/ardour/note.cc
@@ -22,15 +22,17 @@
namespace ARDOUR {
-Note::Note(double t, double d, uint8_t n, uint8_t v)
+Note::Note(uint8_t chan, double t, double d, uint8_t n, uint8_t v)
: _on_event(t, 3, NULL, true)
, _off_event(t + d, 3, NULL, true)
{
- _on_event.buffer()[0] = MIDI_CMD_NOTE_ON;
+ assert(chan < 16);
+
+ _on_event.buffer()[0] = MIDI_CMD_NOTE_ON + chan;
_on_event.buffer()[1] = n;
_on_event.buffer()[2] = v;
- _off_event.buffer()[0] = MIDI_CMD_NOTE_OFF;
+ _off_event.buffer()[0] = MIDI_CMD_NOTE_OFF + chan;
_off_event.buffer()[1] = n;
_off_event.buffer()[2] = 0x40;