# HG changeset patch # User Chris Cannam # Date 1399820563 -3600 # Node ID 8c1b62eb33c7070c44ac4f32f8dc230da70386af # Parent 3b07478932a12411d9f0e2ffc5c31f5122048f8a Some failing resampler tests, matching those currently in qm-dsp diff -r 3b07478932a1 -r 8c1b62eb33c7 src/may/stream/test/test_resample.yeti --- a/src/may/stream/test/test_resample.yeti Thu May 01 11:36:14 2014 +0100 +++ b/src/may/stream/test/test_resample.yeti Sun May 11 16:02:43 2014 +0100 @@ -5,6 +5,7 @@ mat = load may.matrix; syn = load may.stream.syntheticstream; manip = load may.stream.manipulate; +channels = load may.stream.channels; resample = load may.stream.resample; win = load may.signal.window; waves = load may.stream.waves; @@ -12,6 +13,54 @@ { compare, compareUsing, compareMatrices, assert, time } = load may.test; +measureFrequency sampleRate cycles stream = + (case stream.available of + Known n: + (v = channels.mixedDown (stream.read n); + var firstCrossing = -1; + var lastCrossing = -1; + var nCrossings = 0; + for [0..vec.length v - 2] do i: + if nCrossings < cycles and vec.at v i <= 0 and vec.at v (i+1) > 0 then + if firstCrossing < 0 then + firstCrossing := i; + fi; + lastCrossing := i; + nCrossings := nCrossings + 1; + fi; + done; + if nCrossings < 2 then 0 + else + cycle = (lastCrossing - firstCrossing) / (nCrossings - 1); + freq = sampleRate / cycle; + eprintln "lastCrossing = \(lastCrossing), firstCrossing = \(firstCrossing), dist = \(lastCrossing - firstCrossing), nCycles = \(nCrossings - 1), cycle = \(cycle), freq = \(freq)"; + freq; + fi); + _: failWith "Expected stream duration to be known"; + esac); + +testFrequencyIntegrity freq sourceRate targetRate = + (// Test that downsample and then upsample again produces a signal + // at the same frequency as the original (i.e. the overall speed + // is retained exactly, regardless of the SNR on the way). + nCycles = 5000; + duration = int (nCycles * sourceRate / freq); + originals = manip.duplicated 2 + (manip.withDuration duration (syn.sinusoid sourceRate freq)); + there = manip.duplicated 2 + (resample.resampledTo targetRate originals[0]); + back = resample.resampledTo sourceRate there[0]; + origFreq = measureFrequency sourceRate (nCycles - 2) originals[1]; + backFreq = measureFrequency sourceRate (nCycles - 2) back; + if not (compare backFreq origFreq) then + iFreq = measureFrequency targetRate (nCycles - 2) there[1]; + eprintln "** note: rate conversion \(sourceRate) -> \(targetRate) -> \(sourceRate)"; + eprintln "** frequency measured from intermediate stream: \(iFreq)"; + false + else + true + fi); + [ // Test for duration of decimated stream (does not test contents, that @@ -208,6 +257,30 @@ compareMatrices 1e-5 (mat.newRowVector b) (mat.newRowVector data); ), +"down-up-2": \( + testFrequencyIntegrity 440 44100 22050; +), + +"down-up-5": \( + testFrequencyIntegrity 440 44100 8820; +), + +"down-up-16": \( + testFrequencyIntegrity 440 48000 3000; +), + +"up-down-2": \( + testFrequencyIntegrity 440 44100 88200; +), + +"up-down-5": \( + testFrequencyIntegrity 440 9600 48000; +), + +"up-down-16": \( + testFrequencyIntegrity 440 3000 48000; +), + "same-rate": \( // Test that resample to the original rate leaves data unchanged data = vec.fromList [ 0, 0.1, -0.3, -0.4, -0.3, 0, 0.5, 0.2, 0.8, -0.1 ];