Disk I/O: only allocate midi-buffer if needed
authorRobin Gareus <robin@gareus.org>
Thu, 29 Nov 2018 01:05:26 +0000 (02:05 +0100)
committerRobin Gareus <robin@gareus.org>
Thu, 29 Nov 2018 01:05:26 +0000 (02:05 +0100)
This fixes a memory-leak (_midi_buf was allocated in DiskIOProc
but only delete in DiskReader). Also skip midi-refill early on

libs/ardour/disk_io.cc
libs/ardour/disk_reader.cc
libs/ardour/disk_writer.cc

index 427f3644041db6ceec5e5858835c89a2beb74b9c..097794bb3d581b09b0ce0cee25e02fac4a665636 100644 (file)
@@ -55,7 +55,7 @@ DiskIOProcessor::DiskIOProcessor (Session& s, string const & str, Flag f)
        , playback_sample (0)
        , _need_butler (false)
        , channels (new ChannelList)
-       , _midi_buf (new MidiRingBuffer<samplepos_t> (s.butler()->midi_diskstream_buffer_size()))
+       , _midi_buf (0)
        , _samples_written_to_ringbuffer (0)
        , _samples_read_from_ringbuffer (0)
 {
@@ -76,6 +76,7 @@ DiskIOProcessor::~DiskIOProcessor ()
        }
 
        channels.flush ();
+       delete _midi_buf;
 }
 
 
index 4c62b03de25212ffa2cc0b65de9bb2115ec6d585..ed3e612cf29eed9490b2e37f60895043586475c6 100644 (file)
@@ -71,7 +71,6 @@ DiskReader::~DiskReader ()
                        _playlists[n]->release ();
                }
        }
-       delete _midi_buf;
 }
 
 void
@@ -408,7 +407,7 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
        /* MIDI data handling */
 
   midi:
-       if (/*!_session.declick_out_pending() && */ bufs.count().n_midi()) {
+       if (/*!_session.declick_out_pending() && */ bufs.count().n_midi() && _midi_buf) {
                MidiBuffer* dst;
 
                if (_no_disk_output) {
@@ -642,7 +641,9 @@ DiskReader::seek (samplepos_t sample, bool complete_refill)
                reset_tracker ();
        }
 
-       _midi_buf->reset();
+       if (_midi_buf) {
+               _midi_buf->reset();
+       }
        g_atomic_int_set(&_samples_read_from_ringbuffer, 0);
        g_atomic_int_set(&_samples_written_to_ringbuffer, 0);
 
@@ -1209,7 +1210,9 @@ DiskReader::move_processor_automation (boost::weak_ptr<Processor> p, list< Evora
 void
 DiskReader::reset_tracker ()
 {
-       _midi_buf->reset_tracker ();
+       if (_midi_buf) {
+               _midi_buf->reset_tracker ();
+       }
 
        boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
 
@@ -1221,7 +1224,9 @@ DiskReader::reset_tracker ()
 void
 DiskReader::resolve_tracker (Evoral::EventSink<samplepos_t>& buffer, samplepos_t time)
 {
-       _midi_buf->resolve_tracker(buffer, time);
+       if (_midi_buf) {
+               _midi_buf->resolve_tracker(buffer, time);
+       }
 
        boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
 
@@ -1239,6 +1244,8 @@ DiskReader::get_midi_playback (MidiBuffer& dst, samplepos_t start_sample, sample
        MidiBuffer* target;
        samplepos_t nframes = end_sample - start_sample;
 
+       assert (_midi_buf);
+
        if ((ms & MonitoringInput) == 0) {
                /* Route::process_output_buffers() clears the buffer as-needed */
                target = &dst;
@@ -1378,6 +1385,8 @@ DiskReader::midi_read (samplepos_t& start, samplecnt_t dur, bool reversed)
        samplepos_t effective_start = start;
        Evoral::Range<samplepos_t>*  loop_range (0);
 
+       assert(_midi_buf);
+
        DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("MDS::midi_read @ %1 cnt %2\n", start, dur));
 
        boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack>(_route);
@@ -1463,7 +1472,7 @@ DiskReader::midi_read (samplepos_t& start, samplecnt_t dur, bool reversed)
 int
 DiskReader::refill_midi ()
 {
-       if (!_playlists[DataType::MIDI]) {
+       if (!_playlists[DataType::MIDI] || !_midi_buf) {
                return 0;
        }
 
index ed59da92316524f4fa874668814fbcd5c1ec42d9..39859cfdb53c3accdaf07041a29d622b8880b4e4 100644 (file)
@@ -517,6 +517,8 @@ DiskWriter::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
                boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack>(_route);
                MidiChannelFilter* filter = mt ? &mt->capture_filter() : 0;
 
+               assert (buf.size() == 0 || _midi_buf);
+
                for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
                        Evoral::Event<MidiBuffer::TimeType> ev (*i, false);
                        if (ev.time() + rec_offset > rec_nframes) {
@@ -571,6 +573,7 @@ DiskWriter::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
                                _midi_buf->write (event_time, ev.event_type(), ev.size(), ev.buffer());
                        }
                }
+
                g_atomic_int_add (const_cast<gint*>(&_samples_pending_write), nframes);
 
                if (buf.size() != 0) {
@@ -815,7 +818,9 @@ DiskWriter::seek (samplepos_t sample, bool complete_refill)
                (*chan)->wbuf->reset ();
        }
 
-       _midi_buf->reset ();
+       if (_midi_buf) {
+               _midi_buf->reset ();
+       }
        g_atomic_int_set(&_samples_read_from_ringbuffer, 0);
        g_atomic_int_set(&_samples_written_to_ringbuffer, 0);
 
@@ -953,7 +958,7 @@ DiskWriter::do_flush (RunContext ctxt, bool force_flush)
 
        /* MIDI*/
 
-       if (_midi_write_source) {
+       if (_midi_write_source && _midi_buf) {
 
                const samplecnt_t total = g_atomic_int_get(const_cast<gint*> (&_samples_pending_write));