summaryrefslogtreecommitdiff
path: root/libs/backends/dummy/dummy_audiobackend.cc
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2020-05-12 00:05:42 +0200
committerRobin Gareus <robin@gareus.org>2020-05-12 01:49:41 +0200
commit7c15ad099f759f2bfdb2701b96fb5335e916a15b (patch)
tree57e9e0684c0f984af4d70e6b643dd637f4ad7a9c /libs/backends/dummy/dummy_audiobackend.cc
parent20c09ccfc338b59ed321bc7429efa0faa22e067c (diff)
Dummy Backend: add a MTC generator
Diffstat (limited to 'libs/backends/dummy/dummy_audiobackend.cc')
-rw-r--r--libs/backends/dummy/dummy_audiobackend.cc50
1 files changed, 50 insertions, 0 deletions
diff --git a/libs/backends/dummy/dummy_audiobackend.cc b/libs/backends/dummy/dummy_audiobackend.cc
index ca9a93e583..b42f29df84 100644
--- a/libs/backends/dummy/dummy_audiobackend.cc
+++ b/libs/backends/dummy/dummy_audiobackend.cc
@@ -896,6 +896,7 @@ DummyAudioBackend::get_latency_range (PortEngine::PortHandle port_handle, bool f
}
r = port->latency_range (for_playback);
+#ifndef ZERO_LATENCY
if (port->is_physical() && port->is_terminal()) {
if (port->is_input() && for_playback) {
const size_t l_in = _samples_per_period * .25;
@@ -910,6 +911,7 @@ DummyAudioBackend::get_latency_range (PortEngine::PortHandle port_handle, bool f
r.max += l_out;
}
}
+#endif
return r;
}
@@ -1695,6 +1697,10 @@ DummyMidiPort::setup_generator (int seq_id, const float sr)
_midi_seq_spb = sr * .5f; // 120 BPM, beat_time 1.0 per beat.
_midi_seq_pos = 0;
_midi_seq_time = 0;
+
+ if (_midi_seq_dat && _midi_seq_dat[0].beat_time < 0) {
+ _midi_seq_spb = sr / 25; // 25fps MTC
+ }
return DummyMidiData::sequence_names[seq_id];
}
@@ -1728,6 +1734,50 @@ void DummyMidiPort::midi_generate (const pframes_t n_samples)
return;
}
+ if (_midi_seq_dat[0].beat_time < 0) {
+ /* MTC generator */
+ const int audio_samples_per_video_frame = _midi_seq_spb; // sample-rate / 25
+ const int audio_samples_per_qf = audio_samples_per_video_frame / 4;
+
+ samplepos_t tc_frame = _midi_seq_time / audio_samples_per_video_frame;
+ samplepos_t tc_sample = tc_frame * audio_samples_per_video_frame;
+ int qf = (tc_frame & 1) ? 4 : 0;
+ while (tc_sample < _midi_seq_time + n_samples) {
+ if (tc_sample >= _midi_seq_time) {
+ uint8_t buf[2];
+ buf[0] = 0xf1;
+
+ int frame = tc_frame % 25;
+ int second = (tc_frame / 25) % 60;
+ int minute = ((tc_frame / 25) / 60) % 60;
+ int hour = (((tc_frame / 25) / 60) / 60);
+
+ switch(qf & 7) {
+ case 0: buf[1] = 0x00 | (frame & 0x0f); break;
+ case 1: buf[1] = 0x10 | ((frame & 0xf0) >> 4); break;
+ case 2: buf[1] = 0x20 | (second & 0x0f); break;
+ case 3: buf[1] = 0x30 | ((second & 0xf0) >> 4); break;
+ case 4: buf[1] = 0x40 | (minute & 0x0f); break;
+ case 5: buf[1] = 0x50 | ((minute & 0xf0) >> 4); break;
+ case 6: buf[1] = 0x60 | ((/* 25fps*/ 0x20 | hour) & 0x0f); break;
+ case 7: buf[1] = 0x70 | (((/* 25fps*/ 0x20 | hour) & 0xf0)>>4); break;
+ }
+ _buffer.push_back (boost::shared_ptr<DummyMidiEvent>(new DummyMidiEvent (tc_sample - _midi_seq_time, buf, 2)));
+ }
+ tc_sample += audio_samples_per_qf;
+ if (++qf == 8) {
+ ++tc_frame;
+ qf = 0;
+ }
+ }
+
+ _midi_seq_time += n_samples;
+ if (_midi_seq_time >= /* 24 * 3600 * 25 */ 2160000LL * audio_samples_per_video_frame) {
+ _midi_seq_time -= 2160000LL * audio_samples_per_video_frame; // 24h @ 25fps
+ }
+ return;
+ }
+
while (1) {
const int32_t ev_beat_time = _midi_seq_dat[_midi_seq_pos].beat_time * _midi_seq_spb - _midi_seq_time;
if (ev_beat_time < 0) {