OpenShot Library | libopenshot  0.5.0
AudioReaderSource.cpp
Go to the documentation of this file.
1 
9 // Copyright (c) 2008-2019 OpenShot Studios, LLC
10 //
11 // SPDX-License-Identifier: LGPL-3.0-or-later
12 
13 #include "AudioReaderSource.h"
14 #include "Exceptions.h"
15 #include "Frame.h"
16 
17 using namespace std;
18 using namespace openshot;
19 
20 // Constructor that reads samples from a reader
21 AudioReaderSource::AudioReaderSource(ReaderBase *audio_reader, int64_t starting_frame_number)
22  : reader(audio_reader), frame_position(starting_frame_number), videoCache(NULL), frame(NULL),
23  sample_position(0), speed(1), stream_position(0) {
24 }
25 
26 // Destructor
28 {
29 }
30 
31 // Get the next block of audio samples
32 void AudioReaderSource::getNextAudioBlock(const juce::AudioSourceChannelInfo& info)
33 {
34  if (info.numSamples > 0) {
35  int remaining_samples = info.numSamples;
36  int remaining_position = info.startSample;
37 
38  // Pause and fill buffer with silence (wait for pre-roll)
39  if (speed != 1 || !videoCache->isReady()) {
40  info.buffer->clear();
41  return;
42  }
43 
44  while (remaining_samples > 0) {
45  const int previous_remaining = remaining_samples;
46  frame.reset();
47  try {
48  // Get current frame object
49  if (reader) {
50  frame = reader->GetFrame(frame_position);
51  }
52  }
53  catch (const ReaderClosed & e) { }
54  catch (const OutOfBoundsFrame & e) { }
55 
56  // Get audio samples
57  if (reader && frame) {
58  const int frame_samples = frame->GetAudioSamplesCount();
59  const int frame_channels = frame->GetAudioChannelsCount();
60 
61  // Corrupt/unsupported streams can yield frames without audio data.
62  // Avoid a tight loop that never consumes remaining_samples.
63  if (frame_samples <= 0 || frame_channels <= 0) {
64  info.buffer->clear(remaining_position, remaining_samples);
65  break;
66  }
67 
68  if (sample_position + remaining_samples <= frame->GetAudioSamplesCount()) {
69  // Success, we have enough samples
70  for (int channel = 0; channel < frame_channels; channel++) {
71  if (channel < info.buffer->getNumChannels()) {
72  info.buffer->addFrom(channel, remaining_position, *frame->GetAudioSampleBuffer(),
73  channel, sample_position, remaining_samples);
74  }
75  }
76  sample_position += remaining_samples;
77  remaining_position += remaining_samples;
78  remaining_samples = 0;
79 
80  } else if (sample_position + remaining_samples > frame->GetAudioSamplesCount()) {
81  // Not enough samples, take what we can
82  int amount_to_copy = frame->GetAudioSamplesCount() - sample_position;
83  if (amount_to_copy <= 0) {
84  info.buffer->clear(remaining_position, remaining_samples);
85  break;
86  }
87 
88  for (int channel = 0; channel < frame_channels; channel++) {
89  if (channel < info.buffer->getNumChannels()) {
90  info.buffer->addFrom(channel, remaining_position, *frame->GetAudioSampleBuffer(), channel,
91  sample_position, amount_to_copy);
92  }
93  }
94  sample_position += amount_to_copy;
95  remaining_position += amount_to_copy;
96  remaining_samples -= amount_to_copy;
97  }
98 
99  // Increment frame position (if samples are all used up)
100  if (sample_position == frame->GetAudioSamplesCount()) {
101  frame_position += speed;
102  sample_position = 0; // reset for new frame
103  }
104  } else {
105  info.buffer->clear(remaining_position, remaining_samples);
106  break;
107  }
108 
109  if (remaining_samples == previous_remaining) {
110  info.buffer->clear(remaining_position, remaining_samples);
111  break;
112  }
113  }
114  }
115 }
116 
117 // Prepare to play this audio source
119 
120 // Release all resources
122 
123 // Get the total length (in samples) of this audio source
125 {
126  // Get the length
127  if (reader)
128  return reader->info.sample_rate * reader->info.duration;
129  else
130  return 0;
131 }
openshot::ReaderInfo::sample_rate
int sample_rate
The number of audio samples per second (44100 is a common sample rate)
Definition: ReaderBase.h:60
openshot::ReaderBase::GetFrame
virtual std::shared_ptr< openshot::Frame > GetFrame(int64_t number)=0
openshot
This namespace is the default namespace for all code in the openshot library.
Definition: Compressor.h:28
openshot::AudioReaderSource::~AudioReaderSource
~AudioReaderSource()
Destructor.
Definition: AudioReaderSource.cpp:27
openshot::ReaderBase::info
openshot::ReaderInfo info
Information about the current media file.
Definition: ReaderBase.h:88
openshot::AudioReaderSource::prepareToPlay
void prepareToPlay(int, double)
Prepare to play this audio source.
Definition: AudioReaderSource.cpp:118
int64
#define int64
Definition: Clip.h:17
openshot::ReaderInfo::duration
float duration
Length of time (in seconds)
Definition: ReaderBase.h:43
openshot::OutOfBoundsFrame
Exception for frames that are out of bounds.
Definition: Exceptions.h:300
openshot::AudioReaderSource::getTotalLength
juce::int64 getTotalLength() const
Get the total length (in samples) of this audio source.
Definition: AudioReaderSource.cpp:124
AudioReaderSource.h
Header file for AudioReaderSource class.
Frame.h
Header file for Frame class.
openshot::ReaderClosed
Exception when a reader is closed, and a frame is requested.
Definition: Exceptions.h:363
openshot::AudioReaderSource::getNextAudioBlock
void getNextAudioBlock(const juce::AudioSourceChannelInfo &info)
Get the next block of audio samples.
Definition: AudioReaderSource.cpp:32
openshot::ReaderBase
This abstract class is the base class, used by all readers in libopenshot.
Definition: ReaderBase.h:75
openshot::AudioReaderSource::releaseResources
void releaseResources()
Release all resources.
Definition: AudioReaderSource.cpp:121
openshot::VideoCacheThread::isReady
bool isReady()
Definition: VideoCacheThread.cpp:50
Exceptions.h
Header file for all Exception classes.