diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2011-06-21 21:29:22 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2011-06-21 21:29:22 +0000 |
commit | be614d0538ddd78b13b236f760afbd94af540202 (patch) | |
tree | f437fc23359b43969d369e867146e67244c72ad7 | |
parent | 500aaa0deeb386df94fddc4474aa6de43331becb (diff) |
change default overlapping note strategy to "relax" (i.e. do nothing); fix crash when looping with MIDI data; add back note-off resolution at loop point (if it was actually there) so that notes are turned off (but don't forget Ye Olde Sustain Pedal/Controller) when looping; minor other non-functional tweaks
git-svn-id: svn://localhost/ardour2/branches/3.0@9753 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r-- | gtk2_ardour/midi_region_view.cc | 4 | ||||
-rw-r--r-- | libs/ardour/ardour/midi_ring_buffer.h | 16 | ||||
-rw-r--r-- | libs/ardour/ardour/session_configuration_vars.h | 2 | ||||
-rw-r--r-- | libs/ardour/midi_diskstream.cc | 4 | ||||
-rw-r--r-- | libs/ardour/midi_ring_buffer.cc | 42 | ||||
-rw-r--r-- | libs/evoral/evoral/Sequence.hpp | 4 | ||||
-rw-r--r-- | libs/evoral/evoral/midi_util.h | 4 | ||||
-rw-r--r-- | libs/evoral/src/Sequence.cpp | 16 |
8 files changed, 65 insertions, 27 deletions
diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 54f6a2c59a..2de95c1f73 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -1844,9 +1844,7 @@ MidiRegionView::maybe_remove_deleted_note_from_selection (CanvasNoteEvent* cne) return; } - if (_selection.erase (cne) > 0) { - cerr << "Erased a CNE from selection\n"; - } + _selection.erase (cne); } void diff --git a/libs/ardour/ardour/midi_ring_buffer.h b/libs/ardour/ardour/midi_ring_buffer.h index 567f375bc3..14934456e1 100644 --- a/libs/ardour/ardour/midi_ring_buffer.h +++ b/libs/ardour/ardour/midi_ring_buffer.h @@ -21,9 +21,12 @@ #include <iostream> #include <algorithm> + +#include "evoral/EventRingBuffer.hpp" + #include "ardour/types.h" #include "ardour/buffer.h" -#include "evoral/EventRingBuffer.hpp" +#include "ardour/midi_state_tracker.h" namespace ARDOUR { @@ -80,8 +83,19 @@ protected: return (0x80 <= event_type_byte) && (event_type_byte <= 0xE0); } + inline bool is_note_on(uint8_t event_type_byte) { + // mask out channel information + return (event_type_byte & 0xF0) == MIDI_CMD_NOTE_ON; + } + + inline bool is_note_off(uint8_t event_type_byte) { + // mask out channel information + return (event_type_byte & 0xF0) == MIDI_CMD_NOTE_OFF; + } + private: volatile uint32_t _channel_mask; // 16 bits mode, 16 bits mask + MidiStateTracker _tracker; }; diff --git a/libs/ardour/ardour/session_configuration_vars.h b/libs/ardour/ardour/session_configuration_vars.h index 336e694e6a..5924adcc86 100644 --- a/libs/ardour/ardour/session_configuration_vars.h +++ b/libs/ardour/ardour/session_configuration_vars.h @@ -58,6 +58,6 @@ CONFIG_VARIABLE (bool, show_summary, "show-summary", true) CONFIG_VARIABLE (bool, show_group_tabs, "show-group-tabs", true) CONFIG_VARIABLE (bool, external_sync, "external-sync", false) CONFIG_VARIABLE (SyncSource, sync_source, "sync-source", JACK) -CONFIG_VARIABLE (InsertMergePolicy, insert_merge_policy, "insert-merge-policy", InsertMergeReject) +CONFIG_VARIABLE (InsertMergePolicy, insert_merge_policy, "insert-merge-policy", InsertMergeRelax) CONFIG_VARIABLE (framecnt_t, timecode_offset, "timecode-offset", 0) CONFIG_VARIABLE (bool, timecode_offset_negative, "timecode-offset-negative", true) diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc index 0539e3b62f..1c34ff9c03 100644 --- a/libs/ardour/midi_diskstream.cc +++ b/libs/ardour/midi_diskstream.cc @@ -1413,8 +1413,8 @@ MidiDiskstream::get_playback (MidiBuffer& dst, framepos_t start, framepos_t end) #ifndef NDEBUG DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ( - "%1 MDS pre-read read from %2 write to %3\n", _name, - _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr())); + "%1 MDS pre-read read %4..%5 from %2 write to %3\n", _name, + _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr(), start, end)); // cerr << "================\n"; // _playback_buf->dump (cerr); // cerr << "----------------\n"; diff --git a/libs/ardour/midi_ring_buffer.cc b/libs/ardour/midi_ring_buffer.cc index 434fa0c33e..902f6866f1 100644 --- a/libs/ardour/midi_ring_buffer.cc +++ b/libs/ardour/midi_ring_buffer.cc @@ -101,17 +101,28 @@ MidiRingBuffer<T>::read(MidiBuffer& dst, framepos_t start, framepos_t end, frame DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("MRB event @ %1 in range %2 .. %3\n", ev_time, start, end)); } - /* lets see if we are going to be able to write this event into dst. - */ - assert(ev_time >= start); ev_time -= start; ev_time += offset; - // write the timestamp to address (write_loc - 1) - uint8_t* write_loc = dst.reserve(ev_time, ev_size); - if (write_loc == NULL) { + // This event marks a loop end (i.e. the next event's timestamp + // will be non-monotonic). Don't write it into the buffer - the + // significance of this event ends here. + + if (ev_type == LoopEventType) { + assert (ev_size == sizeof (framepos_t)); + framepos_t loop_start; + read_contents (ev_size, (uint8_t *) &loop_start); + loop_offset = ev_time - loop_start; + _tracker.resolve_notes (dst, ev_time); + continue; + } + + /* lets see if we are going to be able to write this event into dst. + */ + uint8_t* write_loc = dst.reserve (ev_time, ev_size); + if (write_loc == 0) { if (stop_on_overflow_in_dst) { DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("MidiRingBuffer: overflow in destination MIDI buffer, stopped after %1 events\n", count)); break; @@ -124,19 +135,7 @@ MidiRingBuffer<T>::read(MidiBuffer& dst, framepos_t start, framepos_t end, frame /* we're good to go ahead and read the data now but since we * have the prefix data already, just skip over that */ - this->increment_read_ptr (prefix_size); - - // This event marks a loop end (i.e. the next event's timestamp will be non-monotonic) - if (ev_type == LoopEventType) { - assert (ev_size == sizeof (framepos_t)); - framepos_t loop_start; - read_contents (ev_size, (uint8_t *) &loop_start); - - loop_offset = ev_time - loop_start; - continue; - } - ev_time += loop_offset; uint8_t status; @@ -172,6 +171,13 @@ MidiRingBuffer<T>::read(MidiBuffer& dst, framepos_t start, framepos_t end, frame #endif if (success) { + + if (is_note_on(write_loc[0]) ) { + _tracker.add (write_loc[1], write_loc[0] & 0xf); + } else if (is_note_off(write_loc[0])) { + _tracker.remove (write_loc[1], write_loc[0] & 0xf); + } + if (is_channel_event(status) && get_channel_mode() == ForceChannel) { write_loc[0] = (write_loc[0] & 0xF0) | (get_channel_mask() & 0x0F); } diff --git a/libs/evoral/evoral/Sequence.hpp b/libs/evoral/evoral/Sequence.hpp index 2b3ba4ace0..922b7594d4 100644 --- a/libs/evoral/evoral/Sequence.hpp +++ b/libs/evoral/evoral/Sequence.hpp @@ -191,6 +191,8 @@ public: inline PatchChanges& patch_changes () { return _patch_changes; } inline const PatchChanges& patch_changes () const { return _patch_changes; } + void dump (std::ostream&) const; + private: typedef std::priority_queue<NotePtr, std::deque<NotePtr>, LaterNoteEndComparator> ActiveNotes; public: @@ -332,5 +334,7 @@ private: } // namespace Evoral +// template<typename Time> std::ostream& operator<<(std::ostream& o, const Evoral::Sequence<Time>& s) { s.dump (o); return o; } + #endif // EVORAL_SEQUENCE_HPP diff --git a/libs/evoral/evoral/midi_util.h b/libs/evoral/evoral/midi_util.h index da7051aefa..e1ae7f4620 100644 --- a/libs/evoral/evoral/midi_util.h +++ b/libs/evoral/evoral/midi_util.h @@ -19,6 +19,8 @@ #ifndef EVORAL_MIDI_UTIL_H #define EVORAL_MIDI_UTIL_H +#include <iostream> + #include <stdint.h> #include <stdbool.h> #include <string> @@ -66,9 +68,11 @@ midi_event_size(uint8_t status) return 1; case MIDI_CMD_COMMON_SYSEX: + std::cerr << "event size called for sysex\n"; return -1; } + std::cerr << "event size called for unknown status byte " << std::hex << (int) status << "\n"; return -1; } diff --git a/libs/evoral/src/Sequence.cpp b/libs/evoral/src/Sequence.cpp index 3c1bda9b96..1d91690a61 100644 --- a/libs/evoral/src/Sequence.cpp +++ b/libs/evoral/src/Sequence.cpp @@ -687,7 +687,7 @@ Sequence<Time>::add_note_unlocked(const NotePtr note, void* arg) _edited = true; - return true; + return true; } template<typename Time> @@ -750,7 +750,7 @@ Sequence<Time>::remove_note_unlocked(const constNotePtr note) } if (!erased) { - cerr << "Unable to find note to erase" << endl; + cerr << "Unable to find note to erase matching " << *note.get() << endl; } } @@ -1214,5 +1214,17 @@ Sequence<Time>::control_list_marked_dirty () template class Sequence<Evoral::MusicalTime>; +template<typename Time> +void +Sequence<Time>::dump (ostream& str) const +{ + Sequence<Time>::const_iterator i; + str << "+++ dump\n"; + for (i = begin(); i != end(); ++i) { + str << *i << endl; + } + str << "--- dump\n"; +} + } // namespace Evoral |