31 #include "../include/AudioReaderSource.h"
37 AudioReaderSource::AudioReaderSource(
ReaderBase *audio_reader, int64_t starting_frame_number,
int buffer_size)
38 : reader(audio_reader), frame_number(starting_frame_number), original_frame_number(starting_frame_number),
39 size(buffer_size), position(0), frame_position(0), estimated_frame(0), speed(1) {
42 buffer =
new juce::AudioSampleBuffer(reader->
info.
channels, size);
57 void AudioReaderSource::GetMoreSamplesFromReader()
60 int amount_needed = position;
61 int amount_remaining = size - amount_needed;
72 estimated_frame = frame_number;
75 juce::AudioSampleBuffer *new_buffer =
new juce::AudioSampleBuffer(reader->
info.
channels, size);
79 if (amount_remaining > 0) {
80 for (
int channel = 0; channel < buffer->getNumChannels(); channel++)
81 new_buffer->addFrom(channel, 0, *buffer, channel, position, amount_remaining);
83 position = amount_remaining;
89 while (amount_needed > 0 && speed == 1 && frame_number >= 1 && frame_number <= reader->info.video_length) {
92 if (frame_position == 0) {
95 frame = reader->
GetFrame(frame_number);
96 frame_number = frame_number + speed;
107 bool frame_completed =
false;
108 int amount_to_copy = 0;
110 amount_to_copy = frame->GetAudioSamplesCount() - frame_position;
111 if (amount_to_copy > amount_needed) {
113 amount_to_copy = amount_needed;
117 amount_needed -= amount_to_copy;
118 frame_completed =
true;
123 for (
int channel = 0; channel < new_buffer->getNumChannels(); channel++)
124 new_buffer->addFrom(channel, position, *frame->GetAudioSampleBuffer(), channel, frame_position, amount_to_copy);
127 position += amount_to_copy;
133 frame_position += amount_to_copy;
146 juce::AudioSampleBuffer* AudioReaderSource::reverse_buffer(juce::AudioSampleBuffer* buffer)
148 int number_of_samples = buffer->getNumSamples();
149 int channels = buffer->getNumChannels();
155 juce::AudioSampleBuffer *reversed =
new juce::AudioSampleBuffer(channels, number_of_samples);
158 for (
int channel = 0; channel < channels; channel++)
161 for (
int s = number_of_samples - 1; s >= 0; s--, n++)
162 reversed->getWritePointer(channel)[n] = buffer->getWritePointer(channel)[s];
168 for (
int channel = 0; channel < channels; channel++)
170 buffer->addFrom(channel, 0, reversed->getReadPointer(channel), number_of_samples, 1.0f);
182 int buffer_samples = buffer->getNumSamples();
183 int buffer_channels = buffer->getNumChannels();
185 if (info.numSamples > 0) {
186 int number_to_copy = 0;
191 if ((reader && reader->
IsOpen() && !frame) or
192 (reader && reader->
IsOpen() && buffer_samples - position < info.numSamples))
194 GetMoreSamplesFromReader();
197 info.buffer->clear();
202 if (position + info.numSamples <= buffer_samples)
205 number_to_copy = info.numSamples;
207 else if (position > buffer_samples)
212 else if (buffer_samples - position > 0)
215 number_to_copy = buffer_samples - position;
225 if (number_to_copy > 0)
228 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);
231 for (
int channel = 0; channel < buffer_channels; channel++)
232 info.buffer->copyFrom(channel, info.startSample, *buffer, channel, position, number_to_copy);
235 position += number_to_copy;
240 estimated_frame += double(info.numSamples) / double(estimated_samples_per_frame);
254 if (newPosition >= 0 && newPosition < buffer->getNumSamples())
255 position = newPosition;
292 buffer = audio_buffer;
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.
Exception when too many seek attempts happen.
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)