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;
float duration
Length of time (in seconds)
void setBuffer(juce::AudioSampleBuffer *audio_buffer)
Update the internal buffer used by this source.
void setNextReadPosition(juce::int64 newPosition)
Set the next read position of this source.
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.
This abstract class is the base class, used by all readers in libopenshot.
void releaseResources()
Release all resources.
~AudioReaderSource()
Destructor.
juce::int64 getNextReadPosition() const
Get the next read position of this source.
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.
virtual std::shared_ptr< openshot::Frame > GetFrame(int64_t number)=0
int GetSamplesPerFrame(openshot::Fraction fps, int sample_rate, int channels)
Calculate the # of samples per video frame (for the current frame number)
void getNextAudioBlock(const juce::AudioSourceChannelInfo &info)
Get the next block of audio samples.
openshot::ReaderInfo info
Information about the current media file.
Exception for frames that are out of bounds.
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.
void prepareToPlay(int, double)
Prepare to play this audio source.
bool isLooping() const
Determines if this audio source should repeat when it reaches the end.
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)
Exception when too many seek attempts happen.
virtual bool IsOpen()=0
Determine if reader is open or closed.