From 0f61cd57963897931cb02857f063c673da5e4e38 Mon Sep 17 00:00:00 2001 From: Maikiwi Date: Thu, 4 Aug 2022 00:01:38 -0700 Subject: [PATCH] lel --- src/main/base/browserwindow.ts | 8 + src/renderer/audio/audio.js | 26 +- src/renderer/audio/impulses/CAP_64.wav | Bin 34604 -> 34604 bytes .../audio/impulses/OptimizerDirac32_96.wav | Bin 0 -> 384046 bytes src/renderer/audio/renderer.js | 963 ++++++++++++++++++ 5 files changed, 984 insertions(+), 13 deletions(-) create mode 100644 src/renderer/audio/impulses/OptimizerDirac32_96.wav create mode 100644 src/renderer/audio/renderer.js diff --git a/src/main/base/browserwindow.ts b/src/main/base/browserwindow.ts index 76f36346..fecfc336 100644 --- a/src/main/base/browserwindow.ts +++ b/src/main/base/browserwindow.ts @@ -512,6 +512,14 @@ export class BrowserWindow { } }); + app.get("/audio/cideraudiorenderer.js", (_req, res) => { + if (existsSync(join(utils.getPath("externals"), "/renderer.js"))) { + res.sendFile(join(utils.getPath("externals"), "/renderer.js")); + } else { + res.sendFile(join(utils.getPath('srcPath'), "./renderer/audio/renderer.js")); + } + }) + app.get("/cideraudio/impulses/:file", (req, res) => { const impulseExternals = join(utils.getPath("externals"), "/impulses/"); const impulseFile = join(impulseExternals, req.params.file); diff --git a/src/renderer/audio/audio.js b/src/renderer/audio/audio.js index 9d20e37b..cf022a7f 100644 --- a/src/renderer/audio/audio.js +++ b/src/renderer/audio/audio.js @@ -392,7 +392,7 @@ const CiderAudio = { } ]; } - + constructor() { super(); this._bufferSize = 1024; @@ -405,15 +405,15 @@ const CiderAudio = { this._buffers.push(new Float32Array(this._bufferSize)); } } - + _initBuffer() { this._bytesWritten = 0; } - + _isBufferEmpty() { return this._bytesWritten === 0; } - + _isBufferFull() { return this._bytesWritten === this._bufferSize; } @@ -430,7 +430,7 @@ const CiderAudio = { this._bytesWritten += 1; } } - + _flush() { let buffers = []; this._buffers.forEach((buffer, channel) => { @@ -446,28 +446,28 @@ const CiderAudio = { }); this._initBuffer(); } - + _recordingStopped() { this.port.postMessage({ eventType: 'stop' }); } - + process(inputs, outputs, parameters) { const isRecordingValues = parameters.isRecording; - const numberOfChannels = parameters.numberOfChannels[0]; + const numberOfChannels = parameters.numberOfChannels[0]; if (this._buffers === null) { this._initBuffers(numberOfChannels); } - - for (let dataIndex = 0; dataIndex < isRecordingValues.length; dataIndex++) + + for (let dataIndex = 0; dataIndex < isRecordingValues.length; dataIndex++) { const shouldRecord = isRecordingValues[dataIndex] === 1; if (!shouldRecord && !this._isBufferEmpty()) { this._flush(); this._recordingStopped(); } - + if (shouldRecord) { let audioRawData = inputs[0]; this._pushToBuffers(audioRawData, numberOfChannels); @@ -475,9 +475,9 @@ const CiderAudio = { } return true; } - + } - + registerProcessor('recorder-worklet', RecorderWorkletProcessor);`; let blob = new Blob([worklet], { type: "application/javascript" }); await CiderAudio.context.audioWorklet.addModule(URL.createObjectURL(blob)).then(() => { diff --git a/src/renderer/audio/impulses/CAP_64.wav b/src/renderer/audio/impulses/CAP_64.wav index ac60adcc1b2ffdd584a2b46563f97c780e05d807..4a5eb93a368935f015d0de30ac965b25ac1e8095 100644 GIT binary patch literal 34604 zcmX8bcU(^I8wc_Uj^4}O>J;fs+rj8b{{kh*Pm5~OGd}bJG3o#y#%T?R>PFWs7@~T zf+MkHSvGvv7~uL17IrmuT?yI-Ec>Mw%NBL9cP)UX-yUUep_^xbLIZ|Bo#r|M9__j4 z`T&Z|UCK+KDY#srl(V$LH5c~&N$)Vey;HeThY`TLdWK;jO@H4fh1iF0j+>XaYs z6WG$&LlFZJ`6J7=!XWl&2iNSY3L4_nCc4JM(}*V>T;0Q5-5~G321O}+n027+6Vzp% z?2y*0kj;RBx8HS0(dO9$(03!p8bijUi)=DX*m;Z{2STv*Tf!M*uqpxUHiVCm=&V zrA&!=X+TtrtpUBY*A?Ai;VI*?1rRVGoQkv!r=%|h3I!|*k+FfWHOR_! z3!FOG$mW7ZbE?7s;x;X2cf#HqQS3ozO*q27ht#CB4s6CAmWGXXT@)K&|LPme9vE_a z0_z16@@FeNAbH|5#bFo}@j@{W0s=27=7MJ0FNF$}SrjNP!%yQo(l780nXCwexK&Z? zZs@uECu;)5gqG_GAPyz4p76vvg?$Pq9L}&O;mg6DV$VZ6#RW;OirMhDbA&=&EkZGM z-%jZe49)n;I>Vgc$I>3Suk%6i0Jf}+Vb*|b=^@4r`e+v^dO~mJj=~T|rXNvwfVs0w z(E~mxq8Ry&%<9Ck^We{n8|+^o%uHE3@SLE-PJ`L=x3E*;r&>|CZ$iCL!DwB@}b65PY` zq-mfgj_Z%IGT44QU6BBh#!n?4PGoSrn91=kvfokX zPrjp~{8vb}kWadc{U~=)HGGZY@76VnWu6DvrEqoUbM`JIm1K7??qkgMhRdf?*z+*V zYBx(k@p(Q789EYW(XSPWMeJ1efhz6-&M z?Jzg&j$#gMAg3x;!sTPuiU+_~s+K8b+wN1Gh7;|c%mtXaQC~3?_KiQLNCn@wf0%i2 z!gDlx5YDHKkrH9p1%K8F9{F@-pF`6_BZbm&ht=$UkfuFnc`z;2Wvt+r{tm?#@b=q5 z<;~wg<;?8QX2QWS2}~{omb_+In3reAdcwe3dqxACes5!3z*v^c{C3G@tXFuk=Fqgn zl>Go}T@$IkY$6qK*_&|zho)?14G>mcB|mVqcr4jKoB9k%O=E^MIBqjD2rdoxkZwY+ zQZI!HSgxO>m<4|;$17B;#w+4(4^d>pzll>6ZJ;>ZBz=T!wO6DhxW4_6bOl~T&mmv! zn?r8w*2v5OjWS(DUtqds3NoEc;a2N@<`TR-aFPx^c#@8Dd?BudmG0isR@id2Q3`}l z=YI$l7k&tD(+9F&;nDZ|lIoB9(&Em$#3!A0iN=M)*gjDCBwH#2+abfHVW9c48`}l+ z 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 QR@b+1F2L!7E?EZt2VCd(t^fc4 literal 34604 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 diff --git a/src/renderer/audio/impulses/OptimizerDirac32_96.wav b/src/renderer/audio/impulses/OptimizerDirac32_96.wav new file mode 100644 index 0000000000000000000000000000000000000000..74d324268f7c6ccc21cd783c7d9fa4d200933900 GIT binary patch literal 384046 zcmeIuF$%&^5CqWC5D@GqXY5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ tfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB=C%2yE>l3OoP+ literal 0 HcmV?d00001 diff --git a/src/renderer/audio/renderer.js b/src/renderer/audio/renderer.js new file mode 100644 index 00000000..da2d12e9 --- /dev/null +++ b/src/renderer/audio/renderer.js @@ -0,0 +1,963 @@ +const CiderAudioRenderer = { + context: null, + source: null, + audioNodes: { + gainNode: null, + spatialNode: null, + audioBands: null, + vibrantbassNode: null, + llpw: null, + recorderNode: null, + intelliGainComp: null, + atmosphereRealizer2: null, + atmosphereRealizer1: null, + opportunisticCorrection: null + }, + off: function () { + CiderAudioRenderer.hierarchical_unloading(); + try { + CiderAudioRenderer.audioNodes = { + gainNode: null, + spatialNode: null, + audioBands: null, + vibrantbassNode: null, + llpw: null, + recorderNode: null, + intelliGainComp: null, + atmosphereRealizer2: null, + atmosphereRealizer1: null, + opportunisticCorrection: null + } + } catch (e) { } + }, + init: function () { + CiderAudioRenderer.context = new OfflineAudioContext({ + numberOfChannels: 2, + length: 96000 * 8, + sampleRate: 96000, + }) + CiderAudioRenderer.hierarchical_loading(); + }, + optimizerProfile: [ + { + "id": 'dirac32_96', + "file": './cideraudio/impulses/OptimizerDirac32_96.wav', + "bitDepth": 32, + "sampleRate": 96000, + "container": "WAV" + } + ], + spatialProfiles: [ + { + "id": "maikiwi", + "file": './cideraudio/impulses/CiderSpatial_Maikiwi.wav', + "name": "Maikiwi", + "description": "", + "gainComp": "1.044" + }, + { + "id": "maikiwiplus", + "file": './cideraudio/impulses/CiderSpatial_MaikiwiPlus.wav', + "name": "Maikiwi+", + "description": "", + "gainComp": "1.044" + }, + { + "id": "71_420maikiwi", + "file": './cideraudio/impulses/CiderSpatial_v71.420_Maikiwi.wav', + "name": "Soundstage", + "description": "", + "gainComp": "1.3963683610559376" + }, + { + "id": "70_422maikiwi", + "file": './cideraudio/impulses/CiderSpatial_v70.422_Maikiwi.wav', + "name": "Separation", + "description": "", + "gainComp": "1.30767553892022" + }, + { + "id": "standard", + "file": './cideraudio/impulses/CiderSpatial_Natural.wav', + "name": "Minimal", + "description": "", + "gainComp": "1.044" + }, + { + "id": "standardplus", + "file": './cideraudio/impulses/CiderSpatial_Natural+.wav', + "name": "Minimal+", + "description": "", + "gainComp": "1.044" + }, + { + "id": "diffused", + "file": './cideraudio/impulses/CiderSpatial_Diffuse.wav', + "name": "Diffused", + "description": "", + "gainComp": "1.044" + }, + { + "id": "BPLK", + "file": './cideraudio/impulses/CiderSpatial_BPLK.wav', + "name": "BPLK", + "description": "", + "gainComp": "1.044" + }, + { + "id": "HW2K", + "file": './cideraudio/impulses/CiderSpatial_HW2K.wav', + "name": "HW2K", + "description": "", + "gainComp": "1.044" + }, + { + "id": "live", + "file": './cideraudio/impulses/CiderSpatial_LIVE_2.wav', + "name": "live", + "description": "", + "gainComp": "1.2647363474711515" + } + ], + atmosphereRealizerProfiles: [ + { + "id": "NATURAL_STANDARD", + "file": './cideraudio/impulses/AtmosphereRealizer_NaturalStandard.wav', + "name": "ほうじ茶チーズクリーマティー", + "description": "", + }, + { + "id": "NATURAL_PLUS", + "file": './cideraudio/impulses/AtmosphereRealizer_Natural+.wav', + "name": "玄米茶タピオカミルクティー", + "description": "", + }, + { + "id": "E68_1", + "file": './cideraudio/impulses/AtmosphereRealizer_E68_1.5.wav', + "name": "岩塩クリームチーズティー", + "description": "Light", + }, + { + "id": "E68_2", + "file": './cideraudio/impulses/AtmosphereRealizer_E68_2.2.wav', + "name": "抹茶ミルクティー", + "description": "Dark", + }, + { + "id": "BSCBM", + "file": './cideraudio/impulses/AtmosphereRealizer_BSCBM.wav', + "name": "BSCBM", + "description": "BSCBM", + }, + { + "id": "CUDDLE", + "file": './cideraudio/impulses/AtmosphereRealizer_Cuddle.wav', + "name": "CUDDLE", + "description": "CUDDLE", + }, + { + "id": "E168_1", + "file": './cideraudio/impulses/AtmosphereRealizer_E168_1.2.wav', + "name": "春毫ジャスミンマキアート", + "description": "Natural Air", + }, + { + "id": "Z3600", + "file": './cideraudio/impulses/AtmosphereRealizer_Z3600.wav', + "name": "ロイヤルミルクティー", + "description": "3600", + }, + { + "id": "Z8500A", + "file": './cideraudio/impulses/AtmosphereRealizer_Z8500_A.wav', + "name": "ムーンライトソフトケーキ", + "description": "8500", + }, + { + "id": "Z8500B", + "file": './cideraudio/impulses/AtmosphereRealizer_Z8500_B.wav', + "name": "Clafoutis aux Cerises", + "description": "8500", + }, + { + "id": "Z8500C", + "file": './cideraudio/impulses/AtmosphereRealizer_Z8500_C.wav', + "name": "宇治抹茶だいふく", + "description": "8500", + } + ], + opportunisticCorrectionProfiles: [ + { + "id": "CHU", + "file": './cideraudio/impulses/MoondropCHU_Cider.wav', + "name": "Moondrop CHU Specific", + "description": "", + } + ], + spatial_ninf: function () { + CiderAudioRenderer.audioNodes.spatialNode = null; + CiderAudioRenderer.audioNodes.spatialNode = CiderAudioRenderer.context.createConvolver(); + CiderAudioRenderer.audioNodes.spatialNode.normalize = false; + + let spatialProfile = CiderAudioRenderer.spatialProfiles.find(function (profile) { + return profile.id === app.cfg.audio.maikiwiAudio.spatialProfile; + }); + + if (spatialProfile === undefined) { + spatialProfile = CiderAudioRenderer.spatialProfiles[0]; + } + fetch(spatialProfile.file).then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudioRenderer.audioNodes.spatialNode.buffer = await CiderAudioRenderer.context.decodeAudioData(bufferedImpulse); + }); + + // Always destination + CiderAudioRenderer.audioNodes.spatialNode.connect(CiderAudioRenderer.context.destination) + + + }, + spatialOff: function () { + CiderAudioRenderer.hierarchical_loading(); + }, + intelliGainComp_n0_0: function () { + let filters = []; const precisionHz = 12; + // Biquad calculation + if (CiderAudioRenderer.audioNodes.audioBands !== null) { filters = filters.concat(CiderAudioRenderer.audioNodes.audioBands) } + if (CiderAudioRenderer.audioNodes.vibrantbassNode !== null) { filters = filters.concat(CiderAudioRenderer.audioNodes.vibrantbassNode) } + if (CiderAudioRenderer.audioNodes.llpw !== null && CiderAudioRenderer.audioNodes.llpw.length > 2) { filters = filters.concat(CiderAudioRenderer.audioNodes.llpw); } + + if (!filters || filters.length === 0) { + let filterlessGain = 1; + // Impulse Calculation + if (CiderAudioRenderer.audioNodes.llpw !== null && CiderAudioRenderer.audioNodes.llpw.length <= 2) { filterlessGain = filterlessGain * 1.109174815262401 } + if (app.cfg.audio.maikiwiAudio.atmosphereRealizer2 === true) { filterlessGain = filterlessGain * 1.096478196143185 } + if (app.cfg.audio.maikiwiAudio.atmosphereRealizer1 === true) { filterlessGain = filterlessGain * 1.096478196143185 } + if (app.cfg.audio.maikiwiAudio.spatial == true) { + let spatialProfile = CiderAudioRenderer.spatialProfiles.find(function (profile) { + return profile.id === app.cfg.audio.maikiwiAudio.spatialProfile; + }); + if (spatialProfile === undefined) { + spatialProfile = CiderAudioRenderer.spatialProfiles[0]; + } + filterlessGain = filterlessGain * spatialProfile.gainComp + } + filterlessGain = Math.pow(10, (-1 * (20 * Math.log10(filterlessGain))) / 20).toFixed(4); + filterlessGain > 1.0 ? CiderAudioRenderer.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(1.0, CiderAudioRenderer.context.currentTime + 0.3) : CiderAudioRenderer.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(filterlessGain, CiderAudioRenderer.context.currentTime + 0.3); + console.debug(`[Cider][Audio] IntelliGainComp: ${filterlessGain > 1.0 ? 0 : (20 * Math.log10(filterlessGain)).toFixed(2)} dB (${filterlessGain > 1.0 ? 1 : filterlessGain})`) + return; + } + + filters.shift(); + let steps = Math.ceil(96000 / precisionHz); + // Generate input array for getFrequencyResponse method + let frequencies = new Float32Array(steps); + for (let i = 0; i < steps; i++) { + frequencies[i] = (i + 1) * precisionHz; + } + // Here we will store combined amplitude response + let totalAmplitudeResp = new Float32Array(steps); + for (let i = 0; i < steps; i++) { + totalAmplitudeResp[i] = 1; + } + // Temporary container for every filter response + let amplitudeResp = new Float32Array(steps), phaseResp = new Float32Array(steps); + for (let i = filters.length - 1; i >= 0; i--) { + let filter = filters[i]; + // Get filter response and convolve it with existing response + filter.getFrequencyResponse(frequencies, amplitudeResp, phaseResp); + for (let j = 0; j < steps; j++) { + totalAmplitudeResp[j] *= amplitudeResp[j]; + } + } + // Find max gain + let maxGain = -120 + for (let i = 0; i < steps; i++) { + let gain = totalAmplitudeResp[i]; + if (gain > maxGain) + maxGain = gain; + } + + // Impulse Calculation + if (CiderAudioRenderer.audioNodes.llpw !== null && CiderAudioRenderer.audioNodes.llpw.length <= 2) { maxGain = maxGain * 1.109174815262401 } + if (app.cfg.audio.maikiwiAudio.atmosphereRealizer2 === true) { maxGain = maxGain * 1.096478196143185 } + if (app.cfg.audio.maikiwiAudio.atmosphereRealizer1 === true) { maxGain = maxGain * 1.096478196143185 } + if (app.cfg.audio.maikiwiAudio.spatial == true) { + let spatialProfile = CiderAudioRenderer.spatialProfiles.find(function (profile) { + return profile.id === app.cfg.audio.maikiwiAudio.spatialProfile; + }); + if (spatialProfile === undefined) { + spatialProfile = CiderAudioRenderer.spatialProfiles[0]; + } + maxGain = maxGain * spatialProfile.gainComp + } + maxGain = Math.pow(10, (-1 * (20 * Math.log10(maxGain))) / 20).toFixed(4); + maxGain > 1.0 ? CiderAudioRenderer.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(1.0, CiderAudioRenderer.context.currentTime + 0.3) : CiderAudioRenderer.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(maxGain, CiderAudioRenderer.context.currentTime + 0.3); + console.debug(`[Cider][Audio] IntelliGainComp: ${maxGain > 1.0 ? 0 : (20 * Math.log10(maxGain)).toFixed(2)} dB (${maxGain > 1.0 ? 1 : maxGain})`); + }, + atmosphereRealizer2_n6: function (status, destination) { + if (status === true) { + CiderAudioRenderer.audioNodes.atmosphereRealizer2 = CiderAudioRenderer.context.createConvolver(); + CiderAudioRenderer.audioNodes.atmosphereRealizer2.normalize = false; + let atmosphereRealizerProfile = CiderAudioRenderer.atmosphereRealizerProfiles.find(function (profile) { + return profile.id === app.cfg.audio.maikiwiAudio.atmosphereRealizer2_value; + }); + + if (atmosphereRealizerProfile === undefined) { + atmosphereRealizerProfile = CiderAudioRenderer.atmosphereRealizerProfiles[0]; + } + fetch(atmosphereRealizerProfile.file).then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudioRenderer.audioNodes.atmosphereRealizer2.buffer = await CiderAudioRenderer.context.decodeAudioData(bufferedImpulse); + }); + + switch (destination) { + case "spatial": + try { CiderAudioRenderer.audioNodes.atmosphereRealizer2.connect(CiderAudioRenderer.audioNodes.spatialNode); console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> Spatial");} catch (e) { } + break; + case "n6": + try { + CiderAudioRenderer.audioNodes.atmosphereRealizer2.connect(CiderAudioRenderer.audioNodes.atmosphereRealizer2); + console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> atmosphereRealizer2"); + } catch (e) { } + break; + case 'n5': + try { + CiderAudioRenderer.audioNodes.atmosphereRealizer2.connect(CiderAudioRenderer.audioNodes.atmosphereRealizer1); + console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> atmosphereRealizer1"); + } catch (e) { } + break; + case 'n4': + try { + CiderAudioRenderer.audioNodes.atmosphereRealizer2.connect(CiderAudioRenderer.audioNodes.vibrantbassNode[0]); + console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> vibrantbassNode"); + } catch (e) { } + break; + case 'n3': + try { + CiderAudioRenderer.audioNodes.atmosphereRealizer2.connect(CiderAudioRenderer.audioNodes.audioBands[0]); + console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> audioBands"); + } catch (e) { } + break; + case 'n2': + try { + CiderAudioRenderer.audioNodes.atmosphereRealizer2.connect(CiderAudioRenderer.audioNodes.opportunisticCorrection); + console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> opportunisticCorrection"); + } catch (e) { } + break; + case 'n1': + try { + CiderAudioRenderer.audioNodes.atmosphereRealizer2.connect(CiderAudioRenderer.audioNodes.llpw[0]); + console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> llpw"); + } catch (e) { } + break; + case 'n0': + try { CiderAudioRenderer.audioNodes.atmosphereRealizer2.connect(CiderAudioRenderer.context.destination); console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> destination");} catch (e) { } + break; + + } + + + } + }, + atmosphereRealizer1_n5: function (status, destination) { + if (status === true) { + CiderAudioRenderer.audioNodes.atmosphereRealizer1 = CiderAudioRenderer.context.createConvolver(); + CiderAudioRenderer.audioNodes.atmosphereRealizer1.normalize = false; + let atmosphereRealizerProfile = CiderAudioRenderer.atmosphereRealizerProfiles.find(function (profile) { + return profile.id === app.cfg.audio.maikiwiAudio.atmosphereRealizer1_value; + }); + + if (atmosphereRealizerProfile === undefined) { + atmosphereRealizerProfile = CiderAudioRenderer.atmosphereRealizerProfiles[0]; + } + fetch(atmosphereRealizerProfile.file).then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudioRenderer.audioNodes.atmosphereRealizer1.buffer = await CiderAudioRenderer.context.decodeAudioData(bufferedImpulse); + }); + + switch (destination) { + case "spatial": + try { CiderAudioRenderer.audioNodes.atmosphereRealizer1.connect(CiderAudioRenderer.audioNodes.spatialNode); console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> Spatial");} catch (e) { } + break; + case "n6": + try { + CiderAudioRenderer.audioNodes.atmosphereRealizer1.connect(CiderAudioRenderer.audioNodes.atmosphereRealizer2); + console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> atmosphereRealizer2"); + } catch (e) { } + break; + case 'n5': + try { + CiderAudioRenderer.audioNodes.atmosphereRealizer1.connect(CiderAudioRenderer.audioNodes.atmosphereRealizer1); + console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> atmosphereRealizer1"); + } catch (e) { } + break; + case 'n4': + try { + CiderAudioRenderer.audioNodes.atmosphereRealizer1.connect(CiderAudioRenderer.audioNodes.vibrantbassNode[0]); + console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> vibrantbassNode"); + } catch (e) { } + break; + case 'n3': + try { + CiderAudioRenderer.audioNodes.atmosphereRealizer1.connect(CiderAudioRenderer.audioNodes.audioBands[0]); + console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> audioBands"); + } catch (e) { } + break; + case 'n2': + try { + CiderAudioRenderer.audioNodes.atmosphereRealizer1.connect(CiderAudioRenderer.audioNodes.opportunisticCorrection); + console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> opportunisticCorrection"); + } catch (e) { } + break; + case 'n1': + try { + CiderAudioRenderer.audioNodes.atmosphereRealizer1.connect(CiderAudioRenderer.audioNodes.llpw[0]); + console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> llpw"); + } catch (e) { } + break; + case 'n0': + try { CiderAudioRenderer.audioNodes.atmosphereRealizer1.connect(CiderAudioRenderer.context.destination); console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> destination");} catch (e) { } + break; + + } + + + } + }, + opportunisticCorrection_n2: function (status, destination) { + if (status === true) { + CiderAudioRenderer.audioNodes.opportunisticCorrection = CiderAudioRenderer.context.createConvolver(); + CiderAudioRenderer.audioNodes.opportunisticCorrection.normalize = false; + let opportunisticCorrectionProfile = CiderAudioRenderer.opportunisticCorrectionProfiles.find(function (profile) { + return profile.id === app.cfg.audio.maikiwiAudio.opportunisticCorrection_state; + }); + + if (opportunisticCorrectionProfile === undefined) { + opportunisticCorrectionProfile = CiderAudioRenderer.opportunisticCorrectionProfiles[0]; + } + fetch(opportunisticCorrectionProfile.file).then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudioRenderer.audioNodes.opportunisticCorrection.buffer = await CiderAudioRenderer.context.decodeAudioData(bufferedImpulse); + }); + + switch (destination) { + case "spatial": + try { CiderAudioRenderer.audioNodes.opportunisticCorrection.connect(CiderAudioRenderer.audioNodes.spatialNode); console.debug("[Cider][Audio] opportunisticCorrection_n2 -> Spatial");} catch (e) { } + break; + case "n6": + try { + CiderAudioRenderer.audioNodes.opportunisticCorrection.connect(CiderAudioRenderer.audioNodes.atmosphereRealizer2); + console.debug("[Cider][Audio] opportunisticCorrection_n2 -> atmosphereRealizer2"); + } catch (e) { } + break; + case 'n5': + try { + CiderAudioRenderer.audioNodes.opportunisticCorrection.connect(CiderAudioRenderer.audioNodes.atmosphereRealizer1); + console.debug("[Cider][Audio] opportunisticCorrection_n2 -> atmosphereRealizer1"); + } catch (e) { } + break; + case 'n4': + try { CiderAudioRenderer.audioNodes.opportunisticCorrection.connect(CiderAudioRenderer.audioNodes.vibrantbassNode[0]); + console.debug("[Cider][Audio] opportunisticCorrection_n2 -> vibrantbassNode");} catch (e) { } + break; + case 'n3': + try { CiderAudioRenderer.audioNodes.opportunisticCorrection.connect(CiderAudioRenderer.audioNodes.audioBands[0]); console.debug("[Cider][Audio] opportunisticCorrection_n2 -> audioBands");} catch (e) { } + break; + case 'n2': + try { + CiderAudioRenderer.audioNodes.opportunisticCorrection.connect(CiderAudioRenderer.audioNodes.opportunisticCorrection); + console.debug("[Cider][Audio] opportunisticCorrection_n2 -> opportunisticCorrection"); + } catch (e) { } + break; + case 'n1': + try { + CiderAudioRenderer.audioNodes.opportunisticCorrection.connect(CiderAudioRenderer.audioNodes.opportunisticCorrection[0]); + console.debug("[Cider][Audio] opportunisticCorrection_n2 -> opportunisticCorrection"); + } catch (e) { } + break; + case 'n0': + try { CiderAudioRenderer.audioNodes.opportunisticCorrection.connect(CiderAudioRenderer.context.destination); console.debug("[Cider][Audio] opportunisticCorrection_n2 -> destination");} catch (e) { } + break; + } + + } + }, + llpw_n1: function (status, destination) { + if (status === true) { + let c_LLPW_Q = [1.250, 0.131, 10, 2.5, 2.293, 0.110, 14.14, 1.552, 28.28, 7.071, 2.847, 5, 0.625, 7.071, 3.856, 3.856, 20, 28.28, 20, 14.14, 2.102, 6.698, 3.536, 10]; + let c_LLPW_GAIN = [-0.11, 0.27, -0.8, 0.57, 1.84, -0.38, 0.47, -1.56, 0.83, 1.58, -1.79, -0.45, 0.48, 1.22, -1.58, -1.59, -2.03, 2.56, -2.2, -2.48, 4.75, 10.5, 1.43, 3.76]; + let c_LLPW_FREQUENCIES = [400.83, 5812.8, 8360, 10413, 10658, 12079, 12899, 13205, 14848, 15591, 15778, 15783, 16716, 16891, 17255, 17496, 18555, 18622, 19219, 19448, 19664, 21341, 21353, 22595]; + let LLPW_Q = [5, 1, 3.536, 1.25, 8.409, 1.25, 14.14, 7.071, 5, 0.625, 16.82, 20, 20, 20, 28.28, 28.28, 28.28, 20, 33.64, 33.64, 10, 28.28, 7.071, 3.856]; + let LLPW_GAIN = [0.38, -1.81, -0.23, -0.51, 0.4, 0.84, 0.36, -0.34, 0.27, -1.2, -0.42, -0.67, 0.81, 1.31, -0.71, 0.68, -1.04, 0.79, -0.73, -1.33, 1.17, 0.57, 0.35, 6.33]; + let LLPW_FREQUENCIES = [16.452, 24.636, 37.134, 74.483, 159.54, 308.18, 670.21, 915.81, 1200.7, 2766.4, 2930.6, 4050.6, 4409.1, 5395.2, 5901.6, 6455.5, 7164.1, 7724.1, 8449, 10573, 12368, 14198, 17910, 18916]; + CiderAudioRenderer.audioNodes.llpw = [] + + switch (app.cfg.audio.maikiwiAudio.ciderPPE_value) { + case "MAIKIWI": + + try { + switch (localStorage.getItem("playingBitrate")) { + case "64": + CiderAudioRenderer.audioNodes.llpw[0] = CiderAudioRenderer.context.createConvolver(); + CiderAudioRenderer.audioNodes.llpw[0].normalize = false; + fetch('./cideraudio/impulses/CAP_64.wav').then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudioRenderer.audioNodes.llpw[0].buffer = await CiderAudioRenderer.context.decodeAudioData(bufferedImpulse); + }); + console.debug("[Cider][Audio] CAP Adaptive - 64kbps"); + + break; + case "256": + CiderAudioRenderer.audioNodes.llpw[0] = CiderAudioRenderer.context.createConvolver(); CiderAudioRenderer.audioNodes.llpw[0].normalize = false; + CiderAudioRenderer.audioNodes.llpw[1] = CiderAudioRenderer.context.createGain(); CiderAudioRenderer.audioNodes.llpw[1].gain.value = 2.37; // Post Gain Compensation + CiderAudioRenderer.audioNodes.llpw[0].connect(CiderAudioRenderer.audioNodes.llpw[1]); + fetch('./cideraudio/impulses/CAP_256_FINAL_48k.wav').then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudioRenderer.audioNodes.llpw[0].buffer = await CiderAudioRenderer.context.decodeAudioData(bufferedImpulse); + }); + console.debug("[Cider][Audio] CAP Adaptive - 256kbps"); + + break; + default: + CiderAudioRenderer.audioNodes.llpw[0] = CiderAudioRenderer.context.createGain(); CiderAudioRenderer.audioNodes.llpw[0].gain.value = 1 + console.debug("[Cider][Audio] CAP Disabled (Passthrough) : Non-Lossy Bitrate."); + + break; + } + + } catch (e) { + CiderAudioRenderer.audioNodes.llpw[0] = CiderAudioRenderer.context.createConvolver(); CiderAudioRenderer.audioNodes.llpw[0].normalize = false; + CiderAudioRenderer.audioNodes.llpw[1] = CiderAudioRenderer.context.createGain(); CiderAudioRenderer.audioNodes.llpw[1].gain.value = 2.37; + CiderAudioRenderer.audioNodes.llpw[0].connect(CiderAudioRenderer.audioNodes.llpw[1]); + fetch('./cideraudio/impulses/CAP_256_FINAL_48k.wav').then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudioRenderer.audioNodes.llpw[0].buffer = await CiderAudioRenderer.context.decodeAudioData(bufferedImpulse); + }); + console.debug("[Cider][Audio] CAP Adaptive - (Error Fallback) 256kbps"); + } + + break; + case "MAIKIWI_LEGACY": + CiderAudioRenderer.audioNodes.llpw[0] = CiderAudioRenderer.context.createConvolver(); + CiderAudioRenderer.audioNodes.llpw[0].normalize = false; + fetch('./cideraudio/impulses/CAP_Maikiwi.wav').then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudioRenderer.audioNodes.llpw[0].buffer = await CiderAudioRenderer.context.decodeAudioData(bufferedImpulse); + }); + console.debug("[Cider][Audio] CAP - Maikiwi Signature Mode"); + break; + case "NATURAL": + CiderAudioRenderer.audioNodes.llpw[0] = CiderAudioRenderer.context.createConvolver(); + CiderAudioRenderer.audioNodes.llpw[0].normalize = false; + fetch('./cideraudio/impulses/CAP_Natural.wav').then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudioRenderer.audioNodes.llpw[0].buffer = await CiderAudioRenderer.context.decodeAudioData(bufferedImpulse); + }); + + console.debug("[Cider][Audio] CAP - Natural Mode"); + break; + + case "LEGACY": + for (let i = 0; i < LLPW_FREQUENCIES.length; i++) { + CiderAudioRenderer.audioNodes.llpw[i] = CiderAudioRenderer.context.createBiquadFilter(); + CiderAudioRenderer.audioNodes.llpw[i].type = 'peaking'; // 'peaking'; + CiderAudioRenderer.audioNodes.llpw[i].frequency.value = LLPW_FREQUENCIES[i]; + CiderAudioRenderer.audioNodes.llpw[i].Q.value = LLPW_Q[i]; + CiderAudioRenderer.audioNodes.llpw[i].gain.value = LLPW_GAIN[i]; + } + for (let i = 1; i < LLPW_FREQUENCIES.length; i ++) { + CiderAudioRenderer.audioNodes.llpw[i-1].connect(CiderAudioRenderer.audioNodes.llpw[i]); + } + console.debug("[Cider][Audio] CAP - Legacy Mode"); + + break; + + default: + CiderAudioRenderer.audioNodes.llpw[0] = CiderAudioRenderer.context.createConvolver(); CiderAudioRenderer.audioNodes.llpw[0].normalize = false; + CiderAudioRenderer.audioNodes.llpw[1] = CiderAudioRenderer.context.createGain(); CiderAudioRenderer.audioNodes.llpw[1].gain.value = 2.57; + CiderAudioRenderer.audioNodes.llpw[0].connect(CiderAudioRenderer.audioNodes.llpw[1]); + fetch('./cideraudio/impulses/CAP_256_FINAL_48k.wav').then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudioRenderer.audioNodes.llpw[0].buffer = await CiderAudioRenderer.context.decodeAudioData(bufferedImpulse); + }); + app.cfg.audio.maikiwiAudio.ciderPPE_value = "MAIKIWI"; + + console.debug("[Cider][Audio] CAP - Maikiwi Adaptive Mode (Defaulted from broki config)"); + break; + } + + switch (destination) { + case "spatial": + try { CiderAudioRenderer.audioNodes.llpw.at(-1).connect(CiderAudioRenderer.audioNodes.spatialNode); console.debug("[Cider][Audio] llpw_n1 -> Spatial");} catch (e) { } + break; + case "n6": + try { + CiderAudioRenderer.audioNodes.llpw.at(-1).connect(CiderAudioRenderer.audioNodes.atmosphereRealizer2); + console.debug("[Cider][Audio] llpw_n1 -> atmosphereRealizer2"); + } catch (e) { } + break; + case 'n5': + try { + CiderAudioRenderer.audioNodes.llpw.at(-1).connect(CiderAudioRenderer.audioNodes.atmosphereRealizer1); + console.debug("[Cider][Audio] llpw_n1 -> atmosphereRealizer1"); + } catch (e) { } + break; + case 'n4': + try { CiderAudioRenderer.audioNodes.llpw.at(-1).connect(CiderAudioRenderer.audioNodes.vibrantbassNode[0]); + console.debug("[Cider][Audio] llpw_n1 -> vibrantbassNode");} catch (e) { } + break; + case 'n3': + try { CiderAudioRenderer.audioNodes.llpw.at(-1).connect(CiderAudioRenderer.audioNodes.audioBands[0]); console.debug("[Cider][Audio] llpw_n1 -> audioBands");} catch (e) { } + break; + case 'n2': + try { + CiderAudioRenderer.audioNodes.llpw.at(-1).connect(CiderAudioRenderer.audioNodes.opportunisticCorrection); + console.debug("[Cider][Audio] llpw_n1 -> opportunisticCorrection"); + } catch (e) { } + break; + case 'n1': + try { + CiderAudioRenderer.audioNodes.llpw.at(-1).connect(CiderAudioRenderer.audioNodes.llpw[0]); + console.debug("[Cider][Audio] llpw_n1 -> llpw"); + } catch (e) { } + break; + case 'n0': + try { CiderAudioRenderer.audioNodes.llpw.at(-1).connect(CiderAudioRenderer.context.destination); console.debug("[Cider][Audio] llpw_n1 -> destination");} catch (e) { } + break; + } + } + + }, + vibrantbass_n4: function (status, destination) { + if (status === true) { + let VIBRANTBASSBANDS = app.cfg.audio.maikiwiAudio.vibrantBass.frequencies; + let VIBRANTBASSGAIN = app.cfg.audio.maikiwiAudio.vibrantBass.gain; + let VIBRANTBASSQ = app.cfg.audio.maikiwiAudio.vibrantBass.Q; + CiderAudioRenderer.audioNodes.vibrantbassNode = [] + + for (let i = 0; i < VIBRANTBASSBANDS.length; i++) { + CiderAudioRenderer.audioNodes.vibrantbassNode[i] = CiderAudioRenderer.context.createBiquadFilter(); + CiderAudioRenderer.audioNodes.vibrantbassNode[i].type = 'peaking'; // 'peaking'; + CiderAudioRenderer.audioNodes.vibrantbassNode[i].frequency.value = VIBRANTBASSBANDS[i]; + CiderAudioRenderer.audioNodes.vibrantbassNode[i].Q.value = VIBRANTBASSQ[i]; + CiderAudioRenderer.audioNodes.vibrantbassNode[i].gain.value = VIBRANTBASSGAIN[i] * (app.cfg.audio.equalizer.vibrantBass / 10); + } + + for (let i = 1; i < VIBRANTBASSBANDS.length; i++) { + CiderAudioRenderer.audioNodes.vibrantbassNode[i - 1].connect(CiderAudioRenderer.audioNodes.vibrantbassNode[i]); + } + + switch (destination) { + case "spatial": + try { CiderAudioRenderer.audioNodes.vibrantbassNode.at(-1).connect(CiderAudioRenderer.audioNodes.spatialNode); console.debug("[Cider][Audio] vibrantbass_n4 -> Spatial");} catch (e) { } + break; + + case "n6": + try { + CiderAudioRenderer.audioNodes.vibrantbassNode.at(-1).connect(CiderAudioRenderer.audioNodes.atmosphereRealizer2); + console.debug("[Cider][Audio] vibrantbass_n4 -> atmosphereRealizer2"); + } catch (e) { } + break; + case 'n5': + try { + CiderAudioRenderer.audioNodes.vibrantbassNode.at(-1).connect(CiderAudioRenderer.audioNodes.atmosphereRealizer1); + console.debug("[Cider][Audio] vibrantbass_n4 -> atmosphereRealizer1"); + } catch (e) { } + break; + case 'n4': + try { + CiderAudioRenderer.audioNodes.vibrantbassNode.at(-1).connect(CiderAudioRenderer.audioNodes.vibrantbassNode[0]); + console.debug("[Cider][Audio] vibrantbass_n4 -> vibrantbassNode"); + } catch (e) { } + break; + case 'n3': + try { + CiderAudioRenderer.audioNodes.vibrantbassNode.at(-1).connect(CiderAudioRenderer.audioNodes.audioBands[0]); + console.debug("[Cider][Audio] vibrantbass_n4 -> audioBands"); + } catch (e) { } + break; + case 'n2': + try { + CiderAudioRenderer.audioNodes.vibrantbassNode.at(-1).connect(CiderAudioRenderer.audioNodes.opportunisticCorrection); + console.debug("[Cider][Audio] vibrantbass_n4 -> opportunisticCorrection"); + } catch (e) { } + break; + case 'n1': + try { + CiderAudioRenderer.audioNodes.vibrantbassNode.at(-1).connect(CiderAudioRenderer.audioNodes.llpw[0]); + console.debug("[Cider][Audio] vibrantbass_n4 -> llpw"); + } catch (e) { } + break; + case 'n0': + try { CiderAudioRenderer.audioNodes.vibrantbassNode.at(-1).connect(CiderAudioRenderer.context.destination); console.debug("[Cider][Audio] vibrantbass_n4 -> destination");} catch (e) { } + break; + } + } + }, + hierarchical_optimizer: function () { + CiderAudioRenderer.intelliGainComp_n0_0() // Calculate headroom for upcoming convolver + + const normValue = CiderAudioRenderer.audioNodes.gainNode.gain.value; // Store this temporarily so we can restore later + + CiderAudioRenderer.audioNodes.gainNode.gain.value = 1; + + // Render and return convolved buffer + let optimizerProfile = CiderAudioRenderer.optimizerProfile.find(function (profile) { + return profile.id === 'dirac32_96'; // Hard code for now + }); + + return fetch(optimizerProfile.file) + .then(async (response) => await response.arrayBuffer()) + .then((arrayBuffer) => CiderAudioRenderer.context.decodeAudioData(arrayBuffer)) + .then((decodedBuffer) => { + const source = new AudioBufferSourceNode(renderer, { + buffer: decodedBuffer, + }); + + source.connect(CiderAudioRenderer.audioNodes.intelliGainComp); + + switch (lastNode) { + case 'spatial': + CiderAudioRenderer.audioNodes.gainNode.connect(CiderAudioRenderer.audioNodes.spatialNode); + break; + case 'n6': + CiderAudioRenderer.audioNodes.gainNode.connect(CiderAudioRenderer.audioNodes.atmosphereRealizer2); + break; + case 'n5': + CiderAudioRenderer.audioNodes.gainNode.connect(CiderAudioRenderer.audioNodes.atmosphereRealizer1); + break; + case 'n4': + CiderAudioRenderer.audioNodes.gainNode.connect(CiderAudioRenderer.audioNodes.vibrantbassNode[0]); + break; + case 'n3': + CiderAudioRenderer.audioNodes.gainNode.connect(CiderAudioRenderer.audioNodes.audioBands[0]); + break; + case 'n2': + CiderAudioRenderer.audioNodes.gainNode.connect(CiderAudioRenderer.audioNodes.opportunisticCorrection); + break; + case 'n1': + CiderAudioRenderer.audioNodes.gainNode.connect(CiderAudioRenderer.audioNodes.llpw[0]); + break; + } + + switch (firstNode) { + case 'spatial': + CiderAudioRenderer.audioNodes.spatialNode.disconnect(); + CiderAudioRenderer.audioNodes.spatialNode.connect(renderer.destination); + break; + case 'n6': + CiderAudioRenderer.audioNodes.atmosphereRealizer2.disconnect(); + CiderAudioRenderer.audioNodes.atmosphereRealizer2.connect(renderer.destination); + break; + case 'n5': + CiderAudioRenderer.audioNodes.atmosphereRealizer1.disconnect(); + CiderAudioRenderer.audioNodes.atmosphereRealizer1.connect(renderer.destination); + break; + case 'n4': + CiderAudioRenderer.audioNodes.vibrantbassNode.at(-1).disconnect(); + CiderAudioRenderer.audioNodes.vibrantbassNode.at(-1).connect(renderer.destination); + break; + case 'n3': + CiderAudioRenderer.audioNodes.audioBands.at(-1).disconnect(); + CiderAudioRenderer.audioNodes.audioBands.at(-1).connect(renderer.destination); + break; + case 'n2': + CiderAudioRenderer.audioNodes.opportunisticCorrection.disconnect(); + CiderAudioRenderer.audioNodes.opportunisticCorrection.connect(renderer.destination); + break; + case 'n1': + CiderAudioRenderer.audioNodes.llpw.at(-1).disconnect(); + CiderAudioRenderer.audioNodes.llpw.at(-1).connect(renderer.destination); + break; + } + + source.start(); + + const res = renderer.startRendering().then(function(res) { + return res; + }) + }) + }, + hierarchical_unloading: function () { + try { CiderAudioRenderer.audioNodes.spatialNode.disconnect(); CiderAudioRenderer.audioNodes.spatialNode = null} catch (e) { } + try { CiderAudioRenderer.audioNodes.gainNode.disconnect(); } catch (e) { } + try { CiderAudioRenderer.audioNodes.atmosphereRealizer2.disconnect(); CiderAudioRenderer.audioNodes.atmosphereRealizer2 = null } catch (e) { } + try { CiderAudioRenderer.audioNodes.atmosphereRealizer1.disconnect(); CiderAudioRenderer.audioNodes.atmosphereRealizer1 = null } catch (e) { } + try { for (var i of CiderAudioRenderer.audioNodes.llpw) { i.disconnect(); } CiderAudioRenderer.audioNodes.llpw = null } catch (e) { } + try { for (var i of CiderAudioRenderer.audioNodes.vibrantbassNode) { i.disconnect(); } CiderAudioRenderer.audioNodes.vibrantbassNode = null } catch (e) { } + try { for (var i of CiderAudioRenderer.audioNodes.audioBands) { i.disconnect(); } CiderAudioRenderer.audioNodes.vibrantbassNode = null} catch (e) { }; + try {CiderAudioRenderer.audioNodes.opportunisticCorrection.disconnect(); CiderAudioRenderer.audioNodes.opportunisticCorrection = null } catch (e) { }; + console.debug("[Cider][Audio] Finished hierarchical unloading") + }, + hierarchical_loading: async function () { + + if (app.cfg.audio.maikiwiAudio.staticOptimizer.lock === true) { return } // Do nothing if locked by optimizer. + + const configMap = new Map([ + ['spatial', app.cfg.audio.maikiwiAudio.spatial === true], + ['n6', app.cfg.audio.maikiwiAudio.atmosphereRealizer2 === true], + ['n5', app.cfg.audio.maikiwiAudio.atmosphereRealizer1 === true], + ['n4', app.cfg.audio.equalizer.vibrantBass != 0], + ['n3', Math.max(...app.cfg.audio.equalizer.gain) != 0], + ['n2', app.cfg.audio.maikiwiAudio.opportunisticCorrection_state !== "OFF"], + ['n1', app.cfg.audio.maikiwiAudio.ciderPPE === true] + ]); + + CiderAudioRenderer.hierarchical_unloading(); + let lastNode = 'n0'; let index = 0; let firstNode = 'n0' + for (let [tier, value] of configMap.entries()) { + if (value === true) { + if (index === 0) {firstNode = tier} + switch (tier) { + case 'spatial': + CiderAudioRenderer.spatial_ninf(); + lastNode = 'spatial'; + break; + case 'n6': + app.cfg.audio.normalization = true; + CiderAudioRenderer.atmosphereRealizer2_n6(true, lastNode); + lastNode = 'n6'; + break; + case 'n5': + app.cfg.audio.normalization = true; + CiderAudioRenderer.atmosphereRealizer1_n5(true, lastNode); + lastNode = 'n5'; + break; + case 'n4': + CiderAudioRenderer.vibrantbass_n4(true, lastNode); + lastNode = 'n4'; + break; + case 'n3': + CiderAudioRenderer.equalizer(true, lastNode); + lastNode = 'n3'; + break; + case 'n2': + CiderAudioRenderer.opportunisticCorrection_n2(true, lastNode); + lastNode = 'n2'; + break; + case 'n1': + app.cfg.audio.normalization = true; + CiderAudioRenderer.llpw_n1(true, lastNode); + lastNode = 'n1'; + break; + } + } + } + + app.cfg.audio.maikiwiAudio.lastNode = lastNode; app.cfg.audio.maikiwiAudio.firstNode = firstNode; // Sync last node & first + + switch (lastNode) { + case 'spatial': + CiderAudioRenderer.audioNodes.gainNode.connect(CiderAudioRenderer.audioNodes.spatialNode); + console.debug("[Cider][Audio] gainNode -> Spatial"); + break; + case 'n6': + CiderAudioRenderer.audioNodes.gainNode.connect(CiderAudioRenderer.audioNodes.atmosphereRealizer2); + console.debug("[Cider][Audio] gainNode -> atmosphereRealizer2"); + break; + case 'n5': + CiderAudioRenderer.audioNodes.gainNode.connect(CiderAudioRenderer.audioNodes.atmosphereRealizer1); + console.debug("[Cider][Audio] gainNode -> atmosphereRealizer1"); + break; + case 'n4': + CiderAudioRenderer.audioNodes.gainNode.connect(CiderAudioRenderer.audioNodes.vibrantbassNode[0]); + console.debug("[Cider][Audio] gainNode -> vibrantbass"); + break; + case 'n3': + CiderAudioRenderer.audioNodes.gainNode.connect(CiderAudioRenderer.audioNodes.audioBands[0]); + console.debug("[Cider][Audio] gainNode -> audioBands"); + + break; + case 'n2': + try { + CiderAudioRenderer.audioNodes.gainNode.connect(CiderAudioRenderer.audioNodes.opportunisticCorrection); + console.debug("[Cider][Audio] gainNode -> opportunisticCorrection"); + } catch (e) { } + break; + case 'n1': + CiderAudioRenderer.audioNodes.gainNode.connect(CiderAudioRenderer.audioNodes.llpw[0]); + console.debug("[Cider][Audio] gainNode -> llpw"); + break; + case 'n0': + CiderAudioRenderer.audioNodes.gainNode.connect(CiderAudioRenderer.context.destination); + console.debug("[Cider][Audio] gainNode -> destination"); + break; + } + + console.debug('[Cider][Audio]\n' + [...configMap.entries()] + '\n lastNode: ' + lastNode); + + CiderAudioRenderer.intelliGainComp_n0_0(); + console.debug("[Cider][Audio] Finished hierarchical loading"); + + }, + + equalizer: function (status, destination) { // n3_1 + if (status === true) { + let BANDS = app.cfg.audio.equalizer.frequencies; + let GAIN = app.cfg.audio.equalizer.gain; + let Q = app.cfg.audio.equalizer.Q; + + CiderAudioRenderer.audioNodes.audioBands = []; + for (let i = 0; i < BANDS.length; i++) { + CiderAudioRenderer.audioNodes.audioBands[i] = CiderAudioRenderer.context.createBiquadFilter(); + CiderAudioRenderer.audioNodes.audioBands[i].type = 'peaking'; // 'peaking'; + CiderAudioRenderer.audioNodes.audioBands[i].frequency.value = BANDS[i]; + CiderAudioRenderer.audioNodes.audioBands[i].Q.value = Q[i]; + CiderAudioRenderer.audioNodes.audioBands[i].gain.value = GAIN[i] * app.cfg.audio.equalizer.mix; + } + + for (let i = 1; i < BANDS.length; i++) { + CiderAudioRenderer.audioNodes.audioBands[i - 1].connect(CiderAudioRenderer.audioNodes.audioBands[i]); + } + + switch (destination) { + case 'spatial': + CiderAudioRenderer.audioNodes.audioBands.at(-1).connect(CiderAudioRenderer.audioNodes.spatialNode); + console.debug("[Cider][Audio] Equalizer -> Spatial"); + break; + case "n6": + try { + CiderAudioRenderer.audioNodes.audioBands.at(-1).connect(CiderAudioRenderer.audioNodes.atmosphereRealizer2); + console.debug("[Cider][Audio] Equalizer -> atmosphereRealizer2"); + } catch (e) { } + break; + case 'n5': + try { + CiderAudioRenderer.audioNodes.audioBands.at(-1).connect(CiderAudioRenderer.audioNodes.atmosphereRealizer1); + console.debug("[Cider][Audio] Equalizer -> atmosphereRealizer1"); + } catch (e) { } + break; + case 'n4': + try { + CiderAudioRenderer.audioNodes.audioBands.at(-1).connect(CiderAudioRenderer.audioNodes.vibrantbassNode[0]); + console.debug("[Cider][Audio] Equalizer -> vibrantbassNode"); + } catch (e) { } + break; + case 'n3': + try { + CiderAudioRenderer.audioNodes.audioBands.at(-1).connect(CiderAudioRenderer.audioNodes.audioBands[0]); + console.debug("[Cider][Audio] Equalizer -> audioBands"); + } catch (e) { } + break; + case 'n2': + try { + CiderAudioRenderer.audioNodes.audioBands.at(-1).connect(CiderAudioRenderer.audioNodes.opportunisticCorrection); + console.debug("[Cider][Audio] Equalizer -> opportunisticCorrection"); + } catch (e) { } + break; + case 'n1': + try { + CiderAudioRenderer.audioNodes.audioBands.at(-1).connect(CiderAudioRenderer.audioNodes.llpw[0]); + console.debug("[Cider][Audio] Equalizer -> llpw"); + } catch (e) { } + break; + case 'n0': + try { CiderAudioRenderer.audioNodes.audioBands.at(-1).connect(CiderAudioRenderer.context.destination); console.debug("[Cider][Audio] Equalizer -> destination");} catch (e) { } + break; + } + + } + } +} +export { CiderAudioRenderer } \ No newline at end of file