• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

Audio klingt komisch, Fensterfunktion gehen nicht

xorg1990

New member
Hi, ich habe ein kompliziertes Problem mit meiner WebAnwendung.

Seit dem ich die DSP Fensterfunktion eingeführt habe schient JS nur noch Gülle zu berechnen.
Es treten 2 Probleme auf (ich nagel das jetzt mal am Hann Window Fest).

Wenn ich das Hann Fenster so schreibe:
Code:
wf.prototype.windowHann = function(sampleBuffer){
	var l = sampleBuffer.length;
	for(var i=0; i<l;i++){
		sampleBuffer[i] *= 0.5-0.5 * Math.cos(this.Pi2 * i / (l - 1));// nicht 0.5 * (1 - Math.cos(DSP.TWO_PI * index / (length - 1)));	
	}
	this.windowCallback(sampleBuffer);

};
Dann ist der Sinus der aus den boxen ertönt kein sinus mehr. Ich schiebe einen 1500 Hz sinus zu Soundkarte rein, das bedeutet das man auch eine 1500 Sinus hören sollte, allerdings hört das sich komisch an(so eine art zirpen). gerendert wird zwar was bei 1500 Hz aber das ist kein Sinus, ein sinus wäre in gerader strich, ich sehe dar nur matsch.
Test Link Achtung Ton Leiser drehen!!!


Schreibe ich das Fenster so:
Code:
wf.prototype.windowHann = function(sampleBuffer){
	var l = sampleBuffer.length;
       var windowedBuffer = new Float32Array(l);
	for(var i=0; i<l;i++){
		windowedBuffer[i] = sampleBuffer[i] * 0.5-0.5 * Math.cos(this.Pi2 * i / (l - 1));// nicht 0.5 * (1 - Math.cos(DSP.TWO_PI * index / (length - 1)));	
	}
	this.windowCallback(windowedBuffer);

};
Dann ertönt auch ein Sinus aus den Boxen. Allerdings wird dann ein Träger bei 50 Hz gerendert mit Starken Oberwellen hä????? wo kommt das her??
Selbst wenn ich den sampleBuffer lösche wird was gerendert
Code:
for(var i=0; i<l;i++){
                sampleBuffer[i] = 0;
		windowedBuffer[i] = sampleBuffer[i] * 0.5-0.5 * Math.cos(this.Pi2 * i / (l - 1));// nicht 0.5 * (1 - Math.cos(DSP.TWO_PI * index / (length - 1)));	
	}
Das Bild sagt mehr als 1000 Worte:
Zwischenablage01.png


Wenn man sich einloggt Realtime Grabber Login Einfach auf den Pfeil klicken, dann wider zurück zur Hauptseite wechseln und in der Tabelle auf 0 - 22,5 kHz klicken. Kann man im Reiter FFT Settings die Windows durchgehen, beim Rechteck-Fenster klingt der Ton auch wider normal bei allen anderen Fenstern nicht.

Überfordere ich js? wen ja wie lösen?

Das komplette Fenster Object
Code:
function wf(defaultWindow, alpha){
	this.alpha = alpha;
	this.Pi2 = Math.PI*2;
	this.init(defaultWindow);
}

wf.prototype.init = function(type){
	 switch(type){
	 case "Hamming":
	      this.performWindow  = this.windowHamming ;
	      break;
	     
	    case "Hann":
	      this.performWindow  = this.windowHann;
	      break;
	      
	    case "Bartlett":
		      this.performWindow  = this.windowBartlett;
		      break;
		      
	    case "BartlettHann":
		      this.performWindow  = this.windowBartlettHann;
		      break;
		      
	    case "Blackman":
		      this.performWindow  = this.windowBlackman;
		      this.alpha = this.alpha || 0.16;
		      break;
		      
	    case "Cosine":
		      this.performWindow  = this.windowCosine;
		      break;
		      
	    case "Gauss":
		      this.performWindow  = this.windowGauss;
		      this.alpha = this.alpha || 0.25;
		      break;
		      
	    case "Triangular":
		      this.performWindow  = this.windowTriangular;
		      break;
		      
	    case "Lanczos":
		      this.performWindow  = this.windowLanczos;
		      break;
		      
	    case "Rectangular":
		      this.performWindow  = this.bypassWindow;
		      break;
		
	 }
};



wf.prototype.windowCallback = function(){};

wf.prototype.windowHann = function(sampleBuffer){
	var l = sampleBuffer.length;
	for(var i=0; i<l;i++){
		sampleBuffer[i] *= 0.5-0.5 * Math.cos(this.Pi2 * i / (l - 1));// nicht 0.5 * (1 - Math.cos(DSP.TWO_PI * index / (length - 1)));	
	}
	this.windowCallback(sampleBuffer);

};

wf.prototype.windowHamming = function(sampleBuffer){
	var l = sampleBuffer.length;
	for(var i=0; i<l;i++){
		sampleBuffer[i] *= 0.54 - 0.46 * Math.cos(this.Pi2 * i / (l - 1));
	}
	this.windowCallback(sampleBuffer);
};

wf.prototype.windowBartlett = function(sampleBuffer){
	var l = sampleBuffer.length;
	for(var i=0; i<l;i++){
		sampleBuffer[i]  *= 2 / (l - 1) * ((l - 1) / 2 - Math.abs(i - (l - 1) / 2));
	}
	this.windowCallback(sampleBuffer);
};

wf.prototype.windowBartlettHann = function(sampleBuffer){
	var l = sampleBuffer.length;
	for(var i=0; i<l;i++){
		sampleBuffer[i] *= 0.62 - 0.48 * Math.abs(i / (l - 1) - 0.5) - 0.38 * Math.cos(this.Pi2 * i/ (l - 1));
	}
	this.windowCallback(sampleBuffer);
};


wf.prototype.windowBlackman = function(sampleBuffer){
	var l = sampleBuffer.length;
	var a0 = (1 - this.alpha) / 2;
	var a1 = 0.5;
	 var a2 = this.alpha / 2;
	for(var i=0; i<l;i++){
		sampleBuffer[i] *= a0 - a1 * Math.cos(this.Pi2 * i / (l - 1)) + a2 * Math.cos(4 * this.pi * i / (l - 1));
	}
	this.windowCallback(sampleBuffer);
};

wf.prototype.windowCosine = function(sampleBuffer){
	var l = sampleBuffer.length;
	for(var i=0; i<l;i++){
		sampleBuffer[i] *= Math.cos(Math.PI * i / (l - 1) - this.pi / 2);
	}
	this.windowCallback(sampleBuffer);
};

wf.prototype.windowGauss = function(sampleBuffer){
	var l = sampleBuffer.length;
	for(var i=0; i<l;i++){
		sampleBuffer[i]  *= Math.pow(Math.E, -0.5 * Math.pow((i - (l - 1) / 2) / (this.alpha * (l - 1) / 2), 2));
	}
	this.windowCallback(sampleBuffer);
};

wf.prototype.windowTriangular = function(sampleBuffer){
	var l = sampleBuffer.length;
	for(var i=0; i<l;i++){
		sampleBuffer[i]  *=  2 / l * (l / 2 - Math.abs(i - (l - 1) / 2));
	}
	this.windowCallback(sampleBuffer);
};

wf.prototype.windowLanczos = function(sampleBuffer){
	var l = sampleBuffer.length;
	for(var i=0; i<l;i++){
		var x = 2 * i / (l - 1) - 1;
		sampleBuffer[i]  *=  Math.sin(Math.PI * x) / (Math.PI * x);
	}
	this.windowCallback(sampleBuffer);
};


wf.prototype.bypassWindow = function(sampleBuffer){
	this.windowCallback(sampleBuffer);
};

wf.prototype.setWindowFunc = function(windowFunc){
	if(typeof windowFunc === 'string') {
		this.init(windowFunc);
	}else{
		console.log("WindowFunction isn't a string");
	}
};
this.performWindow wird durch den Web audio ScriptProcessor ausgelöst. Das könnte das zirpen verursachen. Vielleicht wird der blockiert für ein paar µs.

Folgende Gegenmaßnahmen habe ich unternommen:
- Berechnung über das DataView Object
- FensterFunktion im WebWorker berechnen,
- Statt TypedArray Normale Arrays
Alles erfolglos.

PS: Das ganze läuft über das Raspberry Pi und es ist auch noch nicht alles fertig, bei weitem noch nicht. Wichtig ist herauszufinden was bei den Fensterfunktionen schief läuft

@tsseh auch dich würde ich bitten den test link anzuklicken. weil es ist unmöglich hier den ganzen Quellcode zu posten.
 
@tsseh auch dich würde ich bitten den test link anzuklicken. weil es ist unmöglich hier den ganzen Quellcode zu posten.
was aber auf der anderen seite auch bedeutet, dasss das wahnsinnig viel code ist, den man sich erst mal ansehen muss.
selbst wenn dazu jemand lust und zeit hat, wird das vermutlich nichts, ohne daran rumzuspielen.
von daher sage ich ja immer erst mal eingrenzen. unittests.
also in deinem fall windowHann mit einem statischen sampleBuffer aufrufen und nachsehen, ob das gewünschte ergebniss rauskommt. wenn nicht, kann man sich die funktion mal ansehen, wenn doch, das selbe mit einer funktion vorher das gleiche spiel.
 
tsseh schrieb:
was aber auf der anderen seite auch bedeutet, dasss das wahnsinnig viel code ist, den man sich erst mal ansehen muss.
selbst wenn dazu jemand lust und zeit hat, wird das vermutlich nichts, ohne daran rumzuspielen.
Ja sind schon ein paar viele Zeilen, aber ohne den das jemand wenigstens mal den Quellcode überfliegt wird das nix. Du und kkapsner sind die einzigen die das lösen können.
Weil, ohne mist das ist schon was höheres.

tsseh schrieb:
also in deinem fall windowHann mit einem statischen sampleBuffer aufrufen und nachsehen, ob das gewünschte ergebniss rauskommt. wenn nicht, kann man sich die funktion mal ansehen, wenn doch, das selbe mit einer funktion vorher das gleiche spiel.
Wie genau meinen? Einen Puffer voll Samples in die Hann Funktion packen und ansehen was JS ausrechnet und das mit dem Taschenrechner "zu fuss" nachvollziehen und abgeglichen.

Die Arbeit kann ich mir sparen. Selbst wenn in sampleBuffer nur Nullen stehen kommt bei einer Multiplikation trotzdem was raus. immer das gleiche 0.999944432154.... in jedem Array Element. Die ersten drei ziffern nach den Komma sind immer 0.999 , der Rest ändert sich von Rechner zu Rechner. Bei manchen kommt der Ominöse Träger bei 30 Hz.
Die Oberwellen kommen bestimmt daher das 0.999 fast das float32 max ist bei 1 ist es ja schon wider rum.
The buffer contains data in the following format: non-interleaved IEEE754 32-bit linear PCM with a nominal range between -1 and +1, that is, 32bits floating point buffer, with each samples between -1.0 and 1.0.
https://developer.mozilla.org/de/docs/Web/API/AudioBuffer

tsseh schrieb:
von daher sage ich ja immer erst mal eingrenzen.
Habe ich auch schon gemacht. Es ist ja nicht nur das Hann Fenster betroffen sondern alle, bis auf das Rechteck.
Die Schlüsselstelle ist das Math.sin/Cos nehme ich das raus(dann ist zwar die Rechnung fürn ar****) geht es. Keine Ton Probleme mehr.

Bin jetzt erst mal für 1bis 2h wech, danach grenze ich mal ein.. vielleicht fällt einen was auf. Habe 14 Tage Urlaub, mein ziel ist es eigentlich das Problem zu lösen.
 
Zuletzt bearbeitet:
Wie genau meinen? Einen Puffer voll Samples in die Hann Funktion packen und ansehen was JS ausrechnet und das mit dem Taschenrechner "zu fuss" nachvollziehen und abgeglichen.
muss ja nicht unbedingt ein tachenrechner sein
https://www.r-project.org/

Die Arbeit kann ich mir sparen. Selbst wenn in sampleBuffer nur Nullen stehen kommt bei einer Multiplikation trotzdem was raus. immer das gleiche 0.999944432154.... in jedem Array Element. Die ersten drei ziffern nach den Komma sind immer 0.999 , der Rest ändert sich von Rechner zu Rechner. Bei manchen kommt der Ominöse Träger bei 30 Hz.
und das glaube ich schon mal nicht, probier das mal aus, und poste den code hier nochmal nur mit dem puffer, der funktion wenn es doch so sein sollte
fang erst mal mit nem puffer an wo nur 0en drinn stehen
 
tsseh schrieb:
und das glaube ich schon mal nicht,
Ausgedacht habe ich mir das nicht.
Hm das mit dem R Dingens.... da müsste ich mich jetzt erst wider rein knien. Weiß auf die schnelle nicht genau was ich da tun soll. Habe das auch als schon mal mit Matlab durch exerzirt.
Allerdings weiß ich dann immer noch nicht warum in JS ein Multiplikation mit 0 Zeugs ergibt.

wenn die Funktion so ausschaut:
Code:
	if(this.i<4){
	var l = sampleBuffer.length;
	for(var i=0; i<l;i++){
		sampleBuffer[i]=0;
		sampleBuffer[i] *= 0.5-0.5 * Math.cos(this.Pi2 * i / (l - 1));// nicht 0.5 * (1 - Math.cos(DSP.TWO_PI * index / (length - 1)));	
	}
	this.i++;
	console.log(sampleBuffer);
	this.windowCallback(sampleBuffer);
	}

};
Kommt das dabei Raus:
Code:
Failed to load resource: the server responded with a status of 404 (Not Found)
Float32Array[4096]
Float32Array[4096]
Float32Array[4096]
Float32Array[4096]
temp1
Float32Array[4096][0 ... 99]0: 0.0096196020022034651: 0.010957675054669382: 0.0122681502252817153: 0.0135472398251295094: 0.0147911943495273595: 0.0159963984042406086: 0.0171594414860010157: 0.0182771757245063788: 0.019346743822097789: 0.02036558650434017210: 0.02133141644299030311: 0.02224217168986797312: 0.02309596352279186213: 0.02389098517596721614: 0.0246254559606313715: 0.0252975430339574816: 0.0259053055197000517: 0.0264466758817434318: 0.02691945061087608319: 0.0273213181644678120: 0.02764992788434028621: 0.02790297940373420722: 0.0280783306807279623: 0.028174141421914124: 0.02818899974226951625: 0.02812205627560615526: 0.0279731359332799927: 0.02774282358586788228: 0.02743251062929630329: 0.027044385671615630: 0.02658138237893581431: 0.02604708448052406332: 0.0254455544054508233: 0.02478115446865558634: 0.02405830658972263335: 0.02328126877546310436: 0.02245387807488441537: 0.02157933264970779438: 0.0206600148230791139: 0.01969733648002147740: 0.01869168318808078841: 0.0176424086093902642: 0.01654792390763759643: 0.01540585514158010544: 0.01421327982097864245: 0.0129670267924666446: 0.0116640245541930247: 0.01030167192220687948: 0.00887821894139051449: 0.007393121719360351650: 0.00584735721349716251: 0.00424367422237992352: 0.002586749847978353553: 0.000883255561348050854: -0.000858191750012338255: -0.002627187175676226656: -0.00441180402413010657: -0.00619895290583372158: -0.00797482207417488159: -0.00972536578774452260: -0.01143682934343814861: -0.01309626922011375462: -0.01469204016029834763: -0.0162142291665077264: -0.01765500754117965765: -0.0190088637173175866: -0.02027274854481220267: -0.0214460566639900268: -0.02253051660954952269: -0.02352994307875633270: -0.02444989234209060771: -0.0252972319722175672: -0.02607965841889381473: -0.02680517733097076474: -0.02748159505426883775: -0.02811602875590324476: -0.02871448919177055477: -0.0292815193533897478: -0.02981996722519397779: -0.030330836772918780: -0.03081327304244041481: -0.0312646478414535582: -0.0316807553172111583: -0.03205611184239387584: -0.0323842801153659885: -0.0326582901179790586: -0.03287102654576301687: -0.0330156758427619988: -0.0330860689282417389: -0.0330770127475261790: -0.0329845622181892491: -0.03280616924166679492: -0.03254078328609466693: -0.03218884021043777594: -0.0317521654069423795: -0.03123382665216922896: -0.0306379050016403297: -0.0299692284315824598: -0.02923309057950973599: -0.02843496948480606[100 … 199]100: -0.0323464497923851101: -0.032222725450992584102: -0.03201907500624657103: -0.0317390002310276104: -0.03138639032840729105: -0.0309652891010046106: -0.030479639768600464107: -0.02993309497833252108: -0.0293288491666317109: -0.028669539839029312110: -0.027957187965512276111: -0.027193203568458557112: -0.026378445327281952113: -0.025513319298624992114: -0.024597905576229095115: -0.023632120341062546116: -0.022615881636738777117: -0.021549267694354057118: -0.020432671532034874119: -0.019266922026872635120: -0.018053382635116577121: -0.016794001683592796122: -0.01549134124070406123: -0.014148548245429993124: -0.012769313529133797125: -0.011357784271240234126: -0.009918466210365295127: -0.00845610722899437128: -0.006975580472499132129: -0.0054817721247673035130: -0.003979476634413004131: -0.002473312197253108132: -0.000967657018918544133: 0.0005333870649337769134: 0.002026011236011982135: 0.0035066925920546055136: 0.004972166381776333137: 0.006419382989406586138: 0.007845454849302769139: 0.00924760289490223140: 0.010623099282383919141: 0.011969223618507385142: 0.013283219188451767143: 0.014562275260686874144: 0.015803515911102295145: 0.01700400374829769146: 0.01816076971590519147: 0.01927083358168602148: 0.020331252366304398149: 0.021339165046811104150: 0.02229183167219162151: 0.023186683654785156152: 0.02402135170996189153: 0.024793701246380806154: 0.025501834228634834155: 0.026144102215766907156: 0.026719097048044205157: 0.02722562849521637158: 0.02766270376741886159: 0.02802949585020542160: 0.02832532301545143161: 0.02854960411787033162: 0.02870185673236847163: 0.028781671077013016164: 0.02878871187567711165: 0.028722723945975304166: 0.028583550825715065167: 0.028371155261993408168: 0.02808566391468048169: 0.027727387845516205170: 0.027296870946884155171: 0.02679491601884365172: 0.026222610846161842173: 0.025581348687410355174: 0.024872824549674988175: 0.02409902960062027176: 0.023262226954102516177: 0.022364920005202293178: 0.02140979655086994179: 0.020399687811732292180:



Das
Code:
wf.prototype.windowHann = function(sampleBuffer){
	if(this.i<4){
	var l = sampleBuffer.length;
	var windowedBuffer = new Float32Array(l)
	for(var i=0; i<l;i++){
		sampleBuffer[i]=0;
	windowedBuffer[i] = sampleBuffer[i] * 0.5-0.5 * Math.cos(this.Pi2 * i / (l - 1));// nicht 0.5 * (1 - Math.cos(DSP.TWO_PI * index / (length - 1)));	
	}
	this.i++;
	console.log(windowedBuffer);
	this.windowCallback(sampleBuffer);
	}

};
ergibt das:
Code:
Navigated to http://rtg-test.sytes.net/grabber/DL3ARM?GrabberName=Normal-CW-Mediumwave&RX_Frequency=0%20-%2022,5%20kHz
[-0.5, -0.49999940395355225, -0.49999764561653137, -0.499994695186615, -0.4999905824661255, -0.4999852776527405, -0.49997881054878235, -0.4999711513519287, -0.49996232986450195, -0.4999523162841797, -0.4999411404132843, -0.4999287724494934, -0.4999152421951294, -0.49990054965019226, -0.49988463521003723, -0.49986758828163147, -0.4998493492603302, -0.4998299181461334, -0.4998093247413635, -0.4997875392436981, -0.4997645914554596, -0.49974048137664795, -0.4997151494026184, -0.49968868494033813, -0.49966102838516235, -0.49963217973709106, -0.49960219860076904, -0.4995709955692291, -0.4995386302471161, -0.49950510263442993, -0.49947038292884827, -0.4994345009326935, -0.4993974268436432, -0.4993591904640198, -0.49931979179382324, -0.4992791712284088, -0.49923741817474365, -0.499194473028183, -0.4991503655910492, -0.4991050660610199, -0.4990586042404175, -0.49901095032691956, -0.4989621341228485, -0.49891215562820435, -0.4988609850406647, -0.4988086223602295, -0.4987551271915436, -0.49870043992996216, -0.49864456057548523, -0.4985875189304352, -0.498529314994812, -0.49846991896629333, -0.49840936064720154, -0.4983476400375366, -0.4982847273349762, -0.49822065234184265, -0.498155415058136, -0.4980889856815338, -0.4980213940143585, -0.4979526102542877, -0.4978826642036438, -0.49781155586242676, -0.4977392852306366, -0.4976658225059509, -0.49759119749069214, -0.49751538038253784, -0.4974384009838104, -0.4973602592945099, -0.49728095531463623, -0.49720048904418945, -0.49711883068084717, -0.4970359802246094, -0.49695199728012085, -0.4968668222427368, -0.49678048491477966, -0.4966929852962494, -0.496604323387146, -0.4965144693851471, -0.4964234530925751, -0.49633127450942993, -0.49623793363571167, -0.4961434006690979, -0.4960477352142334, -0.4959508776664734, -0.49585285782814026, -0.495753675699234, -0.49565330147743225, -0.49555179476737976, -0.49544909596443176, -0.49534523487091064, -0.4952402114868164, -0.49513402581214905, -0.49502667784690857, -0.49491816759109497, -0.49480846524238586, -0.494697630405426, -0.4945856034755707, -0.4944724440574646, -0.494358092546463, -0.4942425787448883…]
[-0.5, -0.49999940395355225, -0.49999764561653137, -0.499994695186615, -0.4999905824661255, -0.4999852776527405, -0.49997881054878235, -0.4999711513519287, -0.49996232986450195, -0.4999523162841797, -0.4999411404132843, -0.4999287724494934, -0.4999152421951294, -0.49990054965019226, -0.49988463521003723, -0.49986758828163147, -0.4998493492603302, -0.4998299181461334, -0.4998093247413635, -0.4997875392436981, -0.4997645914554596, -0.49974048137664795, -0.4997151494026184, -0.49968868494033813, -0.49966102838516235, -0.49963217973709106, -0.49960219860076904, -0.4995709955692291, -0.4995386302471161, -0.49950510263442993, -0.49947038292884827, -0.4994345009326935, -0.4993974268436432, -0.4993591904640198, -0.49931979179382324, -0.4992791712284088, -0.49923741817474365, -0.499194473028183, -0.4991503655910492, -0.4991050660610199, -0.4990586042404175, -0.49901095032691956, -0.4989621341228485, -0.49891215562820435, -0.4988609850406647, -0.4988086223602295, -0.4987551271915436, -0.49870043992996216, -0.49864456057548523, -0.4985875189304352, -0.498529314994812, -0.49846991896629333, -0.49840936064720154, -0.4983476400375366, -0.4982847273349762, -0.49822065234184265, -0.498155415058136, -0.4980889856815338, -0.4980213940143585, -0.4979526102542877, -0.4978826642036438, -0.49781155586242676, -0.4977392852306366, -0.4976658225059509, -0.49759119749069214, -0.49751538038253784, -0.4974384009838104, -0.4973602592945099, -0.49728095531463623, -0.49720048904418945, -0.49711883068084717, -0.4970359802246094, -0.49695199728012085, -0.4968668222427368, -0.49678048491477966, -0.4966929852962494, -0.496604323387146, -0.4965144693851471, -0.4964234530925751, -0.49633127450942993, -0.49623793363571167, -0.4961434006690979, -0.4960477352142334, -0.4959508776664734, -0.49585285782814026, -0.495753675699234, -0.49565330147743225, -0.49555179476737976, -0.49544909596443176, -0.49534523487091064, -0.4952402114868164, -0.49513402581214905, -0.49502667784690857, -0.49491816759109497, -0.49480846524238586, -0.494697630405426, -0.4945856034755707, -0.4944724440574646, -0.494358092546463, -0.4942425787448883…]
[-0.5, -0.49999940395355225, -0.49999764561653137, -0.499994695186615, -0.4999905824661255, -0.4999852776527405, -0.49997881054878235, -0.4999711513519287, -0.49996232986450195, -0.4999523162841797, -0.4999411404132843, -0.4999287724494934, -0.4999152421951294, -0.49990054965019226, -0.49988463521003723, -0.49986758828163147, -0.4998493492603302, -0.4998299181461334, -0.4998093247413635, -0.4997875392436981, -0.4997645914554596, -0.49974048137664795, -0.4997151494026184, -0.49968868494033813, -0.49966102838516235, -0.49963217973709106, -0.49960219860076904, -0.4995709955692291, -0.4995386302471161, -0.49950510263442993, -0.49947038292884827, -0.4994345009326935, -0.4993974268436432, -0.4993591904640198, -0.49931979179382324, -0.4992791712284088, -0.49923741817474365, -0.499194473028183, -0.4991503655910492, -0.4991050660610199, -0.4990586042404175, -0.49901095032691956, -0.4989621341228485, -0.49891215562820435, -0.4988609850406647, -0.4988086223602295, -0.4987551271915436, -0.49870043992996216, -0.49864456057548523, -0.4985875189304352, -0.498529314994812, -0.49846991896629333, -0.49840936064720154, -0.4983476400375366, -0.4982847273349762, -0.49822065234184265, -0.498155415058136, -0.4980889856815338, -0.4980213940143585, -0.4979526102542877, -0.4978826642036438, -0.49781155586242676, -0.4977392852306366, -0.4976658225059509, -0.49759119749069214, -0.49751538038253784, -0.4974384009838104, -0.4973602592945099, -0.49728095531463623, -0.49720048904418945, -0.49711883068084717, -0.4970359802246094, -0.49695199728012085, -0.4968668222427368, -0.49678048491477966, -0.4966929852962494, -0.496604323387146, -0.4965144693851471, -0.4964234530925751, -0.49633127450942993, -0.49623793363571167, -0.4961434006690979, -0.4960477352142334, -0.4959508776664734, -0.49585285782814026, -0.495753675699234, -0.49565330147743225, -0.49555179476737976, -0.49544909596443176, -0.49534523487091064, -0.4952402114868164, -0.49513402581214905, -0.49502667784690857, -0.49491816759109497, -0.49480846524238586, -0.494697630405426, -0.4945856034755707, -0.4944724440574646, -0.494358092546463, -0.4942425787448883…]


ok er rechnet nicht 0.999444 au sondern 0.499999 aber egal 0 *x ist 0. Aber Js ist andere Meinung.

Was ich ja überhaupt nicht versteh ist, wieso sich die Fensterfunktion auf die Soundausgabe auswirken. Die Ausgabe ist doch schon geschehen, dann erst werden die Samples zu den Fenstern gereicht.

Der onaudioprocess teil sieht so aus:
Code:
player.prototype.play = function(ev) {
    var outputLeft = ev.outputBuffer.getChannelData(0);
    var Len = ev.outputBuffer.length;
    var total = 0; //var for decibel calculation
    var rms = 0; //Root Mean Square
    var decibel = 0;
    for (ev = 0; ev < Len; ev++) {
        var sample = this.IntBuffer[this.r_ptr];
        var ratio = this.pBs * this.InRate / this.OutRate;
        this.ratioWeight += ratio;
        // Sample Rate calibration
        if (1 <= this.ratioWeight) {
            this.ratioWeight -= 1;
            this.IntBuffer[this.r_ptr] = 0.0;
            this.r_ptr++;
            if (this.bufferSize <= this.r_ptr) this.r_ptr -= this.bufferSize;
            var sample2 = this.IntBuffer[this.r_ptr];
            sample = (this.ratioWeight * sample2 + (ratio - this.ratioWeight) * sample) / ratio;
        }
        sample = sample > 0 ? sample / 32767.0 : sample / 32768.0;
        //detect clipping errors
        if (sample < -1) sample = -1;
        if (sample > 1) sample = 1;
        //FIR Lowpass Filter
        this.delayLine[this.count] = sample;
        var FIR_out = 0.0;
        var idx = this.count;
        for (var i = 0; i < this.coefs.length; i++) {
            FIR_out += this.coefs[i] * this.delayLine[idx--];
            if (idx < 0) idx = this.coefs.length - 1;
        }
        if (++this.count >= this.coefs.length) this.count = 0;
        sample = FIR_out;
        //summ of all 4096 samples   
        total += Math.abs(sample);
        outputLeft[ev] = sample; //sound output
    } //ende for
    this.SamplesCallback(outputLeft);
    //calc decibel
    rms = Math.sqrt(total / Len);
    decibel = 20 * (Math.log(rms) / Math.log(10));
    this.dBCallback(decibel);
    this.SPTime = this.audioctx.currentTime; //(new Date).getTime();
    //debugging SP
   if(0 == outputLeft[0] && this.H++);//console.log("SP abstuerze "+ this.H);
};
this.SamplesCallback(outputLeft); triggert erst nach dem die for loop durch ist. Schreibe ich this.SamplesCallback(new Float32Array(outputLeft)); ist das Ton Problem auch weg, nicht aber das was JS da rechnet

Vielleicht ist das Problem das ich jedes Spektrogramm in einem Object Literal speichere.
Code:
                    $.each(loadedData.Windows, function(key, value) {
                        if (key in GrabberStack) {
                            GrabberStack[key]["Window"] = new Window(key, data.GrabberID, "CSH_" + key, "texterea_" + key)
                            GrabberStack[key]["Resampler"] = new Resampler(GrabberStack.Player.getSampleRate(), value.UserRate, 4096);
                            GrabberStack[key]["DSP_Window"] = new wf(value.DSP_Window);
                            //set values on window 
                            GrabberStack[key]["Window"].setSamplerate(value.UserRate, GrabberStack.Player.getSampleRate());
                            GrabberStack[key]["Window"].setFFT_size(value.FFTInputLength);
                            GrabberStack[key]["Window"].setFrequency(value.F_min, value.F_max, value.Offs);
                            GrabberStack[key]["Window"].setPowerUnits(value.db_from, value.db_to);
                            GrabberStack[key]["Window"].setColors(value.colors);
                            GrabberStack[key]["Window"].setBrighness(value.brightness);
                            GrabberStack[key]["Window"].setContrast(value.contrast);
                            GrabberStack[key]["Window"].setScrollIntervall(value.ScrollInter);
                            //set callbacks
                            //callback from resampler, write data in dsp Window Function  
                            GrabberStack[key]["Resampler"].resampleOutput = function(resampledBuffer) {
                                    GrabberStack[key]["DSP_Window"].performWindow(resampledBuffer);
                                }
                                //callback from dspWidnow, write data in Grabber window last process
                            GrabberStack[key]["DSP_Window"].windowCallback = function(windowSample) {
                                    GrabberStack[key]["Window"].pushSamples(windowSample);
                                }
                                //not used the measured decibels
                            GrabberStack.Player.dBCallback = function(dB) {
                                //document.getElementById("dB").innerHTML = dB +"    dB";
                                //normal_cw_widnow.setDecibel(dB);
                            }
                        } else {
                            console.log("Ein Fehler im Grabber Stack");
                        }
                    }); //each  ende
                    //each Sample callback run a loop through loadedData.Grabber object to put all samples in the various windows.
                    GrabberStack.Player.SamplesCallback = function(sampleBuffer) {
                            for (var key in loadedData.Windows) {
                                if (loadedData.Windows.hasOwnProperty(key)) {
                                    GrabberStack[key]["Resampler"].resample(sampleBuffer);
                                }
                            }
                        } // ende .SamplesCallback 

                })
Puh, das war jetzt viel. Bin am ende mit meinem Latein.
 
Zuletzt bearbeitet:
Allerdings weiß ich dann immer noch nicht warum in JS ein Multiplikation mit 0 Zeugs ergibt.
weil es so nicht ist, probier es mal mit nur dieser funktion und einem 0-puffer

Der onaudioprocess teil sieht so aus:
das ist mir für heute zuviel, aber was mir aufgefallen ist,
*du nutzt ja nicht den inputbuffer, was macht das dann für einen sinn?
*du überschreibst ev, ich glaube nicht, dass es das ist, aber einen versuch ist es wert
 
tsseh schrieb:
probier es mal mit nur dieser funktion und einem 0-puffer
Was genau ist diese funktion? das R ding. Den Puffer habe ich doch schon geleert. sampleBuffer[i]=0;
Mehr als 0 kann ich nicht da rein rein schreiben:confused:
Ok, ich könnte this.SamplesCallback(new Float32Array(4096)); schreiben dann ist auch alles 0.

tsseh schrieb:
du nutzt ja nicht den inputbuffer, was macht das dann für einen sinn?
Die audio Samples werden durch eine websocket Verbindung gespeist und im Jitterbuffer this.IntBuffer abgelagert und abgeholt.
Das streamen und abspielen ist ja auch nicht das Problem. Problematisch wird erst wenn man die Fensterfunktionen dazu holt.


tsseh schrieb:
du überschreibst ev, ich glaube nicht, dass es das ist, aber einen versuch ist es wert
Ja kann man mal probieren. Aber...

=tsseh schrieb:
das ist mir für heute zuviel
Mir auch. Morgen ist ein neuer Tag.

Eventuell kann ja Korbinian was dazu beitragen.

Ich halte ja den Scriprocessor für den Übeltäter warum kann ich nicht genau sagen, aber das ding stand mehrmals bei bugzilla zur Debatte.
https://bugzilla.mozilla.org/show_bug.cgi?id=970083
es gab auch Probleme wegen garbage collecting
https://bugs.webkit.org/show_bug.cgi?id=112521
https://code.google.com/p/chromium/issues/detail?id=379753
web audio - Chrome: onaudioprocess stops getting called after a while - Stack Overflow

PS. ich habe nie verstanden was garbage collecting in js zu suchen hat.:confused:
 
Zuletzt bearbeitet:
Was genau ist diese funktion?
windowHann


Den Puffer habe ich doch schon geleert. sampleBuffer[i]=0;
Mehr als 0 kann ich nicht da rein rein schreiben:confused:
kopier si in ein html file, übergebe ihr eineen 0-puffer und überzeuge dich, dass am ende wieder ein 0-puffer rauskommt

Ok, ich könnte this.SamplesCallback(new Float32Array(4096)); schreiben dann ist auch alles 0.
nein, windowHann (new Float32Array(4096)), schritt für schritt

Die audio Samples werden durch eine websocket Verbindung gespeist und im Jitterbuffer this.IntBuffer abgelagert und abgeholt.
Das streamen und abspielen ist ja auch nicht das Problem. Problematisch wird erst wenn man die Fensterfunktionen dazu holt.
was auch immer du sagst, das kann so niemand nachvollziehen, das sind die vielen nächsten schritte

- - - Aktualisiert - - -

das
Code:
sampleBuffer[i] *= 0.5-0.5 * Math.cos(this.Pi2 * i / (l - 1));
ist übrigens nicht
Code:
windowedBuffer[i] = sampleBuffer[i] * 0.5-0.5 * Math.cos(this.Pi2 * i / (l - 1));
hier fehlt noch ein
Code:
windowedBuffer[i] = sampleBuffer[i] * 0.5-sampleBuffer[i] * 0.5 * Math.cos(this.Pi2 * i / (l - 1));

- - - Aktualisiert - - -

this.SamplesCallback(outputLeft); triggert erst nach dem die for loop durch ist. Schreibe ich this.SamplesCallback(new Float32Array(outputLeft)); ist das Ton Problem auch weg
das könnte darauf hindeuten, dass du ein problem im ablauf hast, also sowas wie dass der buffer irgendwo anders noch benutz wird, und hier irgendwo noch was asynchrones drinn steckt. dazu müsstest du aber mal deinen ablauf darstellen
aber nicht so
Die audio Samples werden durch eine websocket Verbindung gespeist und im Jitterbuffer this.IntBuffer abgelagert und abgeholt.
sondern so
* code von windowHann, ok, den haben wir schon
* wo wird windowHann aufgefufen
* wo wird das was windowHann aufruft aufgefufen
* ...

Vielleicht ist das Problem das ich jedes Spektrogramm in einem Object Literal speichere.
keine ahnung, wo der codeschnipsel jetzt wieder einzuordnen ist
 
tsseh schrieb:
kopier si in ein html file, übergebe ihr eineen 0-puffer und überzeuge dich, dass am ende wieder ein 0-puffer rauskommt
Das habe ich gemacht. Siehe und staune da kam NaN raus... Ok DSP Lektüre aufgeschlagen und alles überprüft. Habe das hann fester dann etwas anders geschrieben dann kam auch 0 Raus.
So:
Code:
<!DOCTYPE html>
<head>
<title>Bla Blub</title>
</head>
<body>
    <script>
function test (sampleBuffer) {
	var l = sampleBuffer.length;
        var arg = 2.0*Math.PI/(l-1)
	for(var i=0; i<l;i++){
	sampleBuffer[i] *= 0.5 - 0.5 * Math.cos(i*arg);	
	}
	console.log(sampleBuffer)
};
    </script>

 <button type="button" id="berechnen" onclick="test(new Float32Array(4096));">berechnen</button>


</body>
</html>

So weit so gut eingebaut ins Skript und genau das selbe Problem Ton Zirpst, Ominöser Träger bei 50 hz. Warum sollte es auch weg sein ist ja bei Jeden Fenster so, nicht nur beim Hann.


tsseh schrieb:
du überschreibst ev, ich glaube nicht, dass es das ist, aber einen versuch ist es wert
Auch das habe ich getestet. Jetzt kommt der brüller, habe das ev in der Schleife durch var i ersetzt. Da passiert auf einmal nix mehr CPU Load 100% In Chrome und FF. Dachte erst mein rechner ist am spinnen aber auf'm Laptop das selbe. Die Browser sind aber nicht komplett eingefroren. Der Hintergrund wird noch gerendet dann ist Schluss. Schließen kann ich die auch noch.
Dann rödelt die svchost.exe für ein paar Sekunden hoch dann ist ruhe.

Und nun webkit Bug???

tsseh schrieb:
das könnte darauf hindeuten, dass du ein problem im ablauf hast, also sowas wie dass der buffer irgendwo anders noch benutz wird, und hier irgendwo noch was asynchrones drinn steckt. dazu müsstest du aber mal deinen ablauf darstellen
aber nicht so

Das erste Glied in der Kette ist der Player gefolgt von einen Resampler(weil die Webaudio Api von Rechner zu Rechner andre Samplerates hat), dann die Fensterfunktion, danach FFT, zum Schluss Canvas.

Player:
PHP:
"use strict";
function player(ID, URL) {
    //Audio Stuff
	if(!window.AudioContext){
		if(!window.webkitAudioContext){
			alert("no audiocontext found!");
		}
		window.AudioContext = window.webkitAudioContext;
	}
    this.audioctx = new AudioContext();
    this.w_ptr = 0;
    this.r_ptr = 30720;
    this.bufferSize = 32768;
    this.IntBuffer = new Int16Array(this.bufferSize);
    this.InRate = 8000; //hz
    //this.outputBuffer = new Float32Array(4096);//this Array goes to the otehr objects (Resampler, windowFunctions)
    this.p = null;
    this.OutRate = this.audioctx.sampleRate;
    //this.N_of_samples = 4096; //number of samples where Script Processor play through
    this.coefs = this.calcCoeffs(this.OutRate, this.InRate, 256); //calculate the lowpass coefficients
    this.delayLine = new Float32Array(this.coefs.length);
    this.count = 0;
    //some varibles for the "jitterbuffer"
    this.pBs = 0.0; //toggle the playback speed if the buffer underruns or overrun
    this.ratioWeight = 0.0;
    this.SPTime = 0.0;
    this.connection();
    this.getSamples(URL);
}

player.prototype.calcCoeffs = function(SR, cutOff, len) {
    len += (len + 1) % 2;
    var freq = cutOff / SR;
    var coefs = new Float32Array(len);
    var center = Math.floor(len / 2);
    var sum = 0;
    for (var i = 0; i < len; ++i) {
        var val;
        if (i == center) {
            val = 2 * Math.PI * freq;
        } else {
            var angle = 2 * Math.PI * (i + 1) / (len + 1);
            val = Math.sin(2 * Math.PI * freq * (i - center)) / (i - center);
            val *= 0.42 - 0.5 * Math.cos(angle) + 0.08 * Math.cos(2 * angle);
        }
        sum += val;
        coefs[i] = val;
    }
    for (var i = 0; i < len; ++i) {
        coefs[i] /= sum;
    }
    return coefs;
};

//connect the web audio Node
player.prototype.connection = function() {
	this.H = 5;
    var K = false, N = 25, that = this;

    var Processor,  ueberwacher;
    if(this.audioctx.createScriptProcessor){
    	Processor = this.audioctx.createScriptProcessor(4096, 0, 1);
    	ueberwacher = this.audioctx.createScriptProcessor(4096, 1, 1);
    }else{
    	Processor = this.audioctx.createjavaScriptNode(4096, 1, 1);
    	ueberwacher = this.audioctx.createjavaScriptNode(4096, 1, 1);
    }
    
  //  var Processor = this.audioctx.createScriptProcessor(4096, 0, 1);
    Processor.onaudioprocess = this.play.bind(this);
    if(!!window.chrome){
  // var ueberwacher = this.audioctx.createScriptProcessor(4096, 1, 1);
    this.p = Processor;
    Processor.connect(ueberwacher);
    ueberwacher.onaudioprocess = function(a) {
        a = a.inputBuffer.getChannelData(0);
        K || (N ? N-- : 0 != a[0] ? that.H = 5 : (that.H--, that.H || (that.H = 5, N = 25, Processor.disconnect(), Processor.onaudioprocess = null, Processor = that.audioctx.createScriptProcessor(4096, 1, 1), Processor.onaudioprocess =
            that.play, that.p = Processor, Processor.connect(that.audioctx.destination), Processor.connect(ueberwacher))));
        
    }//ueberwacher.onaudioprocess
    }//ende var isChrome = !!window.chrome;    
    Processor.connect(this.audioctx.destination);
};


player.prototype.SamplesCallback = function() {};
player.prototype.dBCallback = function() {};
player.prototype.trigger = function() {};

player.prototype.getSampleRate = function() {
    return this.audioctx.sampleRate;
};

player.prototype.play = function(ev) {
    var outputLeft = ev.outputBuffer.getChannelData(0);
    var Len = ev.outputBuffer.length;
    var total = 0; //var for decibel calculation
    var rms = 0; //Root Mean Square
    var decibel = 0;
    for (ev = 0; ev < Len; ev++) {
        var sample = this.IntBuffer[this.r_ptr];
        var ratio = this.pBs * this.InRate / this.OutRate;
        this.ratioWeight += ratio;
        // Sample Rate calibration
        if (1 <= this.ratioWeight) {
            this.ratioWeight -= 1;
            this.IntBuffer[this.r_ptr] = 0.0;
            this.r_ptr++;
            if (this.bufferSize <= this.r_ptr) this.r_ptr -= this.bufferSize;
            var sample2 = this.IntBuffer[this.r_ptr];
            sample = (this.ratioWeight * sample2 + (ratio - this.ratioWeight) * sample) / ratio;
        }
        sample = sample > 0 ? sample / 32767.0 : sample / 32768.0;
        //detect clipping errors
        if (sample < -1) sample = -1;
        if (sample > 1) sample = 1;
        //FIR Lowpass Filter
        this.delayLine[this.count] = sample;
        var FIR_out = 0.0;
        var idx = this.count;
        for (var i = 0; i < this.coefs.length; i++) {
            FIR_out += this.coefs[i] * this.delayLine[idx--];
            if (idx < 0) idx = this.coefs.length - 1;
        }
        if (++this.count >= this.coefs.length) this.count = 0;
        sample = FIR_out;
        //summ of all 4096 samples   
        total += Math.abs(sample);
       // this.outputBuffer[ev] = sample;
        outputLeft[ev] = sample; //sound output
    } //ende for
    this.SamplesCallback(outputLeft);
    //calc decibel
    rms = Math.sqrt(total / Len);
    decibel = 20 * (Math.log(rms) / Math.log(10));
    this.dBCallback(decibel);
    this.SPTime = this.audioctx.currentTime; //(new Date).getTime();
    //debugging SP
   if(0 == outputLeft[0] && this.H++);//console.log("SP abstuerze "+ this.H);
};


player.prototype.getSamples = function(URL) {
    var that = this;
    var ws = new WebSocket(URL);
    ws.binaryType = 'arraybuffer';
    var response_speed = 500; //ms
    ws.onmessage = function(b) {
        var jit = (that.bufferSize * 2 + that.w_ptr - that.r_ptr - (that.audioctx.currentTime - that.SPTime) * that.InRate / 1E3) % that.bufferSize;
        response_speed += 0.01 * (jit - response_speed);
        if (response_speed > 3E3) {
            that.r_ptr = (that.bufferSize + that.w_ptr - 1E3) % that.bufferSize;
            jit = response_speed = 1E3;
        }
        that.pBs = 1 + 1E-5 * (response_speed - 1E3);
        if (1.002 < that.pBs) that.pBs = 1.002;
        if (0.998 > that.pBs) that.pBs = 0.998;
        var dv = new DataView(b.data);
        that.InRate = dv.getUint16(0);//Get the Samplerate from the Buffer
        var I16 = new Int16Array(b.data), i = 1;//i=1 weil die ersten 2 byte die Samplrate sind 
        while (i < I16.length) {
            that.w_ptr++, i++;
            that.IntBuffer[that.w_ptr] = I16[i];
            if (that.bufferSize <= that.w_ptr) that.w_ptr -= that.bufferSize;
        };
    };
};
Wie schon erwähnt liegt der Fehler nicht in den Syntax vom Player Objekt. Selbst ein weises Rauschen(Math.random()) klingt "gezirpt".


Resampler:
PHP:
function Resampler(fromRate, toRate , length){
		this.length = length;
		this.fromRate = fromRate;
		this.init(toRate);
};


Resampler.prototype.init = function(toRate){
	var fromRate =  this.fromRate;
	var length = this.length;
	
	if(fromRate == toRate){
		this.resample = this.bypassResampler;
	}else{
		if(fromRate < toRate){//upsample
			this.ratio = fromRate/toRate;
			this.outputBuffer = new Float32Array(parseInt(length/this.ratio));
			this.resample = this.upSample;
			this.lpf = new audioLib.BiquadFilter.LowPass(toRate, toRate/2, 0.5);
		}else{//downsample
			this.ratio = toRate/fromRate;
			this.outputBuffer = new Float32Array(parseInt(length*this.ratio));
			this.resample = this.downSample;
			this.lpf = new audioLib.BiquadFilter.LowPass(toRate, toRate/2, 0.5);
		}
	}
};

Resampler.prototype.resampleOutput = function(){};

Resampler.prototype.upSample = function(buffer){
	var length = buffer.length;
	var pos = 0.0;
	for(var i=0;i<this.outputBuffer.length;i++){
		var inPos = parseInt(pos);
		var proportion = pos-inPos;
		if(inPos >= length-1){
			inPos = length-2;
			proportion=1.0;
		}
		this.outputBuffer[i] = buffer[inPos]*(1.0-proportion)+buffer[inPos+1]*proportion;
		pos+=this.ratio;
	}
	//Perform Anti-alasing lowPass	
	for(var j=0;j<this.outputBuffer.length;j++){
		this.lpf.pushSample(this.outputBuffer[j]);
		this.outputBuffer[j] = this.lpf.getMix();
	}
	this.resampleOutput(this.outputBuffer);
};

Resampler.prototype.downSample = function(buffer){
	var sum = 0.0;
	var inPos = 0.0;
	var outPos=0;
	var pos=0;
	while(outPos<this.outputBuffer.length){
		var thisVal=buffer[inPos++];
		var nextPos=pos+this.ratio;
		if(nextPos>=1.0){
			sum+=thisVal*(1.0-pos);
			this.outputBuffer[outPos++]=sum;
			nextPos-=1.0;
			sum=nextPos*thisVal;
		}else{
			sum+=this.ratio*thisVal;
		}
		pos=nextPos;
		if(inPos>=buffer.length && outPos<this.outputBuffer.length){
			this.outputBuffer[outPos++]=sum/pos;
		}
	}
	//Perform Anti-alasing lowPass	
	for(var j=0;j<this.outputBuffer.length;j++){
		this.lpf.pushSample(this.outputBuffer[j]);
		this.outputBuffer[j] = this.lpf.getMix();
	}
	this.resampleOutput(this.outputBuffer);
};

Resampler.prototype.bypassResampler = function(buffer){
	this.resampleOutput(buffer);
};

Resampler.prototype.reset = function(toRate){
	this.resample = null;
	toRate = parseInt(toRate);
    this.init(toRate);
};

Gefolgt von den Fensterfunktion.
Dann geht alles in die FFT, die ist von audiolibjs
https://github.com/jussi-kalliokoski/audiolib.js/blob/master/src/processors/fft.js

Aufgerufen wird alles hier:
PHP:
                   $.each(loadedData.Windows, function(key, value) {
                        if (key in GrabberStack) {
                            GrabberStack[key]["Window"] = new Window(key, data.GrabberID, "CSH_" + key, "texterea_" + key)
                            GrabberStack[key]["Resampler"] = new Resampler(GrabberStack.Player.getSampleRate(), value.UserRate, 4096);
                            GrabberStack[key]["DSP_Window"] = new wf(value.DSP_Window);
                            //set values on window 
                            GrabberStack[key]["Window"].setSamplerate(value.UserRate, GrabberStack.Player.getSampleRate());
                            GrabberStack[key]["Window"].setFFT_size(value.FFTInputLength);
                            GrabberStack[key]["Window"].setFrequency(value.F_min, value.F_max, value.Offs);
                            GrabberStack[key]["Window"].setPowerUnits(value.db_from, value.db_to);
                            GrabberStack[key]["Window"].setColors(value.colors);
                            GrabberStack[key]["Window"].setBrighness(value.brightness);
                            GrabberStack[key]["Window"].setContrast(value.contrast);
                            GrabberStack[key]["Window"].setScrollIntervall(value.ScrollInter);
                            //set callbacks
                            //callback from resampler, write data in dsp Window Function  
                            GrabberStack[key]["Resampler"].resampleOutput = function(resampledBuffer) {
                                    GrabberStack[key]["DSP_Window"].performWindow(resampledBuffer);
                                }
                                //callback from dspWidnow, write data in Grabber window last process
                            GrabberStack[key]["DSP_Window"].windowCallback = function(windowSample) {
                                    GrabberStack[key]["Window"].pushSamples(windowSample);
                                }
                                //not used the measured decibels
                            GrabberStack.Player.dBCallback = function(dB) {
                                //document.getElementById("dB").innerHTML = dB +"    dB";
                                //normal_cw_widnow.setDecibel(dB);
                            }
                        } else {
                            console.log("Ein Fehler im Grabber Stack");
Alles wird im Objekt Literal " GrabberStack " aufbewahrt.
 
Habe das hann fester dann etwas anders geschrieben dann kam auch 0 Raus.
...
So weit so gut eingebaut ins Skript und genau das selbe Problem Ton Zirpst, Ominöser Träger bei 50 hz.
also, wir können festhalten, diese funktion ist es nicht
Warum sollte es auch weg sein ist ja bei Jeden Fenster so, nicht nur beim Hann.
sag ich ja, die funktion ist ok

Und nun webkit Bug???
xorg1990 Bug!!!

Das erste Glied in der Kette ist der Player gefolgt von einen Resampler(weil die Webaudio Api von Rechner zu Rechner andre Samplerates hat), dann die Fensterfunktion, danach FFT, zum Schluss Canvas.
ich kuck mal bei gelegenheit

- - - Aktualisiert - - -

also soweit ich das sehe(was hier interessant ist), gibt es die scriptnode processor. die geht direkt ouf den output.
was die in play macht ist ja nur das einlesen aus irgendeinem internen puffer. das sieht zwar auch eigentümlich aus, aber nehmen wir mal an, das funktioniert.
jedenfalls mehr kann ich nicht sehen, da irgendwo noch eine weitere node zw. output und processor hängt, die daten abzweigt.
das was du hörst ist also das was du in play in den output schreibst. klingt das komisch, ist dein internen puffer oder das einlesen daraus komisch.
aber wie kommst du nun zu den daten für deine windowHann? werden die wieder aus deinem internen puffer gelesen? wo?

Aufgerufen wird alles hier:
hier werden nur ein paar eigenshaften gesetzt
Alles wird im Objekt Literal " GrabberStack " aufbewahrt.
was wird hier aufbewahrt und wozu
 
Danke erst mal das du mich so tatkräftig unterstürzt!!

tsseh schrieb:
Ja hast recht... habe ja im FIR Filter schon einen variable i deswegen ging es nicht.


tsseh schrieb:
jedenfalls mehr kann ich nicht sehen, da irgendwo noch eine weitere node zw. output und processor hängt, die daten abzweigt.
Was möchtest du da sehen? Du siehst doch den den selben code den ich sehe oder hast du andre Möglichkeiten zum debuggen? Ja es gibt noch einen 2ten processor, den ich überwacher genant habe.

Code:
  if(!!window.chrome){
  // var ueberwacher = this.audioctx.createScriptProcessor(4096, 1, 1);
    this.p = Processor;
    Processor.connect(ueberwacher);
    ueberwacher.onaudioprocess = function(a) {
        a = a.inputBuffer.getChannelData(0);
        K || (N ? N-- : 0 != a[0] ? that.H = 5 : (that.H--, that.H || (that.H = 5, N = 25, Processor.disconnect(), Processor.onaudioprocess = null, Processor = that.audioctx.createScriptProcessor(4096, 1, 1), Processor.onaudioprocess =
            that.play, that.p = Processor, Processor.connect(that.audioctx.destination), Processor.connect(ueberwacher))));
        
    }//ueberwacher.onaudioprocess
    }//ende var isChrome = !!window.chrome;    
    Processor.connect(this.audioctx.destination);

Der gleich eigentlich nur via InputBuffer ab ob im eigentlichen Processos(der für den output sorgt) überhaupt noch was raus kommt. Ist das nicht der Fall wird der Procesor discconected Processor.disconnect(), Processor.onaudioprocess = null und ein neuer gestartet Processor = that.audioctx.createScriptProcessor(4096, 1, 1), Processor.onaudioprocess =
that.play, that.p = Processor, Processor.connect(that.audioctx.destination), Processor.connect(ueberwacher))));


Die Idee stammt von Chris Wilson https://twitter.com/cwilso und das habe ich auch nur von einer firebug Seite.. tut seien dienst

Ich habe am Player objekt mal noch was geändert.
Code:
    this.outputBuffer[j] = (Math.random()*2-1)*0.01//sample; //sound output
    } //ende for
    outputLeft.set(this.outputBuffer);
    this.SamplesCallback(this.outputBuffer);

Und this.outputBuffer = new Float32Array(4096);

So vom der Akkustik und der Optik her schient das zu funktionieren. Allerdings anhand eine weisen rauschens kann man nicht viel heraus hören/erkennen.#
Probiere das dann glich noch mal mit einen Sinus

tsseh schrieb:
was wird hier aufbewahrt und wozu
na die ganzen objekte Resampler, Fenterfunktion...

GrabberStack[key]["Resampler"] = new Resampler(GrabberStack.Player.getSampleRate(), value.UserRate, 4096);
GrabberStack[key]["DSP_Window"] = new wf(value.DSP_Window);


Wozu?
Na weil ich sonnst nicht weiß wie ich das ganze auseinander halten soll?

Jeder Eigentümer eines Grabbers hat die Möglichkeit mehre Spektrogramme zu erstellen mit verschiedenen Eigenschaften.
Grabber ?:
Spectrum grabbers are an essential part of the QRSS-game. What good is a MEPT or beacon when there are no provision to receive its signal? For scheduled experiments, which are done regularly, require that the transmitting and receiving stations appoint in frequency and time. Automated grabbers allow transmitter operators to experiment whenever wished. Additionally, 24/7 grabbers allow propagation studies.
KnightsQRSS Blog: HowTo Setup a QRSS Grabber

Schaut dann mal so aus:
DM4TR MF Grabber

nur das eben alles in realtime gerendert wird, anhand eines Audio streams.
 
nochmal was generelles vorneweg.
1) warum nutzt du eigentlich hier eine script node als input? logischer würde ich hier eine AudioBufferSourceNode finden
2) ich habe mir den resampler zwar noch nicht richtig angesehen, aber warum machst du das selbst und nicht über die api? 1. ist das über die api sicherlich um größenordnungen schneller und 2. mit sicherheit besser.

Was möchtest du da sehen? Du siehst doch den den selben code den ich sehe oder hast du andre Möglichkeiten zum debuggen? Ja es gibt noch einen 2ten processor, den ich überwacher genant habe.
der ist uninteressant (wobei ich mich schon frage warum du den benötigst - aber andere baustelle)

Der gleich eigentlich nur via InputBuffer ab ob im eigentlichen Processos(der für den output sorgt) überhaupt noch was raus kommt.
das sollte aber nicht passieren

Ich habe am Player objekt mal noch was geändert.
SamplesCallback ist bei dir eine leere funktion, falls du die doch irgendwo neu belegts, wirken sich die änderungen im callback am puffer jetzt nicht mehr auf den output aus.

na die ganzen objekte Resampler, Fenterfunktion...
angelegt, aber nicht aufgerufen. wer ruft denn überhaupt mal am Resampler eine funktion auf? wo?

- - - Aktualisiert - - -

hier auch wieder,
Dann geht alles in die FFT, die ist von audiolibjs
warum nutzt du nicht die api für die fft? die native code und damit schnell

- - - Aktualisiert - - -

1) warum nutzt du eigentlich hier eine script node als input? logischer würde ich hier eine AudioBufferSourceNode finden
das nehme ich wieder zurück, das ende-event ist nicht mit den folgenodes synchronisiert.
(ob scriptnodes das sind ist auch noch die frage, probiere ich mal bei gelegenheit aus)
 
Zuletzt bearbeitet:
tsseh schrieb:
1) warum nutzt du eigentlich hier eine script node als input? logischer würde ich hier eine AudioBufferSourceNode finden
Weil ich nicht weiß wie ich dann einen jitterbuffer realisieren soll/könnte. Meine ersten versuche hatten ergeben das der RAM, wenn man ihn mit PCM Daten aus einer websocket Verbindung befeuert immer größer wird . Bis zum crash.
Ein statischer Puffer mit einer festen größer erschien mir die bessere Wahl.

tsseh schrieb:
2) ich habe mir den resampler zwar noch nicht richtig angesehen, aber warum machst du das selbst und nicht über die api?
Hä, gibt es einen Resampler in der api? und selbst wenn bringt es mir nix, da man keine Samplingrate in der Api setzen kann. Das ist von PC zu PC unterschiedlich. Demzufolge laufen alle eventhandler in dieser Rate. Jetzt fällt mir auch wider ein warum ich die AudioBufferSourceNode nicht nutzen kann, ich streame mit krummen Rates 7119Hz oder 11535Hz, das geht dann beim Client nicht auf.


tsseh schrieb:
das sollte aber nicht passieren
OOOOhhhhh doch sogar sehr oft. sieh die bug reports die ich in #7 geposted habe.
Manchmal klingt das so als hätte einen CD einen Sprung.

tsseh schrieb:
SamplesCallback ist bei dir eine leere funktion, falls du die doch irgendwo neu belegts, wirken sich die änderungen im callback am puffer jetzt nicht mehr auf den output aus.
Ja aber so kommmt es einen vor.

=tsseh schrieb:
angelegt, aber nicht aufgerufen. wer ruft denn überhaupt mal am Resampler eine funktion auf? wo?
Oha, ja mein Fehler, da hatte ich was vergessen zu kopieren.
PHP:
     GrabberStack.Player.SamplesCallback = function(sampleBuffer) {
                            for (var key in loadedData.Windows) {
                                if (loadedData.Windows.hasOwnProperty(key)) {
                                    GrabberStack[key]["Resampler"].resample(sampleBuffer);
                                }
Da wird der Resampler aufgerufen.

tsseh schrieb:
=xorg1990;395720]
Ähm 395720???

tsseh schrieb:
warum nutzt du nicht die api für die fft? die native code und damit schnell
Auch das kann ich dir genau sagen. Weil es bein einer fftsize von 2048 samples aufhört.
Ich also wir brauchen aber bis 524288 input Samples.

Es gibt bestimmte Spektograme die sind nur 1 Hz Breit:
60000.jpg
Dafür brauch man dann extreme Rates und hohe fft input buffer. Sonnst ergibt das dann visuellen Matsch. Der Scroll Intervall spielt auch noch eine Rolle.#

Heute passiert eh nix mehr bin fertsch.
 
Zuletzt bearbeitet:
Hä, gibt es einen Resampler in der api? und selbst wenn bringt es mir nix, da man keine Samplingrate in der Api setzen kann.
doch https://developer.mozilla.org/en-US/docs/Web/API/OfflineAudioContext

OOOOhhhhh doch sogar sehr oft. sieh die bug reports die ich in #7 geposted habe.
Manchmal klingt das so als hätte einen CD einen Sprung.
das glaube ich erst mal so nicht, solange du schnell genug die daten lieferst...

Ja aber so kommmt es einen vor.
was?


Oha, ja mein Fehler, da hatte ich was vergessen zu kopieren.
ach so, und warum ein gesampletes signal überhaupt nochmal samplen?
außerdem erwartet die api ja IHRE samplingrate

kaputtes zitat


Auch das kann ich dir genau sagen. Weil es bein einer fftsize von 2048 samples aufhört.
Ich also wir brauchen aber bis 524288 input Samples.
ähhhh, ... ....wozu das denn, das sind ja auch datenmassen, die erst mal verarbeitet werden müssen

Es gibt bestimmte Spektograme die sind nur 1 Hz Breit
und das ist auch sinnvoll?
 
Zuletzt bearbeitet:
wenn die Funktion so ausschaut:
Code:
	if(this.i<4){
	var l = sampleBuffer.length;
	for(var i=0; i<l;i++){
		sampleBuffer[i]=0;
		sampleBuffer[i] *= 0.5-0.5 * Math.cos(this.Pi2 * i / (l - 1));// nicht 0.5 * (1 - Math.cos(DSP.TWO_PI * index / (length - 1)));	
	}
	this.i++;
	console.log(sampleBuffer);
	this.windowCallback(sampleBuffer);
	}

};
Kommt das dabei Raus:
Code:
Failed to load resource: the server responded with a status of 404 (Not Found)
Float32Array[4096]
Float32Array[4096]
Float32Array[4096]
Float32Array[4096]
temp1
Float32Array[4096][0 ... 99]0: 0.0096196020022034651: 0.010957675054669382: 0.0122681502252817153: 0.0135472398251295094: 0.0147911943495273595: 0.0159963984042406086: 0.0171594414860010157: 0.0182771757245063788: 0.019346743822097789: 0.02036558650434017210: 0.02133141644299030311: 0.02224217168986797312: 0.02309596352279186213: 0.02389098517596721614: 0.0246254559606313715: 0.0252975430339574816: 0.0259053055197000517: 0.0264466758817434318: 0.02691945061087608319: 0.0273213181644678120: 0.02764992788434028621: 0.02790297940373420722: 0.0280783306807279623: 0.028174141421914124: 0.02818899974226951625: 0.02812205627560615526: 0.0279731359332799927: 0.02774282358586788228: 0.02743251062929630329: 0.027044385671615630: 0.02658138237893581431: 0.02604708448052406332: 0.0254455544054508233: 0.02478115446865558634: 0.02405830658972263335: 0.02328126877546310436: 0.02245387807488441537: 0.02157933264970779438: 0.0206600148230791139: 0.01969733648002147740: 0.01869168318808078841: 0.0176424086093902642: 0.01654792390763759643: 0.01540585514158010544: 0.01421327982097864245: 0.0129670267924666446: 0.0116640245541930247: 0.01030167192220687948: 0.00887821894139051449: 0.007393121719360351650: 0.00584735721349716251: 0.00424367422237992352: 0.002586749847978353553: 0.000883255561348050854: -0.000858191750012338255: -0.002627187175676226656: -0.00441180402413010657: -0.00619895290583372158: -0.00797482207417488159: -0.00972536578774452260: -0.01143682934343814861: -0.01309626922011375462: -0.01469204016029834763: -0.0162142291665077264: -0.01765500754117965765: -0.0190088637173175866: -0.02027274854481220267: -0.0214460566639900268: -0.02253051660954952269: -0.02352994307875633270: -0.02444989234209060771: -0.0252972319722175672: -0.02607965841889381473: -0.02680517733097076474: -0.02748159505426883775: -0.02811602875590324476: -0.02871448919177055477: -0.0292815193533897478: -0.02981996722519397779: -0.030330836772918780: -0.03081327304244041481: -0.0312646478414535582: -0.0316807553172111583: -0.03205611184239387584: -0.0323842801153659885: -0.0326582901179790586: -0.03287102654576301687: -0.0330156758427619988: -0.0330860689282417389: -0.0330770127475261790: -0.0329845622181892491: -0.03280616924166679492: -0.03254078328609466693: -0.03218884021043777594: -0.0317521654069423795: -0.03123382665216922896: -0.0306379050016403297: -0.0299692284315824598: -0.02923309057950973599: -0.02843496948480606[100 … 199]100: -0.0323464497923851101: -0.032222725450992584102: -0.03201907500624657103: -0.0317390002310276104: -0.03138639032840729105: -0.0309652891010046106: -0.030479639768600464107: -0.02993309497833252108: -0.0293288491666317109: -0.028669539839029312110: -0.027957187965512276111: -0.027193203568458557112: -0.026378445327281952113: -0.025513319298624992114: -0.024597905576229095115: -0.023632120341062546116: -0.022615881636738777117: -0.021549267694354057118: -0.020432671532034874119: -0.019266922026872635120: -0.018053382635116577121: -0.016794001683592796122: -0.01549134124070406123: -0.014148548245429993124: -0.012769313529133797125: -0.011357784271240234126: -0.009918466210365295127: -0.00845610722899437128: -0.006975580472499132129: -0.0054817721247673035130: -0.003979476634413004131: -0.002473312197253108132: -0.000967657018918544133: 0.0005333870649337769134: 0.002026011236011982135: 0.0035066925920546055136: 0.004972166381776333137: 0.006419382989406586138: 0.007845454849302769139: 0.00924760289490223140: 0.010623099282383919141: 0.011969223618507385142: 0.013283219188451767143: 0.014562275260686874144: 0.015803515911102295145: 0.01700400374829769146: 0.01816076971590519147: 0.01927083358168602148: 0.020331252366304398149: 0.021339165046811104150: 0.02229183167219162151: 0.023186683654785156152: 0.02402135170996189153: 0.024793701246380806154: 0.025501834228634834155: 0.026144102215766907156: 0.026719097048044205157: 0.02722562849521637158: 0.02766270376741886159: 0.02802949585020542160: 0.02832532301545143161: 0.02854960411787033162: 0.02870185673236847163: 0.028781671077013016164: 0.02878871187567711165: 0.028722723945975304166: 0.028583550825715065167: 0.028371155261993408168: 0.02808566391468048169: 0.027727387845516205170: 0.027296870946884155171: 0.02679491601884365172: 0.026222610846161842173: 0.025581348687410355174: 0.024872824549674988175: 0.02409902960062027176: 0.023262226954102516177: 0.022364920005202293178: 0.02140979655086994179: 0.020399687811732292180:
ja, aber nur solange i < 4 ist. und ist nur beim 1. aufruf bei den 4 ersten samples so. und im log sieht man, das das schon
was gekommen ist, also bist du vermutlich nicht mehr im 1. aufruf
Code:
Float32Array[4096]
Float32Array[4096]
Float32Array[4096]
Float32Array[4096]
temp1
Float32Array[4096][0 ... 99]0:

dein downsample funktioniert so nicht
Code:
Resampler.prototype.downSample = function(buffer){
    var sum = 0.0;
    var inPos = 0.0;
    var outPos=0;
    var pos=0;
    while(outPos<this.outputBuffer.length){
        [B]var thisVal=buffer[inPos++];[/B]
        var nextPos=pos+this.ratio;
        if(nextPos>=1.0){
            sum+=thisVal*(1.0-pos);
            this.outputBuffer[outPos++]=sum;
            nextPos-=1.0;
            sum=nextPos*thisVal;
        }else{
            sum+=this.ratio*thisVal;
        }
        pos=nextPos;
        if(inPos>=buffer.length && outPos<this.outputBuffer.length){
            this.outputBuffer[outPos++]=sum/pos;
        }
    }
    //Perform Anti-alasing lowPass    
    for(var j=0;j<this.outputBuffer.length;j++){
        this.lpf.pushSample(this.outputBuffer[j]);
        this.outputBuffer[j] = this.lpf.getMix();
    }
    this.resampleOutput(this.outputBuffer);
};
dein outputBuffer ist größer
Code:
else{//downsample
            this.ratio = toRate/fromRate;
            this.outputBuffer = new Float32Array(parseInt(length*this.ratio));
            this.resample = this.downSample;
            this.lpf = new audioLib.BiquadFilter.LowPass(toRate, toRate/2, 0.5);
        }
warum eigentlich?
also kommst du irgendwann an die stelle in fett
 
tsseh schrieb:
Ah ja der offlineaudioccontext. Da hätte ich auch die createBuffer Methode nehmen können. Das Problem besteht darin, das fs min 22050Hz sind. Das ist mir zu viel. Für ein Qrss Grabber reicht in der regel. eine Bandbreite von 4kHerzen aus. Ala nyquist 8kHz. Mansche haben auch mehr. Ich will ja die TCP Bandbreite so gering wie möglich halten.

tsseh schrieb:
das glaube ich erst mal so nicht, solange du schnell genug die daten lieferst...
Welche daten soll ich den liefern. ein Audio File?

tsseh schrieb:
ach so, und warum ein gesampletes signal überhaupt nochmal samplen?
außerdem erwartet die api ja IHRE samplingrate
Ja das ist richtig die api erwarte ihre Rate, deswegen gilt es meine rate von was weiß ich 7119Hz an die der Api "anzupassen".
Das "anpassen geschieht wie in Soundkarten Treibern. In der Regel ist es so, dass die Input Rate von der Output rate abwicht. zb B. Inrate von 47998Hz und OutRate von 48000Hz.
Wenn man nun ein Signal durch die Soundkarte durchschleifen wollen würde, kommt es da zu Problemen. Ein Träger von 8000Hz kommt dann irgendwo bei 8500Hz wider raus.
Auch ein Störfaktor ist die Erwärmung des ADCs. Bei "Phase measurements" ist dieses ungewollte verhalten besonders störend.

Durch das nochmalige Sampling, erreiche ich eine höhere Rate als die der api, demzufolge ist die Berechnungszeit der FFT nicht so lang demzufolge kann ich das Spektrogramm schneller laufen lassen.
Extrembeispiel ist ein 5mHz breites Spektrum, dafür bräuchte man bei einer Rate von 11025Hz ca. 3 min ehe Daten erfasst sind.


tsseh schrieb:
und das ist auch sinnvoll?
Jup:
spectrogram_with_40uHz_zero_padded_FFT.jpg
Das Problem ist ja das bei einer Übertragung immer irgendwelche Störungen mit dabei sind z.b. rauschen. je größer die bandbreite ist, des mehr Störung. Im Idealfall bewegt man seine Daten auf ein Frequenz wo keine Störung sind zu.b Ghz oder Längstwellen (ELF ca 100Hz). Nun hat aber die Bundesnetzagentur einen Bandplan erstellt und da kommt man nicht ringsum. Wie komme ich nun aus den Sörungen raus?Genau man verlangsamt ein Signal so dermaßen das das Rausche nicht mehr vom Gehör bzw der Soundkarte wahrgenommen wird. Wenn ich aber schwache Sationen darstellen möchte kann ich kein Spektrum von 100Hz in einer Größe von 900x100 Pixer erstellen. Dann sieht man ja nix mehr weil die 100Hz zu dicht bei aneinander gepresst sind.
Also teile ich die 100Hz auf ein Fester von 1024*768 px auf. Das bracht dann eine höher fft Auflösung.

QRSS is a CW mode in which the receiver bandwidth is drastically reduced and the rate at which code is sent is slowed beyond that which would be normally be readable by ear. It is named for QRS, a Q-code indicating "send more slowly".
As received noise is directly proportional to receiver bandwidth, use of bandwidth far less than 1Hz is common in QRSS. This primarily serves the needs of QRP (low-power) operation, as it allows extremely weak signals to be received and decoded in the presence of high levels of background noise.
Morse code dot lengths of anywhere from a few seconds to a minute or more have been successfully employed; while a significant improvement in weak-signal performance is observed, the amount of data transferred is severely constrained.
Due to the narrow bandwidth used, frequency stability is critical at both the receiver and transmitter. A crystal-controlled reference using a crystal oven to maintain constant temperature is therefore recommended.

---
Mathematically, a fast Fourier transform is a calculation which, given a digitized waveform (vs. time) as input, calculates the signal strength at each frequency in the sample. By connecting an SSB receiver to a computer sound card, a received signal may be captured and the signal level at each frequency displayed vs. frequency and time by software.
A computer may store a received signal and replay it at a faster speed; it may also be used (with FFT software) to generate a "waterfall" or "curtain" display graphically. Brightness or colour may be used to indicate signal strength while X:Y axes represent time and frequency. (Axes are assigned so that time runs horizontally for a "curtain" graph and vertically for a "waterfall" - the two graphical depictions are otherwise identical).
As FFT demodulation of CW allows multiple frequencies within the passband to be monitored and displayed simultaneously, it will display a received signal even in the case of frequency drift and can display multiple adjacent-channel signals side-by-side if all fall within the passband.

Zurück zum westlichen.
dein outputBuffer ist größer

Code:
else{//downsample
            this.ratio = toRate/fromRate;
            this.outputBuffer = new Float32Array(parseInt(length*this.ratio));
            this.resample = this.downSample;
            this.lpf = new audioLib.BiquadFilter.LowPass(toRate, toRate/2, 0.5);
        }
warum eigentlich?
wahrscheinlich weil ich toRate/fromRate; vertauscht habe und ich blindist habe es nicht gesehen. Der Resampler steht sowieso auf bypass.
gut beobachtet tsseh


tsseh schrieb:
was gekommen ist, also bist du vermutlich nicht mehr im 1. aufruf
Ja ich hatte die Seite 2 mal aufgerufen. i<4 habe eingeführt weil mir sonst der PC abschmiert wenn in 1 sec 43 mal ein console.log gefeuert wird.

Nun denn ich habe für Testzwecke den Sp ein sinus berechen lassen.
Code:
 this.outputBuffer[j] = 0.006523 * Math.sin(this.x++/(this.audioctx.sampleRate/(1500*2*Math.PI)))//sample; //sound output
        if(this.x>this.audioctx.sampleRate)this.x=0;
    } //ende for
    outputLeft.set(this.outputBuffer);
    this.SamplesCallback(this.outputBuffer);
0.006523 ist die Amplitude, 1500 die Frequenz.

Auf den Spektrum wird wider nur müll gerendert, es kommt zwar ein träger bei 1500Hz aber auch wider viele andere.
Die Amplitude beträgt -20dBFs , übersteuert ist da nix. Irgendwaas ist da noch. mache gleich nochmal Einzeltests.
 
Ah ja der offlineaudioccontext. ... Ich will ja die TCP Bandbreite so gering wie möglich halten.
...Ja das ist richtig die api erwarte ihre Rate, deswegen gilt es meine rate von was weiß ich 7119Hz an die der Api "anzupassen".
ach jetzt, das ist die anpassung des eingangssignals?! die hätte ich im player.getSamples erwartet
aber dann solltest du doch die analyse auch auf den inputwerten aufsetzten. 1. weil das genauer ist, ein resampling macht ein signal ja nicht besser, und 2. hast du weniger daten.

Welche daten soll ich den liefern. ein Audio File?
du kannst mir nicht den beweis liefern, dass das kein fehler von dir ist.
nur den gegenbeweis, dass es geht
indem du eine oscillatornode mit einer scriptnode verschaltest, in dieser nur input auf output kopierst, und dann wartest bis keine daten mehr aus der scriptnode kommen(was vermutlich nie passieren wird)

Das "anpassen geschieht wie in Soundkarten Treibern.
das wage ich aber stark zu bezweifeln. in der audiolib ist auch ein resampler, warum nimmst du nicht den?

Durch das nochmalige Sampling,
welches "nochmalige Sampling"?

erreiche ich eine höhere Rate als die der api demzufolge ist die Berechnungszeit der FFT nicht so lang demzufolge kann ich das Spektrogramm schneller laufen lassen.
niedrigere Rate?! du sagtest, du hast niedrige frequenzen mit kleiner abtastrate. erhöst du Samples hättest du MEHR zu berechnen.

Extrembeispiel ist ein 5mHz breites Spektrum, dafür bräuchte man bei einer Rate von 11025Hz ca. 3 min ehe Daten erfasst sind.
für ein 5mHz signal ist eine abtastrate von 11025Hz zu klein. und 10000000000 samples pro sek mit js zu analysieren dürfte nicht gehen.
das ganze aber auf weniger samples runterzurechnen macht keinen sinn, weil du damit das signal verfälschst

ein katzenbild hätte es auch getan

Wenn ich aber schwache Sationen darstellen möchte kann ich kein Spektrum von 100Hz in einer Größe von 900x100 Pixer erstellen. Dann sieht man ja nix mehr weil die 100Hz zu dicht bei aneinander gepresst sind.
Also teile ich die 100Hz auf ein Fester von 1024*768 px auf. Das bracht dann eine höher fft Auflösung.
ähhh... was?

Nun denn ich habe für Testzwecke den Sp ein sinus berechen lassen.
Code:
 this.outputBuffer[j] = 0.006523 * Math.sin(this.x++/(this.audioctx.sampleRate/(1500*2*Math.PI)))//sample; //sound output
        if(this.x>this.audioctx.sampleRate)this.x=0;
    } //ende for
    outputLeft.set(this.outputBuffer);
    this.SamplesCallback(this.outputBuffer);
bleib erst mal bei deinen 0en. wenn dein pc das nicht schafft, gib nur jedes 10te ergebniss raus.
hab mir jetzt alles angesehen. ich bin mir ziemlich sicher, dass bis zu deiner funktion alles ok ist.
jedennfalls für den fall, dass alles 0-ist.
echte werte würde ich jetzt deinen resampler nicht anvertrauen. ich teste das mal.
 
=tsseh schrieb:
ach jetzt, das ist die anpassung des eingangssignals?!
Jaa.


tsseh schrieb:
indem du eine oscillatornode mit einer scriptnode verschaltest, in dieser nur input auf output kopierst, und dann wartest bis keine daten mehr aus der scriptnode kommen(was vermutlich nie passieren wird)
oscillatornode mit einer scriptnode verschaltest... hatte ich nicht vor.

tsseh schrieb:
in der audiolib ist auch ein resampler, warum nimmst du nicht den?
Echt wo?

tsseh schrieb:
welches "nochmalige Sampling"?
egal habe die Anpassung mir Sampling vertauscht.

tsseh schrieb:
niedrigere Rate?! du sagtest, du hast niedrige frequenzen mit kleiner abtastrate. erhöst du Samples hättest du MEHR zu berechnen.
Ja ein nidrige rate, um die TCP bandbreite so gering wie möglich zu halten. Vor der FFT nochmal ein Upsapling, dann kann man das Spektrogramm schneller laufen lassen.

tsseh schrieb:
und 10000000000 samples pro sek mit js zu analysieren dürfte nicht gehen.
Wieso soll das in JS nicht gehen??
tsseh schrieb:
das ganze aber auf weniger samples runterzurechnen macht keinen sinn, weil du damit das signal verfälschs
Deswegen biete ich den audio output an. So kann wer möchte das Signal in ein C Programm speisen.

tsseh schrieb:
ein katzenbild hätte es auch getan
Hör mir auf mit Katzen, davon hocken gerade 2 auf meinem Schoß.

tsseh schrieb:
Na wenn ich ein Frequenzskala von 100Hz habe die auf 100px breite darstellen möchte das ist das zu klein also nehme ich 768px dann sieht man es besser. Ist die Berechnungszeit zu langsam wird nur Matsch gerendert. Also FFT Length aufdrehen + höhere Sampling Rate.

tsseh schrieb:
bleib erst mal bei deinen 0en. wenn dein pc das nicht schafft, gib nur jedes 10te ergebniss raus.
hab mir jetzt alles angesehen. ich bin mir ziemlich sicher, dass bis zu deiner funktion alles ok ist.
jedennfalls für den fall, dass alles 0-ist.
Wenn ich in der Hann Funktion 0 zuführe kommt auch 0 wider raus, auch der berechnete Sinus klingt fehlerfrei.
Erst wenn ich echte Daten in die Funktion packe kommt wider müll raus.

Ich habe mal was getestet. Habe in der Funktion vor der Berechnung ein console.log gemacht und danach, jeweils nur von ersten SP Aufruf (4096 samples).

Ausgabe vor der berechnung:
[-5.112557528112213e-17, 0.0003200684441253543, 0.0006393658113665879, 0.0009571228874847293, 0.0012725741835311055, 0.0015849596820771694, 0.0018935269908979535, 0.0021975324489176273, 0.0024962439201772213, 0.002788941841572523, 0.0030749209690839052, 0.003353492124006152, 0.003623984521254897, 0.003885746467858553, 0.004138147458434105, 0.0043805791065096855, 0.004612457472831011, 0.004833224229514599, 0.005042347125709057, 0.005239322781562805, 0.00542367622256279, 0.005594963673502207, 0.005752772558480501, 0.005896721966564655, 0.006026466377079487, 0.00614169193431735, 0.006242122035473585, 0.006327514071017504, 0.006397662218660116, 0.006452398374676704, 0.006491589825600386, 0.006515142973512411, 0.006523000076413155, 0.006515142973512411, 0.006491589825600386, 0.006452398374676704, 0.006397662218660116, 0.006327514071017504, 0.006242122035473585, 0.00614169193431735, 0.006026466377079487, 0.005896721966564655, 0.005752772558480501, 0.005594963673502207, 0.00542367622256279, 0.005239322781562805, 0.005042347125709057, 0.004833224229514599, 0.004612457472831011, 0.0043805791065096855, 0.004138147458434105, 0.003885746467858553, 0.003623984521254897, 0.003353492124006152, 0.0030749209690839052, 0.002788941841572523, 0.0024962439201772213, 0.0021975324489176273, 0.0018935269908979535, 0.0015849596820771694, 0.0012725741835311055, 0.0009571228874847293, 0.0006393658113665879, 0.0003200684441253543, 1.2144746486331337e-16, -0.0003200684441253543, -0.0006393658113665879, -0.0009571228874847293, -0.0012725741835311055, -0.0015849596820771694, -0.0018935269908979535, -0.0021975324489176273, -0.0024962439201772213, -0.002788941841572523, -0.0030749209690839052, -0.003353492124006152, -0.003623984521254897, -0.003885746467858553, -0.004138147458434105, -0.0043805791065096855, -0.004612457472831011, -0.004833224229514599, -0.005042347125709057, -0.005239322781562805, -0.00542367622256279, -0.005594963673502207, -0.005752772558480501, -0.005896721966564655, -0.006026466377079487, -0.00614169193431735, -0.006242122035473585, -0.006327514071017504, -0.006397662218660116, -0.006452398374676704, -0.006491589825600386, -0.006515142973512411, -0.006523000076413155, -0.006515142973512411, -0.006491589825600386, -0.006452398374676704…]
Ausgabe nach der Berechnung
[-0, 1.8837996440534965e-10, 1.505223501396813e-9, 5.069923147971167e-9, 1.198377574951337e-8, 2.332104642732702e-8, 4.0120180955227625e-8, 6.337516822441103e-8, 9.402719314266506e-8, 1.3295648670919036e-7, 1.8097449583365233e-7, 2.3881648303358816e-7, 3.071344281124766e-7, 3.864903987960133e-7, 4.773503974320192e-7, 5.800785629617167e-7, 6.949322255422885e-7, 8.220573022299504e-7, 9.614840337235364e-7, 0.000001113123971663299, 0.0000012767668522428721, 0.000001452078890906705, 0.0000016386011338909157, 0.0000018357485487285885, 0.0000020428105926839635, 0.0000022589506443182472, 0.0000024832090730342316, 0.000002714503807510482, 0.0000029516340873669833, 0.0000031932831916492432, 0.000003438023441049154, 0.000003684320290631149, 0.000003930538241547765, 0.000004174947207502555, 0.000004415728199091973, 0.000004650983555620769, 0.0000048787414925755, 0.0000050969674703083, 0.000005303570560499793, 0.000005496415724337567, 0.000005673333816957893, 0.00000583212840865599, 0.000005970592155790655, 0.000006086513167247176, 0.000006177689556352561, 0.000006241939900064608, 0.000006277114152908325, 0.000006281109563133214, 0.00000625187749392353, 0.00000618744070379762, 0.000006085901077312883, 0.000005945455541223055, 0.000005764406068919925, 0.0000055411719586118124, 0.0000052743012020073365, 0.000004962482762493892, 0.000004604556579579366, 0.000004199524482828565, 0.0000037465606510522775, 0.0000032450213893753244, 0.000002694453996809898, 0.00000209460540645523, 0.0000014454303709499072, 7.470982268387161e-7, 2.925440817061364e-19, -7.95246023699292e-7, -0.0000016377892961827456, -0.0000025265433123422554, -0.0000034601812330947723, -0.000004437134975887602, -0.000005455593054648489, -0.000006513499556604074, -0.000007608555279148277, -0.000008738220458326396, -0.000009899715223582461, -0.000011090022780990694, -0.000012305896234465763, -0.000013543864952225704, -0.000014800236385781318, -0.000016071107893367298, -0.000017352374925394543, -0.000018639739209902473, -0.000019928718757000752, -0.000021214667867752723, -0.000022492771677207202, -0.000023758082534186542, -0.00002500551454431843, -0.00002622986721689813, -0.000027425850930740125, -0.000028588079658220522, -0.000029711114621022716, -0.000030789466109126806, -0.00003181761348969303, -0.00003279004158684984, -0.000033701227948768064, -0.00003454570105532184, -0.00003531802576617338, -0.000036012854252476245, -0.00003662492235889658, -0.000037149096897337586…]


Das ganze habe ich noch mal durchexeziert in eiener seperaten html
Code:
<!DOCTYPE HTML>
<body>
<script>
var windowHann = function(sampleBuffer){
	var l = sampleBuffer.length;
	console.log(sampleBuffer);
	var arg = 2.0*Math.PI/(l-1);
	for(var i=0; i<l;i++){
	sampleBuffer[i] *= 0.5-0.5 * Math.cos(arg*i);// nicht 0.5 * (1 - Math.cos(DSP.TWO_PI * index / (length - 1)));	
	}
        console.log(sampleBuffer);
	this.windowCallback(sampleBuffer);

};


function makeSine(){
    var sine = new Float32Array(4096);
    var x = 0;
    for(var i=0;i<4096;i++){
        sine[i] = 0.006523 * Math.sin(x++/(192000/(1500*2*Math.PI)))//sample; //sound output
    }
   
    windowHann(sine);
}

makeSine();
</script>
</body>
</html>


Vor der Berechnung:
[0, 0.0003200684441253543, 0.0006393658113665879, 0.0009571228874847293, 0.0012725741835311055, 0.0015849596820771694, 0.0018935269908979535, 0.0021975324489176273, 0.0024962439201772213, 0.002788941841572523, 0.0030749209690839052, 0.003353492124006152, 0.003623984521254897, 0.003885746467858553, 0.004138147458434105, 0.0043805791065096855, 0.004612457472831011, 0.004833224229514599, 0.005042347125709057, 0.005239322781562805, 0.00542367622256279, 0.005594963673502207, 0.005752772558480501, 0.005896721966564655, 0.006026466377079487, 0.00614169193431735, 0.006242122035473585, 0.006327514071017504, 0.006397662218660116, 0.006452398374676704, 0.006491589825600386, 0.006515142973512411, 0.006523000076413155, 0.006515142973512411, 0.006491589825600386, 0.006452398374676704, 0.006397662218660116, 0.006327514071017504, 0.006242122035473585, 0.00614169193431735, 0.006026466377079487, 0.005896721966564655, 0.005752772558480501, 0.005594963673502207, 0.00542367622256279, 0.005239322781562805, 0.005042347125709057, 0.004833224229514599, 0.004612457472831011, 0.0043805791065096855, 0.004138147458434105, 0.003885746467858553, 0.003623984521254897, 0.003353492124006152, 0.0030749209690839052, 0.002788941841572523, 0.0024962439201772213, 0.0021975324489176273, 0.0018935269908979535, 0.0015849596820771694, 0.0012725741835311055, 0.0009571228874847293, 0.0006393658113665879, 0.0003200684441253543, 7.988371137675333e-19, -0.0003200684441253543, -0.0006393658113665879, -0.0009571228874847293, -0.0012725741835311055, -0.0015849596820771694, -0.0018935269908979535, -0.0021975324489176273, -0.0024962439201772213, -0.002788941841572523, -0.0030749209690839052, -0.003353492124006152, -0.003623984521254897, -0.003885746467858553, -0.004138147458434105, -0.0043805791065096855, -0.004612457472831011, -0.004833224229514599, -0.005042347125709057, -0.005239322781562805, -0.00542367622256279, -0.005594963673502207, -0.005752772558480501, -0.005896721966564655, -0.006026466377079487, -0.00614169193431735, -0.006242122035473585, -0.006327514071017504, -0.006397662218660116, -0.006452398374676704, -0.006491589825600386, -0.006515142973512411, -0.006523000076413155, -0.006515142973512411, -0.006491589825600386, -0.006452398374676704…]

Nach der Berechnung:
[0, 1.8837996440534965e-10, 1.505223501396813e-9, 5.069923147971167e-9, 1.198377574951337e-8, 2.332104642732702e-8, 4.0120180955227625e-8, 6.337516822441103e-8, 9.402719314266506e-8, 1.3295648670919036e-7, 1.8097449583365233e-7, 2.3881648303358816e-7, 3.071344281124766e-7, 3.864903987960133e-7, 4.773503974320192e-7, 5.800785629617167e-7, 6.949322255422885e-7, 8.220573022299504e-7, 9.614840337235364e-7, 0.000001113123971663299, 0.0000012767668522428721, 0.000001452078890906705, 0.0000016386011338909157, 0.0000018357485487285885, 0.0000020428105926839635, 0.0000022589506443182472, 0.0000024832090730342316, 0.000002714503807510482, 0.0000029516340873669833, 0.0000031932831916492432, 0.000003438023441049154, 0.000003684320290631149, 0.000003930538241547765, 0.000004174947207502555, 0.000004415728199091973, 0.000004650983555620769, 0.0000048787414925755, 0.0000050969674703083, 0.000005303570560499793, 0.000005496415724337567, 0.000005673333816957893, 0.00000583212840865599, 0.000005970592155790655, 0.000006086513167247176, 0.000006177689556352561, 0.000006241939900064608, 0.000006277114152908325, 0.000006281109563133214, 0.00000625187749392353, 0.00000618744070379762, 0.000006085901077312883, 0.000005945455541223055, 0.000005764406068919925, 0.0000055411719586118124, 0.0000052743012020073365, 0.000004962482762493892, 0.000004604556579579366, 0.000004199524482828565, 0.0000037465606510522775, 0.0000032450213893753244, 0.000002694453996809898, 0.00000209460540645523, 0.0000014454303709499072, 7.470982268387161e-7, 1.9242482869970873e-21, -7.95246023699292e-7, -0.0000016377892961827456, -0.0000025265433123422554, -0.0000034601812330947723, -0.000004437134975887602, -0.000005455593054648489, -0.000006513499556604074, -0.000007608555279148277, -0.000008738220458326396, -0.000009899715223582461, -0.000011090022780990694, -0.000012305896234465763, -0.000013543864952225704, -0.000014800236385781318, -0.000016071107893367298, -0.000017352374925394543, -0.000018639739209902473, -0.000019928718757000752, -0.000021214667867752723, -0.000022492771677207202, -0.000023758082534186542, -0.00002500551454431843, -0.00002622986721689813, -0.000027425850930740125, -0.000028588079658220522, -0.000029711114621022716, -0.000030789466109126806, -0.00003181761348969303, -0.00003279004158684984, -0.000033701227948768064, -0.00003454570105532184, -0.00003531802576617338, -0.000036012854252476245, -0.00003662492235889658, -0.000037149096897337586…]
Auffällig sind die ersten werte :
0, 1.8837996440534965e-10, 1.505223501396813e-9, 5.069923147971167e-9, 1.198377574951337e-8, 2.332104642732702e-8, 4.0120180955227625e-8, 6.337516822441103e-8, 9.402719314266506e-8, 1.3295648670919036e-7, 1.8097449583365233e-7, 2.3881648303358816e-7, 3.071344281124766e-7, 3.864903987960133e-7, 4.773503974320192e-7, 5.800785629617167e-7, 6.949322255422885e-7, 8.220573022299504e-7, 9.614840337235364e-7,
Das ist doch gar kein Float32 mehr. Die Audiolib FFT wird auf eine Wertebereich von -1bis+1 ausgelegt sein. Ist das, dass Problem?

tsseh schrieb:
echte werte würde ich jetzt deinen resampler nicht anvertrauen. ich teste das mal.
ok, ich halte dich nicht auf xD. Wollte erst diesen nehmen:
https://github.com/taisel/XAudioJS/blob/master/resampler.js
Aber ich kann den code nicht Folgen function mit großem F.. alles im String...Alles komisch.
 
oscillatornode mit einer scriptnode verschaltest... hatte ich nicht vor.
das mag sein, aber wenn das geht und bei dir nicht, hast du irgendwo einen fehler

such mal nach resample auf github im markdown


Vor der FFT nochmal ein Upsapling, dann kann man das Spektrogramm schneller laufen lassen.
also doch nochmal, das ist aber kontraproduktiv. was heißt, "dann kann man das Spektrogramm schneller laufen lassen"? dass du durch mehr samples deinen puffer schneller voll bekommst und deswegen die fft öfter durchführen MUSST? ja, dann mach den puffer kleiner.

Wieso soll das in JS nicht gehen??
geschwindigkeit?

was hat das
Na wenn ich ein Frequenzskala von 100Hz habe die auf 100px breite darstellen möchte das ist das zu klein also nehme ich 768px dann sieht man es besser.
mit dem
Ist die Berechnungszeit zu langsam wird nur Matsch gerendert.
zu tun

Also FFT Length aufdrehen + höhere Sampling Rate.
falsch

Wenn ich in der Hann Funktion 0 zuführe kommt auch 0 wider raus
sag ich ja

Ich habe mal was getestet.
morgen

Das ist doch gar kein Float32 mehr.
doch

Die Audiolib FFT wird auf eine Wertebereich von -1bis+1 ausgelegt sein.
steht das irgendwo?

ok, ich halte dich nicht auf xD.
ich will nur sehen, was dein resampling liefert
ich würde die von der audiolib mal testen an deiner stelle, die bindest du ja eh ein
und nur den input resamplen
 
tsseh schrieb:
"dann kann man das Spektrogramm schneller laufen lassen"? dass du durch mehr samples deinen puffer schneller voll bekommst und deswegen die fft öfter durchführen MUSST?
Richtig, ich rendere das Spektogramm als Wasserfall. Das bedeutet ich scheibe das Spektum(den Wasserfall) in einen festgelegten intervall 1ne pixelzeile nach links,recht oben, unten je nach dem. der Intervall hängt von den Jeweiligen qrss modies ab (qrrs3, qrss20) Spezialfall Normal-CW.
Für einen Optimale Darstellung ist ein Überlappung von 50% Scrollinterval und FFT Berechnungszeit notwendig.

Rechenbeispiel Normal-CW (Bandbreite Mittelwelle sind 7khz 472kHz bis 479kHz) Diese 472kHz versteht die Soundkarte nicht also runtermischen auf 12-19Khz.
19khz macht eine Sampling Frequenz von 38Khz. Einigen wir auf auf eine rate von 44100Hz. Um auf 19Khz zu kommen brauch ich eine FFT Length von 2048.
Weil, Bin_Breite_in_Hertz = fSample / fft_length = 44100 Hz / 4096 = 10.766 Hz. 2048*10.766 Hz = ca 22050 Hz.

Bei einer rate von 44100 und FFT length von 4096 sind wir als schon mal im richtigen bereich.
Nun der Overlap from scroll intervall:
SecFürNeueDaten = fft_Length * (1/Rate) = 4096*(1/44100) = 0,09287981859410430839002267573696 sec.
Scrollintervall ist auf 40ms gesetzt.
X = 100*40/ (0,09287981859410430839002267573696 *1000)
OSI = 100-x
Die Überlappung beträgt: 56,933%

Der Idealfall. Ist das nicht der Fall muss man so lange rumspielen bis man die optimale Einstellung getroffen hat. Zusätzlich kommt noch ein Faktor dazu die Größe des eingestellten Fensters.
Da könne drei Dinge Vorkommen:
1.) Ein Frequenzeimer entspricht genau einem Pixel auf dem Schirm
-> Idealfall, auch "one pixel per bin". genannt
Sieht am besten aus.

2.) Ein Frequenzeimer entspricht MEHREREN PIXELN.
-> Nicht so schön. Sieht etwas "klotzig" aus.

3.) Ein Pixel entspricht MEHREREN Frequenzeimern.
-> Auch nicht schön.

tsseh schrieb:
steht das irgendwo?
Nee aber wenn die Audio Api einen Bereich bereich von -1 bis+1 max hat, dann wird sich Audiolib.Js auch danach richten.
Wenn also -1bis+1 das Dezibel max ist, kann nach der Fensterfunktion nicht 6.949322255422885e-7, 8.220573022299504e-7, 9.614840337235364e-7, rauskommen, das wäre ja viel zu Laut.

do sutra(Kroatisch) Bis Morgen:)
 
Zurück
Oben