xorg1990
New member
Hallo, ich steh mal wieder vor einen Rätsel.
Sicherlich kann sich der eine oder andere noch an den "Hilbert Trafo Thread" erinnern. Diese ganze Sache habe ich nun nach nodejs gebracht.
Das Problem der Prozess verbraucht 100% CPU Load in nodejs.
Ich habe 2 Dateien, in der main.js habe ich eine Methode die von Gstreamer Daten empfängt und in Downmixer.js habe einen Methode pushSample die, die Samples verarbeitet.
main.js
Downmixer.js
Mein Verbesserungsvorschlag wäre, die While Schleife die in Receive steht in die Methode pushSample zu packen,
wenn diese abgearbeitet ist die Methode getMix aufzurufen und ein callback an main.js übergeben nur weiß ich wieder mal nicht wie.
und pushSample wird zu pushSamples
Würde mein „Verbesserungsvorschlag“ überhaupt einen Performancevorteil bringen?
Ps:
Kkapsners Implementierung, mit dem Ringbuffer läuft auf nodejs nicht,
ich weiß zwar jetzt nicht mehr genau was das Problem war, aber irgendwas mit der forEach schleife ging nicht… Der Biquad von audiolib.js geht ja auch nicht.
Mfg Xorg1990
Sicherlich kann sich der eine oder andere noch an den "Hilbert Trafo Thread" erinnern. Diese ganze Sache habe ich nun nach nodejs gebracht.
Das Problem der Prozess verbraucht 100% CPU Load in nodejs.
Ich habe 2 Dateien, in der main.js habe ich eine Methode die von Gstreamer Daten empfängt und in Downmixer.js habe einen Methode pushSample die, die Samples verarbeitet.
main.js
Code:
GstreamerPipe.Receive(function(data){
var j = 0;
while(j!=data.length){
j++;
downmix.pushSample(data[j]);
//console.log(downmix.getMix());
}
});
Downmixer.js
Code:
function Downmixer(VFO_Freq, Samplerate){
this.FILTER_LEN = 100; //FIR Hilbert length
this.VFO_Sine = require('../node_modules/audiolib').Oscillator(Samplerate, VFO_Freq);
this.VFO_Cosine = require('../node_modules/audiolib').Oscillator(Samplerate, VFO_Freq);
this.VFO_Sine.waveShape = 'sine';
this.VFO_Cosine.waveShape = 'cosine';
this.queue_ptr = 0;
this.iDelayIndex = 0;
this.maxi = 0.001;
this.maxq = 0.001;
this.DelayQueue = new Float32Array(this.FILTER_LEN);
this.BufferQueue = new Float32Array(this.FILTER_LEN);
this.calcCoeff();
}
Downmixer.prototype.calcCoeff = function(){
var HILBERT_ARRAY = new Float64Array(this.FILTER_LEN);
HILBERT_ARRAY[this.FILTER_LEN] = 0;
for (var jj = 0; jj <= this.FILTER_LEN / 2; jj++) {
var coeff = jj & 1 ? 2.0 / ((this.FILTER_LEN / 2 - jj) * Math.PI) : 0.0; //<- Implementierung W Kiefer
//var coeff = jj&1 ? 2.0/(jj*Math.PI) : 0.0;//<- Implementierung Wolf Büscher
//var coeff = 1/((jj-FILTER_LEN/2)-0.5)/Math.PI; //<- Eigene Implementierung der Koeffizienten
HILBERT_ARRAY[jj] = coeff;
HILBERT_ARRAY[this.FILTER_LEN - jj] = -coeff;
}
this.coeffs = HILBERT_ARRAY;
};
Downmixer.prototype.pushSample = function(s){
//generate the sine samples from audiolib.js
this.VFO_Sine.generate();
this.VFO_Cosine.generate();
var Sine = this.VFO_Sine.getMix();
var Cosine = this.VFO_Cosine.getMix();
var dbl_i = s * Sine; //<-The index variable run up to 44100 samples, so the sine needs 44100 Samples
var dbl_q = s * Cosine;
//Let the I-channel run through a delay line
if (this.iDelayIndex >= this.FILTER_LEN / 2) this.iDelayIndex = 0;
y = this.DelayQueue[this.iDelayIndex];
this.DelayQueue[this.iDelayIndex++] = dbl_i; //<- DelayLine input
dbl_i = y;
//Ringbuffer pointer calculation
this.queue_ptr = (this.queue_ptr + 1) % this.FILTER_LEN;
this.BufferQueue[this.queue_ptr] = dbl_q; //<- Hilbert trafo input
var n = this.queue_ptr;
var out = 0.0;
for(var i=0;i<this.FILTER_LEN;i++){
out += this.coeffs[i] * this.BufferQueue[n]; // accumulate the Hilbert coeffs with the Q-Channel samples
n--;
if (n < 0) n += this.FILTER_LEN;
}
dbl_q = out;
//Ermittlung der beiden Amplituden:
if (this.maxi < dbl_i) this.maxi = dbl_i;
if (this.maxq < dbl_q) this.maxq = dbl_q;
this.Sample = ((this.maxi / this.maxq) * 2) * dbl_q + 2 * dbl_i;
};
Downmixer.prototype.getMix = function(){
return this.Sample;
};
module.exports = Downmixer;
Mein Verbesserungsvorschlag wäre, die While Schleife die in Receive steht in die Methode pushSample zu packen,
wenn diese abgearbeitet ist die Methode getMix aufzurufen und ein callback an main.js übergeben nur weiß ich wieder mal nicht wie.
Code:
GstreamerPipe.Receive(function(data){
downmix.pushSample(data);
});
//callback von downmixer.js
downmix.getMix(function(BlockofSamples){
//do stuff
});
und pushSample wird zu pushSamples
Code:
Downmixer.prototype.pushSamples = function(BlockOfSamples){
this.NewBlockOfSamples = new Float32Array(BlockOfSamples.length)
var j=0;
while(j!=BlockOfSamples.length){
j++
//Hilbert Trafo Loops
}
//wenn While fertig rufe Methode getMix auf
this.getMix()
}
Downmixer.prototype.getMix = function(){
return this.NewBlockOfSamples // ist sicherlich falsch
//Hier weiß ich nicht weiter
};
Würde mein „Verbesserungsvorschlag“ überhaupt einen Performancevorteil bringen?
Ps:
Kkapsners Implementierung, mit dem Ringbuffer läuft auf nodejs nicht,
ich weiß zwar jetzt nicht mehr genau was das Problem war, aber irgendwas mit der forEach schleife ging nicht… Der Biquad von audiolib.js geht ja auch nicht.
Mfg Xorg1990