@@ -57,14 +57,20 @@ impl Yin {
5757 }
5858 }
5959
60- pub fn yin ( & self , frequencies : & [ f64 ] ) -> YinResult {
60+ pub fn yin ( & self , frequencies : & [ f64 ] ) -> Result < YinResult , String > {
6161 let df = difference_function_values ( frequencies, self . max_lag ) ;
6262 let cmndf = cumulative_mean_normalized_difference_function ( & df, self . max_lag ) ;
6363 let best_lag = find_cmndf_argmin ( & cmndf, self . min_lag , self . max_lag , self . threshold ) ;
64- YinResult {
65- sample_rate : self . sample_rate ,
66- best_lag,
67- cmndf,
64+ match best_lag {
65+ _ if best_lag == 0 => Err ( format ! (
66+ "Could not find lag value which minimizes CMNDF below the given threshold {}" ,
67+ self . threshold
68+ ) ) ,
69+ _ => Ok ( YinResult {
70+ sample_rate : self . sample_rate ,
71+ best_lag,
72+ cmndf,
73+ } ) ,
6874 }
6975 }
7076}
@@ -162,20 +168,23 @@ mod tests {
162168 max_expected_frequency,
163169 sample_rate,
164170 ) ;
171+
165172 let result = yin. yin ( signal. as_slice ( ) ) ;
173+ assert ! ( result. is_ok( ) ) ;
174+ let yin_result = result. unwrap ( ) ;
166175
167176 assert ! ( diff_from_actual_frequency_smaller_than_threshold(
168- result . get_frequency( ) ,
177+ yin_result . get_frequency( ) ,
169178 frequency,
170179 1.0
171180 ) ) ;
172181 assert ! ( diff_from_actual_frequency_smaller_than_threshold(
173- result . get_frequency_with_interpolation( ) ,
182+ yin_result . get_frequency_with_interpolation( ) ,
174183 frequency,
175184 1.0 ,
176185 ) ) ;
177186
178- assert ! ( interpolation_better_than_raw_result( result , frequency) ) ;
187+ assert ! ( interpolation_better_than_raw_result( yin_result , frequency) ) ;
179188 }
180189
181190 #[ test]
@@ -196,22 +205,24 @@ mod tests {
196205 sample_rate,
197206 ) ;
198207 let result = yin. yin ( signal. as_slice ( ) ) ;
208+ assert ! ( result. is_ok( ) ) ;
209+ let yin_result = result. unwrap ( ) ;
199210
200211 if ( sample_rate as i32 % freq) == 0 {
201- assert_eq ! ( result . get_frequency( ) , frequency) ;
212+ assert_eq ! ( yin_result . get_frequency( ) , frequency) ;
202213 } else {
203214 assert ! ( diff_from_actual_frequency_smaller_than_threshold(
204- result . get_frequency( ) ,
215+ yin_result . get_frequency( ) ,
205216 frequency,
206217 1.0
207218 ) ) ;
208219 assert ! ( diff_from_actual_frequency_smaller_than_threshold(
209- result . get_frequency_with_interpolation( ) ,
220+ yin_result . get_frequency_with_interpolation( ) ,
210221 frequency,
211222 1.0 ,
212223 ) ) ;
213224
214- assert ! ( interpolation_better_than_raw_result( result , frequency) ) ;
225+ assert ! ( interpolation_better_than_raw_result( yin_result , frequency) ) ;
215226 }
216227 }
217228 }
@@ -243,9 +254,11 @@ mod tests {
243254 . collect ( ) ;
244255
245256 let result = yin. yin ( & combined_signal) ;
257+ assert ! ( result. is_ok( ) ) ;
258+ let yin_result = result. unwrap ( ) ;
246259
247260 assert ! ( diff_from_actual_frequency_smaller_than_threshold(
248- result . get_frequency( ) ,
261+ yin_result . get_frequency( ) ,
249262 frequency_1,
250263 1.0
251264 ) ) ;
@@ -278,16 +291,48 @@ mod tests {
278291 . collect ( ) ;
279292
280293 let result = yin. yin ( & combined_signal) ;
294+ assert ! ( result. is_ok( ) ) ;
295+ let yin_result = result. unwrap ( ) ;
281296
282297 let expected_frequency = ( frequency_1 - frequency_2) . abs ( ) ;
283298 assert ! ( diff_from_actual_frequency_smaller_than_threshold(
284- result . get_frequency( ) ,
299+ yin_result . get_frequency( ) ,
285300 expected_frequency,
286301 1.0
287302 ) ) ;
288303 assert ! ( interpolation_better_than_raw_result(
289- result ,
304+ yin_result ,
290305 expected_frequency
291306 ) ) ;
292307 }
308+
309+ #[ test]
310+ fn test_err ( ) {
311+ let sample_rate = 2500.0 ;
312+ let seconds = 2.0 ;
313+ let frequency = 440.0 ;
314+
315+ // Can't find frequency 440 between 500 and 700
316+ let min_expected_frequency = 500.0 ;
317+ let max_expected_frequency = 700.0 ;
318+ let yin = Yin :: init (
319+ 0.1 ,
320+ min_expected_frequency,
321+ max_expected_frequency,
322+ sample_rate,
323+ ) ;
324+
325+ let signal = generate_sine_wave ( frequency, sample_rate, seconds) ;
326+ let result = yin. yin ( & signal) ;
327+ assert ! ( result. is_err( ) ) ;
328+
329+ let yin_with_suitable_frequency_range = Yin :: init (
330+ 0.1 ,
331+ min_expected_frequency - 100.0 ,
332+ max_expected_frequency,
333+ sample_rate,
334+ ) ;
335+ let result = yin_with_suitable_frequency_range. yin ( & signal) ;
336+ assert ! ( result. is_ok( ) ) ;
337+ }
293338}
0 commit comments