import CAudioRing import Foundation import Testing @testable import AudioMatrix @Suite struct RingTests { @Test func writesAndReadsAcrossWrap() throws { let ring = try #require(musubi_ring_create(8, 2)) defer { musubi_ring_destroy(ring) } var input: [Float] = (0..<12).map(Float.init) // 6 frames var output = [Float](repeating: 0, count: 12) #expect(musubi_ring_write(ring, &input, 6) == 6) #expect(musubi_ring_read(ring, &output, 4) == 4) #expect(Array(output[0..<8]) == (0..<8).map(Float.init)) // Wraps around the end of the buffer. #expect(musubi_ring_write(ring, &input, 6) == 6) #expect(musubi_ring_available(ring) == 8) #expect(musubi_ring_read(ring, &output, 6) == 6) #expect(Array(output[0..<4]) == [8, 9, 10, 11]) #expect(Array(output[4..<12]) == (0..<8).map(Float.init)) } @Test func dropsWhatDoesNotFit() throws { let ring = try #require(musubi_ring_create(4, 1)) defer { musubi_ring_destroy(ring) } var input: [Float] = [1, 2, 3, 4, 5, 6] #expect(musubi_ring_write(ring, &input, 6) == 4) #expect(musubi_ring_skip(ring, 3) == 3) #expect(musubi_ring_available(ring) == 1) } } @Suite struct ResamplerTests { @Test func unitStepPassesSignalThroughWithDelay() { var resampler = Resampler() let frames = 64 let input: [Float] = (0.. [Float] in let v = Float(sin(2 * Double.pi * 1000 * Double(i) / 44_100)) return [v, v] } var output = [Float](repeating: 0, count: outFrames * 2) input.withUnsafeBufferPointer { resampler.process(input: $0.baseAddress!, output: &output, outputFrames: outFrames, step: step) } // Compare against an ideal 1 kHz sine at 48 kHz (skipping the start-up latency). let latency = 3.0 / step var maxError: Float = 0 for i in 100.. 400 && fill < 2000) #expect(drift.correction > 0) } } @Suite struct LevelTests { @Test func convertsDecibels() { #expect(Level.gain(fromDB: 0) == 1) #expect(abs(Level.gain(fromDB: -6) - 0.501) < 0.001) #expect(Level.gain(fromDB: -60) == 0) #expect(Level.db(fromGain: 0) == Level.floorDB) #expect(abs(Level.db(fromGain: 0.5) + 6.02) < 0.01) } @Test func selectsChannels() { #expect(ChannelSelection.left.sample(left: 1, right: 0) == 1) #expect(ChannelSelection.right.sample(left: 1, right: 0) == 0) #expect(ChannelSelection.mono.sample(left: 1, right: 0) == 0.5) } }