Fix audio when it spans reel boundaries.
authorCarl Hetherington <cth@carlh.net>
Thu, 23 Feb 2017 11:42:48 +0000 (11:42 +0000)
committerCarl Hetherington <cth@carlh.net>
Wed, 19 Apr 2017 22:04:32 +0000 (23:04 +0100)
src/lib/writer.cc

index 74e5e3ec081da7ded20a1da9946aa5cc3996b75e..c507c552758bb4ca8ee9a0f081042b9de20f5f42 100644 (file)
@@ -236,15 +236,33 @@ Writer::fake_write (Frame frame, Eyes eyes)
 void
 Writer::write (shared_ptr<const AudioBuffers> audio)
 {
-       if (_audio_reel == _reels.end ()) {
-               /* This audio is off the end of the last reel; ignore it */
-               return;
-       }
+       /* The audio we get might span a reel boundary, and if so we have to write it in bits */
 
-       _audio_reel->write (audio);
+       int32_t offset = 0;
+       while (offset < audio->frames ()) {
+
+               if (_audio_reel == _reels.end ()) {
+                       /* This audio is off the end of the last reel; ignore it */
+                       return;
+               }
+
+               int32_t const this_time = min (
+                       audio->frames() - offset,
+                       (int32_t) (_audio_reel->period().duration().frames_floor(_film->audio_frame_rate()) - _audio_reel->total_written_audio_frames())
+                       );
+
+               if (this_time == audio->frames()) {
+                       /* Easy case: we can write all the audio to this reel */
+                       _audio_reel->write (audio);
+               } else {
+                       /* Write the part we can */
+                       shared_ptr<AudioBuffers> part (new AudioBuffers (audio->channels(), this_time));
+                       part->copy_from (audio.get(), this_time, offset, 0);
+                       _audio_reel->write (part);
+                       ++_audio_reel;
+               }
 
-       if (_audio_reel->total_written_audio_frames() >= _audio_reel->period().duration().frames_floor (_film->audio_frame_rate())) {
-               ++_audio_reel;
+               offset += this_time;
        }
 }