| 763 | } |
| 764 | |
| 765 | ExportResult OpusExportProcessor::Process(ExportProcessorDelegate& delegate) |
| 766 | { |
| 767 | delegate.SetStatusString(context.status); |
| 768 | |
| 769 | auto exportResult = ExportResult::Success; |
| 770 | |
| 771 | int64_t granulePos = 0; |
| 772 | |
| 773 | int32_t latencyLeft = context.opus.preskip; |
| 774 | |
| 775 | while (exportResult == ExportResult::Success) |
| 776 | { |
| 777 | auto samplesThisRun = context.mixer->Process(); |
| 778 | |
| 779 | if (samplesThisRun == 0) |
| 780 | break; |
| 781 | |
| 782 | auto mixedAudioBuffer = |
| 783 | reinterpret_cast<const float*>(context.mixer->GetBuffer()); |
| 784 | |
| 785 | // bestFrameSize <= context.opus.frameSize by design |
| 786 | auto bestFrameSize = GetBestFrameSize(samplesThisRun); |
| 787 | |
| 788 | if (samplesThisRun < bestFrameSize) |
| 789 | { |
| 790 | // Opus expects that the full frame is passed to the encoder, fill missing data with zeroes |
| 791 | context.encodeBuffer.resize(bestFrameSize * context.numChannels); |
| 792 | |
| 793 | std::copy( |
| 794 | mixedAudioBuffer, mixedAudioBuffer + samplesThisRun * context.numChannels, |
| 795 | context.encodeBuffer.begin()); |
| 796 | |
| 797 | std::fill( |
| 798 | context.encodeBuffer.begin() + samplesThisRun * context.numChannels, |
| 799 | context.encodeBuffer.begin() + bestFrameSize * context.numChannels, |
| 800 | 0); |
| 801 | |
| 802 | mixedAudioBuffer = context.encodeBuffer.data(); |
| 803 | |
| 804 | auto zeroesCount = bestFrameSize - int32_t(samplesThisRun); |
| 805 | |
| 806 | if (zeroesCount < latencyLeft) |
| 807 | samplesThisRun += zeroesCount; |
| 808 | else |
| 809 | samplesThisRun += latencyLeft; |
| 810 | |
| 811 | // Reduce the latency by the number of zeroes pushed (potentially |
| 812 | // removing the need to flush the encoder) |
| 813 | latencyLeft = std::max(0, latencyLeft - zeroesCount); |
| 814 | } |
| 815 | |
| 816 | auto result = opus_multistream_encode_float( |
| 817 | context.opus.encoder, mixedAudioBuffer, bestFrameSize, |
| 818 | context.ogg.audioStreamPacket.GetBuffer(), |
| 819 | context.ogg.audioStreamPacket.GetBufferSize()); |
| 820 | |
| 821 | if (result < 0) |
| 822 | FailExport(XO("Failed to encode input buffer"), result); |
nothing calls this directly
no test coverage detected