basic infrastructure for enabling/disabling MIDI input to a given track

git-svn-id: svn://localhost/ardour2/branches/3.0@9772 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2011-06-28 16:55:41 +00:00
parent 4388556923
commit 84be4eafc5
10 changed files with 231 additions and 36 deletions

View file

@ -399,7 +399,7 @@ widget "*TimeInfoSelectionLabel" style:highest "very_small_bright_when_active"
widget "*TimeInfoPunchTitle" style:highest "very_small_bright_when_active"
widget "*TimeInfoPunchLabel" style:highest "very_small_bright_when_active"
widget "*TimeInfoPunchButton" style:highest "punch_button"
widget "*RouteNameEditorEntry" style:highest "text_cell_entry"
widget "*RegionNameEditorEntry" style:highest "text_cell_entry"
widget "*MixerMidiInputEnableButton" style:highest "mouse_mode_button"

Binary file not shown.

After

Width:  |  Height:  |  Size: 751 B

View file

@ -40,6 +40,7 @@
#include "ardour/route.h"
#include "ardour/route_group.h"
#include "ardour/audio_track.h"
#include "ardour/midi_track.h"
#include "ardour/pannable.h"
#include "ardour/panner.h"
#include "ardour/panner_shell.h"
@ -89,6 +90,7 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session* sess, bool in_mixer)
, middle_button_table (1, 2)
, bottom_button_table (1, 2)
, meter_point_label (_("pre"))
, midi_input_enable_button (0)
{
init ();
@ -113,6 +115,7 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session* sess, boost::shared_ptr<Route> rt
, middle_button_table (1, 2)
, bottom_button_table (1, 2)
, meter_point_label (_("pre"))
, midi_input_enable_button (0)
{
init ();
set_route (rt);
@ -153,8 +156,7 @@ MixerStrip::init ()
input_button.add (input_label);
input_button.set_name ("MixerIOButton");
input_label.set_name ("MixerIOButtonLabel");
Gtkmm2ext::set_size_request_to_display_given_text (input_button, longest_label.c_str(), 4, 4);
input_button_box.pack_start (input_button, true, true);
output_label.set_text (_("Output"));
ARDOUR_UI::instance()->set_tip (&output_button, _("Button 1 to choose outputs from a port matrix, button 3 to select inputs from a menu"), "");
@ -227,7 +229,7 @@ MixerStrip::init ()
button_table.set_spacings (0);
button_table.attach (name_button, 0, 1, 0, 1);
button_table.attach (input_button, 0, 1, 1, 2);
button_table.attach (input_button_box, 0, 1, 1, 2);
button_table.attach (_invert_button_box, 0, 1, 2, 3);
middle_button_table.set_homogeneous (true);
@ -399,6 +401,26 @@ MixerStrip::set_route (boost::shared_ptr<Route> rt)
global_vpacker.pack_start (*spacer, false, false);
}
if (is_midi_track()) {
if (midi_input_enable_button == 0) {
Image* img = manage (new Image (get_icon (X_("midi_socket_small"))));
midi_input_enable_button = manage (new ToggleButton);
midi_input_enable_button->set_name ("MixerMidiInputEnableButton");
midi_input_enable_button->set_image (*img);
midi_input_enable_button->signal_toggled().connect (sigc::mem_fun (*this, &MixerStrip::midi_input_toggled));
ARDOUR_UI::instance()->set_tip (midi_input_enable_button, _("Enable/Disable MIDI input"));
}
/* get current state */
midi_input_status_changed ();
input_button_box.pack_start (*midi_input_enable_button, false, false);
} else {
if (midi_input_enable_button) {
/* removal from the container will delete it */
input_button_box.remove (*midi_input_enable_button);
midi_input_enable_button = 0;
}
}
if (is_audio_track()) {
boost::shared_ptr<AudioTrack> at = audio_track();
at->FreezeChange.connect (route_connections, invalidator (*this), boost::bind (&MixerStrip::map_frozen, this), gui_context());
@ -486,8 +508,7 @@ MixerStrip::set_route (boost::shared_ptr<Route> rt)
meter_point_label.show();
diskstream_button.show();
diskstream_label.show();
input_button.show();
input_label.show();
input_button_box.show_all();
output_button.show();
output_label.show();
name_label.show();
@ -1891,3 +1912,26 @@ MixerStrip::hide_things ()
{
processor_box.hide_things ();
}
void
MixerStrip::midi_input_toggled ()
{
boost::shared_ptr<MidiTrack> mt = midi_track ();
if (!mt) {
return;
}
mt->set_input_active (midi_input_enable_button->get_active());
}
void
MixerStrip::midi_input_status_changed ()
{
if (midi_input_enable_button) {
boost::shared_ptr<MidiTrack> mt = midi_track ();
assert (mt);
cerr << "track input active? " << mt->input_active() << endl;
midi_input_enable_button->set_active (mt->input_active ());
}
}

View file

@ -178,12 +178,17 @@ class MixerStrip : public RouteUI, public Gtk::EventBox
Gtk::Label diskstream_label;
Gtk::Button input_button;
Gtk::ToggleButton* midi_input_enable_button;
Gtk::HBox input_button_box;
Gtk::Label input_label;
Gtk::Button output_button;
Gtk::Label output_label;
std::string longest_label;
void midi_input_status_changed ();
void midi_input_toggled ();
gint mark_update_safe ();
guint32 mode_switch_in_progress;

78
icons/midi_socket.svg Normal file
View file

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.0"
width="454.99899"
height="455"
viewBox="-9.302 -9.782 454.999 455"
id="Layer_1"
xml:space="preserve"
inkscape:version="0.47 r22583"
sodipodi:docname="DIN-5c_Diagram.svg"
inkscape:export-filename="/tmp/DIN-5c_Diagram.png"
inkscape:export-xdpi="4.48"
inkscape:export-ydpi="4.48"><metadata
id="metadata13"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1298"
inkscape:window-height="879"
id="namedview11"
showgrid="false"
inkscape:zoom="0.51868132"
inkscape:cx="-144.59796"
inkscape:cy="223.64407"
inkscape:window-x="435"
inkscape:window-y="77"
inkscape:window-maximized="0"
inkscape:current-layer="Layer_1" /><defs
id="defs4733"><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 227.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="454.99899 : 227.5 : 1"
inkscape:persp3d-origin="227.4995 : 151.66667 : 1"
id="perspective15" /></defs>
<path
style="fill:#ffffff;stroke:#000000;stroke-width:5;fill-opacity:1"
d="M 227 28.5 C 117.377 28.5 28.5 117.376 28.5 227 C 28.5 336.631 117.377 425.5 227 425.5 C 336.626 425.5 425.5 336.631 425.5 227 C 425.5 117.376 336.628 28.5 227 28.5 z M 227 45.125 C 327.447 45.125 408.873 126.557 408.875 227 C 408.875 314.806 346.64 388.073 263.875 405.125 C 261.386 386.958 245.838 372.9375 227 372.9375 C 208.148 372.9375 192.617 386.959 190.125 405.125 C 107.363 388.079 45.125 314.806 45.125 227 C 45.125 126.557 126.552 45.125 227 45.125 z "
transform="translate(-9.302,-9.7820035)"
id="path4718" />
<path
d="M 103.738,283.004 C 110.684,295.034 126.065,299.151 138.093,292.206 C 150.125,285.26 154.245,269.882 147.3,257.853 C 140.359,245.83 124.979,241.705 112.946,248.651 C 100.918,255.597 96.796,270.982 103.738,283.004 z "
style="fill:#ffffff;stroke:#000000;stroke-width:5;fill-opacity:1"
id="path4722" />
<path
d="M 147.298,176.572 C 154.244,164.542 150.119,149.163 138.091,142.219 C 126.059,135.272 110.683,139.394 103.737,151.422 C 96.796,163.445 100.913,178.827 112.944,185.774 C 124.974,192.718 140.356,188.595 147.298,176.572 z "
style="fill:#ffffff;stroke:#000000;stroke-width:5;fill-opacity:1"
id="path4724" />
<path
d="M 217.693,135.931 C 231.584,135.931 242.84,124.669 242.84,110.781 C 242.84,96.886 231.582,85.632 217.693,85.632 C 203.81,85.632 192.547,96.889 192.547,110.781 C 192.548,124.67 203.81,135.931 217.693,135.931 z "
style="fill:#ffffff;stroke:#000000;stroke-width:5;fill-opacity:1"
id="path4726" />
<path
d="M 288.086,176.571 C 295.032,188.601 310.413,192.718 322.44,185.774 C 334.473,178.827 338.591,163.45 331.646,151.421 C 324.705,139.398 309.325,135.273 297.293,142.219 C 285.266,149.165 281.145,164.549 288.086,176.571 z "
style="fill:#ffffff;stroke:#000000;stroke-width:5;fill-opacity:1"
id="path4728" />
<path
d="M 331.646,283.005 C 338.592,270.975 334.467,255.597 322.438,248.651 C 310.406,241.705 295.029,245.826 288.084,257.854 C 281.143,269.876 285.26,285.259 297.292,292.206 C 309.321,299.151 324.705,295.029 331.646,283.005 z "
style="fill:#ffffff;stroke:#000000;stroke-width:5;fill-opacity:1"
id="path4730" />
</svg>

After

Width:  |  Height:  |  Size: 4 KiB

View file

@ -46,6 +46,9 @@ class MidiPort : public Port {
void realtime_locate ();
void reset ();
bool input_active() const { return _input_active; }
void set_input_active (bool yn);
Buffer& get_buffer (pframes_t nframes) {
return get_midi_buffer (nframes);
}
@ -59,8 +62,9 @@ class MidiPort : public Port {
private:
MidiBuffer* _buffer;
bool _has_been_mixed_down;
bool _resolve_required;
bool _has_been_mixed_down;
bool _resolve_required;
bool _input_active;
void resolve_notes (void* jack_buffer, MidiBuffer::TimeType when);
};

View file

@ -105,6 +105,10 @@ public:
PBD::Signal2<void, boost::shared_ptr<MidiBuffer>, boost::weak_ptr<MidiSource> > DataRecorded;
void set_input_active (bool);
bool input_active () const;
PBD::Signal0<void> InputActiveChanged;
protected:
XMLNode& state (bool full);

View file

@ -532,6 +532,10 @@ MidiDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool can
}
if (buf.size() != 0) {
/* XXX this needs fixing - realtime new() call for
every time we get MIDI data in a process callback!
*/
/* Make a copy of this data and emit it for the GUI to see */
boost::shared_ptr<MidiBuffer> copy (new MidiBuffer (buf.capacity ()));
for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {

View file

@ -30,6 +30,7 @@ MidiPort::MidiPort (const std::string& name, Flags flags)
: Port (name, DataType::MIDI, flags)
, _has_been_mixed_down (false)
, _resolve_required (false)
, _input_active (true)
{
_buffer = new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI));
}
@ -62,36 +63,42 @@ MidiPort::get_midi_buffer (pframes_t nframes)
if (receives_input ()) {
void* jack_buffer = jack_port_get_buffer (_jack_port, nframes);
const pframes_t event_count = jack_midi_get_event_count (jack_buffer);
if (_input_active) {
assert (event_count < _buffer->capacity());
void* jack_buffer = jack_port_get_buffer (_jack_port, nframes);
const pframes_t event_count = jack_midi_get_event_count (jack_buffer);
assert (event_count < _buffer->capacity());
/* suck all relevant MIDI events from the JACK MIDI port buffer
into our MidiBuffer
*/
for (pframes_t i = 0; i < event_count; ++i) {
jack_midi_event_t ev;
jack_midi_event_get (&ev, jack_buffer, i);
if (ev.buffer[0] == 0xfe) {
/* throw away active sensing */
continue;
}
/* check that the event is in the acceptable time range */
if ((ev.time >= (_global_port_buffer_offset + _port_buffer_offset)) &&
(ev.time < (_global_port_buffer_offset + _port_buffer_offset + nframes))) {
_buffer->push_back (ev);
} else {
cerr << "Dropping incoming MIDI at time " << ev.time << "; offset="
<< _global_port_buffer_offset << " limit="
<< (_global_port_buffer_offset + _port_buffer_offset + nframes) << "\n";
}
}
/* suck all relevant MIDI events from the JACK MIDI port buffer
into our MidiBuffer
*/
for (pframes_t i = 0; i < event_count; ++i) {
jack_midi_event_t ev;
jack_midi_event_get (&ev, jack_buffer, i);
if (ev.buffer[0] == 0xfe) {
/* throw away active sensing */
continue;
}
/* check that the event is in the acceptable time range */
if ((ev.time >= (_global_port_buffer_offset + _port_buffer_offset)) &&
(ev.time < (_global_port_buffer_offset + _port_buffer_offset + nframes))) {
_buffer->push_back (ev);
} else {
cerr << "Dropping incoming MIDI at time " << ev.time << "; offset="
<< _global_port_buffer_offset << " limit="
<< (_global_port_buffer_offset + _port_buffer_offset + nframes) << "\n";
}
} else {
_buffer->silence (nframes);
}
} else {
@ -205,3 +212,9 @@ MidiPort::reset ()
delete _buffer;
_buffer = new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI));
}
void
MidiPort::set_input_active (bool yn)
{
_input_active = yn;
}

View file

@ -676,3 +676,46 @@ MidiTrack::send_silence () const
{
return false;
}
void
MidiTrack::set_input_active (bool yn)
{
bool changed = false;
if (!_input) {
return;
}
PortSet& ports (_input->ports());
for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
MidiPort* mp = dynamic_cast<MidiPort*> (&*p);
if (yn != mp->input_active()) {
mp->set_input_active (yn);
changed = true;
}
}
if (changed) {
InputActiveChanged (); /* EMIT SIGNAL */
}
}
bool
MidiTrack::input_active () const
{
if (!_input) {
cerr << " no input\n";
return false;
}
if (_input->ports().count().n_midi() == 0) {
cerr << "no input MIDI ports, " << _input->ports().count() << endl;
return false;
}
PortSet::iterator p = _input->ports().begin(DataType::MIDI);
MidiPort* mp = dynamic_cast<MidiPort*> (&*p);
cerr << "first port is active: " << mp->input_active() << endl;
return mp->input_active ();
}