xorg1990
New member
Hi, ich schlage gerade einen neuen weg der OOP ein, weil ich das Prototyp basierende so unübersichtlich finde.
Doch wenn ich das Object erzeuge erhalte ich folgende Fehlermeldung:
Uncaught SyntaxError: Identifier 'useHang' has already been declared
Das Object:
Der Fehler tritt immer dann auf wenn ich das Objekt erstelle.
var AGC = new AutoGain();
Es wird in der console immer an diese Stelle verwiesen.
Änder ich let useHang = true; in var useHang = true; geht es aber warum?
Doch wenn ich das Object erzeuge erhalte ich folgende Fehlermeldung:
Uncaught SyntaxError: Identifier 'useHang' has already been declared
Das Object:
Code:
function AutoGain(){
//signal delay line time delay in seconds.
//adjust to cover the impulse response time of filter
const delayTimeconst = 0.015;
//Peak Detector window time delay in seconds.
const windowTimeconst = 0.018;
//attack time constant in seconds
//just small enough to let attackave charge up within the DELAY_TIMECONST time
const attackRiseTimeconst = 0.002;
const attackFallTimeconst = 0.005;
//ratio between rise and fall times of Decay time constants
const decayRisefallRatio = 0.3;
// hang timer release decay time constant in seconds
const ReleaseTimeconst = 0.05;
//limit output to about 3db of max
const AGCOutscale = 0.7;
let sigDelayBuf;
let magBuf;
let sampleRate = 0;
let decayAve = 0.0;
let attackAve = 0.0;
let attackRiseAlpha = 0.0;
let attackFallAlpha = 0.0;
let decayRiseAlpha = 0.0;
let decayFallAlpha = 0.0;
let fixedGain = 0.0;
let knee = 0.0;
let gainSlope = 0.0;
let peak = 0.0;
let sigDelayPtr = 0;
let magBufPos = 0;
let delaySamples = 0;
let windowSamples = 0;
let hangTime = 0;
let hangTimer = 0;
let threshold = -100;
let slopeFactor = 100;
let decay = 0.0;
let useHang = true;
function init(Fs,useHang, threshold, slope, decay){
useHang = useHang;
threshold = threshold;
slopeFactor = slope;
decay = decay;
if(Fs){
sampleRate = Fs;
delaySamples = parseInt(sampleRate*delayTimeconst);
windowSamples = parseInt(sampleRate*windowTimeconst);
sigDelayBuf = new Float32Array(delaySamples);
magBuf = new Float32Array(windowSamples);
for(let i=0;i<windowSamples;i++){
magBuf[i] = -16.0;
}
//clamp Delay samples within buffer limit
if(delaySamples>=sigDelayBuf.length-1) delaySamples = sigDelayBuf.length-1;
}
knee = threshold/20.0;
gainSlope = slopeFactor/100.0;
//calculate parameters for AGC gain as a function of input magnitude
fixedGain = AGCOutscale * Math.pow(10.0, knee*(gainSlope-1));
//calculate fast and slow filter values.
attackRiseAlpha = (1-Math.exp(-1/(sampleRate*attackRiseTimeconst)));
attackFallAlpha = (1-Math.exp(-1/(sampleRate*attackFallTimeconst)));
//make rise time DECAY_RISEFALL_RATIO of fall
decayRiseAlpha = (1-Math.exp(-1/(sampleRate*decay*0.001*decayRisefallRatio)));
hangTime = parseInt(sampleRate*decay*0.001);
if(useHang){
decayFallAlpha = (1 -Math.exp(-1/(sampleRate*ReleaseTimeconst)));
}else{
decayFallAlpha = (1 - Math.exp(-1/(sampleRate*decay*0.001)));
}
}
function work(buffer){
let len = buffer.length;
for(let i=0;i<len;i++){
let sample = buffer[i];
if(sample == 0.0) continue;
sample *= 1000.0;
let delayedIn = sigDelayBuf[sigDelayPtr];
//put new input sample into signal delay buffer
sigDelayBuf[sigDelayPtr++] = sample;
if(sigDelayPtr >= delaySamples){
sigDelayPtr = 0;
}
//convert |mag| to log |mag|
let mag = Math.log10(Math.abs(sample));
if(isFinite(mag) === false){
mag = -8.0;
}
//create a sliding window of '_WindowSamples' magnitudes and output the peak value within the sliding window
let tmp = magBuf[magBufPos];
magBuf[magBufPos++] = mag;
if(magBufPos >= windowSamples){
magBufPos = 0;
}
if(mag>peak){
peak = mag; //if new sample is larger than current peak then use it, no need to look at buffer values
}else{
//tmp is oldest sample pulled out of buffer
if(tmp == peak){//if oldest sample pulled out was last peak then need to find next highest peak in buffer
peak = -8.0;//set to lowest value to find next max peak
//search all buffer for maximum value and set as new peak
for(let i=0;i<windowSamples;i++){
tmp = magBuf[i];
if(tmp>peak) peak = tmp;
}
}
}
if(useHang){//using hang timer mode
if(peak>attackAve){ //if magnitude is rising (use _AttackRiseAlpha time constant)
attackAve = (1 - attackRiseAlpha) * attackAve + attackRiseAlpha * peak;
}else{ //else magnitude is falling (use _AttackFallAlpha time constant)
attackAve = (1 - attackFallAlpha) * attackAve + attackFallAlpha * peak;
}
if(peak>decayAve){//if magnitude is rising (use _DecayRiseAlpha time constant)
decayAve = (1 - decayRiseAlpha) * decayAve + decayRiseAlpha * peak;
hangTimer = 0;
}else{//here if decreasing signal
if(hangTimer<hangTime){
hangTimer++;//just inc and hold current _DecayAve
}else{//else decay with _DecayFallAlpha which is RELEASE_TIMECONST
decayAve = (1 - decayFallAlpha) * decayAve * decayFallAlpha * peak
}
}
}else{//using exponential decay mode
// perform average of magnitude using 2 averagers each with separate rise and fall time constants
if(peak>attackAve){
attackAve = (1- attackRiseAlpha) * attackAve + attackRiseAlpha * peak;
}else{
attackAve = (1- attackFallAlpha) * attackAve + attackFallAlpha * peak;
}
if(peak>decayAve){
decayAve = (1- decayRiseAlpha) * decayAve + decayRiseAlpha * peak;
}else{
decayAve = (1- decayFallAlpha) * decayAve + decayFallAlpha * peak;
}
}
//use greater magnitude of attack or Decay Averager
mag = attackAve > decayAve ? attackAve : decayAve;
//calc gain depending on which side of knee the magnitude is on
let gain;
if(mag<=knee){
gain = fixedGain;
}else{
gain = AGCOutscale * Math.pow(10.0, mag * (gainSlope-1));
}
buffer[i] = delayedIn * gain * 0.00001;
}//for
return buffer;
}//work
function setSampleRate(Fs){
init(Fs,useHang, threshold, slope, decay);
}
function useHang(hang){
init(null,hang, threshold, slope, decay);
}
function setThreshold(thres){
init(null,useHang, thres, slope, decay);
}
function setSlope(Slope){
init(null,useHang, thres, Slope, decay);
}
function setDecay(Decay){
init(null,useHang, thres, slope, Decay);
}
return{
init: init,
work : work,
useHang : useHang,
setThreshold : setThreshold,
setSlope : setSlope,
setDecay : setDecay
}
}
Der Fehler tritt immer dann auf wenn ich das Objekt erstelle.
var AGC = new AutoGain();
Es wird in der console immer an diese Stelle verwiesen.
Änder ich let useHang = true; in var useHang = true; geht es aber warum?