OpenShot Library | libopenshot 0.6.0
Loading...
Searching...
No Matches
AudioReaderSource.cpp
Go to the documentation of this file.
1
9// Copyright (c) 2008-2019 OpenShot Studios, LLC
10//
11// SPDX-License-Identifier: LGPL-3.0-or-later
12
13#include "AudioReaderSource.h"
14#include "Exceptions.h"
15#include "Frame.h"
16
17using namespace std;
18using namespace openshot;
19
20// Constructor that reads samples from a reader
21AudioReaderSource::AudioReaderSource(ReaderBase *audio_reader, int64_t starting_frame_number)
22 : reader(audio_reader), frame_position(starting_frame_number), videoCache(NULL), frame(NULL),
23 sample_position(0), speed(1), stream_position(0) {
24}
25
26// Destructor
30
31// Get the next block of audio samples
32void AudioReaderSource::getNextAudioBlock(const juce::AudioSourceChannelInfo& info)
33{
34 if (info.numSamples > 0) {
35 int remaining_samples = info.numSamples;
36 int remaining_position = info.startSample;
37
38 // Pause and fill buffer with silence (wait for pre-roll)
39 if (speed != 1 || !videoCache->isReady()) {
40 info.buffer->clear();
41 return;
42 }
43
44 while (remaining_samples > 0) {
45 const int previous_remaining = remaining_samples;
46 frame.reset();
47 try {
48 // Get current frame object
49 if (reader) {
50 frame = reader->GetFrame(frame_position);
51 }
52 }
53 catch (const ReaderClosed & e) { }
54 catch (const OutOfBoundsFrame & e) { }
55
56 // Get audio samples
57 if (reader && frame) {
58 const int frame_samples = frame->GetAudioSamplesCount();
59 const int frame_channels = frame->GetAudioChannelsCount();
60
61 // Corrupt/unsupported streams can yield frames without audio data.
62 // Avoid a tight loop that never consumes remaining_samples.
63 if (frame_samples <= 0 || frame_channels <= 0) {
64 info.buffer->clear(remaining_position, remaining_samples);
65 break;
66 }
67
68 if (sample_position + remaining_samples <= frame->GetAudioSamplesCount()) {
69 // Success, we have enough samples
70 for (int channel = 0; channel < frame_channels; channel++) {
71 if (channel < info.buffer->getNumChannels()) {
72 info.buffer->addFrom(channel, remaining_position, *frame->GetAudioSampleBuffer(),
73 channel, sample_position, remaining_samples);
74 }
75 }
76 sample_position += remaining_samples;
77 remaining_position += remaining_samples;
78 remaining_samples = 0;
79
80 } else if (sample_position + remaining_samples > frame->GetAudioSamplesCount()) {
81 // Not enough samples, take what we can
82 int amount_to_copy = frame->GetAudioSamplesCount() - sample_position;
83 if (amount_to_copy <= 0) {
84 info.buffer->clear(remaining_position, remaining_samples);
85 break;
86 }
87
88 for (int channel = 0; channel < frame_channels; channel++) {
89 if (channel < info.buffer->getNumChannels()) {
90 info.buffer->addFrom(channel, remaining_position, *frame->GetAudioSampleBuffer(), channel,
91 sample_position, amount_to_copy);
92 }
93 }
94 sample_position += amount_to_copy;
95 remaining_position += amount_to_copy;
96 remaining_samples -= amount_to_copy;
97 }
98
99 // Increment frame position (if samples are all used up)
100 if (sample_position == frame->GetAudioSamplesCount()) {
101 frame_position += speed;
102 sample_position = 0; // reset for new frame
103 }
104 } else {
105 info.buffer->clear(remaining_position, remaining_samples);
106 break;
107 }
108
109 if (remaining_samples == previous_remaining) {
110 info.buffer->clear(remaining_position, remaining_samples);
111 break;
112 }
113 }
114 }
115}
116
117// Prepare to play this audio source
119
120// Release all resources
122
123// Get the total length (in samples) of this audio source
125{
126 // Get the length
127 if (reader)
128 return reader->info.sample_rate * reader->info.duration;
129 else
130 return 0;
131}
Header file for AudioReaderSource class.
Header file for all Exception classes.
Header file for Frame class.
AudioReaderSource(ReaderBase *audio_reader, int64_t starting_frame_number)
The cache thread (for pre-roll checking)
void releaseResources()
Release all resources.
juce::int64 getTotalLength() const
Get the total length (in samples) of this audio source.
void prepareToPlay(int, double)
Prepare to play this audio source.
void getNextAudioBlock(const juce::AudioSourceChannelInfo &info)
Get the next block of audio samples.
Exception for frames that are out of bounds.
Definition Exceptions.h:307
This abstract class is the base class, used by all readers in libopenshot.
Definition ReaderBase.h:76
openshot::ReaderInfo info
Information about the current media file.
Definition ReaderBase.h:88
virtual std::shared_ptr< openshot::Frame > GetFrame(int64_t number)=0
Exception when a reader is closed, and a frame is requested.
Definition Exceptions.h:370
This namespace is the default namespace for all code in the openshot library.
Definition Compressor.h:29
float duration
Length of time (in seconds)
Definition ReaderBase.h:43
int sample_rate
The number of audio samples per second (44100 is a common sample rate)
Definition ReaderBase.h:60