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

dsp.js Fensterfunktion komische Ereignisse

xorg1990

New member
Ich dachte ich stehe kurz vorm Ende mit meinem Anaylser da schleicht doch noch ein großes Problem ein:mad:

Das Prob. liegt bei den Fensterfunktion von dsp.js. Die binde ich wie folgt ein:

Code:
function wf(defaultWindow){
	 this.dspWindow = null;
	 this.setWindowFunc(defaultWindow);
}


wf.prototype.setWindowFunc = function(window1){
	if(window1 == "null"){
		this.dspWindow = null;
	}else{	
		this.dspWindow = new WindowFunction(7);// 7 = DSP.HANN
	}
};


wf.prototype.windowCallback = function(){};
wf.prototype.performWindow = function(sampleBuffer){
	
	if(this.dspWindow === null){
			this.windowCallback(sampleBuffer);
    
	}else{
		if(typeof sampleBuffer !== "undefined" ){
		var buffer = this.dspWindow.process(sampleBuffer)
			this.windowCallback(buffer);
		}
	}
	
};
Wenn ich das so mache wie es da steht dann kommt aus meinen Lautsprechern kein Sinus mehr sondern irgendwas, auch das Spectrum sieht grottig aus.
Ändere ich das um var buffer = this.dspWindow.process(sampleBuffer) in var buffer = this.dspWindow.process(new Float32Array(sampleBuffer));, dann ist der Ton ok, aber das Spectrum sieht immer noch komisch aus (1500Hz Träger ist matschig)

Gut hab ich halt gedacht das was an den Daten nicht stimmt, drauf hin habe ich im Player ein Rauschen erzeugt, einfach Math.random(), aber da kommt kein Rauschen aus meinem Lautsprecher, eher ein 50hz brummen.

Tu ich die Fensterfunktion bypassen dann klappt alles.

Ist da was an dsp.js kaputt? Das Script ist schon ein paar Jahre alt.

Ich versteh halt nicht warum sich der Ton verändert, ich mach doch die Soundausgabe vor dem Fenstern.:confused:
@hesst, Du kennst meinen Ablauf bestimmt. Player->Resampler->Festerfunktion->FFT
Habe auch schon einen Ringbuffer dazwischen gehangen hat auch nicht geholfen.

Was läuft schief?
 
hesst schrieb:
Nicht :crushed:, dachte weil du mir so oft geholfen hast, dass du meine Skript(e) schon auswendig kennen müsstest.

hesst schrieb:
vielleicht wird sampleBuffer in der funktion verändert
Hä, na klar wird in this.dspWindow.process auf die Samples das entsprechende Fenster darübergelegt.
den retun speicher in in var buffer ab und mit this.windowCallback(buffer); gehe ich dann zur FFT was ja dann visualisiert wird.

Aber die Soundausgabe darf sich nicht ändern, da ist ja das komische, es gibt ja auch keinen Weg zurück zum Web Audio Scriptprocessor.
Visuell sieht man auch kaum einen Unterschied zu den Fensterfunktion ein 1500Hz träger sollte ein 1500Hz Träger blieben und kein Matsch werden.

Unterm oszi sieht das so aus:
dsp Fensterfunktion Problem.png
Rechts ist alles io und links fuscht was an der Amplitude rum:confused:

Nun bin ich aber mit den Rücken an die Wand gefahren:(

Hatte vergessen zu erwähnen das ich beim Oszilloskop Screenshot die Frequenz geändert habe auf ~400HZ, mir ging das 1500Hz Gepiepse aufm Nerv. Also nicht wunder wenn die Frequenz vom Spektrum anders ist als auf Oszi.
 
Zuletzt bearbeitet:
Nicht :crushed:, dachte weil du mir so oft geholfen hast, dass du meine Skript(e) schon auswendig kennen müsstest.
nee, das versuche ich dir doch schon von anfang an zu sagen.
du beschreibst deine probleme immer so, als würde jeder wissen, was du dort machst. wir kennen deinen code nicht.


Hä, na klar wird in this.dspWindow.process auf die Samples das entsprechende Fenster darübergelegt.
den retun speicher in in var buffer ab und mit this.windowCallback(buffer); gehe ich dann zur FFT was ja dann visualisiert wird.

Aber die Soundausgabe darf sich nicht ändern, da ist ja das komische, es gibt ja auch keinen Weg zurück zum Web Audio Scriptprocessor.
was geht denn an die soundausgabe? der return-buffer oder sampleBuffer was an performWindow übergeben wird?
wenn es sampleBuffer ist, darfst du diesen natürlich in der funktion nicht verändern, da sich dann auch die soundausgabe ändert. es sei denn das willst du.
 
hesst schrieb:
nee, das versuche ich dir doch schon von anfang an zu sagen.
du beschreibst deine probleme immer so, als würde jeder wissen, was du dort machst. wir kennen deinen code nicht.

ok ok, aber ich kann ja auch nicht jedesmal 3000 Zeilen Code, Posten, außerdem meinte ich meinte ich die Verarbeitungskkette:
Ich habe ein PlayerObjekt, das stellt die Samples bereit, dann kommt ein Resampler, dann die FensterFunktion, Dann die FFT, und zum Schluss eine Animation(was auch immer).



hesst schrieb:
was geht denn an die soundausgabe? der return-buffer oder sampleBuffer was an performWindow übergeben wird?
Eigentlich keins von beiden. Samplebuffer kommt vom Playerobjekt und wird "geFenstert" und dann fourier transformirt.

Das ist der onaudioprocess von ScriptProcessor:
Code:
player.prototype.SamplesCallback = function() {};
player.prototype.dBCallback = function() {};

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];
        if (isNaN(sample) == true) console.log(sample);
        if(typeof sample == "undefined") console.log(sample);
        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];
            if (isNaN(sample) == true) console.log(sample);
            if(typeof sample == "undefined") console.log(sample);
            sample = (this.ratioWeight * sample2 + (ratio - this.ratioWeight) * sample) / ratio;
        }
        if (typeof sample == "undefined")  console.log(sample);
        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);
};
Da ist die Soundausabe outputLeft[ev] = sample; //sound output

Mit this.SamplesCallback(outputLeft); gehe ich in den Resampler und dessen output vergebe ich an die Fensterfunktion.
Der Ablauf schaut so aus:
Code:
           Player.SamplesCallback = function(sampleBuffer){
               		resampler.resample(sampleBuffer);
               			
                //	window.performWindow(sampleBuffer);
                }

            resampler.resampleOutput  = function(resampledBuffer){
                //console.log(resampledBuffer.length);
            	window.performWindow(resampledBuffer);
                }

            
            Player.dBCallback = function(dB){
            	document.getElementById("dB").innerHTML = dB +"    dB";
            	//normal_cw_widnow.setDecibel(dB);
                }

           window.windowCallback = function(windowSample){
        	   normal_cw_widnow.pushSamples(windowSample);
               }
Der Resampler steht auf bypass und kann eigentlich nicht für die Störung verantwortlich sein. Wenn Du magst poste ich den resampler code auch noch.
Wie kann es nun sein das sich die Fenster auf die Ausgabe auswirkten obwohl die Ausgabe ja schon geschehen ist:confused:
 
Problem gelöst.

Habe dsp.js verworfen und begonnen die Windows selber zu Programmieren:
Code:
function wf(defaultWindow, alpha){
	this.alpha = alpha;
	 this.Pi2 = Math.PI*2; 
	 this.init("Hann");
}





wf.prototype.init = function(type){
	 switch(type){
	 case "Hamming":
	      this.performWindow  = this.windowHamming ;
	      break;
	     
	    case "Hann":
	      this.performWindow  = this.windowHann;
	      break;
	 }
};



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

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);
};

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

Dabei bin ich dahinter gekommen das das Hann(Hanning) Window auf Wikipedia falsch zu sein scheint. So stehts in meinen Büchern 0.5-0.5 * Math.cos(this.Pi2 * i / (l - 1)) und dann geht es auch. Das Ton Problem ist auf diese Schreibweise auch weg WindowedBuffer = sampleBuffer. Wenn ich das so schreibe sampleBuffer *= dann klingt's wider komisch. :confused: Anscheid darf man den outputbuffer nicht verändern bis onaudioprocess komplett durchgelaufen ist.

Äh nee funzt doch nicht, habe bei jeder WindowFuntion bei 50Hz eine träger auf dem Spektrum das sollte nicht sein... wo das nun wider herkommt Hilfe ich verzweifle.
 
Zuletzt bearbeitet:
Da sich das Problem anscheint nicht so einfach finden lässt, werde ich morgen mal eine live Skript hochladen. Irgend einen Grund muss es ja haben das die FensterFunktionen nicht Funktionieren. Die letzte Möglichkeit die mir einfällt wäre die Berechnung auf eine Webworker zu machen. Es muss ja einen Grund geben warum sich bei fast jeden Fenster ein 50 Hz Träger bildet.

Ich hoffe doch das der No-IP update Client dieses mal mitspielt, das letzte mal hat er nach 24h die ip Adressen nicht abgeglichen.

Ich würde mich sehr sehr freuen wenn sich das Problem irgend wie lösen lässt.

Denke so gegen 22Uhr ist morgen die Seite on... muss ein wenig Technik dazu aufbauen.

VG Xorg1990

... Ich melde mich
 
Zurück
Oben