@@ -233,24 +233,34 @@ impl IIRFilterNode {
233
233
let nquist = sample_rate / 2. ;
234
234
235
235
for ( i, & f) in frequency_hz. iter ( ) . enumerate ( ) {
236
- let freq = f64:: from ( f) . clamp ( 0. , nquist) ;
237
- let z = -2.0 * PI * freq / sample_rate;
238
- let mut num: Complex < f64 > = Complex :: new ( 0. , 0. ) ;
239
- let mut denom: Complex < f64 > = Complex :: new ( 0. , 0. ) ;
236
+ let freq = f64:: from ( f) ;
237
+ // <https://webaudio.github.io/web-audio-api/#dom-iirfilternode-getfrequencyresponse>
238
+ // > If a value in the frequencyHz parameter is not within [0, sampleRate/2],
239
+ // > where sampleRate is the value of the sampleRate property of the AudioContext,
240
+ // > the corresponding value at the same index of the magResponse/phaseResponse
241
+ // > array MUST be NaN.
242
+ if freq < 0. || freq > nquist {
243
+ mag_response[ i] = f32:: NAN ;
244
+ phase_response[ i] = f32:: NAN ;
245
+ } else {
246
+ let z = -2.0 * PI * freq / sample_rate;
247
+ let mut num: Complex < f64 > = Complex :: new ( 0. , 0. ) ;
248
+ let mut denom: Complex < f64 > = Complex :: new ( 0. , 0. ) ;
240
249
241
- for ( idx, & b) in self . feedforward . iter ( ) . enumerate ( ) {
242
- num += Complex :: from_polar ( b, idx as f64 * z) ;
243
- }
250
+ for ( idx, & b) in self . feedforward . iter ( ) . enumerate ( ) {
251
+ num += Complex :: from_polar ( b, idx as f64 * z) ;
252
+ }
244
253
245
- for ( idx, & a) in self . feedback . iter ( ) . enumerate ( ) {
246
- denom += Complex :: from_polar ( a, idx as f64 * z) ;
247
- }
254
+ for ( idx, & a) in self . feedback . iter ( ) . enumerate ( ) {
255
+ denom += Complex :: from_polar ( a, idx as f64 * z) ;
256
+ }
248
257
249
- let response = num / denom;
258
+ let response = num / denom;
250
259
251
- let ( mag, phase) = response. to_polar ( ) ;
252
- mag_response[ i] = mag as f32 ;
253
- phase_response[ i] = phase as f32 ;
260
+ let ( mag, phase) = response. to_polar ( ) ;
261
+ mag_response[ i] = mag as f32 ;
262
+ phase_response[ i] = phase as f32 ;
263
+ }
254
264
}
255
265
}
256
266
}
@@ -897,4 +907,23 @@ mod tests {
897
907
let feedforward = vec ! [ b0, b1, b2] ;
898
908
compare_frequency_response ( BiquadFilterType :: Highshelf , feedback, feedforward) ;
899
909
}
910
+
911
+ #[ test]
912
+ fn test_frequency_response_invalid_frequencies ( ) {
913
+ let context = OfflineAudioContext :: new ( 2 , 555 , 44_100. ) ;
914
+ let options = IIRFilterOptions {
915
+ feedback : vec ! [ 1. ; 10 ] ,
916
+ feedforward : vec ! [ 1. ; 10 ] ,
917
+ audio_node_options : AudioNodeOptions :: default ( ) ,
918
+ } ;
919
+ let iir = IIRFilterNode :: new ( & context, options) ;
920
+
921
+ let frequency_hz = [ -1. , 22_051. ] ;
922
+ let mut mags = [ 0. ; 2 ] ;
923
+ let mut phases = [ 0. ; 2 ] ;
924
+
925
+ iir. get_frequency_response ( & frequency_hz, & mut mags, & mut phases) ;
926
+ mags. iter ( ) . for_each ( |v| assert ! ( v. is_nan( ) ) ) ;
927
+ phases. iter ( ) . for_each ( |v| assert ! ( v. is_nan( ) ) ) ;
928
+ }
900
929
}
0 commit comments