Initial audio support
This commit is contained in:
115
tests/AudioSupportTests.cpp
Normal file
115
tests/AudioSupportTests.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
#include "AudioSupport.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
namespace
|
||||
{
|
||||
int gFailures = 0;
|
||||
|
||||
void Expect(bool condition, const char* message)
|
||||
{
|
||||
if (condition)
|
||||
return;
|
||||
|
||||
std::cerr << "FAIL: " << message << "\n";
|
||||
++gFailures;
|
||||
}
|
||||
|
||||
int32_t ToSample(float value)
|
||||
{
|
||||
const double clamped = std::max(-1.0, std::min(1.0, static_cast<double>(value)));
|
||||
return static_cast<int32_t>(clamped * 2147483647.0);
|
||||
}
|
||||
|
||||
void TestFrameSampleCounts()
|
||||
{
|
||||
Expect(AudioSamplesForVideoFrame(0, 1, 50) == 960, "50 fps first frame has 960 audio samples");
|
||||
Expect(AudioSamplesForVideoFrame(0, 1, 60) == 800, "60 fps first frame has 800 audio samples");
|
||||
|
||||
uint64_t total = 0;
|
||||
for (uint64_t frame = 0; frame < 600; ++frame)
|
||||
total += AudioSamplesForVideoFrame(frame, 1001, 60000);
|
||||
Expect(total == AudioSampleTimeForVideoFrame(600, 1001, 60000), "59.94 fps sample counts do not drift");
|
||||
}
|
||||
|
||||
void TestDelayBuffer()
|
||||
{
|
||||
AudioDelayBuffer buffer;
|
||||
buffer.Reset(4);
|
||||
std::vector<int32_t> input = {
|
||||
11, 12,
|
||||
21, 22,
|
||||
31, 32,
|
||||
41, 42
|
||||
};
|
||||
buffer.PushInterleaved(input.data(), 4);
|
||||
|
||||
bool underrun = false;
|
||||
AudioFrameBlock first = buffer.Pop(4, underrun);
|
||||
Expect(!underrun, "delay-buffer initial silence does not underrun");
|
||||
Expect(first.frameCount() == 4, "delay-buffer returns requested frame count");
|
||||
Expect(first.interleavedSamples[0] == 0 && first.interleavedSamples[7] == 0, "delay-buffer emits initial silence");
|
||||
|
||||
AudioFrameBlock second = buffer.Pop(4, underrun);
|
||||
Expect(!underrun, "delay-buffer emits delayed input without underrun");
|
||||
Expect(second.interleavedSamples == input, "delay-buffer preserves delayed interleaved samples");
|
||||
|
||||
AudioFrameBlock third = buffer.Pop(2, underrun);
|
||||
Expect(underrun, "delay-buffer reports underrun");
|
||||
Expect(third.interleavedSamples[0] == 0 && third.interleavedSamples[3] == 0, "delay-buffer underrun fills silence");
|
||||
}
|
||||
|
||||
void TestAnalyzerSilence()
|
||||
{
|
||||
AudioAnalyzer analyzer;
|
||||
AudioFrameBlock block;
|
||||
block.interleavedSamples.resize(512 * kAudioChannelCount, 0);
|
||||
|
||||
AudioAnalysisSnapshot analysis = analyzer.Analyze(block);
|
||||
Expect(analysis.rms[0] == 0.0f && analysis.rms[1] == 0.0f, "silence rms is zero");
|
||||
Expect(analysis.peak[0] == 0.0f && analysis.peak[1] == 0.0f, "silence peak is zero");
|
||||
Expect(analysis.bands[0] == 0.0f && analysis.bands[3] == 0.0f, "silence bands are zero");
|
||||
}
|
||||
|
||||
void TestAnalyzerSineAndStereo()
|
||||
{
|
||||
AudioAnalyzer analyzer;
|
||||
AudioFrameBlock block;
|
||||
block.interleavedSamples.resize(1024 * kAudioChannelCount, 0);
|
||||
|
||||
for (std::size_t frame = 0; frame < 1024; ++frame)
|
||||
{
|
||||
const float phase = static_cast<float>(frame) * 2.0f * 3.14159265f * 300.0f / static_cast<float>(kAudioSampleRate);
|
||||
block.interleavedSamples[frame * 2] = ToSample(std::sin(phase) * 0.8f);
|
||||
block.interleavedSamples[frame * 2 + 1] = ToSample(0.25f);
|
||||
}
|
||||
|
||||
AudioAnalysisSnapshot analysis = analyzer.Analyze(block);
|
||||
Expect(analysis.peak[0] > 0.75f && analysis.peak[0] <= 0.81f, "left sine peak is detected");
|
||||
Expect(analysis.rms[0] > 0.45f && analysis.rms[0] < 0.65f, "left sine rms is detected");
|
||||
Expect(analysis.peak[1] > 0.24f && analysis.peak[1] < 0.26f, "right constant peak remains independent");
|
||||
Expect(analysis.rms[1] > 0.24f && analysis.rms[1] < 0.26f, "right constant rms remains independent");
|
||||
Expect(analysis.bands[1] >= analysis.bands[0], "300 Hz sine activates lower-mid band");
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
TestFrameSampleCounts();
|
||||
TestDelayBuffer();
|
||||
TestAnalyzerSilence();
|
||||
TestAnalyzerSineAndStereo();
|
||||
|
||||
if (gFailures != 0)
|
||||
{
|
||||
std::cerr << gFailures << " AudioSupport test failure(s).\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "AudioSupport tests passed.\n";
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user