This repository has been archived on 2026-10-10. You can view files and clone it, but cannot push or open issues or pull requests.
molotov/crates/molotov-core/tests/audio_fixes_test.rs

74 lines
2.5 KiB
Rust

// SPDX-License-Identifier: GPL-3.0-or-later
use molotov_core::audio::buffer::AudioRingBuffer;
use molotov_core::audio::c_api::*;
use molotov_core::audio::types::AAudioResult;
#[test]
fn test_ring_buffer_overrun_no_panic_and_preserves_frames() {
let mut buffer = AudioRingBuffer::new_framed(4, 2); // 4 frames capacity, 2 channels per frame
// Write 6 stereo frames (12 samples): [L0, R0, L1, R1, ...]
let samples = [
1.0, 1.5,
2.0, 2.5,
3.0, 3.5,
4.0, 4.5,
5.0, 5.5,
6.0, 6.5,
];
// Must not panic on overrun
buffer.write_frames(&samples);
let mut out = [0.0f32; 8]; // Read 4 frames (8 samples)
let read_frames = buffer.read_frames(&mut out);
assert_eq!(read_frames, 4);
// Channels must remain aligned: left has .fract() == 0.0, right has .fract() == 0.5
for i in 0..4 {
let left = out[i * 2];
let right = out[i * 2 + 1];
assert_eq!(left.fract(), 0.0, "Left channel phase shifted: {}", left);
assert_eq!(right.fract(), 0.5, "Right channel phase shifted: {}", right);
}
}
#[test]
fn test_ring_buffer_underrun_fills_silence() {
let mut buffer = AudioRingBuffer::new_framed(8, 1);
buffer.write_frames(&[0.5, 0.6]); // 2 frames
let mut out = [9.9f32; 6]; // Request 6 frames
let read_frames = buffer.read_frames(&mut out);
assert_eq!(read_frames, 2);
assert_eq!(out[0], 0.5);
assert_eq!(out[1], 0.6);
// Unread frames must be filled with silence (0.0)
for &sample in &out[2..6] {
assert_eq!(sample, 0.0, "Underrun must fill silence");
}
}
#[test]
fn test_c_api_double_close_safety_handle_registry() {
unsafe {
let mut builder = std::ptr::null_mut();
AAudio_createStreamBuilder(&mut builder);
let mut stream = std::ptr::null_mut();
AAudioStreamBuilder_openStream(builder, &mut stream);
assert!(!stream.is_null());
// First close succeeds
let res1 = AAudioStream_close(stream);
assert_eq!(res1, AAudioResult::Ok as i32);
// Second close must NOT double-free; it safely returns ErrorInvalidHandle
let res2 = AAudioStream_close(stream);
assert_eq!(res2, AAudioResult::ErrorInvalidHandle as i32);
// Delete builder
assert_eq!(AAudioStreamBuilder_delete(builder), AAudioResult::Ok as i32);
// Double delete builder also safe
assert_eq!(AAudioStreamBuilder_delete(builder), AAudioResult::ErrorInvalidHandle as i32);
}
}