fix: resolve remaining PR #523 review issues
Guard generateFrequencies against bandCount=1 division by zero, fix inverted HRTF ITD delays for left-side sources, remove unused variable, promote _interpolateGains to public API, and add NaN guard to widening.
This commit is contained in:
parent
589504d7fd
commit
8c9a613bee
5 changed files with 22 additions and 15 deletions
|
|
@ -12,6 +12,12 @@ function generateFrequencies(bandCount, minFreq = 20, maxFreq = 20000) {
|
||||||
const safeMin = Math.max(10, minFreq);
|
const safeMin = Math.max(10, minFreq);
|
||||||
const safeMax = Math.min(96000, maxFreq);
|
const safeMax = Math.min(96000, maxFreq);
|
||||||
|
|
||||||
|
if (bandCount <= 1) {
|
||||||
|
// Single band: use geometric mean of range
|
||||||
|
frequencies.push(Math.round(Math.sqrt(safeMin * safeMax)));
|
||||||
|
return frequencies;
|
||||||
|
}
|
||||||
|
|
||||||
for (let i = 0; i < bandCount; i++) {
|
for (let i = 0; i < bandCount; i++) {
|
||||||
// Logarithmic interpolation
|
// Logarithmic interpolation
|
||||||
const t = i / (bandCount - 1);
|
const t = i / (bandCount - 1);
|
||||||
|
|
@ -175,7 +181,7 @@ class AudioContextManager {
|
||||||
this.frequencies = generateFrequencies(newCount, this.freqRange.min, this.freqRange.max);
|
this.frequencies = generateFrequencies(newCount, this.freqRange.min, this.freqRange.max);
|
||||||
|
|
||||||
// Interpolate current gains to new band count
|
// Interpolate current gains to new band count
|
||||||
const newGains = equalizerSettings._interpolateGains(this.currentGains, newCount);
|
const newGains = equalizerSettings.interpolateGains(this.currentGains, newCount);
|
||||||
this.currentGains = newGains;
|
this.currentGains = newGains;
|
||||||
equalizerSettings.setGains(newGains);
|
equalizerSettings.setGains(newGains);
|
||||||
|
|
||||||
|
|
@ -1079,7 +1085,7 @@ class AudioContextManager {
|
||||||
// Ensure gains array matches current band count
|
// Ensure gains array matches current band count
|
||||||
let adjustedGains = gains;
|
let adjustedGains = gains;
|
||||||
if (gains.length !== this.bandCount) {
|
if (gains.length !== this.bandCount) {
|
||||||
adjustedGains = equalizerSettings._interpolateGains(gains, this.bandCount);
|
adjustedGains = equalizerSettings.interpolateGains(gains, this.bandCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
const now = this.audioContext?.currentTime || 0;
|
const now = this.audioContext?.currentTime || 0;
|
||||||
|
|
@ -1535,7 +1541,7 @@ class AudioContextManager {
|
||||||
const oldGains = this.geqGains;
|
const oldGains = this.geqGains;
|
||||||
this.geqBandCount = newCount;
|
this.geqBandCount = newCount;
|
||||||
this.geqFrequencies = generateFrequencies(newCount, this.geqFreqRange.min, this.geqFreqRange.max);
|
this.geqFrequencies = generateFrequencies(newCount, this.geqFreqRange.min, this.geqFreqRange.max);
|
||||||
this.geqGains = equalizerSettings._interpolateGains(oldGains, newCount);
|
this.geqGains = equalizerSettings.interpolateGains(oldGains, newCount);
|
||||||
|
|
||||||
equalizerSettings.setGraphicEqBandCount(newCount);
|
equalizerSettings.setGraphicEqBandCount(newCount);
|
||||||
equalizerSettings.setGraphicEqGains(this.geqGains);
|
equalizerSettings.setGraphicEqGains(this.geqGains);
|
||||||
|
|
|
||||||
|
|
@ -201,7 +201,7 @@ export class Equalizer {
|
||||||
this.frequencyLabels = generateFrequencyLabels(this.frequencies);
|
this.frequencyLabels = generateFrequencyLabels(this.frequencies);
|
||||||
|
|
||||||
// Interpolate current gains to new band count
|
// Interpolate current gains to new band count
|
||||||
const newGains = equalizerSettings._interpolateGains(this.currentGains, newCount);
|
const newGains = equalizerSettings.interpolateGains(this.currentGains, newCount);
|
||||||
this.currentGains = newGains;
|
this.currentGains = newGains;
|
||||||
equalizerSettings.setGains(newGains);
|
equalizerSettings.setGains(newGains);
|
||||||
|
|
||||||
|
|
@ -455,7 +455,7 @@ export class Equalizer {
|
||||||
// Ensure gains array matches current band count
|
// Ensure gains array matches current band count
|
||||||
let adjustedGains = gains;
|
let adjustedGains = gains;
|
||||||
if (gains.length !== this.bandCount) {
|
if (gains.length !== this.bandCount) {
|
||||||
adjustedGains = equalizerSettings._interpolateGains(gains, this.bandCount);
|
adjustedGains = equalizerSettings.interpolateGains(gains, this.bandCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
const now = this.audioContext?.currentTime || 0;
|
const now = this.audioContext?.currentTime || 0;
|
||||||
|
|
|
||||||
|
|
@ -65,8 +65,9 @@ export function generateHRTF(audioContext, azimuthDeg, elevationDeg = 0) {
|
||||||
const contraData = sourceOnRight ? leftData : rightData;
|
const contraData = sourceOnRight ? leftData : rightData;
|
||||||
|
|
||||||
// Generate ipsilateral (near ear) IR — mostly a delayed impulse with slight coloring
|
// Generate ipsilateral (near ear) IR — mostly a delayed impulse with slight coloring
|
||||||
const ipsiDelay = Math.max(0, sourceOnRight ? 0 : itdSamples);
|
// Ipsilateral ear (near source) receives sound first; contralateral ear is delayed by ITD
|
||||||
const contraDelay = Math.max(0, sourceOnRight ? itdSamples : 0);
|
const ipsiDelay = 0;
|
||||||
|
const contraDelay = Math.abs(itdSamples);
|
||||||
|
|
||||||
// Create frequency-domain representation for head shadow
|
// Create frequency-domain representation for head shadow
|
||||||
const fftSize = IR_LENGTH;
|
const fftSize = IR_LENGTH;
|
||||||
|
|
|
||||||
|
|
@ -1512,7 +1512,7 @@ export async function initializeSettings(scrobbler, player, api, ui) {
|
||||||
const newCount = Math.max(3, Math.min(32, parseInt(geqBandCountInput.value, 10) || 16));
|
const newCount = Math.max(3, Math.min(32, parseInt(geqBandCountInput.value, 10) || 16));
|
||||||
geqBandCountInput.value = newCount;
|
geqBandCountInput.value = newCount;
|
||||||
if (newCount === geqBandCount) return;
|
if (newCount === geqBandCount) return;
|
||||||
geqGains = equalizerSettings._interpolateGains(geqGains, newCount);
|
geqGains = equalizerSettings.interpolateGains(geqGains, newCount);
|
||||||
geqBandCount = newCount;
|
geqBandCount = newCount;
|
||||||
equalizerSettings.setGraphicEqGains(geqGains);
|
equalizerSettings.setGraphicEqGains(geqGains);
|
||||||
audioContextManager.setGraphicEqBandCount(newCount);
|
audioContextManager.setGraphicEqBandCount(newCount);
|
||||||
|
|
@ -1778,7 +1778,7 @@ export async function initializeSettings(scrobbler, player, api, ui) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const adjusted =
|
const adjusted =
|
||||||
gains.length !== geqBandCount ? equalizerSettings._interpolateGains(gains, geqBandCount) : gains;
|
gains.length !== geqBandCount ? equalizerSettings.interpolateGains(gains, geqBandCount) : gains;
|
||||||
geqGains = adjusted.map((g) => {
|
geqGains = adjusted.map((g) => {
|
||||||
const n = Number(g);
|
const n = Number(g);
|
||||||
return Number.isFinite(n)
|
return Number.isFinite(n)
|
||||||
|
|
@ -2446,7 +2446,6 @@ export async function initializeSettings(scrobbler, player, api, ui) {
|
||||||
else if (meas) graphShift = 75 - getNormalizationOffset(meas);
|
else if (meas) graphShift = 75 - getNormalizationOffset(meas);
|
||||||
}
|
}
|
||||||
|
|
||||||
const sampleRate = autoeqSampleRate ? parseInt(autoeqSampleRate.value, 10) : 48000;
|
|
||||||
let closest = -1,
|
let closest = -1,
|
||||||
closestDist = Infinity;
|
closestDist = Infinity;
|
||||||
activeBands.forEach((band, i) => {
|
activeBands.forEach((band, i) => {
|
||||||
|
|
|
||||||
|
|
@ -1329,7 +1329,7 @@ export const equalizerSettings = {
|
||||||
}
|
}
|
||||||
// If different band count, try to interpolate or return flat
|
// If different band count, try to interpolate or return flat
|
||||||
if (gains.length > 0) {
|
if (gains.length > 0) {
|
||||||
return this._interpolateGains(gains, count);
|
return this.interpolateGains(gains, count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1425,7 +1425,7 @@ export const equalizerSettings = {
|
||||||
}
|
}
|
||||||
// Interpolate stored Qs to match requested band count instead of discarding
|
// Interpolate stored Qs to match requested band count instead of discarding
|
||||||
if (Array.isArray(qs) && qs.length >= this.MIN_BANDS) {
|
if (Array.isArray(qs) && qs.length >= this.MIN_BANDS) {
|
||||||
return this._interpolateGains(qs, count);
|
return this.interpolateGains(qs, count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
|
@ -1473,7 +1473,7 @@ export const equalizerSettings = {
|
||||||
/**
|
/**
|
||||||
* Interpolate gains array to match target band count
|
* Interpolate gains array to match target band count
|
||||||
*/
|
*/
|
||||||
_interpolateGains(sourceGains, targetCount) {
|
interpolateGains(sourceGains, targetCount) {
|
||||||
if (sourceGains.length === targetCount) {
|
if (sourceGains.length === targetCount) {
|
||||||
return [...sourceGains];
|
return [...sourceGains];
|
||||||
}
|
}
|
||||||
|
|
@ -1808,7 +1808,7 @@ export const equalizerSettings = {
|
||||||
return parsed.map((v) => (Number.isFinite(v) ? v : 0));
|
return parsed.map((v) => (Number.isFinite(v) ? v : 0));
|
||||||
}
|
}
|
||||||
if (Array.isArray(parsed) && parsed.length > 0) {
|
if (Array.isArray(parsed) && parsed.length > 0) {
|
||||||
return this._interpolateGains(parsed, expectedCount);
|
return this.interpolateGains(parsed, expectedCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
|
@ -1944,7 +1944,8 @@ export const binauralDspSettings = {
|
||||||
|
|
||||||
setWideningAmount(amount) {
|
setWideningAmount(amount) {
|
||||||
const all = this._getAll();
|
const all = this._getAll();
|
||||||
all.wideningAmount = Math.max(0, Math.min(2, amount));
|
const n = Number(amount);
|
||||||
|
all.wideningAmount = Number.isFinite(n) ? Math.max(0, Math.min(2, n)) : 1.0;
|
||||||
this._setAll(all);
|
this._setAll(all);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue