21 AudioReaderSource::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) {
34 if (info.numSamples > 0) {
35 int remaining_samples = info.numSamples;
36 int remaining_position = info.startSample;
39 if (speed != 1 || !videoCache->
isReady()) {
44 while (remaining_samples > 0) {
45 const int previous_remaining = remaining_samples;
50 frame = reader->
GetFrame(frame_position);
57 if (reader && frame) {
58 const int frame_samples = frame->GetAudioSamplesCount();
59 const int frame_channels = frame->GetAudioChannelsCount();
63 if (frame_samples <= 0 || frame_channels <= 0) {
64 info.buffer->clear(remaining_position, remaining_samples);
68 if (sample_position + remaining_samples <= frame->GetAudioSamplesCount()) {
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);
76 sample_position += remaining_samples;
77 remaining_position += remaining_samples;
78 remaining_samples = 0;
80 }
else if (sample_position + remaining_samples > frame->GetAudioSamplesCount()) {
82 int amount_to_copy = frame->GetAudioSamplesCount() - sample_position;
83 if (amount_to_copy <= 0) {
84 info.buffer->clear(remaining_position, remaining_samples);
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);
94 sample_position += amount_to_copy;
95 remaining_position += amount_to_copy;
96 remaining_samples -= amount_to_copy;
100 if (sample_position == frame->GetAudioSamplesCount()) {
101 frame_position += speed;
105 info.buffer->clear(remaining_position, remaining_samples);
109 if (remaining_samples == previous_remaining) {
110 info.buffer->clear(remaining_position, remaining_samples);