mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-07 15:25:01 +01:00
Don't do a linear search through controls for program change for no reason.
Clean up. git-svn-id: svn://localhost/ardour2/branches/3.0@4600 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
458c588e2c
commit
de88640598
2 changed files with 105 additions and 130 deletions
|
|
@ -18,17 +18,17 @@ class CanvasProgramChange : public CanvasFlag
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CanvasProgramChange(
|
CanvasProgramChange(
|
||||||
MidiRegionView& region,
|
MidiRegionView& region,
|
||||||
Group& parent,
|
Group& parent,
|
||||||
string& text,
|
string& text,
|
||||||
double height,
|
double height,
|
||||||
double x,
|
double x,
|
||||||
double y,
|
double y,
|
||||||
string& model_name,
|
string& model_name,
|
||||||
string& custom_device_mode,
|
string& custom_device_mode,
|
||||||
nframes_t event_time,
|
nframes_t event_time,
|
||||||
uint8_t channel,
|
uint8_t channel,
|
||||||
uint8_t program
|
uint8_t program
|
||||||
);
|
);
|
||||||
|
|
||||||
virtual ~CanvasProgramChange();
|
virtual ~CanvasProgramChange();
|
||||||
|
|
|
||||||
|
|
@ -169,7 +169,6 @@ MidiRegionView::init (Gdk::Color& basic_color, bool wfd)
|
||||||
region_locked ();
|
region_locked ();
|
||||||
|
|
||||||
reset_width_dependent_items (_pixel_width);
|
reset_width_dependent_items (_pixel_width);
|
||||||
//reset_width_dependent_items ((double) _region->length() / samples_per_unit);
|
|
||||||
|
|
||||||
set_colors ();
|
set_colors ();
|
||||||
|
|
||||||
|
|
@ -557,17 +556,6 @@ MidiRegionView::redisplay_model()
|
||||||
_model->read_lock();
|
_model->read_lock();
|
||||||
|
|
||||||
MidiModel::Notes notes = _model->notes();
|
MidiModel::Notes notes = _model->notes();
|
||||||
/*
|
|
||||||
cerr << _model->midi_source()->name() << " : redisplaying " << notes.size() << endl;
|
|
||||||
for (MidiModel::Notes::iterator i = notes.begin(); i != notes.end(); ++i) {
|
|
||||||
cerr << "NOTE time: " << (*i)->time()
|
|
||||||
<< " pitch: " << int((*i)->note())
|
|
||||||
<< " length: " << (*i)->length()
|
|
||||||
<< " end-time: " << (*i)->end_time()
|
|
||||||
<< " velocity: " << int((*i)->velocity())
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
for (size_t i = 0; i < _model->n_notes(); ++i) {
|
for (size_t i = 0; i < _model->n_notes(); ++i) {
|
||||||
add_note(_model->note_at(i));
|
add_note(_model->note_at(i));
|
||||||
|
|
@ -585,64 +573,53 @@ MidiRegionView::redisplay_model()
|
||||||
void
|
void
|
||||||
MidiRegionView::display_program_change_flags()
|
MidiRegionView::display_program_change_flags()
|
||||||
{
|
{
|
||||||
for (Automatable::Controls::iterator control = _model->controls().begin();
|
boost::shared_ptr<Evoral::Control> control = _model->control(MidiPgmChangeAutomation);
|
||||||
control != _model->controls().end(); ++control) {
|
if (!control) {
|
||||||
if (control->first.type() == MidiPgmChangeAutomation) {
|
return;
|
||||||
Glib::Mutex::Lock list_lock (control->second->list()->lock());
|
}
|
||||||
|
|
||||||
uint8_t channel = control->first.channel();
|
Glib::Mutex::Lock lock (control->list()->lock());
|
||||||
|
|
||||||
for (AutomationList::const_iterator event = control->second->list()->begin();
|
|
||||||
event != control->second->list()->end(); ++event) {
|
|
||||||
double event_time = (*event)->when;
|
|
||||||
double program_number = floor((*event)->value + 0.5);
|
|
||||||
|
|
||||||
//cerr << " got program change on channel " << int(channel)
|
uint8_t channel = control->parameter().channel();
|
||||||
// << " time: " << event_time << " number: " << program_number << endl;
|
|
||||||
|
|
||||||
// find bank select msb and lsb for the program change
|
|
||||||
Evoral::Parameter bank_select_msb(MidiCCAutomation, channel, MIDI_CTL_MSB_BANK);
|
|
||||||
boost::shared_ptr<Evoral::Control> msb_control = _model->control(bank_select_msb);
|
|
||||||
uint8_t msb = 0;
|
|
||||||
if (msb_control != 0) {
|
|
||||||
msb = uint8_t(floor(msb_control->get_float(true, event_time) + 0.5));
|
|
||||||
}
|
|
||||||
|
|
||||||
Evoral::Parameter bank_select_lsb(MidiCCAutomation, channel, MIDI_CTL_LSB_BANK);
|
for (AutomationList::const_iterator event = control->list()->begin();
|
||||||
boost::shared_ptr<Evoral::Control> lsb_control = _model->control(bank_select_lsb);
|
event != control->list()->end(); ++event) {
|
||||||
uint8_t lsb = 0;
|
double event_time = (*event)->when;
|
||||||
if (lsb_control != 0) {
|
double program_number = floor((*event)->value + 0.5);
|
||||||
lsb = uint8_t(floor(lsb_control->get_float(true, event_time) + 0.5));
|
|
||||||
}
|
// Get current value of bank select MSB at time of the program change
|
||||||
|
Evoral::Parameter bank_select_msb(MidiCCAutomation, channel, MIDI_CTL_MSB_BANK);
|
||||||
//cerr << " got msb " << int(msb) << " and lsb " << int(lsb)
|
boost::shared_ptr<Evoral::Control> msb_control = _model->control(bank_select_msb);
|
||||||
// << " thread_id: " << pthread_self() << endl;
|
uint8_t msb = 0;
|
||||||
|
if (msb_control != 0) {
|
||||||
MIDI::Name::PatchPrimaryKey patch_key(msb, lsb, program_number);
|
msb = uint8_t(floor(msb_control->get_float(true, event_time) + 0.5));
|
||||||
|
|
||||||
boost::shared_ptr<MIDI::Name::Patch> patch =
|
|
||||||
MIDI::Name::MidiPatchManager::instance().find_patch(
|
|
||||||
_model_name,
|
|
||||||
_custom_device_mode,
|
|
||||||
channel,
|
|
||||||
patch_key);
|
|
||||||
|
|
||||||
ControlEvent program_change(beats_to_frames(event_time),
|
|
||||||
uint8_t(program_number), channel);
|
|
||||||
|
|
||||||
if (patch != 0) {
|
|
||||||
//cerr << " got patch with name " << patch->name()
|
|
||||||
// << " number " << patch->number() << endl;
|
|
||||||
add_pgm_change(program_change, patch->name());
|
|
||||||
} else {
|
|
||||||
char buf[4];
|
|
||||||
snprintf(buf, 4, "%d", int(program_number));
|
|
||||||
add_pgm_change(program_change, buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// Get current value of bank select LSB at time of the program change
|
||||||
|
Evoral::Parameter bank_select_lsb(MidiCCAutomation, channel, MIDI_CTL_LSB_BANK);
|
||||||
|
boost::shared_ptr<Evoral::Control> lsb_control = _model->control(bank_select_lsb);
|
||||||
|
uint8_t lsb = 0;
|
||||||
|
if (lsb_control != 0) {
|
||||||
|
lsb = uint8_t(floor(lsb_control->get_float(true, event_time) + 0.5));
|
||||||
|
}
|
||||||
|
|
||||||
|
MIDI::Name::PatchPrimaryKey patch_key(msb, lsb, program_number);
|
||||||
|
|
||||||
|
boost::shared_ptr<MIDI::Name::Patch> patch =
|
||||||
|
MIDI::Name::MidiPatchManager::instance().find_patch(
|
||||||
|
_model_name, _custom_device_mode, channel, patch_key);
|
||||||
|
|
||||||
|
ControlEvent program_change(beats_to_frames(event_time),
|
||||||
|
uint8_t(program_number), channel);
|
||||||
|
|
||||||
|
if (patch != 0) {
|
||||||
|
add_pgm_change(program_change, patch->name());
|
||||||
|
} else {
|
||||||
|
char buf[4];
|
||||||
|
snprintf(buf, 4, "%d", int(program_number));
|
||||||
|
add_pgm_change(program_change, buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -710,54 +687,57 @@ MidiRegionView::set_height (double height)
|
||||||
void
|
void
|
||||||
MidiRegionView::apply_note_range (uint8_t min, uint8_t max, bool force)
|
MidiRegionView::apply_note_range (uint8_t min, uint8_t max, bool force)
|
||||||
{
|
{
|
||||||
if (_enable_display) {
|
if (!_enable_display) {
|
||||||
if (!force && _current_range_min == min && _current_range_max == max) {
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
_current_range_min = min;
|
|
||||||
_current_range_max = max;
|
|
||||||
|
|
||||||
for (Events::const_iterator i = _events.begin(); i != _events.end(); ++i) {
|
if (!force && _current_range_min == min && _current_range_max == max) {
|
||||||
CanvasNoteEvent* event = *i;
|
return;
|
||||||
Item* item = dynamic_cast<Item*>(event);
|
}
|
||||||
assert(item);
|
|
||||||
if (event && event->note()) {
|
_current_range_min = min;
|
||||||
if (event->note()->note() < _current_range_min
|
_current_range_max = max;
|
||||||
|| event->note()->note() > _current_range_max) {
|
|
||||||
if (canvas_item_visible(item)) {
|
|
||||||
item->hide();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!canvas_item_visible(item)) {
|
|
||||||
item->show();
|
|
||||||
}
|
|
||||||
|
|
||||||
event->hide_velocity();
|
for (Events::const_iterator i = _events.begin(); i != _events.end(); ++i) {
|
||||||
if (CanvasNote* note = dynamic_cast<CanvasNote*>(event)) {
|
CanvasNoteEvent* event = *i;
|
||||||
const double y1 = midi_stream_view()->note_to_y(event->note()->note());
|
Item* item = dynamic_cast<Item*>(event);
|
||||||
const double y2 = y1 + floor(midi_stream_view()->note_height());
|
assert(item);
|
||||||
|
if (event && event->note()) {
|
||||||
|
if (event->note()->note() < _current_range_min
|
||||||
|
|| event->note()->note() > _current_range_max) {
|
||||||
|
if (canvas_item_visible(item)) {
|
||||||
|
item->hide();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!canvas_item_visible(item)) {
|
||||||
|
item->show();
|
||||||
|
}
|
||||||
|
|
||||||
note->property_y1() = y1;
|
event->hide_velocity();
|
||||||
note->property_y2() = y2;
|
if (CanvasNote* note = dynamic_cast<CanvasNote*>(event)) {
|
||||||
} else if (CanvasHit* hit = dynamic_cast<CanvasHit*>(event)) {
|
const double y1 = midi_stream_view()->note_to_y(event->note()->note());
|
||||||
double x = trackview.editor().frame_to_pixel(
|
const double y2 = y1 + floor(midi_stream_view()->note_height());
|
||||||
beats_to_frames(event->note()->time()) - _region->start());
|
|
||||||
const double diamond_size = midi_stream_view()->note_height() / 2.0;
|
note->property_y1() = y1;
|
||||||
double y = midi_stream_view()->note_to_y(event->note()->note())
|
note->property_y2() = y2;
|
||||||
+ ((diamond_size-2.0) / 4.0);
|
} else if (CanvasHit* hit = dynamic_cast<CanvasHit*>(event)) {
|
||||||
|
double x = trackview.editor().frame_to_pixel(
|
||||||
hit->set_height(diamond_size);
|
beats_to_frames(event->note()->time()) - _region->start());
|
||||||
hit->move(x-hit->x1(), y-hit->y1());
|
const double diamond_size = midi_stream_view()->note_height() / 2.0;
|
||||||
hit->show();
|
double y = midi_stream_view()->note_to_y(event->note()->note())
|
||||||
}
|
+ ((diamond_size-2.0) / 4.0);
|
||||||
if (event->selected()) {
|
|
||||||
event->show_velocity();
|
hit->set_height(diamond_size);
|
||||||
}
|
hit->move(x-hit->x1(), y-hit->y1());
|
||||||
|
hit->show();
|
||||||
|
}
|
||||||
|
if (event->selected()) {
|
||||||
|
event->show_velocity();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GhostRegion*
|
GhostRegion*
|
||||||
|
|
@ -772,9 +752,8 @@ MidiRegionView::add_ghost (TimeAxisView& tv)
|
||||||
MidiGhostRegion* ghost;
|
MidiGhostRegion* ghost;
|
||||||
|
|
||||||
if (mtv && mtv->midi_view()) {
|
if (mtv && mtv->midi_view()) {
|
||||||
/* if ghost is inserted into midi track, use a dedicated midi ghost canvas group.
|
/* if ghost is inserted into midi track, use a dedicated midi ghost canvas group
|
||||||
this is because it's nice to have midi notes on top of the note lines and
|
to allow having midi notes on top of note lines and waveforms under it.
|
||||||
audio waveforms under it.
|
|
||||||
*/
|
*/
|
||||||
ghost = new MidiGhostRegion (*mtv->midi_view(), trackview, unit_position);
|
ghost = new MidiGhostRegion (*mtv->midi_view(), trackview, unit_position);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -831,7 +810,8 @@ MidiRegionView::resolve_note(uint8_t note, double end_time)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_active_notes && _active_notes[note]) {
|
if (_active_notes && _active_notes[note]) {
|
||||||
_active_notes[note]->property_x2() = trackview.editor().frame_to_pixel((nframes64_t)end_time);
|
const nframes64_t end_time_frames = beats_to_frames(end_time);
|
||||||
|
_active_notes[note]->property_x2() = trackview.editor().frame_to_pixel(end_time_frames);
|
||||||
_active_notes[note]->property_outline_what() = (guint32) 0xF; // all edges
|
_active_notes[note]->property_outline_what() = (guint32) 0xF; // all edges
|
||||||
_active_notes[note] = NULL;
|
_active_notes[note] = NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -1005,18 +985,13 @@ MidiRegionView::add_pgm_change(ControlEvent& program, string displaytext)
|
||||||
double height = midi_stream_view()->contents_height();
|
double height = midi_stream_view()->contents_height();
|
||||||
|
|
||||||
boost::shared_ptr<CanvasProgramChange> pgm_change = boost::shared_ptr<CanvasProgramChange>(
|
boost::shared_ptr<CanvasProgramChange> pgm_change = boost::shared_ptr<CanvasProgramChange>(
|
||||||
new CanvasProgramChange(
|
new CanvasProgramChange(*this, *group,
|
||||||
*this,
|
|
||||||
*group,
|
|
||||||
displaytext,
|
displaytext,
|
||||||
height,
|
height,
|
||||||
x,
|
x, 1.0,
|
||||||
1.0,
|
|
||||||
_model_name,
|
_model_name,
|
||||||
_custom_device_mode,
|
_custom_device_mode,
|
||||||
program.time,
|
program.time, program.channel, program.value));
|
||||||
program.channel,
|
|
||||||
program.value));
|
|
||||||
|
|
||||||
_pgm_changes.push_back(pgm_change);
|
_pgm_changes.push_back(pgm_change);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue