Merge with trunk R2978.
[ardour.git] / libs / ardour / smf_source.cc
index 32f012e3896373ac8a9b5f250c98e26a99e3dc14..29f36cc2cd3be54c2d6d655414f6d847a6762aca 100644 (file)
@@ -159,7 +159,6 @@ SMFSource::open()
                _track_size = 4;
 
                // Write a tentative header just to pad things out so writing happens in the right spot
-               set_timeline_position(0);
                flush_header();
                write_footer();
                seek_to_end();
@@ -327,7 +326,7 @@ SMFSource::read_event(uint32_t* delta_t, uint32_t* size, Byte** buf) const
 nframes_t
 SMFSource::read_unlocked (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, nframes_t stamp_offset) const
 {
-       //cerr << "SMF - read " << start << ", count=" << cnt << ", offset=" << stamp_offset << endl;
+       //cerr << "SMF " << name() << " read " << start << ", count=" << cnt << ", offset=" << stamp_offset << endl;
 
        // 64 bits ought to be enough for anybody
        uint64_t time = 0; // in SMF ticks, 1 tick per _ppqn
@@ -346,7 +345,8 @@ SMFSource::read_unlocked (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, n
        
        // FIXME: assumes tempo never changes after start
        const double frames_per_beat = _session.tempo_map().tempo_at(_timeline_position).frames_per_beat(
-                       _session.engine().frame_rate());
+                       _session.engine().frame_rate(),
+                       _session.tempo_map().meter_at(_timeline_position));
        
        const uint64_t start_ticks = (uint64_t)((start / frames_per_beat) * _ppqn);
 
@@ -398,12 +398,12 @@ SMFSource::write_unlocked (MidiRingBuffer& src, nframes_t cnt)
        size_t buf_capacity = 4;
        Byte* buf = (Byte*)malloc(buf_capacity);
        
-       if (_model && ! _model->currently_writing())
+       if (_model && ! _model->writing())
                _model->start_write();
 
        while (true) {
                bool ret = src.full_peek(sizeof(double), (Byte*)&time);
-               if (!ret || time > _length + cnt)
+               if (!ret || time - _timeline_position > _length + cnt)
                        break;
 
                ret = src.read_prefix(&time, &size);
@@ -423,10 +423,9 @@ SMFSource::write_unlocked (MidiRingBuffer& src, nframes_t cnt)
                
                assert(time >= _timeline_position);
                time -= _timeline_position;
-               assert(time >= _last_ev_time);
 
                const MidiEvent ev(time, size, buf);
-               append_event_unlocked(MidiEvent(ev));
+               append_event_unlocked(ev);
 
                if (_model)
                        _model->append(ev);
@@ -438,7 +437,7 @@ SMFSource::write_unlocked (MidiRingBuffer& src, nframes_t cnt)
        const nframes_t oldlen = _length;
        update_length(oldlen, cnt);
 
-       ViewDataRangeReady (oldlen, cnt); /* EMIT SIGNAL */
+       ViewDataRangeReady (_timeline_position + oldlen, cnt); /* EMIT SIGNAL */
        
        return cnt;
 }
@@ -453,11 +452,14 @@ SMFSource::append_event_unlocked(const MidiEvent& ev)
        }
        printf("\n");*/
 
+       assert(ev.time() >= 0);
+
        assert(ev.time() >= _last_ev_time);
        
        // FIXME: assumes tempo never changes after start
-       const double frames_per_beat = _session.tempo_map().tempo_at
-                       (_timeline_position).frames_per_beat(_session.engine().frame_rate());
+       const double frames_per_beat = _session.tempo_map().tempo_at(_timeline_position).frames_per_beat(
+                       _session.engine().frame_rate(),
+                       _session.tempo_map().meter_at(_timeline_position));
        
        const uint32_t delta_time = (uint32_t)((ev.time() - _last_ev_time) / frames_per_beat * _ppqn);
 
@@ -516,6 +518,13 @@ SMFSource::mark_for_remove ()
        _flags = Flag (_flags | RemoveAtDestroy);
 }
 
+void
+SMFSource::mark_streaming_midi_write_started (NoteMode mode, nframes_t start_frame)
+{
+       MidiSource::mark_streaming_midi_write_started (mode, start_frame);
+       _last_ev_time = 0;
+}
+
 void
 SMFSource::mark_streaming_write_completed ()
 {
@@ -783,7 +792,7 @@ SMFSource::is_empty () const
 
 
 void
-SMFSource::write_chunk_header(char id[4], uint32_t length)
+SMFSource::write_chunk_header(const char id[4], uint32_t length)
 {
        const uint32_t length_be = GUINT32_TO_BE(length);
 
@@ -792,7 +801,7 @@ SMFSource::write_chunk_header(char id[4], uint32_t length)
 }
 
 void
-SMFSource::write_chunk(char id[4], uint32_t length, void* data)
+SMFSource::write_chunk(const char id[4], uint32_t length, void* data)
 {
        write_chunk_header(id, length);
        
@@ -857,6 +866,8 @@ SMFSource::load_model(bool lock, bool force_reload)
                //cerr << _name << " NOT reloading model " << _model.get() << " (" << _model->n_notes()
                //      << " notes)" << endl;
                return;
+       } else {
+               cerr << _name << " loading model" << endl;
        }
 
        if (! _model) {
@@ -879,7 +890,8 @@ SMFSource::load_model(bool lock, bool force_reload)
        
        // FIXME: assumes tempo never changes after start
        const double frames_per_beat = _session.tempo_map().tempo_at(_timeline_position).frames_per_beat(
-                       _session.engine().frame_rate());
+                       _session.engine().frame_rate(),
+                       _session.tempo_map().meter_at(_timeline_position));
        
        uint32_t delta_t = 0;
        int ret;