10 lines
52 KiB
JavaScript
10 lines
52 KiB
JavaScript
|
!/**
|
||
|
* Highcharts JS v11.4.1 (2024-04-04)
|
||
|
*
|
||
|
* Sonification module
|
||
|
*
|
||
|
* (c) 2010-2024 Highsoft AS
|
||
|
* Author: Øystein Moseng
|
||
|
*
|
||
|
* License: www.highcharts.com/license
|
||
|
*/function(e){"object"==typeof module&&module.exports?(e.default=e,module.exports=e):"function"==typeof define&&define.amd?define("highcharts/modules/sonification",["highcharts"],function(t){return e(t),e.Highcharts=t,e}):e("undefined"!=typeof Highcharts?Highcharts:void 0)}(function(e){"use strict";var t=e?e._modules:{};function i(e,t,i,n){e.hasOwnProperty(t)||(e[t]=n.apply(null,i),"function"==typeof CustomEvent&&window.dispatchEvent(new CustomEvent("HighchartsModuleLoaded",{detail:{path:t,module:e[t]}})))}i(t,"Extensions/Sonification/Options.js",[],function(){return{sonification:{enabled:!0,duration:6e3,afterSeriesWait:700,updateInterval:200,masterVolume:.7,order:"sequential",showTooltip:!0,showCrosshair:!0,pointGrouping:{enabled:!0,groupTimespan:15,algorithm:"minmax",prop:"y"},defaultInstrumentOptions:{roundToMusicalNotes:!0,instrument:"piano",mapping:{time:"x",pan:"x",noteDuration:200,pitch:{mapTo:"y",min:"c2",max:"c6",within:"yAxis"},gapBetweenNotes:100}},defaultSpeechOptions:{language:"en-US",mapping:{time:"x",rate:1.3,volume:.4},pointGrouping:{algorithm:"last"}}},exporting:{menuItemDefinitions:{downloadMIDI:{textKey:"downloadMIDI",onclick:function(){this.sonification&&this.sonification.downloadMIDI()}},playAsSound:{textKey:"playAsSound",onclick:function(){let e=this.sonification;e&&e.isPlaying()?e.cancel():this.sonify()}}}},lang:{downloadMIDI:"Download MIDI",playAsSound:"Play as sound"}}}),i(t,"Extensions/Sonification/SynthPatch.js",[t["Core/Utilities.js"]],function(e){let{clamp:t,defined:i,pick:n}=e;function s(e,t){return(.2414*e-.2414)*Math.log(t)+(3.5-1.7*e)/1.8}function o(e,t,i){e.gain.cancelScheduledValues(t),e.gain.setTargetAtTime(i,t,h.stopRampTime/4),e.gain.setValueAtTime(i,t+h.stopRampTime)}function a(e,t,i,n,s=1){let a="attack"===t,l=n.gain;if(l.cancelScheduledValues(i),!e.length){o(n,i,a?s:0);return}e[0].t>1&&e.unshift({t:0,vol:a?0:1}),e.forEach((t,n)=>{let o=e[n-1],a=o?(t.t-o.t)/1e3:0,r=i+(o?o.t/1e3+h.stopRampTime:0);l.setTargetAtTime(t.vol*s,r,Math.max(a,h.stopRampTime)/2)})}class l{constructor(e,t){this.pulseWidth=Math.min(Math.max(0,t.pulseWidth||.5));let i=()=>new OscillatorNode(e,{type:"sawtooth",detune:t.detune,frequency:Math.max(1,t.frequency||350)});this.sawOscA=i(),this.sawOscB=i(),this.phaseInverter=new GainNode(e,{gain:-1}),this.masterGain=new GainNode(e),this.delayNode=new DelayNode(e,{delayTime:this.pulseWidth/this.sawOscA.frequency.value}),this.sawOscA.connect(this.masterGain),this.sawOscB.connect(this.phaseInverter),this.phaseInverter.connect(this.delayNode),this.delayNode.connect(this.masterGain)}connect(e){this.masterGain.connect(e)}getFrequencyFacade(){let e=this;return{cancelScheduledValues:t=>(e.sawOscA.frequency.cancelScheduledValues(t),e.sawOscB.frequency.cancelScheduledValues(t),e.delayNode.delayTime.cancelScheduledValues(t),e.sawOscA.frequency),setValueAtTime(t,i){return this.cancelScheduledValues(i),e.sawOscA.frequency.setValueAtTime(t,i),e.sawOscB.frequency.setValueAtTime(t,i),e.delayNode.delayTime.setValueAtTime(Math.round(1e4*e.pulseWidth/t)/1e4,i),e.sawOscA.frequency},setTargetAtTime(t,i,n){return this.cancelScheduledValues(i),e.sawOscA.frequency.setTargetAtTime(t,i,n),e.sawOscB.frequency.setTargetAtTime(t,i,n),e.delayNode.delayTime.setTargetAtTime(Math.round(1e4*e.pulseWidth/t)/1e4,i,n),e.sawOscA.frequency}}}getPWMTarget(){return this.delayNode.delayTime}start(){this.sawOscA.start(),this.sawOscB.start()}stop(e){this.sawOscA.stop(e),this.sawOscB.stop(e)}}class r{constructor(e,t,i){this.audioContext=e,this.options=t,this.fmOscillatorIx=t.fmOscillator,this.vmOscillatorIx=t.vmOscillator,this.createSoundSource(),this.createGain(),this.createFilters(),this.createVolTracking(),i&&this.connect(i)}connect(e){[this.lowpassNode,this.highpassNode,this.volTrackingNode,this.vmNode,this.gainNode,this.whiteNoise,this.pulseNode,this.oscNode].reduce((e,t)=>t?(t.connect(e),t):e,e)}start(){this.oscNode&&this.oscNode.start(),this.whiteNoise&&this.whiteNoise.start(),this.pulseNode&&this.pulseNode.start()}stopAtTime(e){this.oscNode&&this.oscNode.stop(e),this.whiteNoise&&this.whiteNoise.stop(e),
|