diff --git a/include/AudioReaderSource.h b/include/AudioReaderSource.h
index b78c5a69..8b70982f 100644
--- a/include/AudioReaderSource.h
+++ b/include/AudioReaderSource.h
@@ -54,15 +54,16 @@ namespace openshot
class AudioReaderSource : public PositionableAudioSource
{
private:
- int position;
- int start;
- bool repeat;
- AudioSampleBuffer *buffer;
+ int position; /// The position of the audio source (index of buffer)
+ bool repeat; /// Repeat the audio source when finished
+ int size; /// The size of the internal buffer
+ AudioSampleBuffer *buffer; /// The audio sample buffer
- int size; /// The size of the buffer
ReaderBase *reader; /// The reader to pull samples from
- int64 frame_number; /// The current frame to read from
+ int64 original_frame_number; /// The current frame to read from
+ int64 frame_number; /// The current frame number
tr1::shared_ptr frame; /// The current frame object that is being read
+ int frame_position; /// The position of the current frame's buffer
/// Get more samples from the reader
void GetMoreSamplesFromReader();
diff --git a/src/AudioReaderSource.cpp b/src/AudioReaderSource.cpp
index 2d2ece8e..c85b927c 100644
--- a/src/AudioReaderSource.cpp
+++ b/src/AudioReaderSource.cpp
@@ -32,7 +32,8 @@ using namespace openshot;
// Constructor that reads samples from a reader
AudioReaderSource::AudioReaderSource(ReaderBase *audio_reader, int64 starting_frame_number, int buffer_size)
- : reader(audio_reader), frame_number(starting_frame_number), size(buffer_size) {
+ : reader(audio_reader), frame_number(starting_frame_number), original_frame_number(starting_frame_number),
+ size(buffer_size), position(0), frame_position(0) {
// Initialize an audio buffer (based on reader)
buffer = new juce::AudioSampleBuffer(reader->info.channels, size);
@@ -51,55 +52,86 @@ AudioReaderSource::~AudioReaderSource()
// Get more samples from the reader
void AudioReaderSource::GetMoreSamplesFromReader() {
+
// Determine the amount of samples needed to fill up this buffer
- int amount_needed = start; // replace these used samples
- int amount_remaining = size - start;
+ int amount_needed = position; // replace these used samples
+ int amount_remaining = size - amount_needed; // these are unused samples, and need to be carried forward
if (!frame) {
// If no frame, load entire buffer
amount_needed = size;
- amount_remaining = size;
+ amount_remaining = 0;
}
// Init new buffer
juce::AudioSampleBuffer *new_buffer = new juce::AudioSampleBuffer(reader->info.channels, size);
+ new_buffer->clear();
// Move the remaining samples into new buffer (if any)
- if (start > 0) {
+ if (amount_remaining > 0) {
for (int channel = 0; channel < buffer->getNumChannels(); channel++)
- new_buffer->copyFrom(channel, 0, *buffer, channel, start, amount_remaining);
- start = amount_remaining;
- }
+ new_buffer->addFrom(channel, 0, *buffer, channel, position, amount_remaining);
+ position = amount_remaining;
+ } else
+ // reset position to 0
+ position = 0;
// Loop through frames until buffer filled
- int fill_start = start;
while (amount_needed > 0) {
- // Get the next frame
- try {
- frame = reader->GetFrame(frame_number++);
- } catch (const ReaderClosed & e) {
- break;
- } catch (const TooManySeeks & e) {
- break;
- } catch (const OutOfBoundsFrame & e) {
- break;
- }
+ // Get the next frame (if position is zero)
+ if (frame_position == 0) {
+ try {
+ // Get frame object
+ frame = reader->GetFrame(frame_number++);
- // Is buffer big enough to hold entire frame
- if (fill_start + frame->GetAudioSamplesCount() > size) {
- // Increase size of buffer
- new_buffer->setSize(frame->GetAudioChannelsCount(), fill_start + frame->GetAudioSamplesCount(), true, true, false);
- size = new_buffer->getNumSamples();
+ } catch (const ReaderClosed & e) {
+ break;
+ } catch (const TooManySeeks & e) {
+ break;
+ } catch (const OutOfBoundsFrame & e) {
+ break;
+ }
}
- // Load all of its samples into the buffer
- for (int channel = 0; channel < new_buffer->getNumChannels(); channel++)
- new_buffer->copyFrom(channel, fill_start, *frame->GetAudioSampleBuffer(), channel, 0, frame->GetAudioSamplesCount());
+ bool frame_completed = false;
+ int amount_to_copy = frame->GetAudioSamplesCount();
+ if (amount_to_copy > amount_needed) {
+ // Don't copy too many samples (we don't want to overflow the buffer)
+ amount_to_copy = amount_needed;
+ amount_needed = 0;
+ } else {
+ // Not enough to fill the buffer (so use the entire frame)
+ amount_needed -= amount_to_copy;
+ frame_completed = true;
+ }
+
+ if (frame->number > 200) {
+ frame->DisplayWaveform();
+ for (int y = 0; y < frame->GetAudioSamplesCount(); y++)
+ cout << y << ": " << frame->GetAudioSampleBuffer()->getSampleData(0)[y] << endl;
+
+ // Load all of its samples into the buffer
+ for (int channel = 0; channel < new_buffer->getNumChannels(); channel++)
+ new_buffer->addFrom(channel, position, *frame->GetAudioSampleBuffer(), channel, frame_position, amount_to_copy);
+ }
// Adjust remaining samples
- amount_remaining -= fill_start + frame->GetAudioSamplesCount();
- fill_start += frame->GetAudioSamplesCount();
+ position += amount_to_copy;
+ if (frame_completed)
+ // Reset frame buffer position (which will load a new frame on the next loop)
+ frame_position = 0;
+ else
+ // Continue tracking the current frame's position
+ frame_position += amount_to_copy;
}
+
+ // Delete old buffer
+ buffer->clear();
+ delete buffer;
+
+ // Replace buffer and reset position
+ buffer = new_buffer;
+ position = 0;
}
// Get the next block of audio samples
diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp
index 0b1307ef..d04710d4 100644
--- a/src/FFmpegReader.cpp
+++ b/src/FFmpegReader.cpp
@@ -1290,7 +1290,7 @@ tr1::shared_ptr FFmpegReader::CreateFrame(int requested_frame)
else
{
// Create a new frame on the working cache
- tr1::shared_ptr f(new Frame(requested_frame, info.width, info.height, "#000000", 0, info.channels));
+ tr1::shared_ptr f(new Frame(requested_frame, info.width, info.height, "#000000", Frame::GetSamplesPerFrame(requested_frame, info.fps, info.sample_rate), info.channels));
f->SetPixelRatio(info.pixel_ratio.num, info.pixel_ratio.den);
working_cache.Add(requested_frame, f);
diff --git a/src/Main.cpp b/src/Main.cpp
index cee22e4b..b23b3196 100644
--- a/src/Main.cpp
+++ b/src/Main.cpp
@@ -40,11 +40,23 @@ using namespace tr1;
int main(int argc, char* argv[])
{
- FFmpegReader r99("/home/jonathan/Videos/sintel_trailer-720p.mp4");
- r99.Open();
- for (int count99 = 1; count99 < 10000000; count99++) {
- cout << count99 << endl;
- r99.GetFrame(count99);
+ FFmpegReader sinelReader("/home/jonathan/Videos/sintel_trailer-720p.mp4");
+ sinelReader.Open();
+
+ AudioReaderSource readerSource(&sinelReader, 1, 10000);
+ for (int z = 0; z < 2000; z++) {
+ // Get audio chunks
+ int chunk_size = 750;
+ juce::AudioSampleBuffer *master_buffer = new juce::AudioSampleBuffer(sinelReader.info.channels, chunk_size);
+ master_buffer->clear();
+ const AudioSourceChannelInfo info = {master_buffer, 0, chunk_size};
+
+ // Get next audio block
+ readerSource.getNextAudioBlock(info);
+
+ // Delete buffer
+ master_buffer->clear();
+ delete master_buffer;
}
return 0;