mirror of
https://github.com/Ardour/ardour.git
synced 2026-01-30 08:53:08 +01:00
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:
parent
4388556923
commit
84be4eafc5
10 changed files with 231 additions and 36 deletions
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
BIN
gtk2_ardour/icons/midi_socket_small.png
Normal file
BIN
gtk2_ardour/icons/midi_socket_small.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 751 B |
|
|
@ -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 ());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
78
icons/midi_socket.svg
Normal 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 |
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue