diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2006-07-07 23:51:30 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2006-07-07 23:51:30 +0000 |
commit | 8b46567e0677eb25c965ed46b80da8808fa33b2b (patch) | |
tree | f34e3d1cbdab142e7f155d981fee5fb56a82c431 | |
parent | 6f2e8de6a05d9d52069fa1f95c3264b5f151df5f (diff) |
id_t becomes a fully-fledged object, UUID's used for IDs, generic MIDI now owns bindings, MIDI binding concept removed from libardour itself in favor of generic Controllables
git-svn-id: svn://localhost/ardour2/trunk@669 d708f5d6-7413-0410-9779-e7cbd77b26cf
97 files changed, 1438 insertions, 2082 deletions
diff --git a/SConstruct b/SConstruct index 3fff60f04b..95664ec1ff 100644 --- a/SConstruct +++ b/SConstruct @@ -454,6 +454,15 @@ conf.CheckLib ('FLAC', 'FLAC__stream_decoder_new') libraries['flac'] = conf.Finish () # +# Check for UUID stuff + +libraries['uuid'] = LibraryInfo () + +conf = Configure (libraries['uuid']) +conf.CheckLib ('uuid', 'uuid_generate') +libraries['uuid'] = conf.Finish () + +# # Check for liblo if env['LIBLO']: diff --git a/gtk2_ardour/SConscript b/gtk2_ardour/SConscript index 68e07ebd22..8d66b9298c 100644 --- a/gtk2_ardour/SConscript +++ b/gtk2_ardour/SConscript @@ -42,6 +42,7 @@ gtkardour.Merge ([ libraries['gdkmm2'], libraries['sigc2'], libraries['gtk2'], + libraries['uuid'], libraries['xml'], libraries['xslt'], libraries['soundtouch'], diff --git a/gtk2_ardour/ardev_common.sh b/gtk2_ardour/ardev_common.sh index 5c68933a96..faf5f69531 100755 --- a/gtk2_ardour/ardev_common.sh +++ b/gtk2_ardour/ardev_common.sh @@ -2,7 +2,7 @@ export ARDOUR_PATH=./glade:./pixmaps:. -export LD_LIBRARY_PATH=../libs/surfaces/control_protocol:../libs/ardour:../libs/midi++2:../libs/pbd3:../libs/soundtouch:../libs/gtkmm2ext:../libs/sigc++2:../libs/glibmm2:../libs/gtkmm2/atk:../libs/gtkmm2/pango:../libs/gtkmm2/gdk:../libs/gtkmm2/gtk:../libs/libgnomecanvasmm:../libs/libsndfile:$LD_LIBRARY_PATH +export LD_LIBRARY_PATH=../libs/surfaces/control_protocol:../libs/ardour:../libs/midi++2:../libs/pbd:../libs/soundtouch:../libs/gtkmm2ext:../libs/sigc++2:../libs/glibmm2:../libs/gtkmm2/atk:../libs/gtkmm2/pango:../libs/gtkmm2/gdk:../libs/gtkmm2/gtk:../libs/libgnomecanvasmm:../libs/libsndfile:$LD_LIBRARY_PATH # DYLD_LIBRARY_PATH is for darwin. export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index f452ec9c7e..ce4a12f330 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -374,9 +374,11 @@ ARDOUR_UI::finish() if (session && session->dirty()) { switch (ask_about_saving_session(_("quit"))) { case -1: + cerr << "dialog return -1\n"; return; break; case 1: + cerr << "dialog return +1\n"; /* use the default name */ if (save_state_canfail ("")) { /* failed - don't quit */ @@ -390,7 +392,10 @@ If you still wish to quit, please use the\n\n\ } break; case 0: + cerr << "dialog return 0\n"; break; + default: + cerr << "dialog return other\n"; } } Config->save_state(); @@ -1159,31 +1164,21 @@ ARDOUR_UI::transport_forward (int option) } void -ARDOUR_UI::toggle_monitor_enable (guint32 dstream) +ARDOUR_UI::toggle_record_enable (uint32_t dstream) { if (session == 0) { return; } - AudioDiskstream *ds; - - if ((ds = session->diskstream_by_id (dstream)) != 0) { - Port *port = ds->io()->input (0); - port->request_monitor_input (!port->monitoring_input()); - } -} - -void -ARDOUR_UI::toggle_record_enable (guint32 dstream) -{ - if (session == 0) { - return; - } + Route* r; + + if ((r = session->route_by_remote_id (dstream)) != 0) { - AudioDiskstream *ds; + AudioTrack* at; - if ((ds = session->diskstream_by_id (dstream)) != 0) { - ds->set_record_enabled (!ds->record_enabled(), this); + if ((at = dynamic_cast<AudioTrack*>(r)) != 0) { + at->disk_stream().set_record_enabled (!at->disk_stream().record_enabled(), this); + } } } @@ -1385,63 +1380,6 @@ ARDOUR_UI::stop_blinking () } } - -void -ARDOUR_UI::add_diskstream_to_menu (AudioDiskstream& dstream) -{ - using namespace Gtk; - using namespace Menu_Helpers; - - if (dstream.hidden()) { - return; - } - - MenuList& items = diskstream_menu->items(); - items.push_back (MenuElem (dstream.name(), bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), (gint32) dstream.id()))); -} - -void -ARDOUR_UI::diskstream_selected (gint32 id) -{ - selected_dstream = id; - Main::quit (); -} - -gint32 -ARDOUR_UI::select_diskstream (GdkEventButton *ev) -{ - using namespace Gtk; - using namespace Menu_Helpers; - - if (session == 0) { - return -1; - } - - diskstream_menu = new Menu(); - diskstream_menu->set_name ("ArdourContextMenu"); - using namespace Gtk; - using namespace Menu_Helpers; - - MenuList& items = diskstream_menu->items(); - items.push_back (MenuElem (_("No Stream"), (bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), -1)))); - - session->foreach_audio_diskstream (this, &ARDOUR_UI::add_diskstream_to_menu); - - if (ev) { - diskstream_menu->popup (ev->button, ev->time); - } else { - diskstream_menu->popup (0, 0); - } - - selected_dstream = -1; - - Main::run (); - - delete diskstream_menu; - - return selected_dstream; -} - void ARDOUR_UI::name_io_setup (AudioEngine& engine, string& buf, diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h index 678342f32b..e9fae63677 100644 --- a/gtk2_ardour/ardour_ui.h +++ b/gtk2_ardour/ardour_ui.h @@ -154,8 +154,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI void toggle_tempo_window (); void toggle_editing_space(); - gint32 select_diskstream (GdkEventButton *ev); - Gtk::Tooltips& tooltips() { return _tooltips; } static sigc::signal<void,bool> Blink; @@ -536,14 +534,8 @@ class ARDOUR_UI : public Gtkmm2ext::UI void save_template (); - void session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode); - void add_diskstream_to_menu (ARDOUR::AudioDiskstream&); - void diskstream_selected (gint32); - Gtk::Menu *diskstream_menu; - gint32 selected_dstream; - void set_transport_sensitivity (bool); void remove_last_capture (); @@ -626,8 +618,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI void test_binding_action (const char *); void start_keyboard_prefix(); - void toggle_record_enable (guint32); - void toggle_monitor_enable (guint32); + void toggle_record_enable (uint32_t); uint32_t rec_enabled_diskstreams; void count_recenabled_diskstreams (ARDOUR::AudioDiskstream&); diff --git a/gtk2_ardour/audio_time_axis.cc b/gtk2_ardour/audio_time_axis.cc index 01205abfc8..42bf3f5647 100644 --- a/gtk2_ardour/audio_time_axis.cc +++ b/gtk2_ardour/audio_time_axis.cc @@ -31,10 +31,10 @@ #include <pbd/stl_delete.h> #include <pbd/whitespace.h> -#include <gtkmm2ext/bindable_button.h> #include <gtkmm2ext/gtk_ui.h> #include <gtkmm2ext/selector.h> #include <gtkmm2ext/stop_signal.h> +#include <gtkmm2ext/bindable_button.h> #include <gtkmm2ext/utils.h> #include <ardour/audioplaylist.h> @@ -120,11 +120,9 @@ AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session& sess, Route& rt ignore_toggle = false; - rec_enable_button->set_active (false); mute_button->set_active (false); solo_button->set_active (false); - rec_enable_button->set_name ("TrackRecordEnableButton"); mute_button->set_name ("TrackMuteButton"); solo_button->set_name ("SoloButton"); edit_group_button.set_name ("TrackGroupButton"); @@ -138,7 +136,6 @@ AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session& sess, Route& rt solo_button->signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false); mute_button->signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false); - rec_enable_button->signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false); playlist_button.signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false); automation_button.signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false); size_button.signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false); @@ -149,7 +146,6 @@ AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session& sess, Route& rt solo_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::solo_release), false); mute_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::mute_press), false); mute_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::mute_release), false); - rec_enable_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::rec_enable_press)); edit_group_button.signal_button_release_event().connect (mem_fun(*this, &AudioTimeAxisView::edit_click), false); playlist_button.signal_clicked().connect (mem_fun(*this, &AudioTimeAxisView::playlist_click)); automation_button.signal_clicked().connect (mem_fun(*this, &AudioTimeAxisView::automation_click)); @@ -158,14 +154,19 @@ AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session& sess, Route& rt hide_button.signal_clicked().connect (mem_fun(*this, &AudioTimeAxisView::hide_click)); if (is_audio_track()) { + rec_enable_button->set_active (false); + rec_enable_button->set_name ("TrackRecordEnableButton"); + rec_enable_button->signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false); + rec_enable_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::rec_enable_press)); controls_table.attach (*rec_enable_button, 5, 6, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0); + ARDOUR_UI::instance()->tooltips().set_tip(*rec_enable_button, _("Record")); } + controls_table.attach (*mute_button, 6, 7, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0); controls_table.attach (*solo_button, 7, 8, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::FILL|Gtk::EXPAND, 0, 0); controls_table.attach (edit_group_button, 6, 7, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0); - ARDOUR_UI::instance()->tooltips().set_tip(*rec_enable_button, _("Record")); ARDOUR_UI::instance()->tooltips().set_tip(*solo_button,_("Solo")); ARDOUR_UI::instance()->tooltips().set_tip(*mute_button,_("Mute")); ARDOUR_UI::instance()->tooltips().set_tip(edit_group_button,_("Edit Group")); @@ -1876,7 +1877,6 @@ AudioTimeAxisView::map_frozen () ENSURE_GUI_THREAD (mem_fun(*this, &AudioTimeAxisView::map_frozen)); - switch (audio_track()->freeze_state()) { case AudioTrack::Frozen: playlist_button.set_sensitive (false); diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index be2f3ba44f..9e2fda142e 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -40,7 +40,7 @@ #include <gtkmm2ext/click_box.h> #include <gtkmm2ext/dndtreeview.h> -#include <ardour/stateful.h> +#include <pbd/stateful.h> #include <ardour/session.h> #include <ardour/tempo.h> #include <ardour/location.h> diff --git a/gtk2_ardour/gain_meter.cc b/gtk2_ardour/gain_meter.cc index b7746c4b19..7fa2c33335 100644 --- a/gtk2_ardour/gain_meter.cc +++ b/gtk2_ardour/gain_meter.cc @@ -99,18 +99,13 @@ GainMeter::GainMeter (IO& io, Session& s) gain_slider = manage (new VSliderController (slider, rail, &gain_adjustment, - & _io.midi_gain_control(), + _io.gain_control(), false)); gain_slider->signal_button_press_event().connect (mem_fun(*this, &GainMeter::start_gain_touch)); gain_slider->signal_button_release_event().connect (mem_fun(*this, &GainMeter::end_gain_touch)); gain_slider->set_name ("MixerGainMeter"); - if (_session.midi_port()) { - _io.set_midi_to_gain_function (slider_position_to_gain); - _io.set_gain_to_midi_function (gain_to_slider_position); - } - gain_display.set_print_func (_gain_printer, this); gain_display_box.set_spacing (2); diff --git a/gtk2_ardour/gain_meter.h b/gtk2_ardour/gain_meter.h index ddf93b579f..0ed09ee383 100644 --- a/gtk2_ardour/gain_meter.h +++ b/gtk2_ardour/gain_meter.h @@ -34,8 +34,8 @@ #include <ardour/types.h> -#include <gtkmm2ext/slider_controller.h> #include <gtkmm2ext/click_box.h> +#include <gtkmm2ext/slider_controller.h> #include "enums.h" diff --git a/gtk2_ardour/keyboard.h b/gtk2_ardour/keyboard.h index 06ed4c800d..c13b06afe5 100644 --- a/gtk2_ardour/keyboard.h +++ b/gtk2_ardour/keyboard.h @@ -28,7 +28,7 @@ #include <gtk/gtk.h> #include <ardour/types.h> -#include <ardour/stateful.h> +#include <pbd/stateful.h> #include "selection.h" diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc index 47d884be5e..9913e483fa 100644 --- a/gtk2_ardour/mixer_strip.cc +++ b/gtk2_ardour/mixer_strip.cc @@ -27,10 +27,10 @@ #include <gtkmm2ext/gtk_ui.h> #include <gtkmm2ext/utils.h> #include <gtkmm2ext/choice.h> -#include <gtkmm2ext/slider_controller.h> #include <gtkmm2ext/stop_signal.h> -#include <gtkmm2ext/bindable_button.h> #include <gtkmm2ext/doi.h> +#include <gtkmm2ext/slider_controller.h> +#include <gtkmm2ext/bindable_button.h> #include <ardour/ardour.h> #include <ardour/session.h> @@ -52,7 +52,6 @@ #include "keyboard.h" #include "plugin_selector.h" #include "public_editor.h" - #include "plugin_ui.h" #include "send_ui.h" #include "io_selector.h" @@ -159,9 +158,6 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, Route& rt, bool in_mixer) /* XXX what is this meant to do? */ //meter_point_button.signal_button_release_event().connect (mem_fun (gpm, &GainMeter::meter_release), false); - rec_enable_button->set_name ("MixerRecordEnableButton"); - rec_enable_button->unset_flags (Gtk::CAN_FOCUS); - solo_button->set_name ("MixerSoloButton"); mute_button->set_name ("MixerMuteButton"); @@ -191,6 +187,10 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, Route& rt, bool in_mixer) if (is_audio_track()) { + rec_enable_button->set_name ("MixerRecordEnableButton"); + rec_enable_button->unset_flags (Gtk::CAN_FOCUS); + rec_enable_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::rec_enable_press)); + AudioTrack* at = dynamic_cast<AudioTrack*>(&_route); at->FreezeChange.connect (mem_fun(*this, &MixerStrip::map_frozen)); @@ -301,7 +301,6 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, Route& rt, bool in_mixer) input_button.signal_button_press_event().connect (mem_fun(*this, &MixerStrip::input_press), false); output_button.signal_button_press_event().connect (mem_fun(*this, &MixerStrip::output_press), false); - rec_enable_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::rec_enable_press)); solo_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::solo_press), false); solo_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::solo_release), false); mute_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::mute_press), false); @@ -414,7 +413,9 @@ MixerStrip::set_width (Width w) set_size_request (-1, -1); xml_node->add_property ("strip_width", "wide"); - rec_enable_button->set_label (_("record")); + if (rec_enable_button) { + rec_enable_button->set_label (_("record")); + } mute_button->set_label (_("mute")); solo_button->set_label (_("solo")); @@ -435,7 +436,9 @@ MixerStrip::set_width (Width w) set_size_request (50, -1); xml_node->add_property ("strip_width", "narrow"); - rec_enable_button->set_label (_("Rec")); + if (rec_enable_button) { + rec_enable_button->set_label (_("Rec")); + } mute_button->set_label (_("M")); solo_button->set_label (_("S")); @@ -1200,7 +1203,9 @@ void MixerStrip::engine_stopped () { input_button.set_sensitive (false); - rec_enable_button->set_sensitive (false); + if (rec_enable_button) { + rec_enable_button->set_sensitive (false); + } output_button.set_sensitive (false); } @@ -1208,7 +1213,9 @@ void MixerStrip::engine_running () { input_button.set_sensitive (true); - rec_enable_button->set_sensitive (true); + if (rec_enable_button) { + rec_enable_button->set_sensitive (true); + } output_button.set_sensitive (true); } diff --git a/gtk2_ardour/mixer_strip.h b/gtk2_ardour/mixer_strip.h index 0cc8fed8e3..c914d12404 100644 --- a/gtk2_ardour/mixer_strip.h +++ b/gtk2_ardour/mixer_strip.h @@ -37,14 +37,15 @@ #include <gtkmm/adjustment.h> #include <gtkmm2ext/auto_spin.h> -#include <gtkmm2ext/slider_controller.h> #include <gtkmm2ext/click_box.h> +#include <gtkmm2ext/slider_controller.h> + +#include <pbd/stateful.h> #include <ardour/types.h> #include <ardour/ardour.h> #include <ardour/io.h> #include <ardour/insert.h> -#include <ardour/stateful.h> #include <ardour/redirect.h> #include <pbd/fastlog.h> diff --git a/gtk2_ardour/mixer_ui.h b/gtk2_ardour/mixer_ui.h index 5108df6014..864a110de7 100644 --- a/gtk2_ardour/mixer_ui.h +++ b/gtk2_ardour/mixer_ui.h @@ -33,8 +33,9 @@ #include <gtkmm/menu.h> #include <gtkmm/treeview.h> +#include <pbd/stateful.h> + #include <ardour/ardour.h> -#include <ardour/stateful.h> #include <ardour/io.h> #include "keyboard_target.h" diff --git a/gtk2_ardour/panner_ui.cc b/gtk2_ardour/panner_ui.cc index 63a19867a8..fac92a2844 100644 --- a/gtk2_ardour/panner_ui.cc +++ b/gtk2_ardour/panner_ui.cc @@ -316,13 +316,9 @@ PannerUI::setup_pan () _io.panner()[asz]->Changed.connect (bind (mem_fun(*this, &PannerUI::pan_value_changed), (uint32_t) asz)); bc = new BarController (*pan_adjustments[asz], - &_io.panner()[asz]->midi_control(), + _io.panner()[asz]->control(), bind (mem_fun(*this, &PannerUI::pan_printer), pan_adjustments[asz])); - if (_session.midi_port()) { - _io.panner()[asz]->reset_midi_control (_session.midi_port(), true); - } - bc->set_name ("PanSlider"); bc->set_shadow_type (Gtk::SHADOW_NONE); bc->set_style (BarController::Line); diff --git a/gtk2_ardour/panner_ui.h b/gtk2_ardour/panner_ui.h index 80b14465cf..86a8575802 100644 --- a/gtk2_ardour/panner_ui.h +++ b/gtk2_ardour/panner_ui.h @@ -31,8 +31,8 @@ #include <gtkmm/togglebutton.h> #include <gtkmm/button.h> -#include <gtkmm2ext/slider_controller.h> #include <gtkmm2ext/click_box.h> +#include <gtkmm2ext/slider_controller.h> #include "enums.h" diff --git a/gtk2_ardour/playlist_selector.cc b/gtk2_ardour/playlist_selector.cc index f1a975d5dc..9022c8acb4 100644 --- a/gtk2_ardour/playlist_selector.cc +++ b/gtk2_ardour/playlist_selector.cc @@ -189,7 +189,7 @@ PlaylistSelector::add_playlist_to_map (Playlist *pl) if ((x = dspl_map.find (apl->get_orig_diskstream_id())) == dspl_map.end()) { - pair<ARDOUR::id_t,list<Playlist*>*> newp (apl->get_orig_diskstream_id(), new list<Playlist*>); + pair<PBD::ID,list<Playlist*>*> newp (apl->get_orig_diskstream_id(), new list<Playlist*>); x = dspl_map.insert (dspl_map.end(), newp); } diff --git a/gtk2_ardour/playlist_selector.h b/gtk2_ardour/playlist_selector.h index 863d6cc7f3..2829ba54bb 100644 --- a/gtk2_ardour/playlist_selector.h +++ b/gtk2_ardour/playlist_selector.h @@ -46,7 +46,7 @@ class PlaylistSelector : public ArdourDialog void show_for (RouteUI*); private: - typedef std::map<ARDOUR::id_t,std::list<ARDOUR::Playlist*>*> DSPL_Map; + typedef std::map<PBD::ID,std::list<ARDOUR::Playlist*>*> DSPL_Map; ARDOUR::Session* session; Gtk::ScrolledWindow scroller; diff --git a/gtk2_ardour/plugin_ui.cc b/gtk2_ardour/plugin_ui.cc index 749ab9d4ac..e5c8534df6 100644 --- a/gtk2_ardour/plugin_ui.cc +++ b/gtk2_ardour/plugin_ui.cc @@ -29,10 +29,10 @@ #include <gtkmm2ext/click_box.h> #include <gtkmm2ext/fastmeter.h> -#include <gtkmm2ext/slider_controller.h> #include <gtkmm2ext/barcontroller.h> #include <gtkmm2ext/utils.h> #include <gtkmm2ext/doi.h> +#include <gtkmm2ext/slider_controller.h> #include <midi++/manager.h> @@ -263,7 +263,7 @@ PluginUI::build (AudioEngine &engine) } } - if ((cui = build_control_ui (engine, i, plugin.get_nth_midi_control (i))) == 0) { + if ((cui = build_control_ui (engine, i, plugin.get_nth_control (i))) == 0) { error << string_compose(_("Plugin Editor: could not build control element for port %1"), i) << endmsg; continue; } @@ -419,7 +419,7 @@ PluginUI::print_parameter (char *buf, uint32_t len, uint32_t param) } PluginUI::ControlUI* -PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, MIDI::Controllable* mcontrol) +PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, PBD::Controllable* mcontrol) { ControlUI* control_ui; @@ -516,7 +516,7 @@ PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, MIDI::Contr } else { sigc::slot<void,char*,uint32_t> pslot = sigc::bind (mem_fun(*this, &PluginUI::print_parameter), (uint32_t) port_index); - control_ui->control = new BarController (*control_ui->adjustment, mcontrol, pslot); + control_ui->control = new BarController (*control_ui->adjustment, *mcontrol, pslot); // should really match the height of the text in the automation button+label control_ui->control->set_size_request (200, 22); control_ui->control->set_name (X_("PluginSlider")); diff --git a/gtk2_ardour/plugin_ui.h b/gtk2_ardour/plugin_ui.h index e5800e8ece..351ab0dc2b 100644 --- a/gtk2_ardour/plugin_ui.h +++ b/gtk2_ardour/plugin_ui.h @@ -52,7 +52,7 @@ namespace ARDOUR { class Redirect; } -namespace MIDI { +namespace PBD { class Controllable; } @@ -174,7 +174,7 @@ class PluginUI : public PlugUIBase, public Gtk::VBox void output_update(); void build (ARDOUR::AudioEngine &); - ControlUI* build_control_ui (ARDOUR::AudioEngine &, guint32 port_index, MIDI::Controllable *); + ControlUI* build_control_ui (ARDOUR::AudioEngine &, guint32 port_index, PBD::Controllable *); std::vector<string> setup_scale_values(guint32 port_index, ControlUI* cui); void control_adjustment_changed (ControlUI* cui); void parameter_changed (uint32_t, float, ControlUI* cui); diff --git a/gtk2_ardour/redirect_box.h b/gtk2_ardour/redirect_box.h index bc162fac17..0a4a6d5dee 100644 --- a/gtk2_ardour/redirect_box.h +++ b/gtk2_ardour/redirect_box.h @@ -33,11 +33,12 @@ #include <gtkmm2ext/click_box.h> #include <gtkmm2ext/dndtreeview.h> +#include <pbd/stateful.h> + #include <ardour/types.h> #include <ardour/ardour.h> #include <ardour/io.h> #include <ardour/insert.h> -#include <ardour/stateful.h> #include <ardour/redirect.h> #include <pbd/fastlog.h> diff --git a/gtk2_ardour/route_params_ui.h b/gtk2_ardour/route_params_ui.h index 96b2041db4..29f5b9112a 100644 --- a/gtk2_ardour/route_params_ui.h +++ b/gtk2_ardour/route_params_ui.h @@ -33,8 +33,9 @@ #include <gtkmm/togglebutton.h> #include <gtkmm/treeview.h> +#include <pbd/stateful.h> + #include <ardour/ardour.h> -#include <ardour/stateful.h> #include <ardour/io.h> #include <ardour/redirect.h> diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc index 06f86bb545..a02814839a 100644 --- a/gtk2_ardour/route_ui.cc +++ b/gtk2_ardour/route_ui.cc @@ -21,8 +21,8 @@ #include <gtkmm2ext/gtk_ui.h> #include <gtkmm2ext/stop_signal.h> #include <gtkmm2ext/choice.h> -#include <gtkmm2ext/bindable_button.h> #include <gtkmm2ext/doi.h> +#include <gtkmm2ext/bindable_button.h> #include <ardour/route_group.h> @@ -67,11 +67,9 @@ RouteUI::RouteUI (ARDOUR::Route& rt, ARDOUR::Session& sess, const char* m_name, _route.GoingAway.connect (mem_fun (*this, &RouteUI::route_removed)); _route.active_changed.connect (mem_fun (*this, &RouteUI::route_active_changed)); - mute_button = manage (new BindableToggleButton (& _route.midi_mute_control(), m_name )); - mute_button->set_bind_button_state (2, GDK_CONTROL_MASK); - solo_button = manage (new BindableToggleButton (& _route.midi_solo_control(), s_name )); - solo_button->set_bind_button_state (2, GDK_CONTROL_MASK); - + mute_button = manage (new BindableToggleButton (_route.mute_control(), m_name )); + solo_button = manage (new BindableToggleButton (_route.solo_control(), s_name )); + if (is_audio_track()) { AudioTrack* at = dynamic_cast<AudioTrack*>(&_route); @@ -79,20 +77,18 @@ RouteUI::RouteUI (ARDOUR::Route& rt, ARDOUR::Session& sess, const char* m_name, _session.RecordStateChanged.connect (mem_fun (*this, &RouteUI::session_rec_enable_changed)); - rec_enable_button = manage (new BindableToggleButton (& at->midi_rec_enable_control(), r_name )); - rec_enable_button->set_bind_button_state (2, GDK_CONTROL_MASK); + rec_enable_button = manage (new BindableToggleButton (at->rec_enable_control(), r_name )); - } else { - rec_enable_button = manage (new BindableToggleButton (0, r_name )); - } + rec_enable_button->unset_flags (Gtk::CAN_FOCUS); + + update_rec_display (); + } mute_button->unset_flags (Gtk::CAN_FOCUS); solo_button->unset_flags (Gtk::CAN_FOCUS); - rec_enable_button->unset_flags (Gtk::CAN_FOCUS); /* map the current state */ - update_rec_display (); map_frozen (); } @@ -272,7 +268,7 @@ RouteUI::solo_release(GdkEventButton* ev) gint RouteUI::rec_enable_press(GdkEventButton* ev) { - if (!ignore_toggle && is_audio_track()) { + if (!ignore_toggle && is_audio_track() && rec_enable_button) { if (ev->button == 2 && Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) { // do nothing on midi bind event @@ -484,7 +480,7 @@ RouteUI::build_solo_menu (void) check->show_all(); items.push_back (SeparatorElem()); - items.push_back (MenuElem (_("MIDI Bind"), mem_fun (*mute_button, &BindableToggleButton::midi_learn))); + // items.push_back (MenuElem (_("MIDI Bind"), mem_fun (*mute_button, &BindableToggleButton::midi_learn))); } @@ -527,7 +523,7 @@ RouteUI::build_mute_menu(void) check->show_all(); items.push_back (SeparatorElem()); - items.push_back (MenuElem (_("MIDI Bind"), mem_fun (*mute_button, &BindableToggleButton::midi_learn))); + // items.push_back (MenuElem (_("MIDI Bind"), mem_fun (*mute_button, &BindableToggleButton::midi_learn))); } void diff --git a/gtk2_ardour/route_ui.h b/gtk2_ardour/route_ui.h index 69c9b7f5a9..df2e3aa319 100644 --- a/gtk2_ardour/route_ui.h +++ b/gtk2_ardour/route_ui.h @@ -29,10 +29,6 @@ #include "axis_view.h" -namespace Gtkmm2ext { - class BindableToggleButton; -} - namespace ARDOUR { class AudioTrack; } @@ -43,6 +39,8 @@ namespace Gtk { class Widget; } +class BindableToggleButton; + class RouteUI : public virtual AxisView { public: @@ -65,9 +63,9 @@ class RouteUI : public virtual AxisView bool ignore_toggle; bool wait_for_release; - Gtkmm2ext::BindableToggleButton * mute_button; - Gtkmm2ext::BindableToggleButton * solo_button; - Gtkmm2ext::BindableToggleButton * rec_enable_button; + BindableToggleButton* mute_button; + BindableToggleButton* solo_button; + BindableToggleButton* rec_enable_button; virtual string solo_button_name () const { return "SoloButton"; } virtual string safe_solo_button_name () const { return "SafeSoloButton"; } diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript index 8df33c1f60..bca0a83d1e 100644 --- a/libs/ardour/SConscript +++ b/libs/ardour/SConscript @@ -87,7 +87,6 @@ sndfile_helpers.cc sndfilesource.cc source.cc state_manager.cc -stateful.cc tempo.cc utils.cc version.cc diff --git a/libs/ardour/ardour/ardour.h b/libs/ardour/ardour/ardour.h index c0dfea9a95..dba588702f 100644 --- a/libs/ardour/ardour/ardour.h +++ b/libs/ardour/ardour/ardour.h @@ -58,7 +58,7 @@ namespace ARDOUR { const layer_t max_layer = UCHAR_MAX; - id_t new_id(); + microseconds_t get_microseconds (); Change new_change (); diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h index 9355a3fccb..8409f99b51 100644 --- a/libs/ardour/ardour/audio_diskstream.h +++ b/libs/ardour/ardour/audio_diskstream.h @@ -33,7 +33,7 @@ #include <pbd/fastlog.h> #include <pbd/ringbufferNPT.h> - +#include <pbd/stateful.h> #include <ardour/ardour.h> #include <ardour/configuration.h> @@ -42,7 +42,6 @@ #include <ardour/route.h> #include <ardour/port.h> #include <ardour/utils.h> -#include <ardour/stateful.h> struct tm; @@ -225,7 +224,7 @@ class AudioDiskstream : public Stateful, public sigc::trackable void handle_input_change (IOChange, void *src); - id_t id() const { return _id; } + const PBD::ID& id() const { return _id; } XMLNode* deprecated_io_node; @@ -318,7 +317,7 @@ class AudioDiskstream : public Stateful, public sigc::trackable ARDOUR::IO* _io; ChannelList channels; uint32_t _n_channels; - id_t _id; + PBD::ID _id; mutable gint _record_enabled; AudioPlaylist* _playlist; diff --git a/libs/ardour/ardour/audio_track.h b/libs/ardour/ardour/audio_track.h index 1c17cbc859..da12746c85 100644 --- a/libs/ardour/ardour/audio_track.h +++ b/libs/ardour/ardour/audio_track.h @@ -55,7 +55,7 @@ class AudioTrack : public Route AudioDiskstream& disk_stream() const { return *diskstream; } int set_diskstream (AudioDiskstream&, void *); int use_diskstream (string name); - int use_diskstream (id_t id); + int use_diskstream (const PBD::ID& id); TrackMode mode() const { return _mode; } void set_mode (TrackMode m); @@ -88,13 +88,10 @@ class AudioTrack : public Route XMLNode& get_template(); int set_state(const XMLNode& node); - MIDI::Controllable& midi_rec_enable_control() { - return _midi_rec_enable_control; + PBD::Controllable& rec_enable_control() { + return _rec_enable_control; } - void reset_midi_control (MIDI::Port*, bool); - void send_all_midi_feedback (); - bool record_enabled() const; void set_meter_point (MeterPoint, void* src); @@ -116,9 +113,9 @@ class AudioTrack : public Route FreezeRecordInsertInfo(XMLNode& st) : state (st), insert (0) {} - XMLNode state; - Insert* insert; - id_t id; + XMLNode state; + Insert* insert; + PBD::ID id; UndoAction memento; }; @@ -151,17 +148,16 @@ class AudioTrack : public Route void set_state_part_two (); void set_state_part_three (); - struct MIDIRecEnableControl : public MIDI::Controllable { - MIDIRecEnableControl (AudioTrack&, MIDI::Port *); - void set_value (float); - void send_feedback (bool); - MIDI::byte* write_feedback (MIDI::byte* buf, int32_t& bufsize, bool val, bool force = false); - AudioTrack& track; - bool setting; - bool last_written; + struct RecEnableControllable : public PBD::Controllable { + RecEnableControllable (AudioTrack&); + + void set_value (float); + float get_value (void) const; + + AudioTrack& track; }; - MIDIRecEnableControl _midi_rec_enable_control; + RecEnableControllable _rec_enable_control; bool _destructive; }; diff --git a/libs/ardour/ardour/audiosource.h b/libs/ardour/ardour/audiosource.h index 1dcf5b42f3..492fc9ac2e 100644 --- a/libs/ardour/ardour/audiosource.h +++ b/libs/ardour/ardour/audiosource.h @@ -33,7 +33,7 @@ #include <ardour/source.h> #include <ardour/ardour.h> -#include <ardour/stateful.h> +#include <pbd/stateful.h> #include <pbd/xml++.h> using std::list; diff --git a/libs/ardour/ardour/configuration.h b/libs/ardour/ardour/configuration.h index 60b5e8a2c3..cc4376f781 100644 --- a/libs/ardour/ardour/configuration.h +++ b/libs/ardour/ardour/configuration.h @@ -27,8 +27,9 @@ #include <sys/types.h> #include <string> +#include <pbd/stateful.h> + #include <ardour/types.h> -#include <ardour/stateful.h> #include <ardour/utils.h> #include <ardour/configuration_variable.h> diff --git a/libs/ardour/ardour/connection.h b/libs/ardour/ardour/connection.h index 899bffc06a..da4d4e2684 100644 --- a/libs/ardour/ardour/connection.h +++ b/libs/ardour/ardour/connection.h @@ -25,7 +25,7 @@ #include <string> #include <sigc++/signal.h> #include <glibmm/thread.h> -#include <ardour/stateful.h> +#include <pbd/stateful.h> using std::vector; using std::string; diff --git a/libs/ardour/ardour/control_protocol_manager.h b/libs/ardour/ardour/control_protocol_manager.h index 03b21a299c..9202696dff 100644 --- a/libs/ardour/ardour/control_protocol_manager.h +++ b/libs/ardour/ardour/control_protocol_manager.h @@ -8,7 +8,7 @@ #include <glibmm/thread.h> -#include <ardour/stateful.h> +#include <pbd/stateful.h> namespace ARDOUR { diff --git a/libs/ardour/ardour/insert.h b/libs/ardour/ardour/insert.h index 803e16497d..2d6b672064 100644 --- a/libs/ardour/ardour/insert.h +++ b/libs/ardour/ardour/insert.h @@ -133,9 +133,6 @@ class PluginInsert : public Insert bool is_generator() const; - void reset_midi_control (MIDI::Port*, bool); - void send_all_midi_feedback (); - void set_parameter (uint32_t port, float val); AutoState get_port_automation_state (uint32_t port); diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h index 8ae45fe65c..474d38a5bc 100644 --- a/libs/ardour/ardour/io.h +++ b/libs/ardour/ardour/io.h @@ -31,11 +31,10 @@ #include <pbd/fastlog.h> #include <pbd/undo.h> - -#include <midi++/controllable.h> +#include <pbd/stateful.h> +#include <pbd/controllable.h> #include <ardour/ardour.h> -#include <ardour/stateful.h> #include <ardour/utils.h> #include <ardour/state_manager.h> #include <ardour/curve.h> @@ -177,25 +176,10 @@ class IO : public Stateful, public ARDOUR::StateManager static sigc::signal<void,uint32_t> MoreOutputs; static sigc::signal<int> PortsCreated; - /* MIDI control */ - - void set_midi_to_gain_function (gain_t (*function)(double val)) { - _midi_gain_control.midi_to_gain = function; - } - - void set_gain_to_midi_function (double (*function)(gain_t gain)) { - _midi_gain_control.gain_to_midi = function; - } - - MIDI::Controllable& midi_gain_control() { - return _midi_gain_control; + PBD::Controllable& gain_control() { + return _gain_control; } - virtual void reset_midi_control (MIDI::Port*, bool on); - - virtual void send_all_midi_feedback (); - virtual MIDI::byte* write_midi_feedback (MIDI::byte*, int32_t& bufsize); - /* Peak metering */ float peak_input_power (uint32_t n) { @@ -257,7 +241,7 @@ public: void start_pan_touch (uint32_t which); void end_pan_touch (uint32_t which); - id_t id() const { return _id; } + const PBD::ID& id() const { return _id; } void defer_pan_reset (); void allow_pan_reset (); @@ -286,7 +270,7 @@ public: string _name; Connection* _input_connection; Connection* _output_connection; - id_t _id; + PBD::ID _id; bool no_panner_reset; XMLNode* deferred_state; @@ -300,31 +284,22 @@ public: static void apply_declick (vector<Sample*>&, uint32_t nbufs, jack_nframes_t nframes, gain_t initial, gain_t target, bool invert_polarity); - struct MIDIGainControl : public MIDI::Controllable { - MIDIGainControl (IO&, MIDI::Port *); - void set_value (float); - - void send_feedback (gain_t); - MIDI::byte* write_feedback (MIDI::byte* buf, int32_t& bufsize, gain_t val, bool force = false); - + struct GainControllable : public PBD::Controllable { + GainControllable (IO& i) : io (i) {} + + void set_value (float val); + float get_value (void) const; + IO& io; - bool setting; - MIDI::byte last_written; - - gain_t (*midi_to_gain) (double val); - double (*gain_to_midi) (gain_t gain); }; - MIDIGainControl _midi_gain_control; + GainControllable _gain_control; /* state management */ Change restore_state (State&); StateManager::State* state_factory (std::string why) const; - bool get_midi_node_info (XMLNode * node, MIDI::eventType & ev, MIDI::channel_t & chan, MIDI::byte & additional); - bool set_midi_node_info (XMLNode * node, MIDI::eventType ev, MIDI::channel_t chan, MIDI::byte additional); - /* automation */ jack_nframes_t last_automation_snapshot; diff --git a/libs/ardour/ardour/ladspa_plugin.h b/libs/ardour/ardour/ladspa_plugin.h index 2451953ce5..e4aba93ef6 100644 --- a/libs/ardour/ardour/ladspa_plugin.h +++ b/libs/ardour/ardour/ladspa_plugin.h @@ -27,12 +27,12 @@ #include <string> #include <dlfcn.h> -#include <midi++/controllable.h> #include <sigc++/signal.h> +#include <pbd/stateful.h> + #include <jack/types.h> #include <ardour/ladspa.h> -#include <ardour/stateful.h> #include <ardour/plugin_state.h> #include <ardour/plugin.h> #include <ardour/ladspa_plugin.h> diff --git a/libs/ardour/ardour/location.h b/libs/ardour/ardour/location.h index 75f4c5d12a..2c9f947541 100644 --- a/libs/ardour/ardour/location.h +++ b/libs/ardour/ardour/location.h @@ -32,10 +32,10 @@ #include <glibmm/thread.h> #include <pbd/undo.h> +#include <pbd/stateful.h> -#include "ardour.h" -#include "stateful.h" -#include "state_manager.h" +#include <ardour/ardour.h> +#include <ardour/state_manager.h> using std::string; diff --git a/libs/ardour/ardour/named_selection.h b/libs/ardour/ardour/named_selection.h index 91bb816181..87b71e73ff 100644 --- a/libs/ardour/ardour/named_selection.h +++ b/libs/ardour/ardour/named_selection.h @@ -24,7 +24,7 @@ #include <string> #include <list> -#include <ardour/stateful.h> +#include <pbd/stateful.h> class XMLNode; diff --git a/libs/ardour/ardour/panner.h b/libs/ardour/ardour/panner.h index 806f350e03..37c985a2ef 100644 --- a/libs/ardour/ardour/panner.h +++ b/libs/ardour/ardour/panner.h @@ -27,10 +27,10 @@ #include <iostream> #include <sigc++/signal.h> -#include <midi++/controllable.h> +#include <pbd/stateful.h> +#include <pbd/controllable.h> #include <ardour/types.h> -#include <ardour/stateful.h> #include <ardour/curve.h> using std::istream; @@ -75,24 +75,7 @@ class StreamPanner : public sigc::trackable, public Stateful virtual void set_automation_state (AutoState) = 0; virtual void set_automation_style (AutoStyle) = 0; - /* MIDI control */ - - struct MIDIControl : public MIDI::Controllable { - MIDIControl (StreamPanner&, MIDI::Port *); - void set_value (float); - void send_feedback (gain_t); - MIDI::byte* write_feedback (MIDI::byte* buf, int32_t& bufsize, gain_t val, bool force = false); - - pan_t (*midi_to_pan)(double val); - double (*pan_to_midi)(pan_t p); - - StreamPanner& sp; - bool setting; - gain_t last_written; - }; - - MIDIControl& midi_control() { return _midi_control; } - void reset_midi_control (MIDI::Port *, bool); + PBD::Controllable& control() { return _control; } /* XXX this is wrong. for multi-dimensional panners, there must surely be more than 1 automation curve. @@ -100,7 +83,6 @@ class StreamPanner : public sigc::trackable, public Stateful virtual Curve& automation() = 0; - virtual int load (istream&, string path, uint32_t&) = 0; virtual int save (ostream&) const = 0; @@ -130,12 +112,20 @@ class StreamPanner : public sigc::trackable, public Stateful float effective_z; bool _muted; - MIDIControl _midi_control; - void add_state (XMLNode&); - bool get_midi_node_info (XMLNode * node, MIDI::eventType & ev, MIDI::channel_t & chan, MIDI::byte & additional); - bool set_midi_node_info (XMLNode * node, MIDI::eventType ev, MIDI::channel_t chan, MIDI::byte additional); + struct PanControllable : public PBD::Controllable { + PanControllable (StreamPanner& p) : panner (p) {} + + StreamPanner& panner; + + void set_value (float); + float get_value (void) const; + bool can_send_feedback() const; + }; + PanControllable _control; + + void add_state (XMLNode&); virtual void update () = 0; }; @@ -290,10 +280,6 @@ class Panner : public std::vector<StreamPanner*>, public Stateful, public sigc:: std::vector<Output> outputs; Session& session() const { return _session; } - void reset_midi_control (MIDI::Port *, bool); - void send_all_midi_feedback (); - MIDI::byte* write_midi_feedback (MIDI::byte*, int32_t& bufsize); - enum LinkDirection { SameDirection, OppositeDirection diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h index c653c8502e..9fb1950bfa 100644 --- a/libs/ardour/ardour/playlist.h +++ b/libs/ardour/ardour/playlist.h @@ -31,12 +31,13 @@ #include <glib.h> #include <sigc++/signal.h> + #include <pbd/undo.h> +#include <pbd/stateful.h> #include <ardour/ardour.h> #include <ardour/crossfade_compare.h> #include <ardour/location.h> -#include <ardour/stateful.h> #include <ardour/state_manager.h> namespace ARDOUR { @@ -86,7 +87,7 @@ class Playlist : public Stateful, public StateManager { void duplicate (Region&, jack_nframes_t position, float times); void nudge_after (jack_nframes_t start, jack_nframes_t distance, bool forwards); - Region* find_region (id_t) const; + Region* find_region (const PBD::ID&) const; Playlist* cut (list<AudioRange>&, bool result_is_hidden = true); Playlist* copy (list<AudioRange>&, bool result_is_hidden = true); @@ -135,8 +136,8 @@ class Playlist : public Stateful, public StateManager { Session& session() { return _session; } - id_t get_orig_diskstream_id () const { return _orig_diskstream_id; } - void set_orig_diskstream_id (id_t did) { _orig_diskstream_id = did; } + const PBD::ID& get_orig_diskstream_id () const { return _orig_diskstream_id; } + void set_orig_diskstream_id (const PBD::ID& did) { _orig_diskstream_id = did; } /* destructive editing */ @@ -190,7 +191,7 @@ class Playlist : public Stateful, public StateManager { bool _frozen; uint32_t subcnt; uint32_t _read_data_count; - id_t _orig_diskstream_id; + PBD::ID _orig_diskstream_id; uint64_t layer_op_counter; jack_nframes_t freeze_length; diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h index 211b00d0bb..e7d05aa352 100644 --- a/libs/ardour/ardour/plugin.h +++ b/libs/ardour/ardour/plugin.h @@ -21,12 +21,13 @@ #ifndef __ardour_ladspa_h__ #define __ardour_ladspa_h__ -#include <midi++/controllable.h> #include <sigc++/signal.h> +#include <pbd/stateful.h> +#include <pbd/controllable.h> + #include <jack/types.h> #include <ardour/types.h> -#include <ardour/stateful.h> #include <ardour/plugin_state.h> #include <ardour/cycles.h> @@ -136,10 +137,7 @@ class Plugin : public Stateful, public sigc::trackable sigc::signal<void,uint32_t,float> ParameterChanged; sigc::signal<void,Plugin *> GoingAway; - void reset_midi_control (MIDI::Port*, bool); - void send_all_midi_feedback (); - MIDI::byte* write_midi_feedback (MIDI::byte*, int32_t& bufsize); - MIDI::Controllable *get_nth_midi_control (uint32_t); + PBD::Controllable *get_nth_control (uint32_t); PluginInfo & get_info() { return _info; } void set_info (const PluginInfo &inf) { _info = inf; } @@ -158,16 +156,14 @@ class Plugin : public Stateful, public sigc::trackable map<string,string> presets; bool save_preset(string name, string domain /* vst, ladspa etc. */); - void setup_midi_controls (); - + void setup_controls (); - struct MIDIPortControl : public MIDI::Controllable { - MIDIPortControl (Plugin&, uint32_t abs_port_id, MIDI::Port *, - float lower, float upper, bool toggled, bool logarithmic); + struct PortControllable : public PBD::Controllable { + PortControllable (Plugin&, uint32_t abs_port_id, + float lower, float upper, bool toggled, bool logarithmic); void set_value (float); - void send_feedback (float); - MIDI::byte* write_feedback (MIDI::byte* buf, int32_t& bufsize, float val, bool force = false); + float get_value () const; Plugin& plugin; uint32_t absolute_port; @@ -176,14 +172,9 @@ class Plugin : public Stateful, public sigc::trackable float range; bool toggled; bool logarithmic; - - bool setting; - float last_written; }; - vector<MIDIPortControl*> midi_controls; - - + vector<PortControllable*> controls; }; /* this is actually defined in plugin_manager.cc */ diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h index aae776625e..baf93a8f77 100644 --- a/libs/ardour/ardour/region.h +++ b/libs/ardour/ardour/region.h @@ -97,7 +97,7 @@ class Region : public Stateful, public StateManager Region (const XMLNode&); ~Region(); - ARDOUR::id_t id() const { return _id; } + const PBD::ID& id() const { return _id; } /* Note: changing the name of a Region does not constitute an edit */ @@ -222,7 +222,7 @@ class Region : public Stateful, public StateManager mutable RegionEditState _first_edit; int _frozen; Glib::Mutex lock; - ARDOUR::id_t _id; + PBD::ID _id; ARDOUR::Playlist* _playlist; mutable uint32_t _read_data_count; // modified in read() Change pending_changed; diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index 5686dfc908..6f0ce0ae4a 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -31,10 +31,10 @@ #include <glibmm/thread.h> #include <pbd/xml++.h> #include <pbd/undo.h> -#include <midi++/controllable.h> +#include <pbd/stateful.h> +#include <pbd/controllable.h> #include <ardour/ardour.h> -#include <ardour/stateful.h> #include <ardour/io.h> #include <ardour/session.h> #include <ardour/redirect.h> @@ -212,34 +212,28 @@ class Route : public IO bool feeds (Route *); set<Route *> fed_by; - struct MIDIToggleControl : public MIDI::Controllable { - enum ToggleType { - MuteControl = 0, - SoloControl - }; - - MIDIToggleControl (Route&, ToggleType, MIDI::Port *); - void set_value (float); - void send_feedback (bool); - MIDI::byte* write_feedback (MIDI::byte* buf, int32_t& bufsize, bool val, bool force = false); - - Route& route; - ToggleType type; - bool setting; - bool last_written; + struct ToggleControllable : public PBD::Controllable { + enum ToggleType { + MuteControl = 0, + SoloControl + }; + + ToggleControllable (Route&, ToggleType); + void set_value (float); + float get_value (void) const; + + Route& route; + ToggleType type; }; - MIDI::Controllable& midi_solo_control() { - return _midi_solo_control; + PBD::Controllable& solo_control() { + return _solo_control; } - MIDI::Controllable& midi_mute_control() { - return _midi_mute_control; + + PBD::Controllable& mute_control() { + return _mute_control; } - virtual void reset_midi_control (MIDI::Port*, bool); - virtual void send_all_midi_feedback (); - virtual MIDI::byte* write_midi_feedback (MIDI::byte*, int32_t& bufsize); - void automation_snapshot (jack_nframes_t now); void protect_automation (); @@ -299,8 +293,8 @@ class Route : public IO std::string _comment; bool _have_internal_generator; - MIDIToggleControl _midi_solo_control; - MIDIToggleControl _midi_mute_control; + ToggleControllable _solo_control; + ToggleControllable _mute_control; void passthru (jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset, int declick, bool meter_inputs); diff --git a/libs/ardour/ardour/route_group.h b/libs/ardour/ardour/route_group.h index c9f966666f..19374b4f65 100644 --- a/libs/ardour/ardour/route_group.h +++ b/libs/ardour/ardour/route_group.h @@ -26,7 +26,7 @@ #include <string> #include <stdint.h> #include <sigc++/signal.h> -#include <ardour/stateful.h> +#include <pbd/stateful.h> #include <ardour/types.h> using std::string; diff --git a/libs/ardour/ardour/send.h b/libs/ardour/ardour/send.h index a94318f2a5..54d4cbd7a9 100644 --- a/libs/ardour/ardour/send.h +++ b/libs/ardour/ardour/send.h @@ -24,12 +24,12 @@ #include <sigc++/signal.h> #include <string> + +#include <pbd/stateful.h> #include <ardour/ardour.h> #include <ardour/audioengine.h> - -#include "io.h" -#include "stateful.h" -#include "redirect.h" +#include <ardour/io.h> +#include <ardour/redirect.h> namespace ARDOUR { diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 811941791a..68a79d7320 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -40,10 +40,11 @@ #include <midi++/types.h> #include <midi++/mmc.h> +#include <pbd/stateful.h> + #include <ardour/ardour.h> #include <ardour/configuration.h> #include <ardour/location.h> -#include <ardour/stateful.h> #include <ardour/gain.h> #include <ardour/io.h> @@ -55,6 +56,10 @@ namespace MIDI { class Port; } +namespace PBD { + class Controllable; +} + namespace ARDOUR { class Port; @@ -262,7 +267,7 @@ class Session : public sigc::trackable, public Stateful vector<Sample*>& get_silent_buffers (uint32_t howmany); vector<Sample*>& get_send_buffers () { return _send_buffers; } - AudioDiskstream *diskstream_by_id (id_t id); + AudioDiskstream *diskstream_by_id (const PBD::ID& id); AudioDiskstream *diskstream_by_name (string name); bool have_captured() const { return _have_captured; } @@ -698,7 +703,7 @@ class Session : public sigc::trackable, public Stateful AudioFileSource *create_audio_source_for_session (ARDOUR::AudioDiskstream&, uint32_t which_channel, bool destructive); - Source *get_source (ARDOUR::id_t); + Source *source_by_id (const PBD::ID&); /* playlist management */ @@ -961,7 +966,13 @@ class Session : public sigc::trackable, public Stateful static apply_gain_to_buffer_t apply_gain_to_buffer; static mix_buffers_with_gain_t mix_buffers_with_gain; static mix_buffers_no_gain_t mix_buffers_no_gain; - + + static sigc::signal<void> SendFeedback; + + /* Controllables */ + + PBD::Controllable* controllable_by_id (const PBD::ID&); + protected: friend class AudioEngine; void set_block_size (jack_nframes_t nframes); @@ -1499,7 +1510,7 @@ class Session : public sigc::trackable, public Stateful /* REGION MANAGEMENT */ mutable Glib::Mutex region_lock; - typedef map<ARDOUR::id_t,AudioRegion *> AudioRegionList; + typedef map<PBD::ID,AudioRegion *> AudioRegionList; AudioRegionList audio_regions; void region_renamed (Region *); @@ -1512,7 +1523,7 @@ class Session : public sigc::trackable, public Stateful /* SOURCES */ mutable Glib::Mutex audio_source_lock; - typedef std::map<id_t, AudioSource *> AudioSourceList; + typedef std::map<PBD::ID,AudioSource *> AudioSourceList; AudioSourceList audio_sources; @@ -1740,6 +1751,13 @@ class Session : public sigc::trackable, public Stateful LayerModel layer_model; CrossfadeModel xfade_model; + + typedef std::list<PBD::Controllable*> Controllables; + Glib::Mutex controllables_lock; + Controllables controllables; + + void add_controllable (PBD::Controllable*); + void remove_controllable (PBD::Controllable*); }; }; /* namespace ARDOUR */ diff --git a/libs/ardour/ardour/session_region.h b/libs/ardour/ardour/session_region.h index 13d88a9aa4..4f0fb92e3b 100644 --- a/libs/ardour/ardour/session_region.h +++ b/libs/ardour/ardour/session_region.h @@ -10,7 +10,7 @@ template<class T> void Session::foreach_audio_region (T *obj, void (T::*func)(Au { Glib::Mutex::Lock lm (region_lock); for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); i++) { - (obj->*func) ((*i).second); + (obj->*func) (i->second); } } diff --git a/libs/ardour/ardour/source.h b/libs/ardour/ardour/source.h index f3133c71cd..f57ea79854 100644 --- a/libs/ardour/ardour/source.h +++ b/libs/ardour/ardour/source.h @@ -25,8 +25,9 @@ #include <sigc++/signal.h> +#include <pbd/stateful.h> + #include <ardour/ardour.h> -#include <ardour/stateful.h> namespace ARDOUR { @@ -40,7 +41,7 @@ class Source : public Stateful, public sigc::trackable std::string name() const { return _name; } int set_name (std::string str, bool destructive); - ARDOUR::id_t id() const { return _id; } + const PBD::ID& id() const { return _id; } uint32_t use_cnt() const { return _use_cnt; } void use (); @@ -60,7 +61,7 @@ class Source : public Stateful, public sigc::trackable time_t _timestamp; private: - ARDOUR::id_t _id; + PBD::ID _id; }; } diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h index 13e8eb6348..db06894607 100644 --- a/libs/ardour/ardour/tempo.h +++ b/libs/ardour/ardour/tempo.h @@ -27,10 +27,10 @@ #include <cmath> #include <glibmm/thread.h> #include <pbd/undo.h> +#include <pbd/stateful.h> #include <sigc++/signal.h> #include <ardour/ardour.h> -#include <ardour/stateful.h> #include <ardour/state_manager.h> class XMLNode; diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index a0a209b569..2c6cbe61e2 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -30,6 +30,8 @@ #include <inttypes.h> #include <jack/types.h> #include <control_protocol/smpte.h> +#include <pbd/id.h> + #include <map> #if __GNUC__ < 3 @@ -45,7 +47,7 @@ namespace ARDOUR { typedef float pan_t; typedef float gain_t; typedef uint32_t layer_t; - typedef uint64_t id_t; + typedef uint64_t microseconds_t; enum IOChange { NoChange = 0, diff --git a/libs/ardour/ardour/utils.h b/libs/ardour/ardour/utils.h index 3a9905b3ac..ad471085b5 100644 --- a/libs/ardour/ardour/utils.h +++ b/libs/ardour/ardour/utils.h @@ -50,8 +50,6 @@ int tokenize_fullpath (std::string fullpath, std::string& path, std::string& nam int touch_file(std::string path); -uint32_t long get_uid(); - std::string region_name_from_path (std::string path); std::string path_expand (std::string); diff --git a/libs/ardour/ardour/vst_plugin.h b/libs/ardour/ardour/vst_plugin.h index ee8e6e986b..3cb10d1779 100644 --- a/libs/ardour/ardour/vst_plugin.h +++ b/libs/ardour/ardour/vst_plugin.h @@ -28,11 +28,9 @@ #include <string> #include <dlfcn.h> -#include <midi++/controllable.h> #include <sigc++/signal.h> - +#include <pbd/stateful.h> #include <jack/types.h> -#include <ardour/stateful.h> #include <ardour/plugin_state.h> #include <ardour/plugin.h> diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index 96615fd077..a6103683e4 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -131,7 +131,6 @@ AudioDiskstream::init_channel (ChannelInfo &chan) void AudioDiskstream::init (Flag f) { - _id = new_id(); _refcnt = 0; _flags = f; _io = 0; @@ -1975,7 +1974,7 @@ AudioDiskstream::get_state () node->add_property ("speed", buf); node->add_property("name", _name); - snprintf (buf, sizeof(buf), "%" PRIu64, id()); + id().print (buf); node->add_property("id", buf); if (!capturing_sources.empty() && _session.get_record_enabled()) { @@ -2042,11 +2041,11 @@ AudioDiskstream::set_state (const XMLNode& node) if (deprecated_io_node) { if ((prop = deprecated_io_node->property ("id")) != 0) { - sscanf (prop->value().c_str(), "%" PRIu64, &_id); + _id = prop->value (); } } else { if ((prop = node.property ("id")) != 0) { - sscanf (prop->value().c_str(), "%" PRIu64, &_id); + _id = prop->value (); } } diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc index 74b7dd071c..29496584f6 100644 --- a/libs/ardour/audio_track.cc +++ b/libs/ardour/audio_track.cc @@ -43,7 +43,7 @@ using namespace PBD; AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode mode) : Route (sess, name, 1, -1, -1, -1, flag), diskstream (0), - _midi_rec_enable_control (*this, _session.midi_port()) + _rec_enable_control (*this) { AudioDiskstream::Flag dflags = AudioDiskstream::Flag (0); @@ -65,26 +65,17 @@ AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode _mode = mode; set_diskstream (*ds, this); - - // session.SMPTEOffsetChanged.connect (mem_fun (*this, &AudioTrack::handle_smpte_offset_change)); - - // we do this even though Route already did it in it's init - reset_midi_control (_session.midi_port(), _session.get_midi_control()); - } AudioTrack::AudioTrack (Session& sess, const XMLNode& node) : Route (sess, "to be renamed", 0, 0, -1, -1), diskstream (0), - _midi_rec_enable_control (*this, _session.midi_port()) + _rec_enable_control (*this) { _freeze_record.state = NoFreeze; set_state (node); _declickable = true; _saved_meter_point = _meter_point; - - // we do this even though Route already did it in it's init - reset_midi_control (_session.midi_port(), _session.get_midi_control()); } AudioTrack::~AudioTrack () @@ -191,7 +182,7 @@ AudioTrack::use_diskstream (string name) } int -AudioTrack::use_diskstream (id_t id) +AudioTrack::use_diskstream (const PBD::ID& id) { AudioDiskstream *dstream; @@ -235,10 +226,7 @@ AudioTrack::set_record_enable (bool yn, void *src) set_meter_point (_saved_meter_point, this); } - if (_session.get_midi_feedback()) { - _midi_rec_enable_control.send_feedback (record_enabled()); - } - + _rec_enable_control.Changed (); } void @@ -252,7 +240,6 @@ AudioTrack::set_state (const XMLNode& node) { const XMLProperty *prop; XMLNodeConstIterator iter; - XMLNodeList midi_kids; if (Route::set_state (node)) { return -1; @@ -271,36 +258,6 @@ AudioTrack::set_state (const XMLNode& node) _mode = Normal; } - midi_kids = node.children ("MIDI"); - - for (iter = midi_kids.begin(); iter != midi_kids.end(); ++iter) { - - XMLNodeList kids; - XMLNodeConstIterator miter; - XMLNode* child; - - kids = (*iter)->children (); - - for (miter = kids.begin(); miter != kids.end(); ++miter) { - - child =* miter; - - if (child->name() == "rec_enable") { - - MIDI::eventType ev = MIDI::on; /* initialize to keep gcc happy */ - MIDI::byte additional = 0; /* ditto */ - MIDI::channel_t chn = 0; /* ditto */ - - if (get_midi_node_info (child, ev, chn, additional)) { - _midi_rec_enable_control.set_control_type (chn, ev, additional); - } else { - error << string_compose(_("MIDI rec_enable control specification for %1 is incomplete, so it has been ignored"), _name) << endmsg; - } - } - } - } - - if ((prop = node.property ("diskstream-id")) == 0) { /* some old sessions use the diskstream name rather than the ID */ @@ -317,7 +274,7 @@ AudioTrack::set_state (const XMLNode& node) } else { - id_t id = strtoull (prop->value().c_str(), 0, 10); + PBD::ID id (prop->value()); if (use_diskstream (id)) { return -1; @@ -366,7 +323,7 @@ AudioTrack::state(bool full_state) { XMLNode& root (Route::state(full_state)); XMLNode* freeze_node; - char buf[32]; + char buf[64]; if (_freeze_record.playlist) { XMLNode* inode; @@ -378,7 +335,7 @@ AudioTrack::state(bool full_state) for (vector<FreezeRecordInsertInfo*>::iterator i = _freeze_record.insert_info.begin(); i != _freeze_record.insert_info.end(); ++i) { inode = new XMLNode (X_("insert")); - snprintf (buf, sizeof (buf), "%" PRIu64, (*i)->id); + (*i)->id.print (buf); inode->add_property (X_("id"), buf); inode->add_child_copy ((*i)->state); @@ -402,29 +359,6 @@ AudioTrack::state(bool full_state) align_node->add_property (X_("style"), buf); root.add_child_nocopy (*align_node); - /* MIDI control */ - - MIDI::channel_t chn; - MIDI::eventType ev; - MIDI::byte additional; - XMLNode* midi_node = 0; - XMLNode* child; - XMLNodeList midikids; - - midikids = root.children ("MIDI"); - if (!midikids.empty()) { - midi_node = midikids.front(); - } - else { - midi_node = root.add_child ("MIDI"); - } - - if (_midi_rec_enable_control.get_control_info (chn, ev, additional) && midi_node) { - - child = midi_node->add_child ("rec_enable"); - set_midi_node_info (child, ev, chn, additional); - } - XMLNode* remote_control_node = new XMLNode (X_("remote_control")); snprintf (buf, sizeof (buf), "%d", _remote_control_id); remote_control_node->add_property (X_("id"), buf); @@ -445,7 +379,7 @@ AudioTrack::state(bool full_state) diskstream. */ - snprintf (buf, sizeof (buf), "%" PRIu64, diskstream->id()); + diskstream->id().print (buf); root.add_property ("diskstream-id", buf); return root; @@ -506,7 +440,7 @@ AudioTrack::set_state_part_two () FreezeRecordInsertInfo* frii = new FreezeRecordInsertInfo (*((*citer)->children().front())); frii->insert = 0; - sscanf (prop->value().c_str(), "%" PRIu64, &frii->id); + frii->id = prop->value (); _freeze_record.insert_info.push_back (frii); } } @@ -1050,93 +984,23 @@ AudioTrack::freeze_state() const return _freeze_record.state; } - -void -AudioTrack::reset_midi_control (MIDI::Port* port, bool on) +AudioTrack::RecEnableControllable::RecEnableControllable (AudioTrack& s) + : track (s) { - MIDI::channel_t chn; - MIDI::eventType ev; - MIDI::byte extra; - - Route::reset_midi_control (port, on); - - _midi_rec_enable_control.get_control_info (chn, ev, extra); - if (!on) { - chn = -1; - } - _midi_rec_enable_control.midi_rebind (port, chn); } void -AudioTrack::send_all_midi_feedback () -{ - if (_session.get_midi_feedback()) { - - Route::send_all_midi_feedback(); - - _midi_rec_enable_control.send_feedback (record_enabled()); - } -} - - -AudioTrack::MIDIRecEnableControl::MIDIRecEnableControl (AudioTrack& s, MIDI::Port* port) - : MIDI::Controllable (port, 0), track (s), setting(false) -{ - last_written = false; /* XXX need a good out of bound value */ -} - -void -AudioTrack::MIDIRecEnableControl::set_value (float val) +AudioTrack::RecEnableControllable::set_value (float val) { bool bval = ((val >= 0.5f) ? true: false); - - setting = true; track.set_record_enable (bval, this); - setting = false; -} - -void -AudioTrack::MIDIRecEnableControl::send_feedback (bool value) -{ - - if (!setting && get_midi_feedback()) { - MIDI::byte val = (MIDI::byte) (value ? 127: 0); - MIDI::channel_t ch = 0; - MIDI::eventType ev = MIDI::none; - MIDI::byte additional = 0; - MIDI::EventTwoBytes data; - - if (get_control_info (ch, ev, additional)) { - data.controller_number = additional; - data.value = val; - - track._session.send_midi_message (get_port(), ev, ch, data); - } - } - } -MIDI::byte* -AudioTrack::MIDIRecEnableControl::write_feedback (MIDI::byte* buf, int32_t& bufsize, bool val, bool force) +float +AudioTrack::RecEnableControllable::get_value (void) const { - if (get_midi_feedback()) { - - MIDI::channel_t ch = 0; - MIDI::eventType ev = MIDI::none; - MIDI::byte additional = 0; - - if (get_control_info (ch, ev, additional)) { - if (val != last_written || force) { - *buf++ = ev & ch; - *buf++ = additional; /* controller number */ - *buf++ = (MIDI::byte) (val ? 127: 0); - last_written = val; - bufsize -= 3; - } - } - } - - return buf; + if (track.record_enabled()) { return 1.0f; } + return 0.0f; } void diff --git a/libs/ardour/audiofilesource.cc b/libs/ardour/audiofilesource.cc index 0663f5f9b1..c094e1af97 100644 --- a/libs/ardour/audiofilesource.cc +++ b/libs/ardour/audiofilesource.cc @@ -603,6 +603,8 @@ AudioFileSource::set_header_position_offset (jack_nframes_t offset, bool negativ void AudioFileSource::handle_header_position_change () { + cerr << _path << " handling header position change " << writable() << endl; + if (writable()) { set_header_timeline_position (); flush_header (); diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc index 6b118faa51..6665b8d962 100644 --- a/libs/ardour/audioregion.cc +++ b/libs/ardour/audioregion.cc @@ -267,8 +267,6 @@ AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node) _fade_out (0.0, 2.0, 1.0, false), _envelope (0.0, 2.0, 1.0, false) { - /* basic AudioRegion constructor */ - set<AudioSource*> unique_srcs; for (SourceList::iterator i=srcs.begin(); i != srcs.end(); ++i) { @@ -657,7 +655,7 @@ AudioRegion::state (bool full) for (uint32_t n=0; n < sources.size(); ++n) { snprintf (buf2, sizeof(buf2), "source-%d", n); - snprintf (buf, sizeof(buf), "%" PRIu64, sources[n]->id()); + sources[n]->id().print (buf2); node.add_property (buf2, buf); } diff --git a/libs/ardour/crossfade.cc b/libs/ardour/crossfade.cc index 5d36c63f01..bbe0c63b0a 100644 --- a/libs/ardour/crossfade.cc +++ b/libs/ardour/crossfade.cc @@ -112,7 +112,6 @@ Crossfade::Crossfade (const Playlist& playlist, XMLNode& node) { Region* r; XMLProperty* prop; - id_t id; LocaleGuard lg (X_("POSIX")); /* we have to find the in/out regions before we can do anything else */ @@ -122,7 +121,7 @@ Crossfade::Crossfade (const Playlist& playlist, XMLNode& node) throw failed_constructor(); } - sscanf (prop->value().c_str(), "%" PRIu64, &id); + PBD::ID id (prop->value()); if ((r = playlist.find_region (id)) == 0) { error << string_compose (_("Crossfade: no \"in\" region %1 found in playlist %2"), id, playlist.name()) @@ -139,10 +138,10 @@ Crossfade::Crossfade (const Playlist& playlist, XMLNode& node) throw failed_constructor(); } - sscanf (prop->value().c_str(), "%" PRIu64, &id); + PBD::ID id2 (prop->value()); - if ((r = playlist.find_region (id)) == 0) { - error << string_compose (_("Crossfade: no \"out\" region %1 found in playlist %2"), id, playlist.name()) + if ((r = playlist.find_region (id2)) == 0) { + error << string_compose (_("Crossfade: no \"out\" region %1 found in playlist %2"), id2, playlist.name()) << endmsg; throw failed_constructor(); } @@ -680,9 +679,9 @@ Crossfade::get_state () char buf[64]; LocaleGuard lg (X_("POSIX")); - snprintf (buf, sizeof(buf), "%" PRIu64, _out->id()); + _out->id().print (buf); node->add_property ("out", buf); - snprintf (buf, sizeof(buf), "%" PRIu64, _in->id()); + _in->id().print (buf); node->add_property ("in", buf); node->add_property ("active", (_active ? "yes" : "no")); node->add_property ("follow-overlap", (_follow_overlap ? "yes" : "no")); diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc index f80c9dc287..2ade56f8a9 100644 --- a/libs/ardour/globals.cc +++ b/libs/ardour/globals.cc @@ -322,10 +322,15 @@ ARDOUR::cleanup () return 0; } -ARDOUR::id_t -ARDOUR::new_id () + +microseconds_t +ARDOUR::get_microseconds () { - return get_uid(); + /* XXX need JACK to export its functionality */ + + struct timeval now; + gettimeofday (&now, 0); + return now.tv_sec * 1000000ULL + now.tv_usec; } ARDOUR::Change diff --git a/libs/ardour/insert.cc b/libs/ardour/insert.cc index fc05355d4a..a2b03ad38d 100644 --- a/libs/ardour/insert.cc +++ b/libs/ardour/insert.cc @@ -599,7 +599,7 @@ PluginInsert::state (bool full) node->add_property("id", string(buf)); if (_plugins[0]->state_node_name() == "ladspa") { char buf[32]; - snprintf (buf, 31, "%ld", _plugins[0]->get_info().unique_id); + snprintf (buf, sizeof (buf), "%ld", _plugins[0]->get_info().unique_id); node->add_property("unique-id", string(buf)); } node->add_property("count", string_compose("%1", _plugins.size())); @@ -780,18 +780,6 @@ PluginInsert::describe_parameter (uint32_t what) return _plugins[0]->describe_parameter (what); } -void -PluginInsert::reset_midi_control (MIDI::Port* port, bool on) -{ - _plugins[0]->reset_midi_control (port, on); -} - -void -PluginInsert::send_all_midi_feedback () -{ - _plugins[0]->send_all_midi_feedback(); -} - jack_nframes_t PluginInsert::latency() { diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc index 87c03c6b70..bb2bb52e9e 100644 --- a/libs/ardour/io.cc +++ b/libs/ardour/io.cc @@ -74,17 +74,17 @@ sigc::signal<int> IO::PortsCreated; Glib::StaticMutex IO::m_meter_signal_lock = GLIBMM_STATIC_MUTEX_INIT; -/* this is a default mapper of MIDI control values to a gain coefficient. - others can be imagined. see IO::set_midi_to_gain_function(). +/* this is a default mapper of [0 .. 1.0] control values to a gain coefficient. + others can be imagined. */ -static gain_t direct_midi_to_gain (double fract) { +static gain_t direct_control_to_gain (double fract) { /* XXX Marcus writes: this doesn't seem right to me. but i don't have a better answer ... */ /* this maxes at +6dB */ return pow (2.0,(sqrt(sqrt(sqrt(fract)))*198.0-192.0)/6.0); } -static double direct_gain_to_midi (gain_t gain) { +static double direct_gain_to_control (gain_t gain) { /* XXX Marcus writes: this doesn't seem right to me. but i don't have a better answer ... */ if (gain == 0) return 0.0; @@ -102,14 +102,13 @@ IO::IO (Session& s, string name, int input_min, int input_max, int output_min, int output_max) : _session (s), _name (name), - _midi_gain_control (*this, _session.midi_port()), + _gain_control (*this), _gain_automation_curve (0.0, 2.0, 1.0), _input_minimum (input_min), _input_maximum (input_max), _output_minimum (output_min), _output_maximum (output_max) { - _id = new_id(); _panner = new Panner (name, _session); _gain = 1.0; _desired_gain = 1.0; @@ -121,9 +120,6 @@ IO::IO (Session& s, string name, no_panner_reset = false; deferred_state = 0; - _midi_gain_control.midi_to_gain = direct_midi_to_gain; - _midi_gain_control.gain_to_midi = direct_gain_to_midi; - apply_gain_automation = false; last_automation_snapshot = 0; @@ -1397,7 +1393,7 @@ XMLNode& IO::state (bool full_state) { XMLNode* node = new XMLNode (state_node_name); - char buf[32]; + char buf[64]; string str; bool need_ins = true; bool need_outs = true; @@ -1405,7 +1401,7 @@ IO::state (bool full_state) Glib::Mutex::Lock lm (io_lock); node->add_property("name", _name); - snprintf (buf, sizeof(buf), "%" PRIu64, id()); + id().print (buf); node->add_property("id", buf); str = ""; @@ -1499,22 +1495,6 @@ IO::state (bool full_state) node->add_property ("iolimits", buf); - /* MIDI control */ - - MIDI::channel_t chn; - MIDI::eventType ev; - MIDI::byte additional; - XMLNode* midi_node = 0; - XMLNode* child; - - if (_midi_gain_control.get_control_info (chn, ev, additional)) { - - midi_node = node->add_child ("MIDI"); - - child = midi_node->add_child ("gain"); - set_midi_node_info (child, ev, chn, additional); - } - /* automation */ if (full_state) { @@ -1583,7 +1563,6 @@ IO::set_state (const XMLNode& node) { const XMLProperty* prop; XMLNodeConstIterator iter; - XMLNodeList midi_kids; LocaleGuard lg (X_("POSIX")); /* force use of non-localized representation of decimal point, @@ -1601,7 +1580,7 @@ IO::set_state (const XMLNode& node) } if ((prop = node.property ("id")) != 0) { - sscanf (prop->value().c_str(), "%" PRIu64, &_id); + _id = prop->value (); } if ((prop = node.property ("iolimits")) != 0) { @@ -1623,35 +1602,6 @@ IO::set_state (const XMLNode& node) } } - midi_kids = node.children ("MIDI"); - - for (iter = midi_kids.begin(); iter != midi_kids.end(); ++iter) { - - XMLNodeList kids; - XMLNodeConstIterator miter; - XMLNode* child; - - kids = (*iter)->children (); - - for (miter = kids.begin(); miter != kids.end(); ++miter) { - - child =* miter; - - if (child->name() == "gain") { - - MIDI::eventType ev = MIDI::on; /* initialize to keep gcc happy */ - MIDI::byte additional = 0; /* ditto */ - MIDI::channel_t chn = 0; /* ditto */ - - if (get_midi_node_info (child, ev, chn, additional)) { - _midi_gain_control.set_control_type (chn, ev, additional); - } else { - error << string_compose(_("MIDI gain control specification for %1 is incomplete, so it has been ignored"), _name) << endmsg; - } - } - } - } - if ((prop = node.property ("automation-state")) != 0) { long int x; @@ -1769,50 +1719,6 @@ IO::create_ports (const XMLNode& node) return 0; } -bool -IO::get_midi_node_info (XMLNode * node, MIDI::eventType & ev, MIDI::channel_t & chan, MIDI::byte & additional) -{ - bool ok = true; - const XMLProperty* prop; - int xx; - - if ((prop = node->property ("event")) != 0) { - sscanf (prop->value().c_str(), "0x%x", &xx); - ev = (MIDI::eventType) xx; - } else { - ok = false; - } - - if (ok && ((prop = node->property ("channel")) != 0)) { - sscanf (prop->value().c_str(), "%d", &xx); - chan = (MIDI::channel_t) xx; - } else { - ok = false; - } - - if (ok && ((prop = node->property ("additional")) != 0)) { - sscanf (prop->value().c_str(), "0x%x", &xx); - additional = (MIDI::byte) xx; - } - - return ok; -} - -bool -IO::set_midi_node_info (XMLNode * node, MIDI::eventType ev, MIDI::channel_t chan, MIDI::byte additional) -{ - char buf[32]; - - snprintf (buf, sizeof(buf), "0x%x", ev); - node->add_property ("event", buf); - snprintf (buf, sizeof(buf), "%d", chan); - node->add_property ("channel", buf); - snprintf (buf, sizeof(buf), "0x%x", additional); - node->add_property ("additional", buf); - - return true; -} - int IO::make_connections (const XMLNode& node) @@ -2339,69 +2245,16 @@ IO::output_connection_configuration_changed () use_output_connection (*_output_connection, this); } -IO::MIDIGainControl::MIDIGainControl (IO& i, MIDI::Port* port) - : MIDI::Controllable (port, 0), io (i), setting(false) -{ - midi_to_gain = 0; - gain_to_midi = 0; - setting = false; - last_written = 0; /* XXX need a good out-of-bound-value */ -} - void -IO::MIDIGainControl::set_value (float val) +IO::GainControllable::set_value (float val) { - if (midi_to_gain == 0) return; - - setting = true; - io.set_gain (midi_to_gain (val), this); - setting = false; -} - -void -IO::MIDIGainControl::send_feedback (gain_t gain) -{ - if (!setting && get_midi_feedback() && gain_to_midi) { - MIDI::byte val = (MIDI::byte) (gain_to_midi (gain) * 127.0); - MIDI::channel_t ch = 0; - MIDI::eventType ev = MIDI::none; - MIDI::byte additional = 0; - MIDI::EventTwoBytes data; - - if (get_control_info (ch, ev, additional)) { - data.controller_number = additional; - data.value = val; - last_written = val; - - io._session.send_midi_message (get_port(), ev, ch, data); - } - //send_midi_feedback (gain_to_midi (gain)); - } + io.set_gain (direct_control_to_gain (val), this); } -MIDI::byte* -IO::MIDIGainControl::write_feedback (MIDI::byte* buf, int32_t& bufsize, gain_t val, bool force) +float +IO::GainControllable::get_value (void) const { - if (get_midi_feedback() && gain_to_midi && bufsize > 2) { - MIDI::channel_t ch = 0; - MIDI::eventType ev = MIDI::none; - MIDI::byte additional = 0; - MIDI::byte gm; - - if (get_control_info (ch, ev, additional)) { - gm = (MIDI::byte) (gain_to_midi (val) * 127.0); - - if (gm != last_written) { - *buf++ = (0xF0 & ev) | (0xF & ch); - *buf++ = additional; /* controller number */ - *buf++ = gm; - last_written = gm; - bufsize -= 3; - } - } - } - - return buf; + return direct_gain_to_control (io.effective_gain()); } void @@ -2493,23 +2346,6 @@ IO::meter () } } -void -IO::reset_midi_control (MIDI::Port* port, bool on) -{ - MIDI::channel_t chn; - MIDI::eventType ev; - MIDI::byte extra; - - _midi_gain_control.get_control_info (chn, ev, extra); - if (!on) { - chn = -1; - } - _midi_gain_control.midi_rebind (port, chn); - - _panner->reset_midi_control (port, on); -} - - int IO::save_automation (const string& path) { @@ -2699,10 +2535,7 @@ IO::set_gain (gain_t val, void *src) } gain_changed (src); - - if (_session.get_midi_feedback()) { - _midi_gain_control.send_feedback (_desired_gain); - } + _gain_control.Changed (); /* EMIT SIGNAL */ if (_session.transport_stopped() && src != 0 && src != this && gain_automation_recording()) { _gain_automation_curve.add (_session.transport_frame(), val); @@ -2713,30 +2546,6 @@ IO::set_gain (gain_t val, void *src) } void -IO::send_all_midi_feedback () -{ - if (_session.get_midi_feedback()) { - _midi_gain_control.send_feedback (_effective_gain); - - // panners - _panner->send_all_midi_feedback(); - } -} - -MIDI::byte* -IO::write_midi_feedback (MIDI::byte* buf, int32_t& bufsize) -{ - if (_session.get_midi_feedback()) { - if (gain_automation_playback ()) { - buf = _midi_gain_control.write_feedback (buf, bufsize, _effective_gain); - } - buf = _panner->write_midi_feedback (buf, bufsize); - } - - return buf; -} - -void IO::start_gain_touch () { _gain_automation_curve.start_touch (); diff --git a/libs/ardour/ladspa_plugin.cc b/libs/ardour/ladspa_plugin.cc index 11001655d2..fa19a682e7 100644 --- a/libs/ardour/ladspa_plugin.cc +++ b/libs/ardour/ladspa_plugin.cc @@ -133,20 +133,9 @@ LadspaPlugin::init (void *mod, uint32_t index, jack_nframes_t rate) } } - Plugin::setup_midi_controls (); + Plugin::setup_controls (); latency_compute_run (); - - MIDI::Controllable *mcontrol; - - for (uint32_t i = 0; i < parameter_count(); ++i) { - if (LADSPA_IS_PORT_INPUT(port_descriptor (i)) && - LADSPA_IS_PORT_CONTROL(port_descriptor (i))) { - if ((mcontrol = get_nth_midi_control (i)) != 0) { - mcontrol->midi_rebind (_session.midi_port(), 0); - } - } - } } LadspaPlugin::~LadspaPlugin () @@ -318,17 +307,14 @@ LadspaPlugin::set_parameter (uint32_t which, float val) shadow_data[which] = (LADSPA_Data) val; ParameterChanged (which, val); /* EMIT SIGNAL */ - if (session().get_midi_feedback()) { - - if (which < parameter_count() && midi_controls[which]) { - midi_controls[which]->send_feedback (val); - } + if (which < parameter_count() && controls[which]) { + controls[which]->Changed (); } - + } else { warning << string_compose (_("illegal parameter number used with plugin \"%1\". This may" - "indicate a change in the plugin design, and presets may be" - "invalid"), name()) + "indicate a change in the plugin design, and presets may be" + "invalid"), name()) << endmsg; } } @@ -380,28 +366,6 @@ LadspaPlugin::get_state() snprintf(buf, sizeof(buf), "%+f", shadow_data[i]); child->add_property("value", string(buf)); root->add_child_nocopy (*child); - - MIDI::Controllable *pcontrol = get_nth_midi_control (i); - - if (pcontrol) { - - MIDI::eventType ev; - MIDI::byte additional; - MIDI::channel_t chn; - XMLNode* midi_node; - - if (pcontrol->get_control_info (chn, ev, additional)) { - - midi_node = child->add_child ("midi-control"); - - snprintf (buf, sizeof(buf), "0x%x", ev); - midi_node->add_property ("event", buf); - snprintf (buf, sizeof(buf), "%d", chn); - midi_node->add_property ("channel", buf); - snprintf (buf, sizeof(buf), "0x%x", additional); - midi_node->add_property ("additional", buf); - } - } } } @@ -452,52 +416,6 @@ LadspaPlugin::set_state(const XMLNode& node) sscanf (port, "%" PRIu32, &port_id); set_parameter (port_id, atof(data)); - - XMLNodeList midi_kids; - XMLNodeConstIterator iter; - - midi_kids = child->children ("midi-control"); - - for (iter = midi_kids.begin(); iter != midi_kids.end(); ++iter) { - - child = *iter; - - MIDI::eventType ev = MIDI::on; /* initialize to keep gcc happy */ - MIDI::byte additional = 0; /* initialize to keep gcc happy */ - MIDI::channel_t chn = 0; /* initialize to keep gcc happy */ - bool ok = true; - int xx; - - if ((prop = child->property ("event")) != 0) { - sscanf (prop->value().c_str(), "0x%x", &xx); - ev = (MIDI::eventType) xx; - } else { - ok = false; - } - - if (ok && ((prop = child->property ("channel")) != 0)) { - sscanf (prop->value().c_str(), "%d", &xx); - chn = (MIDI::channel_t) xx; - } else { - ok = false; - } - - if (ok && ((prop = child->property ("additional")) != 0)) { - sscanf (prop->value().c_str(), "0x%x", &xx); - additional = (MIDI::byte) xx; - } - - if (ok) { - MIDI::Controllable* pcontrol = get_nth_midi_control (port_id); - - if (pcontrol) { - pcontrol->set_control_type (chn, ev, additional); - } - - } else { - error << string_compose(_("LADSPA LadspaPlugin MIDI control specification for port %1 is incomplete, so it has been ignored"), port) << endl; - } - } } latency_compute_run (); diff --git a/libs/ardour/panner.cc b/libs/ardour/panner.cc index 83c9e6eb4d..a56424cfea 100644 --- a/libs/ardour/panner.cc +++ b/libs/ardour/panner.cc @@ -53,21 +53,21 @@ float Panner::current_automation_version_number = 1.0; string EqualPowerStereoPanner::name = "Equal Power Stereo"; string Multi2dPanner::name = "Multiple (2D)"; -/* this is a default mapper of MIDI control values to a pan position - others can be imagined. see Panner::set_midi_to_pan_function(). +/* this is a default mapper of control values to a pan position + others can be imagined. */ -static pan_t direct_midi_to_pan (double fract) { +static pan_t direct_control_to_pan (double fract) { return fract; } -static double direct_pan_to_midi (pan_t val) { +static double direct_pan_to_control (pan_t val) { return val; } StreamPanner::StreamPanner (Panner& p) : parent (p), - _midi_control (*this, (MIDI::Port*) 0) + _control (*this) { _muted = false; @@ -80,84 +80,30 @@ StreamPanner::~StreamPanner () { } -StreamPanner::MIDIControl::MIDIControl (StreamPanner& s, MIDI::Port* port) - : MIDI::Controllable (port, 0), sp (s), setting(false) -{ - midi_to_pan = direct_midi_to_pan; - pan_to_midi = direct_pan_to_midi; - last_written = 0; /* XXX need a good out-of-bound-value */ -} - void -StreamPanner::MIDIControl::set_value (float val) +StreamPanner::PanControllable::set_value (float val) { - setting = true; - sp.set_position (midi_to_pan (val)); - setting = false; -} - -void -StreamPanner::MIDIControl::send_feedback (pan_t value) -{ - - if (!setting && get_midi_feedback() && pan_to_midi) { - MIDI::byte val = (MIDI::byte) (pan_to_midi (value) * 127.0f); - MIDI::channel_t ch = 0; - MIDI::eventType ev = MIDI::none; - MIDI::byte additional = 0; - MIDI::EventTwoBytes data; - - if (get_control_info (ch, ev, additional)) { - data.controller_number = additional; - data.value = val; - last_written = val; - - sp.get_parent().session().send_midi_message (get_port(), ev, ch, data); - } - - // send_midi_feedback (pan_to_midi (val)); - } - + panner.set_position (direct_control_to_pan (val)); } -MIDI::byte* -StreamPanner::MIDIControl::write_feedback (MIDI::byte* buf, int32_t& bufsize, pan_t val, bool force) +float +StreamPanner::PanControllable::get_value (void) const { - if (get_midi_feedback() && pan_to_midi && bufsize > 2) { - MIDI::channel_t ch = 0; - MIDI::eventType ev = MIDI::none; - MIDI::byte additional = 0; - MIDI::byte pm; - if (get_control_info (ch, ev, additional)) { - - pm = (MIDI::byte) (pan_to_midi (val) * 127.0); - - if (pm != last_written || force) { - *buf++ = (0xF0 & ev) | (0xF & ch); - *buf++ = additional; /* controller number */ - *buf++ = pm; - last_written = pm; - bufsize -= 3; - } - } - } - - return buf; + float xpos; + panner.get_effective_position (xpos); + return direct_pan_to_control (xpos); } - -void -StreamPanner::reset_midi_control (MIDI::Port* port, bool on) +bool +StreamPanner::PanControllable::can_send_feedback () const { - MIDI::channel_t chn; - MIDI::eventType ev; - MIDI::byte extra; + AutoState astate = panner.get_parent().automation_state (); - _midi_control.get_control_info (chn, ev, extra); - if (!on) { - chn = -1; + if ((astate == Play) || (astate == Touch && !panner.get_parent().touching())) { + return true; } - _midi_control.midi_rebind (port, chn); + + return false; } void @@ -180,10 +126,7 @@ StreamPanner::set_position (float xpos, bool link_call) x = xpos; update (); Changed (); - - if (parent.session().get_midi_feedback()) { - _midi_control.send_feedback (x); - } + _control.Changed (); } } @@ -224,42 +167,11 @@ StreamPanner::set_state (const XMLNode& node) { const XMLProperty* prop; XMLNodeConstIterator iter; - XMLNodeList midi_kids; if ((prop = node.property (X_("muted")))) { set_muted (prop->value() == "yes"); } - midi_kids = node.children ("MIDI"); - - for (iter = midi_kids.begin(); iter != midi_kids.end(); ++iter) { - - XMLNodeList kids; - XMLNodeConstIterator miter; - XMLNode* child; - - kids = (*iter)->children (); - - for (miter = kids.begin(); miter != kids.end(); ++miter) { - - child =* miter; - - if (child->name() == "pan") { - - MIDI::eventType ev = MIDI::on; /* initialize to keep gcc happy */ - MIDI::byte additional = 0; /* ditto */ - MIDI::channel_t chn = 0; /* ditto */ - - if (get_midi_node_info (child, ev, chn, additional)) { - _midi_control.set_control_type (chn, ev, additional); - } else { - error << _("MIDI pan control specification is incomplete, so it has been ignored") << endmsg; - } - } - } - } - - return 0; } @@ -267,68 +179,6 @@ void StreamPanner::add_state (XMLNode& node) { node.add_property (X_("muted"), (muted() ? "yes" : "no")); - - /* MIDI control */ - - MIDI::channel_t chn; - MIDI::eventType ev; - MIDI::byte additional; - XMLNode* midi_node = 0; - XMLNode* child; - - if (_midi_control.get_control_info (chn, ev, additional)) { - - midi_node = node.add_child ("MIDI"); - - child = midi_node->add_child ("pan"); - set_midi_node_info (child, ev, chn, additional); - } - -} - - -bool -StreamPanner::get_midi_node_info (XMLNode * node, MIDI::eventType & ev, MIDI::channel_t & chan, MIDI::byte & additional) -{ - bool ok = true; - const XMLProperty* prop; - int xx; - - if ((prop = node->property ("event")) != 0) { - sscanf (prop->value().c_str(), "0x%x", &xx); - ev = (MIDI::eventType) xx; - } else { - ok = false; - } - - if (ok && ((prop = node->property ("channel")) != 0)) { - sscanf (prop->value().c_str(), "%d", &xx); - chan = (MIDI::channel_t) xx; - } else { - ok = false; - } - - if (ok && ((prop = node->property ("additional")) != 0)) { - sscanf (prop->value().c_str(), "0x%x", &xx); - additional = (MIDI::byte) xx; - } - - return ok; -} - -bool -StreamPanner::set_midi_node_info (XMLNode * node, MIDI::eventType ev, MIDI::channel_t chan, MIDI::byte additional) -{ - char buf[32]; - - snprintf (buf, sizeof(buf), "0x%x", ev); - node->add_property ("event", buf); - snprintf (buf, sizeof(buf), "%d", chan); - node->add_property ("channel", buf); - snprintf (buf, sizeof(buf), "0x%x", additional); - node->add_property ("additional", buf); - - return true; } /*---------------------------------------------------------------------- */ @@ -959,8 +809,6 @@ Panner::Panner (string name, Session& s) _linked = false; _link_direction = SameDirection; _bypassed = false; - - reset_midi_control (_session.mmc_port(), _session.get_mmc_control()); } Panner::~Panner () @@ -1107,8 +955,6 @@ Panner::reset (uint32_t nouts, uint32_t npans) (*x)->update (); } - reset_midi_control (_session.mmc_port(), _session.get_mmc_control()); - /* force hard left/right panning in a common case: 2in/2out */ @@ -1490,14 +1336,6 @@ Panner::touching () const } void -Panner::reset_midi_control (MIDI::Port* port, bool on) -{ - for (vector<StreamPanner*>::const_iterator i = begin(); i != end(); ++i) { - (*i)->reset_midi_control (port, on); - } -} - -void Panner::set_position (float xpos, StreamPanner& orig) { float xnow; @@ -1639,42 +1477,3 @@ Panner::set_position (float xpos, float ypos, float zpos, StreamPanner& orig) } } } - -void -Panner::send_all_midi_feedback () -{ - if (_session.get_midi_feedback()) { - float xpos; - - // do feedback for all panners - for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) { - (*i)->get_effective_position (xpos); - - (*i)->midi_control().send_feedback (xpos); - } - - } -} - -MIDI::byte* -Panner::write_midi_feedback (MIDI::byte* buf, int32_t& bufsize) -{ - AutoState astate = automation_state (); - - if (_session.get_midi_feedback() && - (astate == Play || (astate == Touch && !touching()))) { - - float xpos; - - // do feedback for all panners - for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) { - (*i)->get_effective_position (xpos); - - buf = (*i)->midi_control().write_feedback (buf, bufsize, xpos); - } - - } - - return buf; -} - diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc index 7dee866767..fc1dd84066 100644 --- a/libs/ardour/playlist.cc +++ b/libs/ardour/playlist.cc @@ -77,7 +77,6 @@ Playlist::Playlist (Session& sess, string nom, bool hide) { init (hide); _name = nom; - _orig_diskstream_id = 0; } @@ -86,7 +85,6 @@ Playlist::Playlist (Session& sess, const XMLNode& node, bool hide) { init (hide); _name = "unnamed"; /* reset by set_state */ - _orig_diskstream_id = 0; if (set_state (node)) { throw failed_constructor(); @@ -1343,7 +1341,7 @@ Playlist::set_state (const XMLNode& node) if (prop->name() == X_("name")) { _name = prop->value(); } else if (prop->name() == X_("orig_diskstream_id")) { - sscanf (prop->value().c_str(), "%" PRIu64, &_orig_diskstream_id); + _orig_diskstream_id = prop->value (); } else if (prop->name() == X_("frozen")) { _frozen = (prop->value() == X_("yes")); } @@ -1404,7 +1402,7 @@ Playlist::state (bool full_state) node->add_property (X_("name"), _name); - snprintf (buf, sizeof(buf), "%" PRIu64, _orig_diskstream_id); + _orig_diskstream_id.print (buf); node->add_property (X_("orig_diskstream_id"), buf); node->add_property (X_("frozen"), _frozen ? "yes" : "no"); @@ -1725,7 +1723,7 @@ Playlist::nudge_after (jack_nframes_t start, jack_nframes_t distance, bool forwa } Region* -Playlist::find_region (id_t id) const +Playlist::find_region (const ID& id) const { RegionLock rlock (const_cast<Playlist*> (this)); RegionList::const_iterator i; diff --git a/libs/ardour/plugin.cc b/libs/ardour/plugin.cc index 9fc6c57909..6763e7f508 100644 --- a/libs/ardour/plugin.cc +++ b/libs/ardour/plugin.cc @@ -35,8 +35,6 @@ #include <pbd/pathscanner.h> #include <pbd/xml++.h> -#include <midi++/manager.h> - #include <ardour/ardour.h> #include <ardour/session.h> #include <ardour/audioengine.h> @@ -61,64 +59,59 @@ Plugin::Plugin (const Plugin& other) } void -Plugin::setup_midi_controls () +Plugin::setup_controls () { - uint32_t port_cnt; - - port_cnt = parameter_count(); + uint32_t port_cnt = parameter_count(); - /* set up a vector of null pointers for the MIDI controls. + /* set up a vector of null pointers for the controls. we'll fill this in on an as-needed basis. */ for (uint32_t i = 0; i < port_cnt; ++i) { - midi_controls.push_back (0); + controls.push_back (0); } } Plugin::~Plugin () { - for (vector<MIDIPortControl*>::iterator i = midi_controls.begin(); i != midi_controls.end(); ++i) { + for (vector<PortControllable*>::iterator i = controls.begin(); i != controls.end(); ++i) { if (*i) { delete *i; } } } -MIDI::Controllable * -Plugin::get_nth_midi_control (uint32_t n) +Controllable * +Plugin::get_nth_control (uint32_t n) { if (n >= parameter_count()) { return 0; } - if (midi_controls[n] == 0) { + if (controls[n] == 0) { Plugin::ParameterDescriptor desc; get_parameter_descriptor (n, desc); - - midi_controls[n] = new MIDIPortControl (*this, n, _session.midi_port(), desc.lower, desc.upper, desc.toggled, desc.logarithmic); + + controls[n] = new PortControllable (*this, n, desc.lower, desc.upper, desc.toggled, desc.logarithmic); } - return midi_controls[n]; + return controls[n]; } -Plugin::MIDIPortControl::MIDIPortControl (Plugin& p, uint32_t port_id, MIDI::Port *port, - float low, float up, bool t, bool loga) - : MIDI::Controllable (port, 0), plugin (p), absolute_port (port_id) +Plugin::PortControllable::PortControllable (Plugin& p, uint32_t port_id, float low, float up, bool t, bool loga) + : plugin (p), absolute_port (port_id) { toggled = t; logarithmic = loga; lower = low; upper = up; range = upper - lower; - last_written = 0; /* XXX need a good out-of-bound-value */ - setting = false; } void -Plugin::MIDIPortControl::set_value (float value) +Plugin::PortControllable::set_value (float value) { if (toggled) { if (value > 0.5) { @@ -140,138 +133,27 @@ Plugin::MIDIPortControl::set_value (float value) } } - setting = true; plugin.set_parameter (absolute_port, value); - setting = false; -} - -void -Plugin::MIDIPortControl::send_feedback (float value) -{ - - if (!setting && get_midi_feedback()) { - MIDI::byte val; - MIDI::channel_t ch = 0; - MIDI::eventType ev = MIDI::none; - MIDI::byte additional = 0; - MIDI::EventTwoBytes data; - - if (toggled) { - val = (MIDI::byte) (value * 127.0f); - } else { - if (logarithmic) { - value = log(value); - } - - val = (MIDI::byte) (((value - lower) / range) * 127.0f); - } - - if (get_control_info (ch, ev, additional)) { - data.controller_number = additional; - data.value = val; - last_written = val; - - plugin.session().send_midi_message (get_port(), ev, ch, data); - } - } - } -MIDI::byte* -Plugin::MIDIPortControl::write_feedback (MIDI::byte* buf, int32_t& bufsize, float value, bool force) +float +Plugin::PortControllable::get_value (void) const { - if (get_midi_feedback() && bufsize > 2) { - MIDI::channel_t ch = 0; - MIDI::eventType ev = MIDI::none; - MIDI::byte additional = 0; - - if (get_control_info (ch, ev, additional)) { - - MIDI::byte val; - - if (toggled) { + float val = plugin.get_parameter (absolute_port); - val = (MIDI::byte) (value * 127.0f); - - } else { - - if (logarithmic) { - value = log(value); - } - - val = (MIDI::byte) (((value - lower) / range) * 127.0f); - } - - if (val != last_written || force) { - *buf++ = MIDI::controller & ch; - *buf++ = additional; /* controller number */ - *buf++ = val; - last_written = val; - bufsize -= 3; - } - } - } - - return buf; -} - - -void -Plugin::reset_midi_control (MIDI::Port* port, bool on) -{ - MIDI::channel_t chn; - MIDI::eventType ev; - MIDI::byte extra; - - for (vector<MIDIPortControl*>::iterator i = midi_controls.begin(); i != midi_controls.end(); ++i) { - if (*i == 0) - continue; - (*i)->get_control_info (chn, ev, extra); - if (!on) { - chn = -1; - } - (*i)->midi_rebind (port, chn); - } -} - -void -Plugin::send_all_midi_feedback () -{ - if (_session.get_midi_feedback()) { - float val = 0.0; - uint32_t n = 0; + if (toggled) { - for (vector<MIDIPortControl*>::iterator i = midi_controls.begin(); i != midi_controls.end(); ++i, ++n) { - if (*i == 0) { - continue; - } - - val = (*i)->plugin.get_parameter (n); - (*i)->send_feedback (val); - } + return val; - } -} - -MIDI::byte* -Plugin::write_midi_feedback (MIDI::byte* buf, int32_t& bufsize) -{ - if (_session.get_midi_feedback()) { - float val = 0.0; - uint32_t n = 0; + } else { - for (vector<MIDIPortControl*>::iterator i = midi_controls.begin(); i != midi_controls.end(); ++i, ++n) { - if (*i == 0) { - continue; - } - - val = (*i)->plugin.get_parameter (n); - buf = (*i)->write_feedback (buf, bufsize, val); + if (logarithmic) { + val = log(val); } + + return ((val - lower) / range); } - - return buf; -} +} vector<string> Plugin::get_presets() diff --git a/libs/ardour/po/el_GR.po b/libs/ardour/po/el_GR.po index 33c1bb6e85..5d8adef7d0 100644 --- a/libs/ardour/po/el_GR.po +++ b/libs/ardour/po/el_GR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: libardour 0.664.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2006-06-27 13:00-0400\n" +"POT-Creation-Date: 2006-06-29 21:03-0400\n" "PO-Revision-Date: 2003-05-21 12:50+0500\n" "Last-Translator: Muadibas\n" "Language-Team: Hellenic(Greek)\n" @@ -56,47 +56,47 @@ msgid "AudioDiskstream \"%1\": cannot flush captured data to disk!" msgstr "" "DiskStream \"%1\": δεν γίνεται να αποÏÏιφθοÏν δειγματοληψίες στο δίσκο!" -#: libs/ardour/audio_diskstream.cc:1795 +#: libs/ardour/audio_diskstream.cc:1796 msgid "%1: could not create region for complete audio file" msgstr "%1: δεν μπόÏεσα να δημιουÏγήσω πεÏιοχή για ολόκληÏο audio file" -#: libs/ardour/audio_diskstream.cc:1818 +#: libs/ardour/audio_diskstream.cc:1819 #, fuzzy msgid "AudioDiskstream: could not create region for captured audio!" msgstr "DiskStream: δεν μπόÏεσα να δημιουÏγήσω πεÏιοχή για δειγματοληψίες!" -#: libs/ardour/audio_diskstream.cc:1873 +#: libs/ardour/audio_diskstream.cc:1874 #, fuzzy msgid "programmer error: %1" msgstr "σφάλμα Ï€ÏογÏαμματισμοÏ: %1" -#: libs/ardour/audio_diskstream.cc:2145 +#: libs/ardour/audio_diskstream.cc:2146 #, fuzzy msgid "AudioDiskstream: channel %1 out of range" msgstr "DiskStream: κανάλι εκτός διαστήματος" -#: libs/ardour/audio_diskstream.cc:2170 +#: libs/ardour/audio_diskstream.cc:2171 msgid "%1:%2 new capture file not initialized correctly" msgstr "%1:%2 νÎα δειγματοληψία δεν εκκινήθη σωστά" -#: libs/ardour/audio_diskstream.cc:2403 +#: libs/ardour/audio_diskstream.cc:2404 msgid "Location \"%1\" not valid for track loop (start >= end)" msgstr "Η Τοποθεσία \"%1\" δεν είναι ικανή για track loop (αÏχή >= Ï„Îλος)" -#: libs/ardour/audio_diskstream.cc:2484 +#: libs/ardour/audio_diskstream.cc:2485 #, fuzzy msgid "%1: cannot restore pending capture source file %2" msgstr "Εισαγωγή: δεν μποÏÏŽ να ανοίξω το εισαγμÎνο αÏχείο ήχου \"%1\"" -#: libs/ardour/audio_diskstream.cc:2506 +#: libs/ardour/audio_diskstream.cc:2507 msgid "%1: incorrect number of pending sources listed - ignoring them all" msgstr "" -#: libs/ardour/audio_diskstream.cc:2522 +#: libs/ardour/audio_diskstream.cc:2523 msgid "%1: cannot create whole-file region from pending capture sources" msgstr "" -#: libs/ardour/audio_diskstream.cc:2534 +#: libs/ardour/audio_diskstream.cc:2535 #, fuzzy msgid "%1: cannot create region from pending capture sources" msgstr "%1: δεν μπόÏεσα να δημιουÏγήσω πεÏιοχή για ολόκληÏο audio file" @@ -155,36 +155,36 @@ msgstr "αλλαγή xfade" msgid "region modified" msgstr "η πεÏιοχή μετεβλήθη" -#: libs/ardour/audio_track.cc:133 libs/ardour/io.cc:1716 +#: libs/ardour/audio_track.cc:125 libs/ardour/io.cc:1716 #: libs/ardour/io.cc:1826 msgid "Unknown connection \"%1\" listed for input of %2" msgstr "Άγνωστη σÏνδεση \"%1\" στη λίστα εισόδου του %2" -#: libs/ardour/audio_track.cc:135 libs/ardour/io.cc:1718 +#: libs/ardour/audio_track.cc:127 libs/ardour/io.cc:1718 #: libs/ardour/io.cc:1828 #, fuzzy msgid "in 1" msgstr "in %lu" -#: libs/ardour/audio_track.cc:136 libs/ardour/io.cc:1719 +#: libs/ardour/audio_track.cc:128 libs/ardour/io.cc:1719 #: libs/ardour/io.cc:1829 msgid "No input connections available as a replacement" msgstr "" -#: libs/ardour/audio_track.cc:140 libs/ardour/io.cc:1723 +#: libs/ardour/audio_track.cc:132 libs/ardour/io.cc:1723 #: libs/ardour/io.cc:1833 msgid "Connection %1 was not available - \"in 1\" used instead" msgstr "" -#: libs/ardour/audio_track.cc:149 libs/ardour/io.cc:1842 +#: libs/ardour/audio_track.cc:141 libs/ardour/io.cc:1842 msgid "improper input channel list in XML node (%1)" msgstr "ακατάλληλη λίστα καναλιών εισόδου στον κόμβο XML (%1)" -#: libs/ardour/audio_track.cc:194 libs/ardour/audio_track.cc:207 +#: libs/ardour/audio_track.cc:186 libs/ardour/audio_track.cc:199 msgid "AudioTrack: diskstream \"%1\" not known by session" msgstr "AudioTrack: το diskstream \"%1\" είναι μή αναγνωÏίσιμο από τη συνεδÏία" -#: libs/ardour/audio_track.cc:305 +#: libs/ardour/audio_track.cc:297 #, fuzzy msgid "" "MIDI rec_enable control specification for %1 is incomplete, so it has been " @@ -193,7 +193,7 @@ msgstr "" "Η Ï€ÏοδιαγÏαφή ελÎγχου του MIDI gain για το %1 είναι ημιτελής, με αποτÎλεσμα " "να αγνοηθεί" -#: libs/ardour/audio_track.cc:317 +#: libs/ardour/audio_track.cc:309 msgid "programming error: AudioTrack given state without diskstream!" msgstr "" "σφάλμα Ï€ÏογÏαμματισμοÏ: εδόθη κατάσταση στην AudioTrack δίχως diskstream!" @@ -272,24 +272,24 @@ msgstr "Σφάλμα: δεν μπόÏεσα να γÏάψω %1" msgid "could not reconnect %1 and %2 (err = %3)" msgstr "" -#: libs/ardour/audiofilesource.cc:445 libs/ardour/session_state.cc:3095 +#: libs/ardour/audiofilesource.cc:444 libs/ardour/session_state.cc:3095 msgid "" "there are already 1000 files with names like %1; versioning discontinued" msgstr "ΥπάÏχουν ήδη 1000 αÏχεία με ονόματα όπως %1; μη-συνεχÎÏ‚ versioning" -#: libs/ardour/audiofilesource.cc:459 libs/ardour/session_state.cc:3109 +#: libs/ardour/audiofilesource.cc:458 libs/ardour/session_state.cc:3109 msgid "cannot rename audio file source from %1 to %2 (%3)" msgstr "δεν μποÏÏŽ να μετονομάσω την πηγή του audio file από %1 σε %2 (%3)" -#: libs/ardour/audiofilesource.cc:466 libs/ardour/session_state.cc:3124 +#: libs/ardour/audiofilesource.cc:465 libs/ardour/session_state.cc:3124 msgid "cannot remove peakfile %1 for %2 (%3)" msgstr "δεν μποÏÏŽ να απαλοίψω το peakfile %1 για %2 (%3)" -#: libs/ardour/audiofilesource.cc:510 +#: libs/ardour/audiofilesource.cc:509 msgid "FileSource: search path not set" msgstr "FileSource: μονοπάτι αναζητήσεως δεν ετÎθη" -#: libs/ardour/audiofilesource.cc:534 +#: libs/ardour/audiofilesource.cc:533 msgid "" "FileSource: \"%1\" is ambigous when searching %2\n" "\t" @@ -297,25 +297,25 @@ msgstr "" "FileSource: \"%1\" είναι αμφίβολο κατά την αναζήτηση του %2\n" "\t" -#: libs/ardour/audiofilesource.cc:540 +#: libs/ardour/audiofilesource.cc:539 #, fuzzy msgid "Filesource: cannot find required file (%1): while searching %2" msgstr "Filesource: δεν ευÏÎθη το απαιτοÏμενο αÏχείο (%1): %2" -#: libs/ardour/audiofilesource.cc:563 +#: libs/ardour/audiofilesource.cc:562 msgid "Filesource: cannot find required file (%1): %2" msgstr "Filesource: δεν ευÏÎθη το απαιτοÏμενο αÏχείο (%1): %2" -#: libs/ardour/audiofilesource.cc:568 +#: libs/ardour/audiofilesource.cc:567 msgid "Filesource: cannot check for existing file (%1): %2" msgstr "Filesource: δεν μποÏÏŽ να ελÎγξω για το υπάÏχον αÏχείο (%1): %2" -#: libs/ardour/audiofilesource.cc:640 libs/ardour/insert.cc:525 -#: libs/ardour/sndfilesource.cc:112 +#: libs/ardour/audiofilesource.cc:636 libs/ardour/insert.cc:525 +#: libs/ardour/sndfilesource.cc:113 msgid "programming error: %1" msgstr "σφάλμα Ï€ÏογÏαμματισμοÏ: %1" -#: libs/ardour/audiofilesource.cc:645 +#: libs/ardour/audiofilesource.cc:641 #, fuzzy msgid "cannot rename audio file for %1 to %2" msgstr "δεν μποÏÏŽ να μετονομάσω την πηγή του audio file από %1 σε %2 (%3)" @@ -1837,7 +1837,7 @@ msgstr "" msgid "cannot remove dead sound file %1 (%2)" msgstr "δεν μποÏÏŽ να απαλοίψω το 'νεκÏο' ηχο-αÏχείο %1 (%2)" -#: libs/ardour/session_time.cc:375 +#: libs/ardour/session_time.cc:374 msgid "Unknown JACK transport state %1 in sync callback" msgstr "Άγνωστη κατάσταση του JACK transport %1 στην ανάκληση sync" @@ -1979,24 +1979,24 @@ msgstr "Little-endian (Intel)" msgid "Big-endian (Mac)" msgstr "Big-endian (Mac)" -#: libs/ardour/sndfilesource.cc:146 +#: libs/ardour/sndfilesource.cc:147 msgid "FileSource: cannot get host information for BWF header (%1)" msgstr "" "FileSource: δεν μποÏÏŽ να βÏÏŽ πληÏοφοÏίες οικοδεσπότη(host) για επικεφαλίδα " "BWF (%1)" -#: libs/ardour/sndfilesource.cc:168 +#: libs/ardour/sndfilesource.cc:169 msgid "" "cannot set broadcast info for audio file %1 (%2); dropping broadcast info " "for this file" msgstr "" -#: libs/ardour/sndfilesource.cc:224 +#: libs/ardour/sndfilesource.cc:220 #, fuzzy msgid "SndFileSource: cannot open file \"%1\" for %2 (%3)" msgstr "SndFileSource: δεν μποÏÏŽ να ανοίξω το αÏχείο \"%1\" (%2)" -#: libs/ardour/sndfilesource.cc:230 +#: libs/ardour/sndfilesource.cc:226 msgid "" "SndFileSource: file only contains %1 channels; %2 is invalid as a channel " "number" @@ -2004,22 +2004,22 @@ msgstr "" "SndFileSource: το αÏχείο πεÏιÎχει μόνο %1 κανάλια; %2 δεν Îχει αξία σαν " "κανάλι number" -#: libs/ardour/sndfilesource.cc:307 +#: libs/ardour/sndfilesource.cc:327 msgid "SndFileSource: could not seek to frame %1 within %2 (%3)" msgstr "SndFileSource: δεν μποÏοÏσα να αναζητήσω στο frame %1 μÎσα στο %2 (%3)" -#: libs/ardour/sndfilesource.cc:358 +#: libs/ardour/sndfilesource.cc:378 #, fuzzy msgid "programming error: %1 %2" msgstr "σφάλμα Ï€ÏογÏαμματισμοÏ: %1" -#: libs/ardour/sndfilesource.cc:458 +#: libs/ardour/sndfilesource.cc:487 libs/ardour/sndfilesource.cc:533 msgid "" "cannot set broadcast info for audio file %1; Dropping broadcast info for " "this file" msgstr "" -#: libs/ardour/sndfilesource.cc:500 +#: libs/ardour/sndfilesource.cc:544 #, fuzzy msgid "%1: cannot seek to %2" msgstr "%1: δεν μποÏÏŽ να αναζητήσω στο %2 για εξαγωγή" @@ -2166,7 +2166,7 @@ msgid "no support for presets using chunks at this time" msgstr "" "καμμία υποστήÏιξη αυτή τη στιγμή για Ïυθμίσεις που χÏησιμοποιοÏν κομμάτια" -#: libs/ardour/coreaudio_source.cc:99 +#: libs/ardour/coreaudiosource.cc:97 #, fuzzy msgid "" "CoreAudioSource: file only contains %1 channels; %2 is invalid as a channel " @@ -2175,7 +2175,7 @@ msgstr "" "SndFileSource: το αÏχείο πεÏιÎχει μόνο %1 κανάλια; %2 δεν Îχει αξία σαν " "κανάλι number" -#: libs/ardour/coreaudio_source.cc:164 +#: libs/ardour/coreaudiosource.cc:162 #, fuzzy msgid "CoreAudioSource: could not seek to frame %1 within %2 (%3)" msgstr "SndFileSource: δεν μποÏοÏσα να αναζητήσω στο frame %1 μÎσα στο %2 (%3)" diff --git a/libs/ardour/po/it_IT.po b/libs/ardour/po/it_IT.po index 63089ea77f..2ce02827bd 100644 --- a/libs/ardour/po/it_IT.po +++ b/libs/ardour/po/it_IT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: libardour 0.664.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2006-06-27 13:00-0400\n" +"POT-Creation-Date: 2006-06-29 21:03-0400\n" "PO-Revision-Date: 2003-05-21 12:50+0500\n" "Last-Translator: Filippo Pappalardo <filippo@email.it>\n" "Language-Team: Italian\n" @@ -50,48 +50,48 @@ msgstr "DiskStream %1: impossibile scrivere sul disco" msgid "AudioDiskstream \"%1\": cannot flush captured data to disk!" msgstr "DiskStream \"%1\": impossibile scaricare i dati acquisiti sul disco!" -#: libs/ardour/audio_diskstream.cc:1795 +#: libs/ardour/audio_diskstream.cc:1796 msgid "%1: could not create region for complete audio file" msgstr "%1: impossibile creare una regione per il file audio completo" -#: libs/ardour/audio_diskstream.cc:1818 +#: libs/ardour/audio_diskstream.cc:1819 #, fuzzy msgid "AudioDiskstream: could not create region for captured audio!" msgstr "DiskStream: impossibile creare una regione per l'audio registrato!" -#: libs/ardour/audio_diskstream.cc:1873 +#: libs/ardour/audio_diskstream.cc:1874 #, fuzzy msgid "programmer error: %1" msgstr "errore di programmazione: %1" -#: libs/ardour/audio_diskstream.cc:2145 +#: libs/ardour/audio_diskstream.cc:2146 #, fuzzy msgid "AudioDiskstream: channel %1 out of range" msgstr "DiskStream: canale fuori margine" -#: libs/ardour/audio_diskstream.cc:2170 +#: libs/ardour/audio_diskstream.cc:2171 msgid "%1:%2 new capture file not initialized correctly" msgstr "%1:%2 nuovo file di registrazione non è stato avviato correttamente" -#: libs/ardour/audio_diskstream.cc:2403 +#: libs/ardour/audio_diskstream.cc:2404 msgid "Location \"%1\" not valid for track loop (start >= end)" msgstr "La Location \"%1\" non valida per il loop (inizio >= fine)" -#: libs/ardour/audio_diskstream.cc:2484 +#: libs/ardour/audio_diskstream.cc:2485 #, fuzzy msgid "%1: cannot restore pending capture source file %2" msgstr "Import: impossibile aprire il file audio di input \"%1\"" -#: libs/ardour/audio_diskstream.cc:2506 +#: libs/ardour/audio_diskstream.cc:2507 msgid "%1: incorrect number of pending sources listed - ignoring them all" msgstr "" -#: libs/ardour/audio_diskstream.cc:2522 +#: libs/ardour/audio_diskstream.cc:2523 #, fuzzy msgid "%1: cannot create whole-file region from pending capture sources" msgstr "Playlist: impossibile creare la Regione dal file di stato" -#: libs/ardour/audio_diskstream.cc:2534 +#: libs/ardour/audio_diskstream.cc:2535 #, fuzzy msgid "%1: cannot create region from pending capture sources" msgstr "Playlist: impossibile creare la Regione dal file di stato" @@ -145,41 +145,41 @@ msgstr "cambio dello smorzamento incrociato" msgid "region modified" msgstr "regione modificata" -#: libs/ardour/audio_track.cc:133 libs/ardour/io.cc:1716 +#: libs/ardour/audio_track.cc:125 libs/ardour/io.cc:1716 #: libs/ardour/io.cc:1826 msgid "Unknown connection \"%1\" listed for input of %2" msgstr "Connessione sconosciuta \"%1\" come input di %2" -#: libs/ardour/audio_track.cc:135 libs/ardour/io.cc:1718 +#: libs/ardour/audio_track.cc:127 libs/ardour/io.cc:1718 #: libs/ardour/io.cc:1828 msgid "in 1" msgstr "" -#: libs/ardour/audio_track.cc:136 libs/ardour/io.cc:1719 +#: libs/ardour/audio_track.cc:128 libs/ardour/io.cc:1719 #: libs/ardour/io.cc:1829 msgid "No input connections available as a replacement" msgstr "" -#: libs/ardour/audio_track.cc:140 libs/ardour/io.cc:1723 +#: libs/ardour/audio_track.cc:132 libs/ardour/io.cc:1723 #: libs/ardour/io.cc:1833 msgid "Connection %1 was not available - \"in 1\" used instead" msgstr "" -#: libs/ardour/audio_track.cc:149 libs/ardour/io.cc:1842 +#: libs/ardour/audio_track.cc:141 libs/ardour/io.cc:1842 msgid "improper input channel list in XML node (%1)" msgstr "" -#: libs/ardour/audio_track.cc:194 libs/ardour/audio_track.cc:207 +#: libs/ardour/audio_track.cc:186 libs/ardour/audio_track.cc:199 msgid "AudioTrack: diskstream \"%1\" not known by session" msgstr "AudioTrack: diskstream \"%1\" non riconosciuto dalla sessione" -#: libs/ardour/audio_track.cc:305 +#: libs/ardour/audio_track.cc:297 msgid "" "MIDI rec_enable control specification for %1 is incomplete, so it has been " "ignored" msgstr "" -#: libs/ardour/audio_track.cc:317 +#: libs/ardour/audio_track.cc:309 msgid "programming error: AudioTrack given state without diskstream!" msgstr "" @@ -268,25 +268,25 @@ msgstr "Esportazione: impossibile scrivere dati sul file di output (%1)" msgid "could not reconnect %1 and %2 (err = %3)" msgstr "" -#: libs/ardour/audiofilesource.cc:445 libs/ardour/session_state.cc:3095 +#: libs/ardour/audiofilesource.cc:444 libs/ardour/session_state.cc:3095 msgid "" "there are already 1000 files with names like %1; versioning discontinued" msgstr "" "ci sono gia' 1000 file con nomi come %1; tracciamento di versione interrotto" -#: libs/ardour/audiofilesource.cc:459 libs/ardour/session_state.cc:3109 +#: libs/ardour/audiofilesource.cc:458 libs/ardour/session_state.cc:3109 msgid "cannot rename audio file source from %1 to %2 (%3)" msgstr "impossibile rinominare file audio sorgente da %1 a %2 (%3)" -#: libs/ardour/audiofilesource.cc:466 libs/ardour/session_state.cc:3124 +#: libs/ardour/audiofilesource.cc:465 libs/ardour/session_state.cc:3124 msgid "cannot remove peakfile %1 for %2 (%3)" msgstr "impossibile eliminare il peakfile %1 per %2 (%3)" -#: libs/ardour/audiofilesource.cc:510 +#: libs/ardour/audiofilesource.cc:509 msgid "FileSource: search path not set" msgstr "FileSource: percorso di ricerca non specificato" -#: libs/ardour/audiofilesource.cc:534 +#: libs/ardour/audiofilesource.cc:533 msgid "" "FileSource: \"%1\" is ambigous when searching %2\n" "\t" @@ -294,25 +294,25 @@ msgstr "" "FileSource: \"%1\" è risultato ambiguo nel cercare %2\n" "\t" -#: libs/ardour/audiofilesource.cc:540 +#: libs/ardour/audiofilesource.cc:539 #, fuzzy msgid "Filesource: cannot find required file (%1): while searching %2" msgstr "FileSource: impossibile trovare il file richiesto (%1): %2" -#: libs/ardour/audiofilesource.cc:563 +#: libs/ardour/audiofilesource.cc:562 msgid "Filesource: cannot find required file (%1): %2" msgstr "FileSource: impossibile trovare il file richiesto (%1): %2" -#: libs/ardour/audiofilesource.cc:568 +#: libs/ardour/audiofilesource.cc:567 msgid "Filesource: cannot check for existing file (%1): %2" msgstr "FileSource: impossibile controllare il file esistente (%1): %2" -#: libs/ardour/audiofilesource.cc:640 libs/ardour/insert.cc:525 -#: libs/ardour/sndfilesource.cc:112 +#: libs/ardour/audiofilesource.cc:636 libs/ardour/insert.cc:525 +#: libs/ardour/sndfilesource.cc:113 msgid "programming error: %1" msgstr "errore di programmazione: %1" -#: libs/ardour/audiofilesource.cc:645 +#: libs/ardour/audiofilesource.cc:641 #, fuzzy msgid "cannot rename audio file for %1 to %2" msgstr "impossibile rinominare file audio sorgente da %1 a %2 (%3)" @@ -1782,7 +1782,7 @@ msgstr "Nodo sconosciuto \"%1\" trovato in Connections list dal file di stato" msgid "cannot remove dead sound file %1 (%2)" msgstr "impossibile accedere al file audio per il click %1 (%2)" -#: libs/ardour/session_time.cc:375 +#: libs/ardour/session_time.cc:374 msgid "Unknown JACK transport state %1 in sync callback" msgstr "" @@ -1915,22 +1915,22 @@ msgstr "" msgid "Big-endian (Mac)" msgstr "" -#: libs/ardour/sndfilesource.cc:146 +#: libs/ardour/sndfilesource.cc:147 msgid "FileSource: cannot get host information for BWF header (%1)" msgstr "FileSource: impossibile ottenere info sull'host dall'header BWF (%1)" -#: libs/ardour/sndfilesource.cc:168 +#: libs/ardour/sndfilesource.cc:169 msgid "" "cannot set broadcast info for audio file %1 (%2); dropping broadcast info " "for this file" msgstr "" -#: libs/ardour/sndfilesource.cc:224 +#: libs/ardour/sndfilesource.cc:220 #, fuzzy msgid "SndFileSource: cannot open file \"%1\" for %2 (%3)" msgstr "SndFileSource: impossibile accedere al file \"%1\" (%2)" -#: libs/ardour/sndfilesource.cc:230 +#: libs/ardour/sndfilesource.cc:226 msgid "" "SndFileSource: file only contains %1 channels; %2 is invalid as a channel " "number" @@ -1938,22 +1938,22 @@ msgstr "" "SndFileSource: il file contiene solo %1 canali; %2 non è valido come numero " "di canale" -#: libs/ardour/sndfilesource.cc:307 +#: libs/ardour/sndfilesource.cc:327 msgid "SndFileSource: could not seek to frame %1 within %2 (%3)" msgstr "" -#: libs/ardour/sndfilesource.cc:358 +#: libs/ardour/sndfilesource.cc:378 #, fuzzy msgid "programming error: %1 %2" msgstr "errore di programmazione: %1" -#: libs/ardour/sndfilesource.cc:458 +#: libs/ardour/sndfilesource.cc:487 libs/ardour/sndfilesource.cc:533 msgid "" "cannot set broadcast info for audio file %1; Dropping broadcast info for " "this file" msgstr "" -#: libs/ardour/sndfilesource.cc:500 +#: libs/ardour/sndfilesource.cc:544 msgid "%1: cannot seek to %2" msgstr "" @@ -2100,7 +2100,7 @@ msgstr "" msgid "no support for presets using chunks at this time" msgstr "" -#: libs/ardour/coreaudio_source.cc:99 +#: libs/ardour/coreaudiosource.cc:97 #, fuzzy msgid "" "CoreAudioSource: file only contains %1 channels; %2 is invalid as a channel " @@ -2109,7 +2109,7 @@ msgstr "" "SndFileSource: il file contiene solo %1 canali; %2 non è valido come numero " "di canale" -#: libs/ardour/coreaudio_source.cc:164 +#: libs/ardour/coreaudiosource.cc:162 msgid "CoreAudioSource: could not seek to frame %1 within %2 (%3)" msgstr "" diff --git a/libs/ardour/po/ru_RU.po b/libs/ardour/po/ru_RU.po index 2ca30cba55..aeeb1bf547 100644 --- a/libs/ardour/po/ru_RU.po +++ b/libs/ardour/po/ru_RU.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: libardour 0.716.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2006-06-27 13:00-0400\n" +"POT-Creation-Date: 2006-06-29 21:03-0400\n" "PO-Revision-Date: 2004-03-31 00:55+0300\n" "Last-Translator: Igor Blinov pitstop@nm.ru\n" "Language-Team: Russian\n" @@ -43,44 +43,44 @@ msgstr "" msgid "AudioDiskstream \"%1\": cannot flush captured data to disk!" msgstr "" -#: libs/ardour/audio_diskstream.cc:1795 +#: libs/ardour/audio_diskstream.cc:1796 msgid "%1: could not create region for complete audio file" msgstr "" -#: libs/ardour/audio_diskstream.cc:1818 +#: libs/ardour/audio_diskstream.cc:1819 msgid "AudioDiskstream: could not create region for captured audio!" msgstr "" -#: libs/ardour/audio_diskstream.cc:1873 +#: libs/ardour/audio_diskstream.cc:1874 #, fuzzy msgid "programmer error: %1" msgstr "ÏÛÉÂËÁ ÐÒÏÇÒÁÍÍÙ: " -#: libs/ardour/audio_diskstream.cc:2145 +#: libs/ardour/audio_diskstream.cc:2146 msgid "AudioDiskstream: channel %1 out of range" msgstr "" -#: libs/ardour/audio_diskstream.cc:2170 +#: libs/ardour/audio_diskstream.cc:2171 msgid "%1:%2 new capture file not initialized correctly" msgstr "" -#: libs/ardour/audio_diskstream.cc:2403 +#: libs/ardour/audio_diskstream.cc:2404 msgid "Location \"%1\" not valid for track loop (start >= end)" msgstr "" -#: libs/ardour/audio_diskstream.cc:2484 +#: libs/ardour/audio_diskstream.cc:2485 msgid "%1: cannot restore pending capture source file %2" msgstr "" -#: libs/ardour/audio_diskstream.cc:2506 +#: libs/ardour/audio_diskstream.cc:2507 msgid "%1: incorrect number of pending sources listed - ignoring them all" msgstr "" -#: libs/ardour/audio_diskstream.cc:2522 +#: libs/ardour/audio_diskstream.cc:2523 msgid "%1: cannot create whole-file region from pending capture sources" msgstr "" -#: libs/ardour/audio_diskstream.cc:2534 +#: libs/ardour/audio_diskstream.cc:2535 msgid "%1: cannot create region from pending capture sources" msgstr "" @@ -133,41 +133,41 @@ msgstr "" msgid "region modified" msgstr "" -#: libs/ardour/audio_track.cc:133 libs/ardour/io.cc:1716 +#: libs/ardour/audio_track.cc:125 libs/ardour/io.cc:1716 #: libs/ardour/io.cc:1826 msgid "Unknown connection \"%1\" listed for input of %2" msgstr "" -#: libs/ardour/audio_track.cc:135 libs/ardour/io.cc:1718 +#: libs/ardour/audio_track.cc:127 libs/ardour/io.cc:1718 #: libs/ardour/io.cc:1828 msgid "in 1" msgstr "" -#: libs/ardour/audio_track.cc:136 libs/ardour/io.cc:1719 +#: libs/ardour/audio_track.cc:128 libs/ardour/io.cc:1719 #: libs/ardour/io.cc:1829 msgid "No input connections available as a replacement" msgstr "" -#: libs/ardour/audio_track.cc:140 libs/ardour/io.cc:1723 +#: libs/ardour/audio_track.cc:132 libs/ardour/io.cc:1723 #: libs/ardour/io.cc:1833 msgid "Connection %1 was not available - \"in 1\" used instead" msgstr "" -#: libs/ardour/audio_track.cc:149 libs/ardour/io.cc:1842 +#: libs/ardour/audio_track.cc:141 libs/ardour/io.cc:1842 msgid "improper input channel list in XML node (%1)" msgstr "" -#: libs/ardour/audio_track.cc:194 libs/ardour/audio_track.cc:207 +#: libs/ardour/audio_track.cc:186 libs/ardour/audio_track.cc:199 msgid "AudioTrack: diskstream \"%1\" not known by session" msgstr "" -#: libs/ardour/audio_track.cc:305 +#: libs/ardour/audio_track.cc:297 msgid "" "MIDI rec_enable control specification for %1 is incomplete, so it has been " "ignored" msgstr "" -#: libs/ardour/audio_track.cc:317 +#: libs/ardour/audio_track.cc:309 msgid "programming error: AudioTrack given state without diskstream!" msgstr "" @@ -243,48 +243,48 @@ msgstr "" msgid "could not reconnect %1 and %2 (err = %3)" msgstr "" -#: libs/ardour/audiofilesource.cc:445 libs/ardour/session_state.cc:3095 +#: libs/ardour/audiofilesource.cc:444 libs/ardour/session_state.cc:3095 msgid "" "there are already 1000 files with names like %1; versioning discontinued" msgstr "" -#: libs/ardour/audiofilesource.cc:459 libs/ardour/session_state.cc:3109 +#: libs/ardour/audiofilesource.cc:458 libs/ardour/session_state.cc:3109 msgid "cannot rename audio file source from %1 to %2 (%3)" msgstr "" -#: libs/ardour/audiofilesource.cc:466 libs/ardour/session_state.cc:3124 +#: libs/ardour/audiofilesource.cc:465 libs/ardour/session_state.cc:3124 msgid "cannot remove peakfile %1 for %2 (%3)" msgstr "" -#: libs/ardour/audiofilesource.cc:510 +#: libs/ardour/audiofilesource.cc:509 msgid "FileSource: search path not set" msgstr "" -#: libs/ardour/audiofilesource.cc:534 +#: libs/ardour/audiofilesource.cc:533 msgid "" "FileSource: \"%1\" is ambigous when searching %2\n" "\t" msgstr "" -#: libs/ardour/audiofilesource.cc:540 +#: libs/ardour/audiofilesource.cc:539 msgid "Filesource: cannot find required file (%1): while searching %2" msgstr "" -#: libs/ardour/audiofilesource.cc:563 +#: libs/ardour/audiofilesource.cc:562 msgid "Filesource: cannot find required file (%1): %2" msgstr "" -#: libs/ardour/audiofilesource.cc:568 +#: libs/ardour/audiofilesource.cc:567 msgid "Filesource: cannot check for existing file (%1): %2" msgstr "" -#: libs/ardour/audiofilesource.cc:640 libs/ardour/insert.cc:525 -#: libs/ardour/sndfilesource.cc:112 +#: libs/ardour/audiofilesource.cc:636 libs/ardour/insert.cc:525 +#: libs/ardour/sndfilesource.cc:113 #, fuzzy msgid "programming error: %1" msgstr "ÏÛÉÂËÁ ÐÒÏÇÒÁÍÍÙ: " -#: libs/ardour/audiofilesource.cc:645 +#: libs/ardour/audiofilesource.cc:641 msgid "cannot rename audio file for %1 to %2" msgstr "" @@ -1684,7 +1684,7 @@ msgstr "" msgid "cannot remove dead sound file %1 (%2)" msgstr "" -#: libs/ardour/session_time.cc:375 +#: libs/ardour/session_time.cc:374 msgid "Unknown JACK transport state %1 in sync callback" msgstr "" @@ -1816,42 +1816,42 @@ msgstr "" msgid "Big-endian (Mac)" msgstr "" -#: libs/ardour/sndfilesource.cc:146 +#: libs/ardour/sndfilesource.cc:147 msgid "FileSource: cannot get host information for BWF header (%1)" msgstr "" -#: libs/ardour/sndfilesource.cc:168 +#: libs/ardour/sndfilesource.cc:169 msgid "" "cannot set broadcast info for audio file %1 (%2); dropping broadcast info " "for this file" msgstr "" -#: libs/ardour/sndfilesource.cc:224 +#: libs/ardour/sndfilesource.cc:220 msgid "SndFileSource: cannot open file \"%1\" for %2 (%3)" msgstr "" -#: libs/ardour/sndfilesource.cc:230 +#: libs/ardour/sndfilesource.cc:226 msgid "" "SndFileSource: file only contains %1 channels; %2 is invalid as a channel " "number" msgstr "" -#: libs/ardour/sndfilesource.cc:307 +#: libs/ardour/sndfilesource.cc:327 msgid "SndFileSource: could not seek to frame %1 within %2 (%3)" msgstr "" -#: libs/ardour/sndfilesource.cc:358 +#: libs/ardour/sndfilesource.cc:378 #, fuzzy msgid "programming error: %1 %2" msgstr "ÏÛÉÂËÁ ÐÒÏÇÒÁÍÍÙ: " -#: libs/ardour/sndfilesource.cc:458 +#: libs/ardour/sndfilesource.cc:487 libs/ardour/sndfilesource.cc:533 msgid "" "cannot set broadcast info for audio file %1; Dropping broadcast info for " "this file" msgstr "" -#: libs/ardour/sndfilesource.cc:500 +#: libs/ardour/sndfilesource.cc:544 msgid "%1: cannot seek to %2" msgstr "" @@ -1989,12 +1989,12 @@ msgstr "" msgid "no support for presets using chunks at this time" msgstr "" -#: libs/ardour/coreaudio_source.cc:99 +#: libs/ardour/coreaudiosource.cc:97 msgid "" "CoreAudioSource: file only contains %1 channels; %2 is invalid as a channel " "number" msgstr "" -#: libs/ardour/coreaudio_source.cc:164 +#: libs/ardour/coreaudiosource.cc:162 msgid "CoreAudioSource: could not seek to frame %1 within %2 (%3)" msgstr "" diff --git a/libs/ardour/redirect.cc b/libs/ardour/redirect.cc index 33fec5088f..9800c5b1a2 100644 --- a/libs/ardour/redirect.cc +++ b/libs/ardour/redirect.cc @@ -231,9 +231,9 @@ Redirect::state (bool full_state) string path; string legal_name; - snprintf (buf, sizeof(buf), "%" PRIu64, id()); path = _session.snap_name(); path += "-redirect-"; + id().print (buf); path += buf; path += ".automation"; diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index 8c27a3bebc..f195e42148 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -53,7 +53,6 @@ Region::Region (jack_nframes_t start, jack_nframes_t length, const string& name, { /* basic Region constructor */ - _id = ARDOUR::new_id(); _flags = flags; _playlist = 0; _read_data_count = 0; @@ -76,7 +75,6 @@ Region::Region (const Region& other, jack_nframes_t offset, jack_nframes_t lengt { /* create a new Region from part of an existing one */ - _id = ARDOUR::new_id(); _frozen = 0; pending_changed = Change (0); _playlist = 0; @@ -102,7 +100,6 @@ Region::Region (const Region &other) { /* Pure copy constructor */ - _id = ARDOUR::new_id(); _frozen = 0; pending_changed = Change (0); _playlist = 0; @@ -130,7 +127,6 @@ Region::Region (const Region &other) Region::Region (const XMLNode& node) { - _id = 0; _frozen = 0; pending_changed = Change (0); _playlist = 0; @@ -844,7 +840,7 @@ Region::state (bool full_state) XMLNode *node = new XMLNode ("Region"); char buf[64]; - snprintf (buf, sizeof (buf), "%" PRIu64, _id); + _id.print (buf); node->add_property ("id", buf); node->add_property ("name", _name); snprintf (buf, sizeof (buf), "%u", _start); @@ -886,7 +882,7 @@ Region::set_state (const XMLNode& node) return -1; } - sscanf (prop->value().c_str(), "%" PRIu64, &_id); + _id = prop->value(); if ((prop = node.property ("name")) == 0) { error << _("Session: XMLNode describing a Region is incomplete (no name)") << endmsg; diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 3f51b2f140..8d6ecf7eb5 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -53,16 +53,16 @@ uint32_t Route::order_key_cnt = 0; Route::Route (Session& sess, string name, int input_min, int input_max, int output_min, int output_max, Flag flg) : IO (sess, name, input_min, input_max, output_min, output_max), _flags (flg), - _midi_solo_control (*this, MIDIToggleControl::SoloControl, _session.midi_port()), - _midi_mute_control (*this, MIDIToggleControl::MuteControl, _session.midi_port()) + _solo_control (*this, ToggleControllable::SoloControl), + _mute_control (*this, ToggleControllable::MuteControl) { init (); } Route::Route (Session& sess, const XMLNode& node) : IO (sess, "route"), - _midi_solo_control (*this, MIDIToggleControl::SoloControl, _session.midi_port()), - _midi_mute_control (*this, MIDIToggleControl::MuteControl, _session.midi_port()) + _solo_control (*this, ToggleControllable::SoloControl), + _mute_control (*this, ToggleControllable::MuteControl) { init (); set_state (node); @@ -105,8 +105,6 @@ Route::init () input_changed.connect (mem_fun (this, &Route::input_change_handler)); output_changed.connect (mem_fun (this, &Route::output_change_handler)); - - reset_midi_control (_session.midi_port(), _session.get_midi_control()); } Route::~Route () @@ -712,11 +710,8 @@ Route::set_solo (bool yn, void *src) if (_soloed != yn) { _soloed = yn; - solo_changed (src); /* EMIT SIGNAL */ - - if (_session.get_midi_feedback()) { - _midi_solo_control.send_feedback (_soloed); - } + solo_changed (src); /* EMIT SIGNAL */ + _solo_control.Changed (); /* EMIT SIGNAL */ } } @@ -753,9 +748,7 @@ Route::set_mute (bool yn, void *src) _muted = yn; mute_changed (src); /* EMIT SIGNAL */ - if (_session.get_midi_feedback()) { - _midi_mute_control.send_feedback (_muted); - } + _mute_control.Changed (); /* EMIT SIGNAL */ Glib::Mutex::Lock lm (declick_lock); desired_mute_gain = (yn?0.0f:1.0f); @@ -1362,26 +1355,6 @@ Route::state(bool full_state) node->add_property("mix-group", _mix_group->name()); } - /* MIDI control */ - - MIDI::channel_t chn; - MIDI::eventType ev; - MIDI::byte additional; - XMLNode* midi_node = 0; - XMLNode* child; - - midi_node = node->add_child ("MIDI"); - - if (_midi_mute_control.get_control_info (chn, ev, additional)) { - child = midi_node->add_child ("mute"); - set_midi_node_info (child, ev, chn, additional); - } - if (_midi_solo_control.get_control_info (chn, ev, additional)) { - child = midi_node->add_child ("solo"); - set_midi_node_info (child, ev, chn, additional); - } - - string order_string; OrderKeys::iterator x = order_keys.begin(); @@ -1526,8 +1499,6 @@ Route::set_state (const XMLNode& node) XMLNode *child; XMLPropertyList plist; const XMLProperty *prop; - XMLNodeList midi_kids; - if (node.name() != "Route"){ error << string_compose(_("Bad node sent to Route::set_state() [%1]"), node.name()) << endmsg; @@ -1716,45 +1687,6 @@ Route::set_state (const XMLNode& node) } } - midi_kids = node.children ("MIDI"); - - for (niter = midi_kids.begin(); niter != midi_kids.end(); ++niter) { - - XMLNodeList kids; - XMLNodeConstIterator miter; - XMLNode* child; - - kids = (*niter)->children (); - - for (miter = kids.begin(); miter != kids.end(); ++miter) { - - child =* miter; - - MIDI::eventType ev = MIDI::on; /* initialize to keep gcc happy */ - MIDI::byte additional = 0; /* ditto */ - MIDI::channel_t chn = 0; /* ditto */ - - if (child->name() == "mute") { - - if (get_midi_node_info (child, ev, chn, additional)) { - _midi_mute_control.set_control_type (chn, ev, additional); - } else { - error << string_compose(_("MIDI mute control specification for %1 is incomplete, so it has been ignored"), _name) << endmsg; - } - } - else if (child->name() == "solo") { - - if (get_midi_node_info (child, ev, chn, additional)) { - _midi_solo_control.set_control_type (chn, ev, additional); - } else { - error << string_compose(_("MIDI mute control specification for %1 is incomplete, so it has been ignored"), _name) << endmsg; - } - } - - } - } - - return 0; } @@ -2211,67 +2143,6 @@ Route::has_external_redirects () const } void -Route::reset_midi_control (MIDI::Port* port, bool on) -{ - MIDI::channel_t chn; - MIDI::eventType ev; - MIDI::byte extra; - - for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) { - (*i)->reset_midi_control (port, on); - } - - IO::reset_midi_control (port, on); - - _midi_solo_control.get_control_info (chn, ev, extra); - if (!on) { - chn = -1; - } - _midi_solo_control.midi_rebind (port, chn); - - _midi_mute_control.get_control_info (chn, ev, extra); - if (!on) { - chn = -1; - } - _midi_mute_control.midi_rebind (port, chn); -} - -void -Route::send_all_midi_feedback () -{ - if (_session.get_midi_feedback()) { - - { - Glib::RWLock::ReaderLock lm (redirect_lock); - for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) { - (*i)->send_all_midi_feedback (); - } - } - - IO::send_all_midi_feedback(); - - _midi_solo_control.send_feedback (_soloed); - _midi_mute_control.send_feedback (_muted); - } -} - -MIDI::byte* -Route::write_midi_feedback (MIDI::byte* buf, int32_t& bufsize) -{ - buf = _midi_solo_control.write_feedback (buf, bufsize, _soloed); - buf = _midi_mute_control.write_feedback (buf, bufsize, _muted); - - { - Glib::RWLock::ReaderLock lm (redirect_lock); - for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) { - buf = (*i)->write_midi_feedback (buf, bufsize); - } - } - - return IO::write_midi_feedback (buf, bufsize); -} - -void Route::flush_redirects () { /* XXX shouldn't really try to take this lock, since @@ -2341,106 +2212,46 @@ Route::automation_snapshot (jack_nframes_t now) } } -Route::MIDIToggleControl::MIDIToggleControl (Route& s, ToggleType tp, MIDI::Port* port) - : MIDI::Controllable (port, true), route (s), type(tp), setting(false) +Route::ToggleControllable::ToggleControllable (Route& s, ToggleType tp) + : route (s), type(tp) { - last_written = false; /* XXX need a good out-of-bound-value */ + } void -Route::MIDIToggleControl::set_value (float val) +Route::ToggleControllable::set_value (float val) { - MIDI::eventType et; - MIDI::channel_t chn; - MIDI::byte additional; - - get_control_info (chn, et, additional); - - setting = true; - -#ifdef HOLD_TOGGLE_VALUES - if (et == MIDI::off || et == MIDI::on) { - - /* literal toggle */ - - switch (type) { - case MuteControl: - route.set_mute (!route.muted(), this); - break; - case SoloControl: - route.set_solo (!route.soloed(), this); - break; - default: - break; - } - - } else { -#endif - - /* map full control range to a boolean */ - - bool bval = ((val >= 0.5f) ? true: false); - - switch (type) { - case MuteControl: - route.set_mute (bval, this); - break; - case SoloControl: - route.set_solo (bval, this); - break; - default: - break; - } - -#ifdef HOLD_TOGGLE_VALUES + bool bval = ((val >= 0.5f) ? true: false); + + switch (type) { + case MuteControl: + route.set_mute (bval, this); + break; + case SoloControl: + route.set_solo (bval, this); + break; + default: + break; } -#endif - - setting = false; } -void -Route::MIDIToggleControl::send_feedback (bool value) +float +Route::ToggleControllable::get_value (void) const { - - if (!setting && get_midi_feedback()) { - MIDI::byte val = (MIDI::byte) (value ? 127: 0); - MIDI::channel_t ch = 0; - MIDI::eventType ev = MIDI::none; - MIDI::byte additional = 0; - MIDI::EventTwoBytes data; - - if (get_control_info (ch, ev, additional)) { - data.controller_number = additional; - data.value = val; - last_written = value; - - route._session.send_midi_message (get_port(), ev, ch, data); - } - } + float val = 0.0f; -} - -MIDI::byte* -Route::MIDIToggleControl::write_feedback (MIDI::byte* buf, int32_t& bufsize, bool val, bool force) -{ - if (get_midi_feedback() && bufsize > 2) { - MIDI::channel_t ch = 0; - MIDI::eventType ev = MIDI::none; - MIDI::byte additional = 0; - - if (get_control_info (ch, ev, additional)) { - if (val != last_written || force) { - *buf++ = (0xF0 & ev) | (0xF & ch); - *buf++ = additional; /* controller number */ - *buf++ = (MIDI::byte) (val ? 127 : 0); - bufsize -= 3; - last_written = val; - } - } + switch (type) { + case MuteControl: + val = route.muted() ? 1.0f : 0.0f; + break; + case SoloControl: + val = route.soloed() ? 1.0f : 0.0f; + break; + default: + break; } - return buf; + return val; } void diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 864e6178d2..3f400b0b2b 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -90,6 +90,8 @@ Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0; sigc::signal<int> Session::AskAboutPendingState; sigc::signal<void> Session::SMPTEOffsetChanged; +sigc::signal<void> Session::SendFeedback; + int Session::find_session (string str, string& path, string& snapshot, bool& isnew) @@ -438,7 +440,7 @@ Session::~Session () tmp =i; ++tmp; - delete (*i).second; + delete i->second; i = tmp; } @@ -477,7 +479,7 @@ Session::~Session () tmp = i; ++tmp; - delete (*i).second; + delete i->second; i = tmp; } @@ -2289,7 +2291,7 @@ Session::diskstream_by_name (string name) } AudioDiskstream * -Session::diskstream_by_id (id_t id) +Session::diskstream_by_id (const PBD::ID& id) { Glib::RWLock::ReaderLock lm (diskstream_lock); @@ -2337,7 +2339,7 @@ Session::new_region_name (string old) sbuf = buf; for (i = audio_regions.begin(); i != audio_regions.end(); ++i) { - if ((*i).second->name() == sbuf) { + if (i->second->name() == sbuf) { break; } } @@ -2402,7 +2404,7 @@ Session::region_name (string& result, string base, bool newlevel) const name_taken = false; for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) { - if ((*i).second->name() == result) { + if (i->second->name() == result) { name_taken = true; break; } @@ -2447,8 +2449,8 @@ Session::add_region (Region* region) if (x == audio_regions.end()) { - pair<AudioRegionList::key_type, AudioRegionList::mapped_type> entry; - + pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry; + entry.first = region->id(); entry.second = ar; @@ -2505,16 +2507,18 @@ Session::remove_region (Region* region) AudioRegionList::iterator i; AudioRegion* ar = 0; bool removed = false; - + { Glib::Mutex::Lock lm (region_lock); - if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) { + if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) { if ((i = audio_regions.find (region->id())) != audio_regions.end()) { audio_regions.erase (i); removed = true; - } + } + } else { + fatal << _("programming error: ") << X_("unknown region type passed to Session::remove_region()") << endmsg; @@ -2542,7 +2546,7 @@ Session::find_whole_file_parent (AudioRegion& child) for (i = audio_regions.begin(); i != audio_regions.end(); ++i) { - region = (*i).second; + region = i->second; if (region->whole_file()) { @@ -2646,12 +2650,12 @@ Session::add_audio_source (AudioSource* source) { pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry; - { - Glib::Mutex::Lock lm (audio_source_lock); + { + Glib::Mutex::Lock lm (audio_source_lock); entry.first = source->id(); entry.second = source; audio_sources.insert (entry); - } + } source->GoingAway.connect (mem_fun (this, &Session::remove_source)); set_dirty(); @@ -2669,7 +2673,7 @@ Session::remove_source (Source* source) if ((i = audio_sources.find (source->id())) != audio_sources.end()) { audio_sources.erase (i); - } + } } if (!_state_of_the_state & InCleanup) { @@ -2685,23 +2689,19 @@ Session::remove_source (Source* source) } Source * -Session::get_source (ARDOUR::id_t id) +Session::source_by_id (const PBD::ID& id) { Glib::Mutex::Lock lm (audio_source_lock); AudioSourceList::iterator i; Source* source = 0; if ((i = audio_sources.find (id)) != audio_sources.end()) { - source = (*i).second; - } - - if (source) { - return source; + source = i->second; } /* XXX search MIDI or other searches here */ - return 0; + return source; } string diff --git a/libs/ardour/session_midi.cc b/libs/ardour/session_midi.cc index 60bd95464f..5d513de2fc 100644 --- a/libs/ardour/session_midi.cc +++ b/libs/ardour/session_midi.cc @@ -109,13 +109,6 @@ Session::set_midi_control (bool yn) set_dirty(); poke_midi_thread (); - if (_midi_port) { - Glib::RWLock::ReaderLock guard (route_lock); - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { - (*i)->reset_midi_control (_midi_port, midi_control); - } - } - ControlChanged (MidiControl); /* EMIT SIGNAL */ } diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc index ad4e9a64bb..5568b2a16c 100644 --- a/libs/ardour/session_process.cc +++ b/libs/ardour/session_process.cc @@ -59,6 +59,8 @@ Session::process (jack_nframes_t nframes) } (this->*process_function) (nframes); + + SendFeedback (); /* EMIT SIGNAL */ } void diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 4cf3c2e425..9fb20973e2 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -273,6 +273,9 @@ Session::first_stage_init (string fullpath, string snapshot_name) AudioDiskstream::AudioDiskstreamCreated.connect (mem_fun (*this, &Session::add_diskstream)); NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection)); + Controllable::Created.connect (mem_fun (*this, &Session::add_controllable)); + Controllable::GoingAway.connect (mem_fun (*this, &Session::remove_controllable)); + IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers)); /* stop IO objects from doing stuff until we're ready for them */ @@ -1343,7 +1346,7 @@ Session::state(bool full_state) AudioFileSource* fs; - if ((fs = dynamic_cast<AudioFileSource*> ((*siter).second)) != 0) { + if ((fs = dynamic_cast<AudioFileSource*> (siter->second)) != 0) { DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> (fs); /* destructive file sources are OK if they are empty, because @@ -1357,7 +1360,7 @@ Session::state(bool full_state) } } - child->add_child_nocopy ((*siter).second->get_state()); + child->add_child_nocopy (siter->second->get_state()); } } @@ -1370,7 +1373,7 @@ Session::state(bool full_state) /* only store regions not attached to playlists */ - if ((*i).second->playlist() == 0) { + if (i->second->playlist() == 0) { child->add_child_nocopy (i->second->state (true)); } } @@ -1730,12 +1733,10 @@ Session::load_regions (const XMLNode& node) set_dirty(); for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - if ((region = XMLRegionFactory (**niter, false)) == 0) { error << _("Session: cannot create Region from XML description.") << endmsg; } } - return 0; } @@ -1743,7 +1744,6 @@ AudioRegion * Session::XMLRegionFactory (const XMLNode& node, bool full) { const XMLProperty* prop; - id_t s_id; Source* source; AudioSource* as; AudioRegion::SourceList sources; @@ -1766,9 +1766,9 @@ Session::XMLRegionFactory (const XMLNode& node, bool full) } } - sscanf (prop->value().c_str(), "%" PRIu64, &s_id); + PBD::ID s_id (prop->value()); - if ((source = get_source (s_id)) == 0) { + if ((source = source_by_id (s_id)) == 0) { error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg; return 0; } @@ -1786,23 +1786,23 @@ Session::XMLRegionFactory (const XMLNode& node, bool full) for (uint32_t n=1; n < nchans; ++n) { snprintf (buf, sizeof(buf), X_("source-%d"), n); if ((prop = node.property (buf)) != 0) { - sscanf (prop->value().c_str(), "%" PRIu64, &s_id); - if ((source = get_source (s_id)) == 0) { - error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg; + PBD::ID id2 (prop->value()); + + if ((source = source_by_id (id2)) == 0) { + error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg; return 0; } as = dynamic_cast<AudioSource*>(source); if (!as) { - error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg; + error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg; return 0; } sources.push_back (as); } } - try { return new AudioRegion (sources, node); } @@ -1820,7 +1820,7 @@ Session::get_sources_as_xml () Glib::Mutex::Lock lm (audio_source_lock); for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) { - node->add_child_nocopy ((*i).second->get_state()); + node->add_child_nocopy (i->second->get_state()); } /* XXX get MIDI and other sources here */ @@ -2946,7 +2946,7 @@ Session::cleanup_sources (Session::cleanup_report& rep) capture files. */ - if ((*i).second->use_cnt() == 0 && (*i).second->length() > 0) { + if (i->second->use_cnt() == 0 && i->second->length() > 0) { dead_sources.push_back (i->second); /* remove this source from our own list to avoid us @@ -2973,7 +2973,7 @@ Session::cleanup_sources (Session::cleanup_report& rep) tmp = r; ++tmp; - ar = (*r).second; + ar = r->second; for (uint32_t n = 0; n < ar->n_channels(); ++n) { if (&ar->source (n) == (*i)) { @@ -3026,7 +3026,7 @@ Session::cleanup_sources (Session::cleanup_report& rep) for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) { AudioFileSource* fs; - if ((fs = dynamic_cast<AudioFileSource*> ((*i).second)) != 0) { + if ((fs = dynamic_cast<AudioFileSource*> (i->second)) != 0) { all_sources.insert (fs->path()); } } @@ -3235,3 +3235,30 @@ Session::set_clean () } } +void +Session::add_controllable (Controllable* c) +{ + Glib::Mutex::Lock lm (controllables_lock); + controllables.push_back (c); +} + +void +Session::remove_controllable (Controllable* c) +{ + Glib::Mutex::Lock lm (controllables_lock); + controllables.remove (c); +} + +Controllable* +Session::controllable_by_id (const PBD::ID& id) +{ + Glib::Mutex::Lock lm (controllables_lock); + + for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) { + if ((*i)->id() == id) { + return *i; + } + } + + return 0; +} diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc index 443a24e3c2..1374d9bd31 100644 --- a/libs/ardour/sndfilesource.cc +++ b/libs/ardour/sndfilesource.cc @@ -246,6 +246,8 @@ SndFileSource::open () _flags = Flag (_flags & ~Broadcast); } + set_timeline_position (0); + } else { /* XXX 64 bit alert: when JACK switches to a 64 bit frame count, this needs to use the high bits @@ -280,7 +282,7 @@ SndFileSource::~SndFileSource () } if (_broadcast_info) { - free (_broadcast_info); + delete _broadcast_info; } } @@ -501,6 +503,8 @@ SndFileSource::set_header_timeline_position () return; } + cerr << "timeline pos = " << timeline_position << " offset = " << header_position_offset << endl; + _broadcast_info->time_reference_high = 0; if (header_position_negative) { @@ -523,6 +527,8 @@ SndFileSource::set_header_timeline_position () _broadcast_info->time_reference_high = (pos >> 32); _broadcast_info->time_reference_low = (pos & 0xffffffff); + cerr << "set binfo pos to " << _broadcast_info->time_reference_high << " + " << _broadcast_info->time_reference_low << endl; + if (sf_command (sf, SFC_SET_BROADCAST_INFO, _broadcast_info, sizeof (*_broadcast_info)) != SF_TRUE) { error << string_compose (_("cannot set broadcast info for audio file %1; Dropping broadcast info for this file"), _path) << endmsg; _flags = Flag (_flags & ~Broadcast); diff --git a/libs/ardour/source.cc b/libs/ardour/source.cc index 0d32ea4a21..eebc64d463 100644 --- a/libs/ardour/source.cc +++ b/libs/ardour/source.cc @@ -45,7 +45,6 @@ using namespace ARDOUR; Source::Source (string name) { _name = name; - _id = ARDOUR::new_id(); _use_cnt = 0; _timestamp = 0; } @@ -71,7 +70,7 @@ Source::get_state () char buf[64]; node->add_property ("name", _name); - snprintf (buf, sizeof(buf)-1, "%" PRIu64, _id); + _id.print (buf); node->add_property ("id", buf); if (_timestamp != 0) { @@ -94,7 +93,7 @@ Source::set_state (const XMLNode& node) } if ((prop = node.property ("id")) != 0) { - sscanf (prop->value().c_str(), "%" PRIu64, &_id); + _id = prop->value (); } else { return -1; } diff --git a/libs/ardour/utils.cc b/libs/ardour/utils.cc index 9adc7c72cd..f021639028 100644 --- a/libs/ardour/utils.cc +++ b/libs/ardour/utils.cc @@ -186,15 +186,6 @@ touch_file (string path) return 1; } -uint32_t long -get_uid() -{ - struct timeval tv; - gettimeofday(&tv, 0); - - return (uint32_t long) tv.tv_sec * 1000000 + tv.tv_usec; -} - string placement_as_string (Placement p) { diff --git a/libs/gtkmm2ext/SConscript b/libs/gtkmm2ext/SConscript index 5d8489f103..bb28945641 100644 --- a/libs/gtkmm2ext/SConscript +++ b/libs/gtkmm2ext/SConscript @@ -10,7 +10,6 @@ gtkmm2ext = env.Copy() gtkmm2ext.Merge ([ libraries['sigc2'], libraries['pbd'], - libraries['midi++2'], libraries['gtk2'], libraries['glibmm2'], libraries['pangomm'], @@ -28,16 +27,16 @@ domain = 'libgtkmm2ext' gtkmm2ext.Append(DOMAIN=domain,MAJOR=0,MINOR=8,MICRO=2) gtkmm2ext.Append(CXXFLAGS="-DPACKAGE=\\\"" + domain + "\\\"") gtkmm2ext.Append(CXXFLAGS="-DLIBSIGC_DISABLE_DEPRECATED") +gtkmm2ext.Append(CPPPATH='#libs/surfaces/control_protocol') gtkmm2ext.Append(PACKAGE=domain) gtkmm2ext.Append(POTFILE=domain + '.pot') gtkmm2ext_files = Split(""" auto_spin.cc barcontroller.cc -bindable_button.cc +binding_proxy.cc choice.cc click_box.cc -controller.cc dndtreeview.cc fastmeter.cc gtk_ui.cc diff --git a/libs/gtkmm2ext/barcontroller.cc b/libs/gtkmm2ext/barcontroller.cc index c977f3e5f7..eefe6ca843 100644 --- a/libs/gtkmm2ext/barcontroller.cc +++ b/libs/gtkmm2ext/barcontroller.cc @@ -23,7 +23,7 @@ #include <cmath> #include <algorithm> -#include <midi++/controllable.h> +#include <pbd/controllable.h> #include <gtkmm2ext/gtk_ui.h> #include <gtkmm2ext/utils.h> @@ -36,16 +36,13 @@ using namespace Gtk; using namespace Gtkmm2ext; BarController::BarController (Gtk::Adjustment& adj, - MIDI::Controllable *mc, + PBD::Controllable& mc, sigc::slot<void,char*,unsigned int> lc) : adjustment (adj), - prompter (Gtk::WIN_POS_MOUSE, 30000, false), - midi_control (mc), + binding_proxy (mc), label_callback (lc), - spinner (adjustment), - bind_button (2), - bind_statemask (Gdk::CONTROL_MASK) + spinner (adjustment) { _style = LeftToRight; @@ -77,16 +74,6 @@ BarController::BarController (Gtk::Adjustment& adj, darea.signal_button_release_event().connect (mem_fun (*this, &BarController::button_release)); darea.signal_scroll_event().connect (mem_fun (*this, &BarController::scroll)); - prompter.signal_unmap_event().connect (mem_fun (*this, &BarController::prompter_hiding)); - - prompting = false; - unprompting = false; - - if (mc) { - mc->learning_started.connect (mem_fun (*this, &BarController::midicontrol_prompt)); - mc->learning_stopped.connect (mem_fun (*this, &BarController::midicontrol_unprompt)); - } - spinner.signal_activate().connect (mem_fun (*this, &BarController::entry_activated)); spinner.signal_focus_out_event().connect (mem_fun (*this, &BarController::entry_focus_out)); spinner.set_digits (3); @@ -95,24 +82,13 @@ BarController::BarController (Gtk::Adjustment& adj, show_all (); } -void -BarController::set_bind_button_state (guint button, guint statemask) -{ - bind_button = button; - bind_statemask = statemask; -} - -void -BarController::get_bind_button_state (guint &button, guint &statemask) -{ - button = bind_button; - statemask = bind_statemask; -} - - bool BarController::button_press (GdkEventButton* ev) { + if (binding_proxy.button_press_handler (ev)) { + return true; + } + switch (ev->button) { case 1: if (ev->type == GDK_2BUTTON_PRESS) { @@ -174,8 +150,8 @@ BarController::button_release (GdkEventButton* ev) break; case 2: - if ((ev->state & bind_statemask) && bind_button == 2) { - midi_learn (); + if (true) { // XXX FIX ME + /* relax */ } else { double fract; fract = ev->x / (darea.get_width() - 2.0); @@ -185,10 +161,6 @@ BarController::button_release (GdkEventButton* ev) return true; case 3: - if ((ev->state & bind_statemask) && bind_button == 3) { - midi_learn (); - return TRUE; - } return false; default: @@ -408,61 +380,6 @@ BarController::set_with_text (bool yn) } void -BarController::midicontrol_set_tip () -{ - if (midi_control) { - // Gtkmm2ext::UI::instance()->set_tip (&darea, midi_control->control_description()); - } -} - -void -BarController::midi_learn() -{ - if (midi_control) { - prompting = true; - midi_control->learn_about_external_control (); - } -} - - -void -BarController::midicontrol_prompt () -{ - if (prompting) { - string prompt = _("operate MIDI controller now"); - prompter.set_text (prompt); - Gtkmm2ext::UI::instance()->touch_display (&prompter); - - unprompting = true; - prompting = false; - } -} - -void -BarController::midicontrol_unprompt () -{ - if (unprompting) { - Gtkmm2ext::UI::instance()->touch_display (&prompter); - - unprompting = false; - } -} - -gint -BarController::prompter_hiding (GdkEventAny *ev) -{ - if (unprompting) { - if (midi_control) { - midi_control->stop_learning(); - } - unprompting = false; - } - - return FALSE; -} - - -void BarController::set_style (Style s) { _style = s; diff --git a/libs/gtkmm2ext/controller.cc b/libs/gtkmm2ext/controller.cc deleted file mode 100644 index 98d5566c69..0000000000 --- a/libs/gtkmm2ext/controller.cc +++ /dev/null @@ -1,92 +0,0 @@ -/* - Copyright (C) 1998-99 Paul Davis - 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; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id$ -*/ - -#include <string> -#include <climits> - -#include <midi++/channel.h> -#include <gtkmm2ext/gtk_ui.h> -#include <gtkmm2ext/controller.h> - -#include "i18n.h" - -using namespace Gtkmm2ext; - -Controller::Controller (Gtk::Adjustment *adj, MIDI::Port *p) - : MIDI::Controllable (p), - adjustment (adj), - prompter (Gtk::WIN_POS_MOUSE, 30000, false) -{ - new_value_pending = false; - - /* hear about MIDI control learning */ - - learning_started.connect - (mem_fun (*this, &Controller::midicontrol_prompt)); - learning_stopped.connect - (mem_fun (*this, &Controller::midicontrol_unprompt)); -} - -void -Controller::midicontrol_prompt () - -{ - string prompt = _("operate MIDI controller now"); - - prompter.set_text (prompt); - Gtkmm2ext::UI::instance()->touch_display (&prompter); -} - -void -Controller::midicontrol_unprompt () - -{ - Gtkmm2ext::UI::instance()->touch_display (&prompter); -} - -int -Controller::update_controller_value (void *arg) - -{ - Controller *c = (Controller *) arg; - - c->adjustment->set_value (c->new_value); - c->new_value_pending = false; - - return FALSE; -} - -void -Controller::set_value (float v) - -{ - /* This is called from a MIDI callback. It could happen - a thousand times a second, or more. Therefore, instead - of going straight to the X server, which may not work for - thread-related reasons, simply request an update whenever - the GTK main loop is idle. - */ - - new_value = v; - - if (!new_value_pending) { - new_value_pending = true; - Gtkmm2ext::UI::instance()->idle_add (update_controller_value, this); - } -} diff --git a/libs/gtkmm2ext/gtkmm2ext/barcontroller.h b/libs/gtkmm2ext/gtkmm2ext/barcontroller.h index 67c8221a55..ebce4e2de9 100644 --- a/libs/gtkmm2ext/gtkmm2ext/barcontroller.h +++ b/libs/gtkmm2ext/gtkmm2ext/barcontroller.h @@ -21,9 +21,9 @@ #define __gtkmm2ext_bar_controller_h__ #include <gtkmm.h> -#include <gtkmm2ext/popup.h> +#include <gtkmm2ext/binding_proxy.h> -namespace MIDI { +namespace ARDOUR { class Controllable; } @@ -32,14 +32,9 @@ namespace Gtkmm2ext { class BarController : public Gtk::Frame { public: - BarController (Gtk::Adjustment& adj, MIDI::Controllable*, sigc::slot<void,char*,unsigned int>); + BarController (Gtk::Adjustment& adj, PBD::Controllable&, sigc::slot<void,char*,unsigned int>); virtual ~BarController () {} - void set_bind_button_state (guint button, guint statemask); - void get_bind_button_state (guint &button, guint &statemask); - void midicontrol_set_tip (); - void midi_learn (); - void set_sensitive (bool yn) { darea.set_sensitive (yn); } @@ -69,9 +64,8 @@ class BarController : public Gtk::Frame protected: Gtk::Adjustment& adjustment; + BindingProxy binding_proxy; Gtk::DrawingArea darea; - Gtkmm2ext::PopUp prompter; - MIDI::Controllable* midi_control; sigc::slot<void,char*,unsigned int> label_callback; Glib::RefPtr<Pango::Layout> layout; Style _style; @@ -85,10 +79,6 @@ class BarController : public Gtk::Frame Gtk::SpinButton spinner; bool use_parent; - guint bind_button; - guint bind_statemask; - bool prompting, unprompting; - bool button_press (GdkEventButton *); bool button_release (GdkEventButton *); bool motion (GdkEventMotion *); @@ -98,11 +88,6 @@ class BarController : public Gtk::Frame gint mouse_control (double x, GdkWindow* w, double scaling); - gint prompter_hiding (GdkEventAny *); - void midicontrol_prompt (); - void midicontrol_unprompt (); - void update_midi_control (); - gint switch_to_bar (); gint switch_to_spinner (); diff --git a/libs/gtkmm2ext/gtkmm2ext/bindable_button.h b/libs/gtkmm2ext/gtkmm2ext/bindable_button.h index 7400cf15d0..1936125405 100644 --- a/libs/gtkmm2ext/gtkmm2ext/bindable_button.h +++ b/libs/gtkmm2ext/gtkmm2ext/bindable_button.h @@ -18,59 +18,31 @@ $Id$ */ -#ifndef __pbd_gtkmm_bindable_button_h__ -#define __pbd_gtkmm_bindable_button_h__ +#ifndef __bindable_button_h__ +#define __bindable_button_h__ #include <string> #include <gtkmm2ext/stateful_button.h> -#include <gtkmm2ext/popup.h> +#include "binding_proxy.h" -namespace MIDI { +namespace PBD { class Controllable; } -namespace Gtkmm2ext { - class BindableToggleButton : public Gtk::ToggleButton { public: - BindableToggleButton(MIDI::Controllable *); - - //: Create a check button with a label. - //- You won't be able - //- to add a widget in this button since it already has a {\class Gtk_Label} - //- in it. - explicit BindableToggleButton(MIDI::Controllable *, const std::string &label); - + BindableToggleButton (PBD::Controllable& c) : binding_proxy (c) {} + explicit BindableToggleButton (PBD::Controllable& c, const std::string &label) : Gtk::ToggleButton (label), binding_proxy (c) {} virtual ~BindableToggleButton() {} - void set_bind_button_state (guint button, guint statemask); - void get_bind_button_state (guint &button, guint &statemask); - - void midicontrol_set_tip (); - - void midi_learn (); - - protected: - - Gtkmm2ext::PopUp prompter; - - MIDI::Controllable* midi_control; - - guint bind_button; - guint bind_statemask; - - bool prompting, unprompting; - - void init_events (); - bool prompter_hiding (GdkEventAny *); - void midicontrol_prompt (); - void midicontrol_unprompt (); - - bool on_button_press_event (GdkEventButton *); -}; + bool on_button_press_event (GdkEventButton *ev) { + return binding_proxy.button_press_handler (ev); + } + private: + BindingProxy binding_proxy; }; #endif diff --git a/libs/gtkmm2ext/gtkmm2ext/controller.h b/libs/gtkmm2ext/gtkmm2ext/controller.h deleted file mode 100644 index b72f6c7ed7..0000000000 --- a/libs/gtkmm2ext/gtkmm2ext/controller.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - Copyright (C) 1998-99 Paul Davis - 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; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id$ -*/ - -#ifndef __gtkmm2ext_controller_h__ -#define __gtkmm2ext_controller_h__ - -#include <gtkmm.h> -#include <gtkmm2ext/popup.h> -#include <midi++/controllable.h> - -namespace Gtkmm2ext { - -class Controller : public MIDI::Controllable - -{ - public: - Controller (Gtk::Adjustment *, MIDI::Port *); - virtual ~Controller () {} - - void set_value (float); - float lower () { return adjustment->get_lower(); } - float upper () { return adjustment->get_upper(); } - float range () { return upper() - lower() /* XXX +1 ??? */ ; } - - void midicontrol_prompt (); - void midicontrol_unprompt (); - - protected: - Gtk::Adjustment *adjustment; - - private: - Gtkmm2ext::PopUp prompter; - gfloat new_value; - bool new_value_pending; - - static gint update_controller_value (void *); -}; - -}; /* namespace */ - -#endif // __gtkmm2ext_controller_h__ - - diff --git a/libs/gtkmm2ext/gtkmm2ext/slider_controller.h b/libs/gtkmm2ext/gtkmm2ext/slider_controller.h index 7abaf285d1..8054fdd1b7 100644 --- a/libs/gtkmm2ext/gtkmm2ext/slider_controller.h +++ b/libs/gtkmm2ext/gtkmm2ext/slider_controller.h @@ -1,5 +1,5 @@ /* - Copyright (C) 1998-99 Paul Davis + Copyright (C) 1998-2006 Paul Davis 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 @@ -17,18 +17,19 @@ $Id$ */ -#ifndef __gtkmm2ext_motion_controller_h__ -#define __gtkmm2ext_motion_controller_h__ +#ifndef __gtkmm2ext_slider_controller_h__ +#define __gtkmm2ext_slider_controller_h__ #include <gtkmm.h> #include <gtkmm2ext/popup.h> #include <gtkmm2ext/pixscroller.h> +#include <gtkmm2ext/binding_proxy.h> namespace Gtkmm2ext { class Pix; } -namespace MIDI { +namespace PBD { class Controllable; } @@ -40,41 +41,26 @@ class SliderController : public Gtkmm2ext::PixScroller SliderController (Glib::RefPtr<Gdk::Pixbuf> slider, Glib::RefPtr<Gdk::Pixbuf> rail, Gtk::Adjustment* adj, - MIDI::Controllable*, + PBD::Controllable&, bool with_numeric = true); virtual ~SliderController () {} - void set_bind_button_state (guint button, guint statemask); - void get_bind_button_state (guint &button, guint &statemask); - void midicontrol_set_tip (); - void midi_learn (); - void set_value (float); - // void set_sensitive (bool yn) { - // spin.set_sensitive (yn); - // } - Gtk::SpinButton & get_spin_button () { return spin; } + Gtk::SpinButton& get_spin_button () { return spin; } + bool on_button_press_event (GdkEventButton *ev) { + return binding_proxy.button_press_handler (ev); + } + protected: + BindingProxy binding_proxy; Glib::RefPtr<Gdk::Pixbuf> slider; Glib::RefPtr<Gdk::Pixbuf> rail; Gtk::SpinButton spin; Gtk::Frame spin_frame; Gtk::HBox spin_hbox; - Gtkmm2ext::PopUp prompter; - MIDI::Controllable* midi_control; - - guint bind_button; - guint bind_statemask; - bool prompting, unprompting; - - bool button_press (GdkEventButton *); - bool prompter_hiding (GdkEventAny *); - void midicontrol_prompt (); - void midicontrol_unprompt (); - void update_midi_control (); }; class VSliderController : public SliderController @@ -83,7 +69,7 @@ class VSliderController : public SliderController VSliderController (Glib::RefPtr<Gdk::Pixbuf> slider, Glib::RefPtr<Gdk::Pixbuf> rail, Gtk::Adjustment *adj, - MIDI::Controllable *, + PBD::Controllable&, bool with_numeric = true); }; @@ -93,11 +79,11 @@ class HSliderController : public SliderController HSliderController (Glib::RefPtr<Gdk::Pixbuf> slider, Glib::RefPtr<Gdk::Pixbuf> rail, Gtk::Adjustment *adj, - MIDI::Controllable *, + PBD::Controllable&, bool with_numeric = true); }; }; /* namespace */ -#endif // __gtkmm2ext_motion_controller_h__ +#endif // __gtkmm2ext_slider_controller_h__ diff --git a/libs/gtkmm2ext/slider_controller.cc b/libs/gtkmm2ext/slider_controller.cc index 734d5eb62f..aba58724eb 100644 --- a/libs/gtkmm2ext/slider_controller.cc +++ b/libs/gtkmm2ext/slider_controller.cc @@ -18,47 +18,30 @@ */ #include <string> -#include <climits> - -#include <midi++/controllable.h> #include <gtkmm2ext/gtk_ui.h> -#include <gtkmm2ext/slider_controller.h> #include <gtkmm2ext/pixscroller.h> +#include <gtkmm2ext/slider_controller.h> #include "i18n.h" using namespace Gtkmm2ext; +using namespace PBD; SliderController::SliderController (Glib::RefPtr<Gdk::Pixbuf> slide, Glib::RefPtr<Gdk::Pixbuf> rail, Gtk::Adjustment *adj, - MIDI::Controllable *mc, + Controllable& c, bool with_numeric) : PixScroller (*adj, slide, rail), - spin (*adj, 0, 2), - prompter (Gtk::WIN_POS_MOUSE, 30000, false), - midi_control (mc), - bind_button (2), - bind_statemask (Gdk::CONTROL_MASK) - + binding_proxy (c), + spin (*adj, 0, 2) { - signal_button_press_event().connect (mem_fun (this, &SliderController::button_press)); spin.set_name ("SliderControllerValue"); spin.set_size_request (70,-1); // should be based on font size somehow spin.set_numeric (true); spin.set_snap_to_ticks (false); - - prompter.signal_unmap_event().connect (mem_fun (*this, &SliderController::prompter_hiding)); - - prompting = false; - unprompting = false; - - if (mc) { - mc->learning_started.connect (mem_fun (*this, &SliderController::midicontrol_prompt)); - mc->learning_stopped.connect (mem_fun (*this, &SliderController::midicontrol_unprompt)); - } } void @@ -67,95 +50,13 @@ SliderController::set_value (float v) adj.set_value (v); } -void -SliderController::set_bind_button_state (guint button, guint statemask) -{ - bind_button = button; - bind_statemask = statemask; -} - -void -SliderController::get_bind_button_state (guint &button, guint &statemask) -{ - button = bind_button; - statemask = bind_statemask; -} - -void -SliderController::midi_learn() -{ - if (midi_control) { - prompting = true; - midi_control->learn_about_external_control (); - } -} - -bool -SliderController::button_press (GdkEventButton *ev) -{ - if ((ev->state & bind_statemask) && ev->button == bind_button) { - midi_learn (); - return true; - } - - return false; -} - -void -SliderController::midicontrol_set_tip () - -{ - if (midi_control) { - // Gtkmm2ext::UI::instance()->set_tip (this, midi_control->control_description()); - } -} - -bool -SliderController::prompter_hiding (GdkEventAny *ev) -{ - if (unprompting) { - if (midi_control) { - midi_control->stop_learning(); - } - unprompting = false; - } - - return false; -} - -void -SliderController::midicontrol_prompt () - -{ - if (prompting) { - - string prompt = _("operate MIDI controller now"); - prompter.set_text (prompt); - Gtkmm2ext::UI::instance()->touch_display (&prompter); - - unprompting = true; - prompting = false; - } -} - -void -SliderController::midicontrol_unprompt () - -{ - if (unprompting) { - Gtkmm2ext::UI::instance()->touch_display (&prompter); - unprompting = false; - } -} - - VSliderController::VSliderController (Glib::RefPtr<Gdk::Pixbuf> slide, Glib::RefPtr<Gdk::Pixbuf> rail, Gtk::Adjustment *adj, - MIDI::Controllable *mcontrol, + Controllable& control, bool with_numeric) - : SliderController (slide, rail, adj, mcontrol, with_numeric) + : SliderController (slide, rail, adj, control, with_numeric) { if (with_numeric) { spin_frame.add (spin); @@ -169,10 +70,10 @@ VSliderController::VSliderController (Glib::RefPtr<Gdk::Pixbuf> slide, HSliderController::HSliderController (Glib::RefPtr<Gdk::Pixbuf> slide, Glib::RefPtr<Gdk::Pixbuf> rail, Gtk::Adjustment *adj, - MIDI::Controllable *mcontrol, + Controllable& control, bool with_numeric) - : SliderController (slide, rail, adj, mcontrol, with_numeric) + : SliderController (slide, rail, adj, control, with_numeric) { if (with_numeric) { spin_frame.add (spin); diff --git a/libs/pbd/SConscript b/libs/pbd/SConscript index a9166d9505..ba8d6ef91e 100644 --- a/libs/pbd/SConscript +++ b/libs/pbd/SConscript @@ -21,8 +21,10 @@ pbd_files = Split(""" basename.cc base_ui.cc convert.cc +controllable.cc dmalloc.cc error.cc +id.cc mountpoint.cc path.cc pathscanner.cc @@ -30,6 +32,7 @@ pool.cc pthread_utils.cc receiver.cc stacktrace.cc +stateful.cc strsplit.cc textreceiver.cc transmitter.cc @@ -46,7 +49,11 @@ if conf.CheckCHeader('execinfo.h'): conf.env.Append(CXXFLAGS="-DHAVE_EXECINFO") pbd = conf.Finish() -pbd.Merge ([ libraries['sigc2'], libraries['xml'], libraries['glibmm2'], libraries['glib2'] ]) +pbd.Merge ([ libraries['sigc2'], + libraries['uuid'], + libraries['xml'], + libraries['glibmm2'], + libraries['glib2'] ]) pbd.VersionBuild(['version.cc','pbd/version.h'], 'SConscript') diff --git a/libs/pbd/controllable.cc b/libs/pbd/controllable.cc new file mode 100644 index 0000000000..b1176c64a5 --- /dev/null +++ b/libs/pbd/controllable.cc @@ -0,0 +1,26 @@ +#include <pbd/controllable.h> +#include <pbd/xml++.h> + +#include "i18n.h" + +using namespace PBD; + +sigc::signal<void,Controllable*> Controllable::Created; +sigc::signal<void,Controllable*> Controllable::GoingAway; +sigc::signal<bool,Controllable*> Controllable::StartLearning; +sigc::signal<void,Controllable*> Controllable::StopLearning; + +Controllable::Controllable () +{ + Created (this); +} + +XMLNode& +Controllable::get_state () +{ + XMLNode* node = new XMLNode (X_("Controllable")); + char buf[64]; + _id.print (buf); + node->add_property (X_("id"), buf); + return *node; +} diff --git a/libs/pbd/id.cc b/libs/pbd/id.cc new file mode 100644 index 0000000000..57ddb5b128 --- /dev/null +++ b/libs/pbd/id.cc @@ -0,0 +1,75 @@ +#include <ostream> +#include <iostream> + +#include <string.h> +#include <uuid/uuid.h> + +#include <pbd/id.h> + +using namespace std; +using namespace PBD; + +ID::ID () +{ + uuid_generate (id); +} + +ID::ID (string str) +{ + string_assign (str); +} + +int +ID::string_assign (string str) +{ + /* first check for old-style all-numeric ID's */ + + if (strcspn (str.c_str(), "0123456789") == 0) { + /* all chars are numeric. just render the existing ID into the space in + which we would otherwise store a UUID. + */ + + memset (id, ' ', sizeof (id)); + snprintf ((char*) id, sizeof (id), str.c_str()); + + } else { + + /* OK, its UUID, probably */ + + if (uuid_parse (str.c_str(), id)) { + /* XXX error */ + return -1; + } + } + + return 0; +} + +void +ID::print (char* buf) const +{ + uuid_unparse (id, buf); +} + +ID& +ID::operator= (string str) +{ + string_assign (str); + return *this; +} + +bool +ID::operator== (const ID& other) const +{ + return memcmp (id, other.id, sizeof (id)) == 0; +} + +ostream& +operator<< (ostream& ostr, const ID& id) +{ + char buf[37]; + id.print (buf); + ostr << buf; + return ostr; +} + diff --git a/libs/pbd/pbd/controllable.h b/libs/pbd/pbd/controllable.h new file mode 100644 index 0000000000..4948e4e4a0 --- /dev/null +++ b/libs/pbd/pbd/controllable.h @@ -0,0 +1,44 @@ +#ifndef __pbd_controllable_h__ +#define __pbd_controllable_h__ + +#include <sigc++/trackable.h> +#include <sigc++/signal.h> + +#include <pbd/stateful.h> +#include <pbd/id.h> + +class XMLNode; + +namespace PBD { + +class Controllable : public virtual sigc::trackable, public Stateful { + public: + Controllable (); + virtual ~Controllable() { GoingAway (this); } + + virtual void set_value (float) = 0; + virtual float get_value (void) const = 0; + + virtual bool can_send_feedback() const { return true; } + + static sigc::signal<void,Controllable*> Created; + static sigc::signal<void,Controllable*> GoingAway; + + + static sigc::signal<bool,PBD::Controllable*> StartLearning; + static sigc::signal<void,PBD::Controllable*> StopLearning; + + sigc::signal<void> Changed; + + const PBD::ID& id() const { return _id; } + + int set_state (const XMLNode&) { return 0; } + XMLNode& get_state (); + + private: + PBD::ID _id; +}; + +} + +#endif /* __pbd_controllable_h__ */ diff --git a/libs/pbd/pbd/id.h b/libs/pbd/pbd/id.h new file mode 100644 index 0000000000..95ac00bed0 --- /dev/null +++ b/libs/pbd/pbd/id.h @@ -0,0 +1,34 @@ +#ifndef __pbd_id_h__ +#define __pbd_id_h__ + +#include <uuid/uuid.h> +#include <string> + +namespace PBD { + +class ID { + public: + ID (); + ID (std::string); + + bool operator== (const ID& other) const; + bool operator!= (const ID& other) const { + return !operator== (other); + } + ID& operator= (std::string); + + bool operator< (const ID& other) const { + return memcmp (id, other.id, sizeof (id)) < 0; + } + + void print (char* buf) const; + + private: + uuid_t id; + int string_assign (std::string); +}; + +} +std::ostream& operator<< (std::ostream& ostr, const PBD::ID&); + +#endif /* __pbd_id_h__ */ diff --git a/libs/ardour/ardour/stateful.h b/libs/pbd/pbd/stateful.h index 4f4cb20b39..3038f16b4f 100644 --- a/libs/ardour/ardour/stateful.h +++ b/libs/pbd/pbd/stateful.h @@ -15,11 +15,11 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ + $Id: stateful.h 17 2005-09-24 19:13:41Z taybin $ */ -#ifndef __ardour_stateful_h__ -#define __ardour_stateful_h__ +#ifndef __pbd_stateful_h__ +#define __pbd_stateful_h__ #include <string> @@ -47,5 +47,5 @@ class Stateful { XMLNode *_instant_xml; }; -#endif /* __ardour_stateful_h__ */ +#endif /* __pbd_stateful_h__ */ diff --git a/libs/ardour/stateful.cc b/libs/pbd/stateful.cc index b8e301b273..16aa528f59 100644 --- a/libs/ardour/stateful.cc +++ b/libs/pbd/stateful.cc @@ -15,15 +15,14 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ + $Id: stateful.cc 629 2006-06-21 23:01:03Z paul $ */ -#include <cstdio> #include <unistd.h> -#include <ardour/stateful.h> -#include <ardour/utils.h> +#include <pbd/stateful.h> #include <pbd/xml++.h> +#include <pbd/error.h> #include "i18n.h" @@ -39,7 +38,10 @@ Stateful::~Stateful () { // Do not delete _extra_xml. The use of add_child_nocopy() // means it needs to live on indefinately. - delete _instant_xml; + + if (_instant_xml) { + delete _instant_xml; + } } void diff --git a/libs/surfaces/generic_midi/SConscript b/libs/surfaces/generic_midi/SConscript index 213a81a99d..f9c2de08f8 100644 --- a/libs/surfaces/generic_midi/SConscript +++ b/libs/surfaces/generic_midi/SConscript @@ -23,6 +23,7 @@ genericmidi.Append(POTFILE = domain + '.pot') genericmidi_files=Split(""" interface.cc generic_midi_control_protocol.cc +midicontrollable.cc """) genericmidi.Append(CCFLAGS="-D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE") diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc index 95b9d22393..dec891703e 100644 --- a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc +++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc @@ -1,20 +1,54 @@ +/* + Copyright (C) 2006 Paul Davis + + 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; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#include <algorithm> + #include <midi++/port.h> +#include <midi++/manager.h> +#include <midi++/port_request.h> #include <ardour/route.h> #include <ardour/session.h> #include "generic_midi_control_protocol.h" +#include "midicontrollable.h" using namespace ARDOUR; +using namespace PBD; #include "i18n.h" GenericMidiControlProtocol::GenericMidiControlProtocol (Session& s) : ControlProtocol (s, _("GenericMIDI")) { - _port = s.midi_port(); - s.MIDI_PortChanged.connect (mem_fun (*this, &GenericMidiControlProtocol::port_change)); + MIDI::Manager* mm = MIDI::Manager::instance(); + MIDI::PortRequest pr ("ardour:MIDI control", "ardour:MIDI control", "duplex", "alsa/seq"); + _port = mm->add_port (pr); + + _feedback_interval = 10000; // microseconds + last_feedback_time = 0; + + Controllable::StartLearning.connect (mem_fun (*this, &GenericMidiControlProtocol::start_learning)); + Controllable::StopLearning.connect (mem_fun (*this, &GenericMidiControlProtocol::stop_learning)); + Session::SendFeedback.connect (mem_fun (*this, &GenericMidiControlProtocol::send_feedback)); } GenericMidiControlProtocol::~GenericMidiControlProtocol () @@ -24,42 +58,101 @@ GenericMidiControlProtocol::~GenericMidiControlProtocol () int GenericMidiControlProtocol::set_active (bool yn) { - /* start delivery/outbound thread */ + /* start/stop delivery/outbound thread */ return 0; } void -GenericMidiControlProtocol::port_change () +GenericMidiControlProtocol::set_feedback_interval (microseconds_t ms) { - _port = session->midi_port (); + _feedback_interval = ms; } -void -GenericMidiControlProtocol::set_port (MIDI::Port* p) +void +GenericMidiControlProtocol::send_feedback () { - _port = p; + microseconds_t now = get_microseconds (); + + if (last_feedback_time != 0) { + if ((now - last_feedback_time) < _feedback_interval) { + return; + } + } + + _send_feedback (); + + last_feedback_time = now; } void -GenericMidiControlProtocol::send_route_feedback (list<Route*>& routes) +GenericMidiControlProtocol::_send_feedback () { - if (_port != 0) { - - const int32_t bufsize = 16 * 1024; - MIDI::byte buf[bufsize]; - int32_t bsize = bufsize; - MIDI::byte* end = buf; - - for (list<Route*>::iterator r = routes.begin(); r != routes.end(); ++r) { - end = (*r)->write_midi_feedback (end, bsize); - } - - if (end == buf) { - return; - } - - _port->write (buf, (int32_t) (end - buf)); - //cerr << "MIDI feedback: wrote " << (int32_t) (end - buf) << " to midi port\n"; + const int32_t bufsize = 16 * 1024; + MIDI::byte buf[bufsize]; + int32_t bsize = bufsize; + MIDI::byte* end = buf; + + for (MIDIControllables::iterator r = controllables.begin(); r != controllables.end(); ++r) { + end = (*r)->write_feedback (end, bsize); + } + + if (end == buf) { + return; + } + + _port->write (buf, (int32_t) (end - buf)); +} + +bool +GenericMidiControlProtocol::start_learning (Controllable* c) +{ + if (c == 0) { + return false; + } + + MIDIControllable* mc = new MIDIControllable (*_port, *c); + + + { + Glib::Mutex::Lock lm (pending_lock); + pending_controllables.push_back (mc); + mc->learning_stopped.connect (bind (mem_fun (*this, &GenericMidiControlProtocol::learning_stopped), mc)); + } + + mc->learn_about_external_control (); + return true; +} + +void +GenericMidiControlProtocol::learning_stopped (MIDIControllable* mc) +{ + Glib::Mutex::Lock lm (pending_lock); + Glib::Mutex::Lock lm2 (controllables_lock); + + MIDIControllables::iterator i = find (pending_controllables.begin(), pending_controllables.end(), mc); + + if (i != pending_controllables.end()) { + pending_controllables.erase (i); } + + controllables.push_back (mc); } +void +GenericMidiControlProtocol::stop_learning (Controllable* c) +{ + Glib::Mutex::Lock lm (pending_lock); + + /* learning timed out, and we've been told to consider this attempt to learn to be cancelled. find the + relevant MIDIControllable and remove it from the pending list. + */ + + for (MIDIControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ++i) { + if (&(*i)->get_controllable() == c) { + (*i)->stop_learning (); + delete (*i); + pending_controllables.erase (i); + break; + } + } +} diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.h b/libs/surfaces/generic_midi/generic_midi_control_protocol.h index 70cbd181c8..f86f5f6434 100644 --- a/libs/surfaces/generic_midi/generic_midi_control_protocol.h +++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.h @@ -1,34 +1,55 @@ #ifndef ardour_generic_midi_control_protocol_h #define ardour_generic_midi_control_protocol_h +#include <vector> +#include <glibmm/thread.h> +#include <ardour/types.h> + #include <control_protocol/control_protocol.h> namespace MIDI { class Port; } +namespace PBD { + class Controllable; +} + namespace ARDOUR { + class Session; +} -class GenericMidiControlProtocol : public ControlProtocol { +class MIDIControllable; + +class GenericMidiControlProtocol : public ARDOUR::ControlProtocol { public: - GenericMidiControlProtocol (Session&); + GenericMidiControlProtocol (ARDOUR::Session&); virtual ~GenericMidiControlProtocol(); int set_active (bool yn); static bool probe() { return true; } - void set_port (MIDI::Port*); MIDI::Port* port () const { return _port; } + void set_feedback_interval (ARDOUR::microseconds_t); - void send_route_feedback (std::list<Route*>&); - private: - void route_feedback (ARDOUR::Route&, bool); MIDI::Port* _port; + ARDOUR::microseconds_t _feedback_interval; + ARDOUR::microseconds_t last_feedback_time; - void port_change (); -}; + void _send_feedback (); + void send_feedback (); -} + typedef std::vector<MIDIControllable*> MIDIControllables; + MIDIControllables controllables; + MIDIControllables pending_controllables; + Glib::Mutex controllables_lock; + Glib::Mutex pending_lock; + + bool start_learning (PBD::Controllable*); + void stop_learning (PBD::Controllable*); + + void learning_stopped (MIDIControllable*); +}; -#endif // ardour_generic_midi_control_protocol_h +#endif /* ardour_generic_midi_control_protocol_h */ diff --git a/libs/surfaces/generic_midi/midicontrollable.cc b/libs/surfaces/generic_midi/midicontrollable.cc new file mode 100644 index 0000000000..f4b7ef665b --- /dev/null +++ b/libs/surfaces/generic_midi/midicontrollable.cc @@ -0,0 +1,367 @@ +/* + Copyright (C) 1998-2006 Paul Davis + + 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; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id: midicontrollable.cc 629 2006-06-21 23:01:03Z paul $ +*/ + +#include <cstdio> /* for sprintf, sigh */ +#include <climits> +#include <pbd/error.h> +#include <pbd/xml++.h> +#include <midi++/port.h> +#include <midi++/channel.h> + +#include "midicontrollable.h" + +using namespace sigc; +using namespace MIDI; +using namespace PBD; +using namespace ARDOUR; + +bool MIDIControllable::_send_feedback = false; + +MIDIControllable::MIDIControllable (Port& p, Controllable& c, bool is_bistate) + : controllable (c), _port (p), bistate (is_bistate) +{ + setting = false; + last_written = 0; // got a better idea ? + control_type = none; + _control_description = "MIDI Control: none"; + control_additional = (byte) -1; + connections = 0; + feedback = true; // for now + + /* use channel 0 ("1") as the initial channel */ + + midi_rebind (0); +} + +MIDIControllable::~MIDIControllable () +{ + drop_external_control (); +} + +void +MIDIControllable::midi_forget () +{ + /* stop listening for incoming messages, but retain + our existing event + type information. + */ + + if (connections > 0) { + midi_sense_connection[0].disconnect (); + } + + if (connections > 1) { + midi_sense_connection[1].disconnect (); + } + + connections = 0; + midi_learn_connection.disconnect (); + +} + +void +MIDIControllable::midi_rebind (channel_t c) +{ + if (c >= 0) { + bind_midi (c, control_type, control_additional); + } else { + midi_forget (); + } +} + +void +MIDIControllable::learn_about_external_control () +{ + drop_external_control (); + midi_learn_connection = _port.input()->any.connect (mem_fun (*this, &MIDIControllable::midi_receiver)); + learning_started (); +} + +void +MIDIControllable::stop_learning () +{ + midi_learn_connection.disconnect (); +} + +void +MIDIControllable::drop_external_control () +{ + if (connections > 0) { + midi_sense_connection[0].disconnect (); + } + if (connections > 1) { + midi_sense_connection[1].disconnect (); + } + + connections = 0; + midi_learn_connection.disconnect (); + + control_type = none; + control_additional = (byte) -1; +} + +void +MIDIControllable::midi_sense_note_on (Parser &p, EventTwoBytes *tb) +{ + midi_sense_note (p, tb, true); +} + +void +MIDIControllable::midi_sense_note_off (Parser &p, EventTwoBytes *tb) +{ + midi_sense_note (p, tb, false); +} + +void +MIDIControllable::midi_sense_note (Parser &p, EventTwoBytes *msg, bool is_on) +{ + if (!bistate) { + controllable.set_value (msg->note_number/127.0); + } else { + + /* Note: parser handles the use of zero velocity to + mean note off. if we get called with is_on=true, then we + got a *real* note on. + */ + + if (msg->note_number == control_additional) { + controllable.set_value (is_on ? 1 : 0); + } + } +} + +void +MIDIControllable::midi_sense_controller (Parser &, EventTwoBytes *msg) +{ + if (control_additional == msg->controller_number) { + if (!bistate) { + controllable.set_value (msg->value/127.0); + } else { + if (msg->value > 64.0) { + controllable.set_value (1); + } else { + controllable.set_value (0); + } + } + } +} + +void +MIDIControllable::midi_sense_program_change (Parser &p, byte msg) +{ + /* XXX program change messages make no sense for bistates */ + + if (!bistate) { + controllable.set_value (msg/127.0); + } +} + +void +MIDIControllable::midi_sense_pitchbend (Parser &p, pitchbend_t pb) +{ + /* pitchbend messages make no sense for bistates */ + + /* XXX gack - get rid of assumption about typeof pitchbend_t */ + + controllable.set_value ((pb/(float) SHRT_MAX)); +} + +void +MIDIControllable::midi_receiver (Parser &p, byte *msg, size_t len) +{ + /* we only respond to channel messages */ + + if ((msg[0] & 0xF0) < 0x80 || (msg[0] & 0xF0) > 0xE0) { + return; + } + + /* if the our port doesn't do input anymore, forget it ... */ + + if (!_port.input()) { + return; + } + + bind_midi ((channel_t) (msg[0] & 0xf), eventType (msg[0] & 0xF0), msg[1]); + + learning_stopped (); +} + +void +MIDIControllable::bind_midi (channel_t chn, eventType ev, MIDI::byte additional) +{ + char buf[64]; + + drop_external_control (); + + control_type = ev; + control_channel = chn; + control_additional = additional; + + if (_port.input() == 0) { + return; + } + + Parser& p = *_port.input(); + + int chn_i = chn; + switch (ev) { + case MIDI::off: + midi_sense_connection[0] = p.channel_note_off[chn_i].connect + (mem_fun (*this, &MIDIControllable::midi_sense_note_off)); + + /* if this is a bistate, connect to noteOn as well, + and we'll toggle back and forth between the two. + */ + + if (bistate) { + midi_sense_connection[1] = p.channel_note_on[chn_i].connect + (mem_fun (*this, &MIDIControllable::midi_sense_note_on)); + connections = 2; + } else { + connections = 1; + } + _control_description = "MIDI control: NoteOff"; + break; + + case MIDI::on: + midi_sense_connection[0] = p.channel_note_on[chn_i].connect + (mem_fun (*this, &MIDIControllable::midi_sense_note_on)); + if (bistate) { + midi_sense_connection[1] = p.channel_note_off[chn_i].connect + (mem_fun (*this, &MIDIControllable::midi_sense_note_off)); + connections = 2; + } else { + connections = 1; + } + _control_description = "MIDI control: NoteOn"; + break; + + case MIDI::controller: + midi_sense_connection[0] = p.channel_controller[chn_i].connect + (mem_fun (*this, &MIDIControllable::midi_sense_controller)); + connections = 1; + snprintf (buf, sizeof (buf), "MIDI control: Controller %d", control_additional); + _control_description = buf; + break; + + case MIDI::program: + if (!bistate) { + midi_sense_connection[0] = p.channel_program_change[chn_i].connect + (mem_fun (*this, + &MIDIControllable::midi_sense_program_change)); + connections = 1; + _control_description = "MIDI control: ProgramChange"; + } + break; + + case MIDI::pitchbend: + if (!bistate) { + midi_sense_connection[0] = p.channel_pitchbend[chn_i].connect + (mem_fun (*this, &MIDIControllable::midi_sense_pitchbend)); + connections = 1; + _control_description = "MIDI control: Pitchbend"; + } + break; + + default: + break; + } +} + +void +MIDIControllable::send_feedback () +{ + byte msg[3]; + + if (setting || !_send_feedback || control_type == none) { + return; + } + + msg[0] = (control_type & 0xF0) | (control_channel & 0xF); + msg[1] = control_additional; + msg[2] = (byte) (controllable.get_value() * 127.0f); + + _port.write (msg, 3); +} + +MIDI::byte* +MIDIControllable::write_feedback (MIDI::byte* buf, int32_t& bufsize, bool force) +{ + if (control_type != none &&_send_feedback && bufsize > 2) { + + MIDI::byte gm = (MIDI::byte) (controllable.get_value() * 127.0); + + if (gm != last_written) { + *buf++ = (0xF0 & control_type) | (0xF & control_channel); + *buf++ = control_additional; /* controller number */ + *buf++ = gm; + last_written = gm; + bufsize -= 3; + } + } + + return buf; +} + +int +MIDIControllable::set_state (const XMLNode& node) +{ + const XMLProperty* prop; + int xx; + + if ((prop = node.property ("event")) != 0) { + sscanf (prop->value().c_str(), "0x%x", &xx); + control_type = (MIDI::eventType) xx; + } else { + return -1; + } + + if ((prop = node.property ("channel")) != 0) { + sscanf (prop->value().c_str(), "%d", &xx); + control_channel = (MIDI::channel_t) xx; + } else { + return -1; + } + + if ((prop = node.property ("additional")) != 0) { + sscanf (prop->value().c_str(), "0x%x", &xx); + control_additional = (MIDI::byte) xx; + } else { + return -1; + } + + return 0; +} + +XMLNode& +MIDIControllable::get_state () +{ + char buf[32]; + XMLNode& node (controllable.get_state ()); + + snprintf (buf, sizeof(buf), "0x%x", (int) control_type); + node.add_property ("event", buf); + snprintf (buf, sizeof(buf), "%d", (int) control_channel); + node.add_property ("channel", buf); + snprintf (buf, sizeof(buf), "0x%x", (int) control_additional); + node.add_property ("additional", buf); + + return node; +} + diff --git a/libs/surfaces/generic_midi/midicontrollable.h b/libs/surfaces/generic_midi/midicontrollable.h new file mode 100644 index 0000000000..7dd0be1d87 --- /dev/null +++ b/libs/surfaces/generic_midi/midicontrollable.h @@ -0,0 +1,100 @@ +/* + Copyright (C) 1998-2006 Paul Davis + + 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; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id: controllable.h 4 2005-05-13 20:47:18Z taybin $ +*/ + +#ifndef __gm_midicontrollable_h__ +#define __gm_midicontrollable_h__ + +#include <string> + +#include <sigc++/sigc++.h> + +#include <midi++/types.h> +#include <pbd/controllable.h> +#include <pbd/stateful.h> +#include <ardour/types.h> + +namespace MIDI { + +class Channel; +class Port; +class Parser; + +} + +class MIDIControllable : public Stateful +{ + public: + MIDIControllable (MIDI::Port&, PBD::Controllable&, bool bistate = false); + virtual ~MIDIControllable (); + + void send_feedback (); + MIDI::byte* write_feedback (MIDI::byte* buf, int32_t& bufsize, bool force = false); + + void midi_rebind (MIDI::channel_t channel=-1); + void midi_forget (); + void learn_about_external_control (); + void stop_learning (); + void drop_external_control (); + + sigc::signal<void> learning_started; + sigc::signal<void> learning_stopped; + + bool get_midi_feedback () { return feedback; } + void set_midi_feedback (bool val) { feedback = val; } + + MIDI::Port& get_port() const { return _port; } + PBD::Controllable& get_controllable() const { return controllable; } + + std::string control_description() const { return _control_description; } + + XMLNode& get_state (void); + int set_state (const XMLNode&); + + private: + PBD::Controllable& controllable; + MIDI::Port& _port; + bool setting; + MIDI::byte last_written; + bool bistate; + int midi_msg_id; /* controller ID or note number */ + sigc::connection midi_sense_connection[2]; + sigc::connection midi_learn_connection; + size_t connections; + MIDI::eventType control_type; + MIDI::byte control_additional; + MIDI::channel_t control_channel; + std::string _control_description; + bool feedback; + + static bool _send_feedback; + + void midi_receiver (MIDI::Parser &p, MIDI::byte *, size_t); + void midi_sense_note (MIDI::Parser &, MIDI::EventTwoBytes *, bool is_on); + void midi_sense_note_on (MIDI::Parser &p, MIDI::EventTwoBytes *tb); + void midi_sense_note_off (MIDI::Parser &p, MIDI::EventTwoBytes *tb); + void midi_sense_controller (MIDI::Parser &, MIDI::EventTwoBytes *); + void midi_sense_program_change (MIDI::Parser &, MIDI::byte); + void midi_sense_pitchbend (MIDI::Parser &, MIDI::pitchbend_t); + + void bind_midi (MIDI::channel_t, MIDI::eventType, MIDI::byte); +}; + +#endif // __gm_midicontrollable_h__ + diff --git a/libs/surfaces/tranzport/tranzport_control_protocol.cc b/libs/surfaces/tranzport/tranzport_control_protocol.cc index ee8fa95bc2..09ab88e4ed 100644 --- a/libs/surfaces/tranzport/tranzport_control_protocol.cc +++ b/libs/surfaces/tranzport/tranzport_control_protocol.cc @@ -579,7 +579,7 @@ TranzportControlProtocol::monitor_work () if ((err = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) { // do we care? not particularly. - info << string_compose (_("%1: thread not running with realtime scheduling (%2)"), name(), strerror (errno)) << endmsg; + PBD::info << string_compose (_("%1: thread not running with realtime scheduling (%2)"), name(), strerror (errno)) << endmsg; } pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0); diff --git a/vst/SConscript b/vst/SConscript index 02ae15eb0c..a711a1386d 100644 --- a/vst/SConscript +++ b/vst/SConscript @@ -17,8 +17,8 @@ winmain.c """ ) -ardour_vst.Append (CCFLAGS="-DVST_SUPPORT", CPPPATH="#libs/fst", LIBPATH='#gtk2_ardour') -ardour_vst.Append (LINKFLAGS='-L/usr/X11R6/lib -lasound -lardourgtk -lX11 -lpthread') +ardour_vst.Append (CCFLAGS="-DVST_SUPPORT", CPPPATH="#libs/fst", LIBPATH='#gtk2_ardour', LIBS="ardourgtk") +ardour_vst.Append (LINKFLAGS='-L/usr/X11R6/lib -lasound -lX11 -lpthread') ardour_vst["CC"] ="winegcc" ardour_vst["LINK"] ="wineg++ -mwindows" |