diff options
author | David Robillard <d@drobilla.net> | 2008-05-15 05:00:28 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2008-05-15 05:00:28 +0000 |
commit | 05801cc3d62298453385eae40ea7692386bf7f84 (patch) | |
tree | 75882f6f0c0c9bc5c8bf9c556ce302a8f2afd629 | |
parent | a65044d097105a1b9915ead5e51054bb7947771e (diff) |
Eliminate excessive allocation (for every event) during MidiModel iteration.
git-svn-id: svn://localhost/ardour2/branches/3.0@3351 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r-- | gtk2_ardour/canvas-program-change.cc | 37 | ||||
-rw-r--r-- | gtk2_ardour/canvas-program-change.h | 1 | ||||
-rw-r--r-- | gtk2_ardour/midi_region_view.cc | 25 | ||||
-rw-r--r-- | libs/ardour/ardour/midi_model.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/note.h | 2 | ||||
-rw-r--r-- | libs/ardour/midi_buffer.cc | 8 | ||||
-rw-r--r-- | libs/ardour/midi_model.cc | 47 | ||||
-rw-r--r-- | libs/midi++2/midi++/event.h | 35 |
8 files changed, 73 insertions, 84 deletions
diff --git a/gtk2_ardour/canvas-program-change.cc b/gtk2_ardour/canvas-program-change.cc index ccaf333ef5..6f7182e2cd 100644 --- a/gtk2_ardour/canvas-program-change.cc +++ b/gtk2_ardour/canvas-program-change.cc @@ -12,19 +12,16 @@ CanvasProgramChange::CanvasProgramChange( double height, double x, double y) - : Group(parent, x, y), - _region(region), - _event(event), - _text(0), - _line(0), - _rect(0), - _widget(0) + : Group(parent, x, y) + , _region(region) + , _event(event) + , _text(0) + , _line(0) + , _rect(0) { - _text = new Text(*this); - assert(_text); - ostringstream pgm(ios::ate); - pgm << int(event->pgm_number()); - _text->property_text() = pgm.str(); + char pgm_str[4]; + snprintf(pgm_str, 4, "%d", (int)event->pgm_number()); + _text = new Text(*this, 0.0, 0.0, pgm_str); _text->property_justification() = Gtk::JUSTIFY_CENTER; _text->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_MidiProgramChangeOutline.get(); double flagwidth = _text->property_text_width() + 10.0; @@ -39,22 +36,12 @@ CanvasProgramChange::CanvasProgramChange( _rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_MidiProgramChangeFill.get(); _text->lower_to_bottom(); _text->raise(2); - assert(_widget == 0); - assert(_text != 0); - assert(_line != 0); - assert(_rect != 0); } CanvasProgramChange::~CanvasProgramChange() { - if(_line) - delete _line; - if(_rect) - delete _rect; - if(_text) - delete _text; - if(_widget) - delete _widget; + delete _line; + delete _rect; + delete _text; } - diff --git a/gtk2_ardour/canvas-program-change.h b/gtk2_ardour/canvas-program-change.h index 37dc0cc8da..3ac9b10383 100644 --- a/gtk2_ardour/canvas-program-change.h +++ b/gtk2_ardour/canvas-program-change.h @@ -33,7 +33,6 @@ private: Text* _text; SimpleLine* _line; SimpleRect* _rect; - Widget* _widget; }; } // namespace Canvas diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index b70e1c7b08..b9af0a81a2 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -466,29 +466,28 @@ MidiRegionView::redisplay_model() << " 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)); - } - for (Automatable::Controls::iterator - control = _model->controls().begin(); + // Draw program change 'flags' + for (Automatable::Controls::iterator control = _model->controls().begin(); control != _model->controls().end(); ++control) { - - if ( control->first.type() == MidiPgmChangeAutomation ) { + if (control->first.type() == MidiPgmChangeAutomation) { Glib::Mutex::Lock list_lock (control->second->list()->lock()); for (AutomationList::const_iterator event = control->second->list()->begin(); - event != control->second->list()->end(); ++event) { + event != control->second->list()->end(); ++event) { MidiControlIterator iter(control->second->list(), (*event)->when, (*event)->value); - add_pgm_change(_model->control_to_midi_event(iter)); + boost::shared_ptr<MIDI::Event> event(new MIDI::Event()); + _model->control_to_midi_event(event, iter); + add_pgm_change(event); } break; } } - // Is this necessary ?????????? + // Is this necessary? /*for (Automatable::Controls::const_iterator i = _model->controls().begin(); i != _model->controls().end(); ++i) { @@ -821,12 +820,8 @@ MidiRegionView::add_pgm_change(boost::shared_ptr<MIDI::Event> event) assert(event->time() >= 0); // dont display notes beyond the region bounds - if ( - event->time() - _region->start() >= _region->length() || - event->time() < _region->start() - ) { + if (event->time() - _region->start() >= _region->length() || event->time() < _region->start()) return; - } ArdourCanvas::Group* const group = (ArdourCanvas::Group*)get_canvas_group(); const double x = trackview.editor.frame_to_pixel((nframes_t)event->time() - _region->start()); diff --git a/libs/ardour/ardour/midi_model.h b/libs/ardour/ardour/midi_model.h index 98e159002a..a49a878371 100644 --- a/libs/ardour/ardour/midi_model.h +++ b/libs/ardour/ardour/midi_model.h @@ -200,7 +200,7 @@ public: const MidiSource* midi_source() const { return _midi_source; } void set_midi_source(MidiSource* source) { _midi_source = source; } - boost::shared_ptr<MIDI::Event> control_to_midi_event(const MidiControlIterator& iter) const; + bool control_to_midi_event(boost::shared_ptr<MIDI::Event> ev, const MidiControlIterator& iter) const; private: friend class DeltaCommand; diff --git a/libs/ardour/ardour/note.h b/libs/ardour/ardour/note.h index f32a2e75f9..0f649b3370 100644 --- a/libs/ardour/ardour/note.h +++ b/libs/ardour/ardour/note.h @@ -62,7 +62,7 @@ public: inline void set_note(uint8_t n) { _on_event.buffer()[1] = n; _off_event.buffer()[1] = n; } inline void set_velocity(uint8_t n) { _on_event.buffer()[2] = n; } inline void set_duration(double d) { _off_event.time() = _on_event.time() + d; } - inline void set_channel(uint8_t channel) { _on_event.set_channel(channel); _off_event.set_channel(channel); } + inline void set_channel(uint8_t c) { _on_event.set_channel(c); _off_event.set_channel(c); } inline MIDI::Event& on_event() { return _on_event; } inline MIDI::Event& off_event() { return _off_event; } diff --git a/libs/ardour/midi_buffer.cc b/libs/ardour/midi_buffer.cc index 4628de4a6a..9c82397142 100644 --- a/libs/ardour/midi_buffer.cc +++ b/libs/ardour/midi_buffer.cc @@ -145,7 +145,7 @@ MidiBuffer::push_back(const MIDI::Event& ev) memcpy(write_loc, ev.buffer(), ev.size()); _events[_size] = ev; - _events[_size].set_buffer(write_loc, false); + _events[_size].set_buffer(ev.size(), write_loc, false); ++_size; //cerr << "MidiBuffer: pushed, size = " << _size << endl; @@ -173,8 +173,7 @@ MidiBuffer::push_back(const jack_midi_event_t& ev) memcpy(write_loc, ev.buffer, ev.size); _events[_size].time() = (double)ev.time; - _events[_size].size() = ev.size; - _events[_size].set_buffer(write_loc, false); + _events[_size].set_buffer(ev.size, write_loc, false); ++_size; //cerr << "MidiBuffer: pushed, size = " << _size << endl; @@ -206,8 +205,7 @@ MidiBuffer::reserve(double time, size_t size) Byte* const write_loc = _data + (_size * MAX_EVENT_SIZE); _events[_size].time() = time; - _events[_size].size() = size; - _events[_size].set_buffer(write_loc, false); + _events[_size].set_buffer(size, write_loc, false); ++_size; //cerr << "MidiBuffer: reserved, size = " << _size << endl; diff --git a/libs/ardour/midi_model.cc b/libs/ardour/midi_model.cc index fc5a9f4125..d9d1632590 100644 --- a/libs/ardour/midi_model.cc +++ b/libs/ardour/midi_model.cc @@ -59,6 +59,7 @@ void MidiModel::read_unlock() const { MidiModel::const_iterator::const_iterator(const MidiModel& model, double t) : _model(&model) + , _event(new MIDI::Event(0.0, 4, NULL, true)) , _is_end( (t == DBL_MAX) || model.empty()) , _locked( !_is_end) { @@ -120,9 +121,7 @@ MidiModel::const_iterator::const_iterator(const MidiModel& model, double t) } if (_note_iter != model.notes().end()) { - MIDI::Event *new_event = new MIDI::Event((*_note_iter)->on_event(), true); - assert(new_event); - _event = boost::shared_ptr<MIDI::Event>(new_event); + *_event = (*_note_iter)->on_event(); } double time = DBL_MAX; @@ -138,7 +137,7 @@ MidiModel::const_iterator::const_iterator(const MidiModel& model, double t) // <=, because we probably would want to send control events first if (earliest_control.automation_list.get() && earliest_control.x <= time) { - _event = model.control_to_midi_event(earliest_control); + model.control_to_midi_event(_event, earliest_control); } else { _control_iter = _control_iters.end(); } @@ -238,20 +237,16 @@ const MidiModel::const_iterator& MidiModel::const_iterator::operator++() if (type == NOTE_ON) { //cerr << "********** MIDI Iterator = note on" << endl; - MIDI::Event *new_event = new MIDI::Event((*_note_iter)->on_event(), true); - assert(new_event); - _event = boost::shared_ptr<MIDI::Event>(new_event); + *_event = (*_note_iter)->on_event(); _active_notes.push(*_note_iter); ++_note_iter; } else if (type == NOTE_OFF) { //cerr << "********** MIDI Iterator = note off" << endl; - MIDI::Event *new_event = new MIDI::Event(_active_notes.top()->off_event(), true); - assert(new_event); - _event = boost::shared_ptr<MIDI::Event>(new_event); + *_event = (*_note_iter)->off_event(); _active_notes.pop(); } else if (type == AUTOMATION) { //cerr << "********** MIDI Iterator = Automation" << endl; - _event = _model->control_to_midi_event(*_control_iter); + _model->control_to_midi_event(_event, *_control_iter); } else { //cerr << "********** MIDI Iterator = End" << endl; _is_end = true; @@ -278,7 +273,7 @@ MidiModel::const_iterator& MidiModel::const_iterator::operator=(const const_iter } _model = other._model; - _event = other._event; + _event = boost::shared_ptr<MIDI::Event>(new MIDI::Event(*other._event, true)); _active_notes = other._active_notes; _is_end = other._is_end; _locked = other._locked; @@ -349,15 +344,14 @@ size_t MidiModel::read(MidiRingBuffer& dst, nframes_t start, nframes_t nframes, } /** Write the controller event pointed to by \a iter to \a ev. - * Ev will have a newly allocated buffer containing the event. + * The buffer of \a ev will be allocated or resized as necessary. + * \return true on success */ -boost::shared_ptr<MIDI::Event> -MidiModel::control_to_midi_event(const MidiControlIterator& iter) const +bool +MidiModel::control_to_midi_event(boost::shared_ptr<MIDI::Event> ev, const MidiControlIterator& iter) const { assert(iter.automation_list.get()); - boost::shared_ptr<MIDI::Event> ev; - switch (iter.automation_list->parameter().type()) { case MidiCCAutomation: assert(iter.automation_list.get()); @@ -365,7 +359,8 @@ MidiModel::control_to_midi_event(const MidiControlIterator& iter) const assert(iter.automation_list->parameter().id() <= INT8_MAX); assert(iter.y <= INT8_MAX); - ev = boost::shared_ptr<MIDI::Event>(new MIDI::Event(iter.x, 3, (uint8_t *)malloc(3), true)); + ev->time() = iter.x; + ev->realloc(3); ev->buffer()[0] = MIDI_CMD_CONTROL + iter.automation_list->parameter().channel(); ev->buffer()[1] = (Byte)iter.automation_list->parameter().id(); ev->buffer()[2] = (Byte)iter.y; @@ -377,7 +372,8 @@ MidiModel::control_to_midi_event(const MidiControlIterator& iter) const assert(iter.automation_list->parameter().id() == 0); assert(iter.y <= INT8_MAX); - ev = boost::shared_ptr<MIDI::Event>(new MIDI::Event(iter.x, 2, (uint8_t *)malloc(2), true)); + ev->time() = iter.x; + ev->realloc(2); ev->buffer()[0] = MIDI_CMD_PGM_CHANGE + iter.automation_list->parameter().channel(); ev->buffer()[1] = (Byte)iter.y; break; @@ -388,7 +384,8 @@ MidiModel::control_to_midi_event(const MidiControlIterator& iter) const assert(iter.automation_list->parameter().id() == 0); assert(iter.y < (1<<14)); - ev = boost::shared_ptr<MIDI::Event>(new MIDI::Event(iter.x, 3, (uint8_t *)malloc(3), true)); + ev->time() = iter.x; + ev->realloc(3); ev->buffer()[0] = MIDI_CMD_BENDER + iter.automation_list->parameter().channel(); ev->buffer()[1] = ((Byte)iter.y) & 0x7F; // LSB ev->buffer()[2] = (((Byte)iter.y) >> 7) & 0x7F; // MSB @@ -400,18 +397,18 @@ MidiModel::control_to_midi_event(const MidiControlIterator& iter) const assert(iter.automation_list->parameter().id() == 0); assert(iter.y <= INT8_MAX); - ev = boost::shared_ptr<MIDI::Event>(new MIDI::Event(iter.x, 2, (uint8_t *)malloc(2), true)); + ev->time() = iter.x; + ev->realloc(2); ev->buffer()[0] = MIDI_CMD_CHANNEL_PRESSURE + iter.automation_list->parameter().channel(); ev->buffer()[1] = (Byte)iter.y; break; default: - break; + return false; } - - assert(ev.get()); - return ev; + + return true; } diff --git a/libs/midi++2/midi++/event.h b/libs/midi++2/midi++/event.h index fed5c5dd44..5734c1228c 100644 --- a/libs/midi++2/midi++/event.h +++ b/libs/midi++2/midi++/event.h @@ -93,9 +93,8 @@ struct Event { _time = copy._time; if (_owns_buffer) { if (copy._buffer) { - if (!_buffer || _size < copy._size) { + if (copy._size > _size) _buffer = (uint8_t*)::realloc(_buffer, copy._size); - } memcpy(_buffer, copy._buffer, copy._size); } else { free(_buffer); @@ -108,19 +107,31 @@ struct Event { _size = copy._size; return *this; } + + inline void shallow_copy(const Event& copy) { + if (_owns_buffer) { + free(_buffer); + _buffer = false; + _owns_buffer = false; + } + + _time = copy._time; + _size = copy._size; + _buffer = copy._buffer; + } - inline void set (uint8_t* msg, size_t msglen, timestamp_t t) { + inline void set(uint8_t* buf, size_t size, double t) { if (_owns_buffer) { - if (_size < msglen) { - free (_buffer); - _buffer = (uint8_t*) malloc (msglen); + if (_size < size) { + _buffer = (uint8_t*) ::realloc(_buffer, size); } } else { - _buffer = (uint8_t*) malloc (msglen); + _buffer = (uint8_t*) malloc(size); _owns_buffer = true; } - memcpy (_buffer, msg, msglen); + _size = size; + memcpy (_buffer, buf, size); _time = t; } @@ -145,18 +156,20 @@ struct Event { inline bool owns_buffer() const { return _owns_buffer; } - inline void set_buffer(uint8_t* buf, bool own) { + inline void set_buffer(size_t size, uint8_t* buf, bool own) { if (_owns_buffer) { free(_buffer); _buffer = NULL; } + _size = size; _buffer = buf; _owns_buffer = own; } inline void realloc(size_t size) { if (_owns_buffer) { - _buffer = (uint8_t*) ::realloc(_buffer, size); + if (size > _size) + _buffer = (uint8_t*) ::realloc(_buffer, size); } else { _buffer = (uint8_t*) ::malloc(size); _owns_buffer = true; @@ -176,7 +189,7 @@ struct Event { inline uint32_t size() const { return _size; } inline uint32_t& size() { return _size; } inline uint8_t type() const { return (_buffer[0] & 0xF0); } - inline void set_type(uint8_t type ) { _buffer[0] = (0x0F & _buffer[0]) | (0xF0 & type); } + inline void set_type(uint8_t type) { _buffer[0] = (0x0F & _buffer[0]) | (0xF0 & type); } inline uint8_t channel() const { return (_buffer[0] & 0x0F); } inline void set_channel(uint8_t channel) { _buffer[0] = (0xF0 & _buffer[0]) | (0x0F & channel); } inline bool is_note_on() const { return (type() == MIDI_CMD_NOTE_ON); } |