#include "pbd/stateful_diff_command.h"
#include "pbd/stacktrace.h"
-#include "ardour/ardour.h"
#include "ardour/audioengine.h"
#include "ardour/butler.h"
-#include "ardour/configuration.h"
-#include "ardour/cycle_timer.h"
#include "ardour/debug.h"
#include "ardour/io.h"
#include "ardour/midi_diskstream.h"
#include "ardour/midi_region.h"
#include "ardour/playlist_factory.h"
#include "ardour/region_factory.h"
-#include "ardour/route.h"
-#include "ardour/send.h"
#include "ardour/session.h"
#include "ardour/session_playlists.h"
#include "ardour/smf_source.h"
+#include "ardour/types.h"
#include "ardour/utils.h"
#include "midi++/types.h"
_write_source->model()->set_note_mode(m);
}
-#if 0
-static void
-trace_midi (ostream& o, MIDI::byte *msg, size_t len)
-{
- using namespace MIDI;
- eventType type;
- const char trace_prefix = ':';
-
- type = (eventType) (msg[0]&0xF0);
-
- switch (type) {
- case off:
- o << trace_prefix
- << "Channel "
- << (msg[0]&0xF)+1
- << " NoteOff NoteNum "
- << (int) msg[1]
- << " Vel "
- << (int) msg[2]
- << endl;
- break;
-
- case on:
- o << trace_prefix
- << "Channel "
- << (msg[0]&0xF)+1
- << " NoteOn NoteNum "
- << (int) msg[1]
- << " Vel "
- << (int) msg[2]
- << endl;
- break;
-
- case polypress:
- o << trace_prefix
- << "Channel "
- << (msg[0]&0xF)+1
- << " PolyPressure"
- << (int) msg[1]
- << endl;
- break;
-
- case MIDI::controller:
- o << trace_prefix
- << "Channel "
- << (msg[0]&0xF)+1
- << " Controller "
- << (int) msg[1]
- << " Value "
- << (int) msg[2]
- << endl;
- break;
-
- case program:
- o << trace_prefix
- << "Channel "
- << (msg[0]&0xF)+1
- << " Program Change ProgNum "
- << (int) msg[1]
- << endl;
- break;
-
- case chanpress:
- o << trace_prefix
- << "Channel "
- << (msg[0]&0xF)+1
- << " Channel Pressure "
- << (int) msg[1]
- << endl;
- break;
-
- case MIDI::pitchbend:
- o << trace_prefix
- << "Channel "
- << (msg[0]&0xF)+1
- << " Pitch Bend "
- << ((msg[2]<<7)|msg[1])
- << endl;
- break;
-
- case MIDI::sysex:
- if (len == 1) {
- switch (msg[0]) {
- case 0xf8:
- o << trace_prefix
- << "Clock"
- << endl;
- break;
- case 0xfa:
- o << trace_prefix
- << "Start"
- << endl;
- break;
- case 0xfb:
- o << trace_prefix
- << "Continue"
- << endl;
- break;
- case 0xfc:
- o << trace_prefix
- << "Stop"
- << endl;
- break;
- case 0xfe:
- o << trace_prefix
- << "Active Sense"
- << endl;
- break;
- case 0xff:
- o << trace_prefix
- << "System Reset"
- << endl;
- break;
- default:
- o << trace_prefix
- << "System Exclusive (1 byte : " << hex << (int) *msg << dec << ')'
- << endl;
- break;
- }
- } else {
- o << trace_prefix
- << "System Exclusive (" << len << ") = [ " << hex;
- for (unsigned int i = 0; i < len; ++i) {
- o << (int) msg[i] << ' ';
- }
- o << dec << ']' << endl;
-
- }
- break;
-
- case MIDI::song:
- o << trace_prefix << "Song" << endl;
- break;
-
- case MIDI::tune:
- o << trace_prefix << "Tune" << endl;
- break;
-
- case MIDI::eox:
- o << trace_prefix << "End-of-System Exclusive" << endl;
- break;
-
- case MIDI::timing:
- o << trace_prefix << "Timing" << endl;
- break;
-
- case MIDI::start:
- o << trace_prefix << "Start" << endl;
- break;
-
- case MIDI::stop:
- o << trace_prefix << "Stop" << endl;
- break;
-
- case MIDI::contineu:
- o << trace_prefix << "Continue" << endl;
- break;
-
- case active:
- o << trace_prefix << "Active Sense" << endl;
- break;
-
- default:
- o << trace_prefix << "Unrecognized MIDI message" << endl;
- break;
- }
-}
-#endif
-
int
MidiDiskstream::process (framepos_t transport_frame, pframes_t nframes, framecnt_t& playback_distance)
{
adjust_capture_position = 0;
if (nominally_recording || (re && was_recording && _session.get_record_enabled() && _session.config.get_punch_in())) {
- OverlapType ot = coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
+ Evoral::OverlapType ot = Evoral::coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
calculate_record_range(ot, transport_frame, nframes, rec_nframes, rec_offset);
uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
- if ((frames_written - frames_read) + playback_distance < midi_readahead) {
- need_butler = true;
+
+ /*
+ cerr << name() << " MDS written: " << frames_written << " - read: " << frames_read <<
+ " = " << frames_written - frames_read
+ << " + " << playback_distance << " < " << midi_readahead << " = " << need_butler << ")" << endl;
+ */
+
+ /* frames_read will generally be less than frames_written, but
+ * immediately after an overwrite, we can end up having read some data
+ * before we've written any. we don't need to trip an assert() on this,
+ * but we do need to check so that the decision on whether or not we
+ * need the butler is done correctly.
+ */
+
+ if (frames_read <= frames_written) {
+ if ((frames_written - frames_read) + playback_distance < midi_readahead) {
+ need_butler = true;
+ }
}
- /*cerr << "MDS written: " << frames_written << " - read: " << frames_read <<
- " = " << frames_written - frames_read
- << " + " << nframes << " < " << midi_readahead << " = " << need_butler << ")" << endl;*/
return need_butler;
}
start = loop_start + ((start - loop_start) % loop_length);
//cerr << "to " << start << endl;
}
- //cerr << "start is " << start << " loopstart: " << loop_start << " loopend: " << loop_end << endl;
+ // cerr << "start is " << start << " end " << start+dur << " loopstart: " << loop_start << " loopend: " << loop_end << endl;
}
while (dur) {
/* take any loop into account. we can't read past the end of the loop. */
- if (loc && (loop_end - start < dur)) {
+ if (loc && (loop_end - start <= dur)) {
this_read = loop_end - start;
- //cerr << "reloop true: thisread: " << this_read << " dur: " << dur << endl;
+ // cerr << "reloop true: thisread: " << this_read << " dur: " << dur << endl;
reloop = true;
} else {
reloop = false;
return -1;
}
- g_atomic_int_add(&_frames_written_to_ringbuffer, this_read);
+ g_atomic_int_add (&_frames_written_to_ringbuffer, this_read);
if (reversed) {
no_capture_stuff_to_do:
- if (_playlist) {
- midi_playlist()->clear_note_trackers ();
- }
+ reset_tracker ();
}
void
last_recordable_frame = max_framepos;
was_recording = true;
}
+
+ if (!Config->get_seamless_loop()) {
+ reset_tracker ();
+ }
}
void
b->copy (_gui_feed_buffer);
return b;
}
+
+void
+MidiDiskstream::reset_tracker ()
+{
+ _playback_buf->reset_tracker ();
+
+ boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
+
+ if (mp) {
+ mp->clear_note_trackers ();
+ }
+}