#pragma once #include #include #include #include #include constexpr unsigned kAudioSampleRate = 48000; constexpr unsigned kAudioChannelCount = 2; constexpr unsigned kAudioTextureWidth = 64; constexpr unsigned kAudioTextureHeight = 2; struct AudioFrameBlock { std::vector interleavedSamples; std::size_t frameCount() const { return interleavedSamples.size() / kAudioChannelCount; } }; struct AudioAnalysisSnapshot { std::array rms = { 0.0f, 0.0f }; std::array peak = { 0.0f, 0.0f }; float monoRms = 0.0f; float monoPeak = 0.0f; std::array bands = { 0.0f, 0.0f, 0.0f, 0.0f }; std::array texture = {}; }; struct AudioStatusSnapshot { bool enabled = false; unsigned bufferedSampleFrames = 0; uint64_t underrunCount = 0; AudioAnalysisSnapshot analysis; }; class AudioDelayBuffer { public: void Reset(unsigned delaySampleFrames); void PushInterleaved(const int32_t* samples, std::size_t sampleFrameCount); AudioFrameBlock Pop(std::size_t sampleFrameCount, bool& underrun); unsigned BufferedSampleFrames() const; uint64_t UnderrunCount() const; private: mutable std::mutex mMutex; std::deque mSamples; uint64_t mUnderrunCount = 0; }; class AudioAnalyzer { public: void Reset(); AudioAnalysisSnapshot Analyze(const AudioFrameBlock& block); const AudioAnalysisSnapshot& Current() const { return mCurrent; } private: std::deque mMonoHistory; std::array mSmoothedBands = { 0.0f, 0.0f, 0.0f, 0.0f }; AudioAnalysisSnapshot mCurrent; }; uint64_t AudioSampleTimeForVideoFrame(uint64_t videoFrameIndex, uint64_t frameDuration, uint64_t frameTimescale, uint64_t audioSampleRate = kAudioSampleRate); unsigned AudioSamplesForVideoFrame(uint64_t videoFrameIndex, uint64_t frameDuration, uint64_t frameTimescale, uint64_t audioSampleRate = kAudioSampleRate);