diff --git a/gtk2_ardour/automation_region_view.cc b/gtk2_ardour/automation_region_view.cc index 9efb03c9f9..5eae11463f 100644 --- a/gtk2_ardour/automation_region_view.cc +++ b/gtk2_ardour/automation_region_view.cc @@ -68,6 +68,7 @@ AutomationRegionView::create_line (boost::shared_ptr lis ARDOUR::EventTypeMap::instance().to_symbol(list->parameter()), trackview, *get_canvas_group(), list)); _line->set_colors(); + _line->set_interpolation(list->interpolation()); _line->show(); _line->show_all_control_points(); _line->set_height ((uint32_t)rint(trackview.current_height() - NAME_HIGHLIGHT_SIZE)); diff --git a/gtk2_ardour/automation_streamview.cc b/gtk2_ardour/automation_streamview.cc index b02d511d07..e7ab760709 100644 --- a/gtk2_ardour/automation_streamview.cc +++ b/gtk2_ardour/automation_streamview.cc @@ -158,11 +158,13 @@ AutomationStreamView::redisplay_diskstream () { list::iterator i, tmp; - for (i = region_views.begin(); i != region_views.end(); ++i) + for (i = region_views.begin(); i != region_views.end(); ++i) { (*i)->set_valid (false); + } if (_trackview.is_track()) { - _trackview.get_diskstream()->playlist()->foreach_region (static_cast(this), &StreamView::add_region_view); + _trackview.get_diskstream()->playlist()->foreach_region ( + static_cast(this), &StreamView::add_region_view); } for (i = region_views.begin(); i != region_views.end(); ) { diff --git a/gtk2_ardour/automation_time_axis.cc b/gtk2_ardour/automation_time_axis.cc index e3b5ee9f4c..3fa98003ce 100644 --- a/gtk2_ardour/automation_time_axis.cc +++ b/gtk2_ardour/automation_time_axis.cc @@ -377,7 +377,11 @@ void AutomationTimeAxisView::set_height (uint32_t h) { bool changed = (height != (uint32_t) h) || first_call_to_set_height; - bool changed_between_small_and_normal = ( (height < hNormal && h >= hNormal) || (height >= hNormal || h < hNormal) ); + bool changed_between_small_and_normal = ( + (height < hNormal && h >= hNormal) || + (height >= hNormal || + h < hNormal) + ); TimeAxisView* state_parent = get_parent_with_state (); assert(state_parent); @@ -527,7 +531,9 @@ AutomationTimeAxisView::build_display_menu () items.push_back (MenuElem (_("State"), *auto_state_menu)); /* mode menu */ - + + // To be deleted: MIDI events should always be discrete, so no choice for the user here. + /* if ( EventTypeMap::instance().is_midi_parameter(_control->parameter()) ) { Menu* auto_mode_menu = manage (new Menu); @@ -540,16 +546,17 @@ AutomationTimeAxisView::build_display_menu () mem_fun(*this, &AutomationTimeAxisView::set_interpolation), AutomationList::Discrete))); mode_discrete_item = dynamic_cast(&am_items.back()); - //mode_discrete_item->set_active(_control->list()->interpolation() == AutomationList::Discrete); + mode_discrete_item->set_active(_control->list()->interpolation() == AutomationList::Discrete); am_items.push_back (RadioMenuElem (group, _("Line"), bind ( mem_fun(*this, &AutomationTimeAxisView::set_interpolation), AutomationList::Linear))); mode_line_item = dynamic_cast(&am_items.back()); - //mode_line_item->set_active(_control->list()->interpolation() == AutomationList::Linear); + mode_line_item->set_active(_control->list()->interpolation() == AutomationList::Linear); items.push_back (MenuElem (_("Mode"), *auto_mode_menu)); } + */ /* make sure the automation menu state is correct */ diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 1c18dd60c4..b00a4a5550 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -147,8 +147,9 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other, boost::shared_ptrmidi_source(0)->load_model(); + } const Meter& m = trackview.session().tempo_map().meter_at(_region->position()); const Tempo& t = trackview.session().tempo_map().tempo_at(_region->position()); diff --git a/gtk2_ardour/midi_streamview.cc b/gtk2_ardour/midi_streamview.cc index 4646729c42..f3d807af03 100644 --- a/gtk2_ardour/midi_streamview.cc +++ b/gtk2_ardour/midi_streamview.cc @@ -177,8 +177,9 @@ MidiStreamView::display_region(MidiRegionView* region_view, bool load_model) boost::shared_ptr source(region_view->midi_region()->midi_source(0)); - if (load_model) + if (load_model) { source->load_model(); + } _range_dirty = update_data_note_range( source->model()->lowest_note(), diff --git a/gtk2_ardour/midi_time_axis.cc b/gtk2_ardour/midi_time_axis.cc index c482c744cf..3376a9da9f 100644 --- a/gtk2_ardour/midi_time_axis.cc +++ b/gtk2_ardour/midi_time_axis.cc @@ -503,6 +503,8 @@ MidiTimeAxisView::create_automation_child (const Evoral::Parameter& param, bool c = boost::dynamic_pointer_cast(_route->control_factory(param)); _route->add_control(c); } + + assert(c); boost::shared_ptr track(new AutomationTimeAxisView (_session, _route, boost::shared_ptr(), c, diff --git a/libs/ardour/ardour/event_type_map.h b/libs/ardour/ardour/event_type_map.h index b0ccdc8efd..feddc45968 100644 --- a/libs/ardour/ardour/event_type_map.h +++ b/libs/ardour/ardour/event_type_map.h @@ -23,8 +23,7 @@ #include #include - -namespace Evoral { class Parameter; } +#include namespace ARDOUR { @@ -36,6 +35,7 @@ public: bool type_is_midi(uint32_t type) const; uint8_t parameter_midi_type(const Evoral::Parameter& param) const; uint32_t midi_event_type(uint8_t status) const; + Evoral::ControlList::InterpolationStyle interpolation_of(const Evoral::Parameter& param); bool is_integer(const Evoral::Parameter& param) const; Evoral::Parameter new_parameter(uint32_t type, uint8_t channel=0, uint32_t id=0) const; diff --git a/libs/ardour/event_type_map.cc b/libs/ardour/event_type_map.cc index a4d8317a42..3b4fefdcea 100644 --- a/libs/ardour/event_type_map.cc +++ b/libs/ardour/event_type_map.cc @@ -75,6 +75,63 @@ EventTypeMap::is_integer(const Evoral::Parameter& param) const && param.type() <= MidiChannelPressureAutomation); } +Evoral::ControlList::InterpolationStyle +EventTypeMap::interpolation_of(const Evoral::Parameter& param) +{ + switch (param.type()) { + case MidiCCAutomation: + switch (param.id()) { + case MIDI_CTL_LSB_BANK: + case MIDI_CTL_MSB_BANK: + case MIDI_CTL_LSB_EFFECT1: + case MIDI_CTL_LSB_EFFECT2: + case MIDI_CTL_MSB_EFFECT1: + case MIDI_CTL_MSB_EFFECT2: + case MIDI_CTL_MSB_GENERAL_PURPOSE1: + case MIDI_CTL_MSB_GENERAL_PURPOSE2: + case MIDI_CTL_MSB_GENERAL_PURPOSE3: + case MIDI_CTL_MSB_GENERAL_PURPOSE4: + case MIDI_CTL_SUSTAIN: + case MIDI_CTL_PORTAMENTO: + case MIDI_CTL_SOSTENUTO: + case MIDI_CTL_SOFT_PEDAL: + case MIDI_CTL_LEGATO_FOOTSWITCH: + case MIDI_CTL_HOLD2: + case MIDI_CTL_GENERAL_PURPOSE5: + case MIDI_CTL_GENERAL_PURPOSE6: + case MIDI_CTL_GENERAL_PURPOSE7: + case MIDI_CTL_GENERAL_PURPOSE8: + case MIDI_CTL_DATA_INCREMENT: + case MIDI_CTL_DATA_DECREMENT: + case MIDI_CTL_NONREG_PARM_NUM_LSB: + case MIDI_CTL_NONREG_PARM_NUM_MSB: + case MIDI_CTL_REGIST_PARM_NUM_LSB: + case MIDI_CTL_REGIST_PARM_NUM_MSB: + case MIDI_CTL_ALL_SOUNDS_OFF: + case MIDI_CTL_RESET_CONTROLLERS: + case MIDI_CTL_LOCAL_CONTROL_SWITCH: + case MIDI_CTL_ALL_NOTES_OFF: + case MIDI_CTL_OMNI_OFF: + case MIDI_CTL_OMNI_ON: + case MIDI_CTL_MONO: + case MIDI_CTL_POLY: + + return Evoral::ControlList::Discrete; + break; + + default: return Evoral::ControlList::Linear; break; + } + + break; + + case MidiPgmChangeAutomation: return Evoral::ControlList::Discrete; break; + case MidiChannelPressureAutomation: return Evoral::ControlList::Linear; break; + case MidiPitchBenderAutomation: return Evoral::ControlList::Linear; break; + default: assert(false); + } +} + + Evoral::Parameter EventTypeMap::new_parameter(uint32_t type, uint8_t channel, uint32_t id) const { diff --git a/libs/ardour/midi_source.cc b/libs/ardour/midi_source.cc index ac52b81ee5..2aed2cad28 100644 --- a/libs/ardour/midi_source.cc +++ b/libs/ardour/midi_source.cc @@ -147,8 +147,9 @@ MidiSource::mark_streaming_midi_write_started (NoteMode mode, nframes_t start_fr void MidiSource::mark_streaming_write_started () { - if (_model) + if (_model) { _model->start_write(); + } _writing = true; } @@ -156,8 +157,9 @@ MidiSource::mark_streaming_write_started () void MidiSource::mark_streaming_write_completed () { - if (_model) + if (_model) { _model->end_write(false); // FIXME: param? + } _writing = false; } diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc index 9caf005833..cc521336e3 100644 --- a/libs/ardour/smf_source.cc +++ b/libs/ardour/smf_source.cc @@ -241,8 +241,9 @@ SMFSource::write_unlocked (MidiRingBuffer& src, nframes_t cnt) append_event_unlocked(Frames, ev); - if (_model) + if (_model) { _model->append(ev); + } } SMF::flush(); @@ -601,14 +602,18 @@ SMFSource::set_source_name (string newname, bool destructive) void SMFSource::load_model(bool lock, bool force_reload) { - if (_writing) + if (_writing) { return; + } + - if (lock) + if (lock) { Glib::Mutex::Lock lm (_lock); + } - if (_model && !force_reload && !_model->empty()) + if (_model && !force_reload && !_model->empty()) { return; + } if (! _model) { _model = boost::shared_ptr(new MidiModel(this)); @@ -648,10 +653,18 @@ SMFSource::load_model(bool lock, bool force_reload) _model->append(ev); } - if (ev.size() > scratch_size) + if (ev.size() > scratch_size) { scratch_size = ev.size(); - else + } else { ev.size() = scratch_size; + } + } + + // set interpolation style to defaults, can be changed by the GUI later + Evoral::ControlSet::Controls controls = _model->controls(); + for (Evoral::ControlSet::Controls::iterator c = controls.begin(); c != controls.end(); ++c) { + (*c).second->list()->set_interpolation( + EventTypeMap::instance().interpolation_of((*c).first)); } _model->end_write(false); diff --git a/libs/evoral/evoral/midi_events.h b/libs/evoral/evoral/midi_events.h index d0329cdaf8..a235d9a3fc 100644 --- a/libs/evoral/evoral/midi_events.h +++ b/libs/evoral/evoral/midi_events.h @@ -100,8 +100,8 @@ #define MIDI_CTL_ALL_NOTES_OFF 0x7B /**< All Notes Off */ #define MIDI_CTL_OMNI_OFF 0x7C /**< Omni Off */ #define MIDI_CTL_OMNI_ON 0x7D /**< Omni On */ -#define MIDI_CTL_MONO1 0x7E /**< Mono1 */ -#define MIDI_CTL_MONO2 0x7F /**< Mono2 */ +#define MIDI_CTL_MONO 0x7E /**< Monophonic mode */ +#define MIDI_CTL_POLY 0x7F /**< Polyphonic mode */ // Commands #define MIDI_CMD_NOTE_OFF 0x80 /**< Note Off */ diff --git a/libs/evoral/src/ControlList.cpp b/libs/evoral/src/ControlList.cpp index 022945b0f8..b54e2373f8 100644 --- a/libs/evoral/src/ControlList.cpp +++ b/libs/evoral/src/ControlList.cpp @@ -987,14 +987,17 @@ ControlList::rt_safe_earliest_event_discrete_unlocked (double start, double end, assert(x >= start); assert(x < end); + cerr << "returned something" << endl; return true; } else { + cerr << "not between start and end" << endl; return false; } /* No points in range */ } else { + cerr << "no points in range" << endl; return false; } } diff --git a/libs/evoral/src/Sequence.cpp b/libs/evoral/src/Sequence.cpp index ce037d985f..6a860ac833 100644 --- a/libs/evoral/src/Sequence.cpp +++ b/libs/evoral/src/Sequence.cpp @@ -630,7 +630,8 @@ Sequence::append_control_unlocked(const Parameter& param, EventTime time, double { debugout << this << " " << _type_map.to_symbol(param) << " @ " << time << " \t= \t" << value << " # controls: " << _controls.size() << endl; - control(param, true)->list()->rt_add(time, value); + boost::shared_ptr c = control(param, true); + c->list()->rt_add(time, value); } diff --git a/libs/midi++2/midi++/events.h b/libs/midi++2/midi++/events.h index 1f8e63eea2..1de77b726d 100644 --- a/libs/midi++2/midi++/events.h +++ b/libs/midi++2/midi++/events.h @@ -125,8 +125,8 @@ #define MIDI_CTL_ALL_NOTES_OFF 0x7B /**< All notes off */ #define MIDI_CTL_OMNI_OFF 0x7C /**< Omni off */ #define MIDI_CTL_OMNI_ON 0x7D /**< Omni on */ -#define MIDI_CTL_MONO1 0x7E /**< Mono1 */ -#define MIDI_CTL_MONO2 0x7F /**< Mono2 */ +#define MIDI_CTL_MONO 0x7E /**< Monophonic mode */ +#define MIDI_CTL_POLY 0x7F /**< Polyphonic mode */ //@} diff --git a/libs/midi++2/midi++/names.h b/libs/midi++2/midi++/names.h index a02fed8a3d..e4fdd241db 100644 --- a/libs/midi++2/midi++/names.h +++ b/libs/midi++2/midi++/names.h @@ -208,17 +208,17 @@ inline static const char* midi_name(uint8_t status) case MIDI_CTL_RESET_CONTROLLERS: return "Reset Controllers"; break; case MIDI_CTL_LOCAL_CONTROL_SWITCH: - return "Local Control Switch"; break; + return "Local Keyboard on/off"; break; case MIDI_CTL_ALL_NOTES_OFF: return "All Notes Off"; break; case MIDI_CTL_OMNI_OFF: return "Omni Off"; break; case MIDI_CTL_OMNI_ON: return "Omni On"; break; - case MIDI_CTL_MONO1: - return "Mono 1"; break; - case MIDI_CTL_MONO2: - return "Mono 2"; break; + case MIDI_CTL_MONO: + return "Monophonic Mode"; break; + case MIDI_CTL_POLY: + return "Polyphonic Mode"; break; default: return "Unnamed"; break; }