28 #include "../include/AudioReaderSource.h" 34 AudioReaderSource::AudioReaderSource(
ReaderBase *audio_reader, int64_t starting_frame_number,
int buffer_size)
35 : reader(audio_reader), frame_number(starting_frame_number), original_frame_number(starting_frame_number),
36 size(buffer_size), position(0), frame_position(0), estimated_frame(0), speed(1) {
39 buffer =
new juce::AudioSampleBuffer(reader->
info.
channels, size);
54 void AudioReaderSource::GetMoreSamplesFromReader()
57 int amount_needed = position;
58 int amount_remaining = size - amount_needed;
66 ZmqLogger::Instance()->
AppendDebugMethod(
"AudioReaderSource::GetMoreSamplesFromReader",
"amount_needed", amount_needed,
"amount_remaining", amount_remaining,
"", -1,
"", -1,
"", -1,
"", -1);
69 estimated_frame = frame_number;
72 juce::AudioSampleBuffer *new_buffer =
new juce::AudioSampleBuffer(reader->
info.
channels, size);
76 if (amount_remaining > 0) {
77 for (
int channel = 0; channel < buffer->getNumChannels(); channel++)
78 new_buffer->addFrom(channel, 0, *buffer, channel, position, amount_remaining);
80 position = amount_remaining;
86 while (amount_needed > 0 && speed == 1 && frame_number >= 1 && frame_number <= reader->info.video_length) {
89 if (frame_position == 0) {
92 frame = reader->
GetFrame(frame_number);
93 frame_number = frame_number + speed;
104 bool frame_completed =
false;
105 int amount_to_copy = 0;
107 amount_to_copy = frame->GetAudioSamplesCount() - frame_position;
108 if (amount_to_copy > amount_needed) {
110 amount_to_copy = amount_needed;
114 amount_needed -= amount_to_copy;
115 frame_completed =
true;
120 for (
int channel = 0; channel < new_buffer->getNumChannels(); channel++)
121 new_buffer->addFrom(channel, position, *frame->GetAudioSampleBuffer(), channel, frame_position, amount_to_copy);
124 position += amount_to_copy;
130 frame_position += amount_to_copy;
143 juce::AudioSampleBuffer* AudioReaderSource::reverse_buffer(juce::AudioSampleBuffer* buffer)
145 int number_of_samples = buffer->getNumSamples();
146 int channels = buffer->getNumChannels();
149 ZmqLogger::Instance()->
AppendDebugMethod(
"AudioReaderSource::reverse_buffer",
"number_of_samples", number_of_samples,
"channels", channels,
"", -1,
"", -1,
"", -1,
"", -1);
152 AudioSampleBuffer *reversed =
new juce::AudioSampleBuffer(channels, number_of_samples);
155 for (
int channel = 0; channel < channels; channel++)
158 for (
int s = number_of_samples - 1; s >= 0; s--, n++)
159 reversed->getWritePointer(channel)[n] = buffer->getWritePointer(channel)[s];
165 for (
int channel = 0; channel < channels; channel++)
167 buffer->addFrom(channel, 0, reversed->getReadPointer(channel), number_of_samples, 1.0f);
179 int buffer_samples = buffer->getNumSamples();
180 int buffer_channels = buffer->getNumChannels();
182 if (info.numSamples > 0) {
183 int number_to_copy = 0;
188 if ((reader && reader->
IsOpen() && !frame) or
189 (reader && reader->
IsOpen() && buffer_samples - position < info.numSamples))
191 GetMoreSamplesFromReader();
194 info.buffer->clear();
199 if (position + info.numSamples <= buffer_samples)
202 number_to_copy = info.numSamples;
204 else if (position > buffer_samples)
209 else if (buffer_samples - position > 0)
212 number_to_copy = buffer_samples - position;
222 if (number_to_copy > 0)
225 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);
228 for (
int channel = 0; channel < buffer_channels; channel++)
229 info.buffer->copyFrom(channel, info.startSample, *buffer, channel, position, number_to_copy);
232 position += number_to_copy;
237 estimated_frame += double(info.numSamples) / double(estimated_samples_per_frame);
251 if (newPosition >= 0 && newPosition < buffer->getNumSamples())
252 position = newPosition;
289 buffer = audio_buffer;
void setBuffer(AudioSampleBuffer *audio_buffer)
Update the internal buffer used by this source.
float duration
Length of time (in seconds)
void getNextAudioBlock(const AudioSourceChannelInfo &info)
Get the next block of audio samples.
void setNextReadPosition(int64 newPosition)
Set the next read position of this 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.
Exception when a reader is closed, and a frame is requested.
virtual std::shared_ptr< Frame > GetFrame(int64_t number)=0
void AppendDebugMethod(string method_name, string arg1_name, float arg1_value, string arg2_name, float arg2_value, string arg3_name, float arg3_value, string arg4_name, float arg4_value, string arg5_name, float arg5_value, string arg6_name, float arg6_value)
Append debug information.
int64 getNextReadPosition() const
Get the next read position of this source.
ReaderInfo info
Information about the current media file.
Fraction fps
Frames per second, as a fraction (i.e. 24/1 = 24 fps)
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.
int64 getTotalLength() const
Get the total length (in samples) of this audio source.
int GetSamplesPerFrame(Fraction fps, int sample_rate, int channels)
Calculate the # of samples per video frame (for the current frame number)
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.