38 AudioReaderSource::AudioReaderSource(
ReaderBase *audio_reader, int64_t starting_frame_number,
int buffer_size)
39 : reader(audio_reader), frame_number(starting_frame_number),
40 size(buffer_size), position(0), frame_position(0), estimated_frame(0), speed(1) {
43 buffer =
new juce::AudioSampleBuffer(reader->
info.
channels, size);
58 void AudioReaderSource::GetMoreSamplesFromReader()
61 int amount_needed = position;
62 int amount_remaining = size - amount_needed;
73 estimated_frame = frame_number;
76 juce::AudioSampleBuffer *new_buffer =
new juce::AudioSampleBuffer(reader->
info.
channels, size);
80 if (amount_remaining > 0) {
81 for (
int channel = 0; channel < buffer->getNumChannels(); channel++)
82 new_buffer->addFrom(channel, 0, *buffer, channel, position, amount_remaining);
84 position = amount_remaining;
90 while (amount_needed > 0 && speed == 1 && frame_number >= 1 && frame_number <= reader->info.video_length) {
93 if (frame_position == 0) {
96 frame = reader->
GetFrame(frame_number);
97 frame_number = frame_number + speed;
106 bool frame_completed =
false;
107 int amount_to_copy = 0;
109 amount_to_copy = frame->GetAudioSamplesCount() - frame_position;
110 if (amount_to_copy > amount_needed) {
112 amount_to_copy = amount_needed;
116 amount_needed -= amount_to_copy;
117 frame_completed =
true;
122 for (
int channel = 0; channel < new_buffer->getNumChannels(); channel++)
123 new_buffer->addFrom(channel, position, *frame->GetAudioSampleBuffer(), channel, frame_position, amount_to_copy);
126 position += amount_to_copy;
132 frame_position += amount_to_copy;
145 juce::AudioSampleBuffer* AudioReaderSource::reverse_buffer(juce::AudioSampleBuffer* buffer)
147 int number_of_samples = buffer->getNumSamples();
148 int channels = buffer->getNumChannels();
154 juce::AudioSampleBuffer *reversed =
new juce::AudioSampleBuffer(channels, number_of_samples);
157 for (
int channel = 0; channel < channels; channel++)
160 for (
int s = number_of_samples - 1; s >= 0; s--, n++)
161 reversed->getWritePointer(channel)[n] = buffer->getWritePointer(channel)[s];
167 for (
int channel = 0; channel < channels; channel++)
169 buffer->addFrom(channel, 0, reversed->getReadPointer(channel), number_of_samples, 1.0f);
181 int buffer_samples = buffer->getNumSamples();
182 int buffer_channels = buffer->getNumChannels();
184 if (info.numSamples > 0) {
185 int number_to_copy = 0;
190 if ((reader && reader->
IsOpen() && !frame) or
191 (reader && reader->
IsOpen() && buffer_samples - position < info.numSamples))
193 GetMoreSamplesFromReader();
196 info.buffer->clear();
201 if (position + info.numSamples <= buffer_samples)
204 number_to_copy = info.numSamples;
206 else if (position > buffer_samples)
211 else if (buffer_samples - position > 0)
214 number_to_copy = buffer_samples - position;
224 if (number_to_copy > 0)
227 ZmqLogger::Instance()->
AppendDebugMethod(
"AudioReaderSource::getNextAudioBlock",
"number_to_copy", number_to_copy,
"buffer_samples", buffer_samples,
"buffer_channels", buffer_channels,
"info.numSamples", info.numSamples,
"speed", speed,
"position", position);
230 for (
int channel = 0; channel < buffer_channels; channel++)
231 info.buffer->copyFrom(channel, info.startSample, *buffer, channel, position, number_to_copy);
234 position += number_to_copy;
239 estimated_frame += double(info.numSamples) / double(estimated_samples_per_frame);
253 if (newPosition >= 0 && newPosition < buffer->getNumSamples())
254 position = newPosition;
291 buffer = audio_buffer;
Header file for AudioReaderSource class.
Header file for all Exception classes.
juce::int64 getNextReadPosition() const
Get the next read position of this source.
void setNextReadPosition(juce::int64 newPosition)
Set the next read position of this source.
void releaseResources()
Release all resources.
bool isLooping() const
Determines if this audio source should repeat when it reaches the end.
juce::int64 getTotalLength() const
Get the total length (in samples) of this audio source.
void setLooping(bool shouldLoop)
Set if this audio source should repeat when it reaches the end.
void prepareToPlay(int, double)
Prepare to play this audio source.
void setBuffer(juce::AudioSampleBuffer *audio_buffer)
Update the internal buffer used by this source.
void getNextAudioBlock(const juce::AudioSourceChannelInfo &info)
Get the next block of audio samples.
~AudioReaderSource()
Destructor.
int GetSamplesPerFrame(openshot::Fraction fps, int sample_rate, int channels)
Calculate the # of samples per video frame (for the current frame number)
Exception for frames that are out of bounds.
This abstract class is the base class, used by all readers in libopenshot.
virtual bool IsOpen()=0
Determine if reader is open or closed.
openshot::ReaderInfo info
Information about the current media file.
virtual std::shared_ptr< openshot::Frame > GetFrame(int64_t number)=0
Exception when a reader is closed, and a frame is requested.
void AppendDebugMethod(std::string method_name, std::string arg1_name="", float arg1_value=-1.0, std::string arg2_name="", float arg2_value=-1.0, std::string arg3_name="", float arg3_value=-1.0, std::string arg4_name="", float arg4_value=-1.0, std::string arg5_name="", float arg5_value=-1.0, std::string arg6_name="", float arg6_value=-1.0)
Append debug information.
static ZmqLogger * Instance()
Create or get an instance of this logger singleton (invoke the class with this method)
This namespace is the default namespace for all code in the openshot library.
float duration
Length of time (in seconds)
int channels
The number of audio channels used in the audio stream.
openshot::Fraction fps
Frames per second, as a fraction (i.e. 24/1 = 24 fps)
int sample_rate
The number of audio samples per second (44100 is a common sample rate)