import { assignNativeAudioNodeAudioParamValue } from '../helpers/assign-native-audio-node-audio-param-value'; import { assignNativeAudioNodeOption } from '../helpers/assign-native-audio-node-option'; import { assignNativeAudioNodeOptions } from '../helpers/assign-native-audio-node-options'; import { wrapAudioScheduledSourceNodeStartMethodNegativeParameters } from '../helpers/wrap-audio-scheduled-source-node-start-method-negative-parameters'; import { wrapAudioScheduledSourceNodeStopMethodNegativeParameters } from '../helpers/wrap-audio-scheduled-source-node-stop-method-negative-parameters'; import { TNativeOscillatorNodeFactoryFactory } from '../types'; export const createNativeOscillatorNodeFactory: TNativeOscillatorNodeFactoryFactory = ( addSilentConnection, cacheTestResult, testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport, testAudioScheduledSourceNodeStopMethodNegativeParametersSupport, wrapAudioScheduledSourceNodeStopMethodConsecutiveCalls ) => { return (nativeContext, options) => { const nativeOscillatorNode = nativeContext.createOscillator(); assignNativeAudioNodeOptions(nativeOscillatorNode, options); assignNativeAudioNodeAudioParamValue(nativeOscillatorNode, options, 'detune'); assignNativeAudioNodeAudioParamValue(nativeOscillatorNode, options, 'frequency'); if (options.periodicWave !== undefined) { nativeOscillatorNode.setPeriodicWave(options.periodicWave); } else { assignNativeAudioNodeOption(nativeOscillatorNode, options, 'type'); } // Bug #44: Only Chrome & Edge throw a RangeError yet. if ( !cacheTestResult(testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, () => testAudioScheduledSourceNodeStartMethodNegativeParametersSupport(nativeContext) ) ) { wrapAudioScheduledSourceNodeStartMethodNegativeParameters(nativeOscillatorNode); } // Bug #19: Safari does not ignore calls to stop() of an already stopped AudioBufferSourceNode. if ( !cacheTestResult(testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport, () => testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport(nativeContext) ) ) { wrapAudioScheduledSourceNodeStopMethodConsecutiveCalls(nativeOscillatorNode, nativeContext); } // Bug #44: Only Firefox does not throw a RangeError yet. if ( !cacheTestResult(testAudioScheduledSourceNodeStopMethodNegativeParametersSupport, () => testAudioScheduledSourceNodeStopMethodNegativeParametersSupport(nativeContext) ) ) { wrapAudioScheduledSourceNodeStopMethodNegativeParameters(nativeOscillatorNode); } // Bug #175: Safari will not fire an ended event if the OscillatorNode is unconnected. addSilentConnection(nativeContext, nativeOscillatorNode); return nativeOscillatorNode; }; };