2014-01-28 17:17:38 -06:00
|
|
|
/**
|
|
|
|
|
* @file
|
|
|
|
|
* @brief Source file for AudioReaderSource class
|
|
|
|
|
* @author Jonathan Thomas <jonathan@openshot.org>
|
|
|
|
|
*
|
2019-06-09 08:31:04 -04:00
|
|
|
* @ref License
|
|
|
|
|
*/
|
|
|
|
|
|
2021-10-16 01:26:26 -04:00
|
|
|
// Copyright (c) 2008-2019 OpenShot Studios, LLC
|
|
|
|
|
//
|
|
|
|
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
2014-01-28 17:17:38 -06:00
|
|
|
|
2020-10-18 07:43:37 -04:00
|
|
|
#include "AudioReaderSource.h"
|
2021-01-26 10:52:04 -05:00
|
|
|
#include "Exceptions.h"
|
2021-09-18 04:16:30 -04:00
|
|
|
#include "Frame.h"
|
2022-01-31 15:18:07 -06:00
|
|
|
|
2014-01-28 17:17:38 -06:00
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
using namespace openshot;
|
|
|
|
|
|
|
|
|
|
// Constructor that reads samples from a reader
|
2022-01-31 15:18:07 -06:00
|
|
|
AudioReaderSource::AudioReaderSource(ReaderBase *audio_reader, int64_t starting_frame_number)
|
|
|
|
|
: reader(audio_reader), frame_position(starting_frame_number), videoCache(NULL), frame(NULL),
|
|
|
|
|
sample_position(0), speed(1), stream_position(0) {
|
2014-01-28 17:17:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Destructor
|
|
|
|
|
AudioReaderSource::~AudioReaderSource()
|
|
|
|
|
{
|
2014-03-23 01:12:29 -05:00
|
|
|
}
|
|
|
|
|
|
2014-01-28 17:17:38 -06:00
|
|
|
// Get the next block of audio samples
|
2019-10-27 03:56:13 -04:00
|
|
|
void AudioReaderSource::getNextAudioBlock(const juce::AudioSourceChannelInfo& info)
|
2014-01-28 17:17:38 -06:00
|
|
|
{
|
|
|
|
|
if (info.numSamples > 0) {
|
2022-01-31 15:18:07 -06:00
|
|
|
int remaining_samples = info.numSamples;
|
|
|
|
|
int remaining_position = info.startSample;
|
2014-01-28 17:17:38 -06:00
|
|
|
|
2022-01-31 15:18:07 -06:00
|
|
|
// Pause and fill buffer with silence (wait for pre-roll)
|
|
|
|
|
if (speed != 1 || !videoCache->isReady()) {
|
2015-12-24 16:44:45 -06:00
|
|
|
info.buffer->clear();
|
|
|
|
|
return;
|
|
|
|
|
}
|
2014-01-28 17:17:38 -06:00
|
|
|
|
2022-01-31 15:18:07 -06:00
|
|
|
while (remaining_samples > 0) {
|
2014-01-28 17:17:38 -06:00
|
|
|
|
2022-01-31 15:18:07 -06:00
|
|
|
try {
|
|
|
|
|
// Get current frame object
|
|
|
|
|
if (reader) {
|
|
|
|
|
frame = reader->GetFrame(frame_position);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (const ReaderClosed & e) { }
|
|
|
|
|
catch (const OutOfBoundsFrame & e) { }
|
2015-02-04 23:56:43 -06:00
|
|
|
|
2022-01-31 15:18:07 -06:00
|
|
|
// Get audio samples
|
|
|
|
|
if (reader && frame) {
|
|
|
|
|
if (sample_position + remaining_samples <= frame->GetAudioSamplesCount()) {
|
|
|
|
|
// Success, we have enough samples
|
|
|
|
|
for (int channel = 0; channel < frame->GetAudioChannelsCount(); channel++) {
|
|
|
|
|
if (channel < info.buffer->getNumChannels()) {
|
|
|
|
|
info.buffer->addFrom(channel, remaining_position, *frame->GetAudioSampleBuffer(),
|
|
|
|
|
channel, sample_position, remaining_samples);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
sample_position += remaining_samples;
|
|
|
|
|
remaining_position += remaining_samples;
|
|
|
|
|
remaining_samples = 0;
|
2016-04-21 01:39:17 -05:00
|
|
|
|
2022-01-31 15:18:07 -06:00
|
|
|
} else if (sample_position + remaining_samples > frame->GetAudioSamplesCount()) {
|
|
|
|
|
// Not enough samples, take what we can
|
|
|
|
|
int amount_to_copy = frame->GetAudioSamplesCount() - sample_position;
|
|
|
|
|
for (int channel = 0; channel < frame->GetAudioChannelsCount(); channel++) {
|
|
|
|
|
if (channel < info.buffer->getNumChannels()) {
|
|
|
|
|
info.buffer->addFrom(channel, remaining_position, *frame->GetAudioSampleBuffer(), channel,
|
|
|
|
|
sample_position, amount_to_copy);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
sample_position += amount_to_copy;
|
|
|
|
|
remaining_position += amount_to_copy;
|
|
|
|
|
remaining_samples -= amount_to_copy;
|
|
|
|
|
}
|
2014-01-28 17:17:38 -06:00
|
|
|
|
2022-01-31 15:18:07 -06:00
|
|
|
// Increment frame position (if samples are all used up)
|
|
|
|
|
if (sample_position == frame->GetAudioSamplesCount()) {
|
|
|
|
|
frame_position += speed;
|
|
|
|
|
sample_position = 0; // reset for new frame
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
2014-01-28 17:17:38 -06:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Prepare to play this audio source
|
2021-12-06 15:47:32 -06:00
|
|
|
void AudioReaderSource::prepareToPlay(int, double) {}
|
2014-01-28 17:17:38 -06:00
|
|
|
|
|
|
|
|
// Release all resources
|
|
|
|
|
void AudioReaderSource::releaseResources() { }
|
|
|
|
|
|
|
|
|
|
// Get the total length (in samples) of this audio source
|
2019-10-27 03:56:13 -04:00
|
|
|
juce::int64 AudioReaderSource::getTotalLength() const
|
2014-01-28 17:17:38 -06:00
|
|
|
{
|
|
|
|
|
// Get the length
|
2014-02-10 17:16:33 -06:00
|
|
|
if (reader)
|
|
|
|
|
return reader->info.sample_rate * reader->info.duration;
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
2014-01-28 17:17:38 -06:00
|
|
|
}
|