Get the next block of audio samples
| 30 | |
| 31 | // Get the next block of audio samples |
| 32 | void 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()) { |
no test coverage detected