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

wieder mal ein Problem mit audiolib.js in NodeJS

xorg1990

New member
Hi, ich habe mal wieder ein kurioses Problem mit audiolib.js.

Und zwar wollte ich mir den LP12Filter von audiolib.js zunutze machen, doch der produziert unter Nodejs nur ein Weißes rauschen, bzw. ist total übersteuert.
audiolib Problem.jpg
Dasselbe Problem besteht auch bei den anderen IIR von audillib.js

Ganz komisch ist das der IIR schon rauscht obwohl noch nicht mal ein Eingangssample anliegt.
Im Browser Funktionen die Filter einwandfrei.

Der Filter hängt wider in meinem Gstreamer callback, ich hatte schon falsche Daten von Gstreamer in Verdacht, doch wenn man den Filter weglässt kommt normaler Ton an.

Code:
// param1 = Samplerate, param2= cutoff, param3=resonance
var Lowpass = require('audiolib').LP12Filter(192000, 5000, 1);


GstreamerPipe.Receive(function(data){
	//downmix.pushSamples(data);
	var send_buffer = new Buffer(data.length);
	for(var i = 0;i<data.length;i++){
	Lowpass.pushSample(data[i]);
	send_buffer[i] = Lowpass.getMix();
	
	}
    //senden der Daten ueber Websocket
		wss.send(send_buffer);
	
});

Wer weiß wo das Problem liegt?
MfG Xorg1990

- - - Aktualisiert - - -

Hä??? Linux will mich veraschen:
Zu Erklärung:
Ich hatte zum Testen des Filters mein IPod an die Soundkarte eingestöpselt und die gefilterten Daten über Websocket auf einen anderen Rechner gstreaemt,
das hat einwandfrei funktioniert.

Dann ist mir eingefallen das man den Filter nicht mit Musik testen sollte sondern mit einen weißen rauschen, um vorfallen die Filterflanke zu sehen.
Also habe ich mit Simplynoise ein Rauschen erzeugt und bin von einer Soundkarte raus mit einer anderen (USB) wieder rein.
Aber irgendwas ist dabei Putt gegangen, denn wenn ich meinen IPod wieder anschließe wird die Musik mit dem weißen rauschen gemischt, deshalb ist alles übersteuert.

Ist es möglich, dass sich das Rauschen irgendwo in der Swap Partition aufhält auch wenn man den Strom vom Rechner herausgezogen hat??
Denn wenn ich mein Node Skript starte erscheint in Debian ein Mikrofon und da kann ich die Lautstärke Regeln von den „Imaginären Rauschen“ obwohl noch nicht mal was an geklemmt ist.

Oder es hat sich was im Bussystem verabschiedet.
Das erklärt aber nicht warum das Problem bei einer Internen und USB Soundkarte auftritt. Software Fehler ist auch ausgeschlossen, da bei ALSA und OSS (Open Sound System), selbe Problematik.

Hat das Symptom schon mal jemand gehabt?
 
kkapsner schrieb:
ist wahrscheinlich wieder eine deiner Soundkarten durchgeschmort.
Nee kann nicht sein da ich mehre USB Soundkarten habe, das Problem bleibt dasselbe.

Ich habe heute folgendes gemacht, ich habe mir einen andren Rechner geschnappt und drauf Debian neu installiert
+ Gstreamer, Nodejs usw. mein Skript gestartet, selbes Problem.

Dann hebe ich auf eine aktuellere Gstreamer Version geupdated … hat nix gebracht, immer noch ein weißes Rauschen (aber im Hintergrund hört man die Musik) .

- Dann habe ich noch den Bowsercache geleert brachte auch keinen Erfolg. Mir ist aufgefallen das das Rauschen nur im Chrome existiert im Firefox hört man gar nix, FF ging aber zuvor auch.

- Dann hatte ich noch den Switch im Verdacht… den also auch noch getauscht nix.

- Dann kommt die Krönung ich habe dann von float32 auf S16LE (16Bit Little endian) umgestellt, das dann auf den Client in float umgewandelt doch daraufhin hat sich die Playback Rate (es kling als wenn man vorspult) geändert, obwohl ich an der Samplerate nichts verändert habe. Das Rauschen war auch noch da nur nicht mehr so schlimm.

Bei dem rauschen hätte ja auf Quantisierungsfehler getippt aber auf 2 unterrichtlichen Rechnern??
Das erklärt aber nicht die verändertere Playback Rate

Die USB soundkarten sind i.o da bei windoof alles funktioniert.

Bleibt nur noch Gstreamer was aber auch nicht sein kann da, A vorher alles prima ging und B ich auf 2 Rechner mit 2 unterschiedlichen Gstreamer-versionen dieselben Probleme habe.

So kann ich nicht weiterarbeiten, könnte alles kurz und klein kloppen:mad:, stand kurz vor der Fertigstellung nur der Downsampler und dazugehöriger Lowpass(alasing-Fliter) war noch zu testen.

Eins noch:
Ich Streame die Daten via binaryjs und das Skript ist im Browser über einen URL eingebunden
<script src="http://cdn.binaryjs.com/0/binary.js"></script>
Ist es möglich das die da was geupdated haben was den Fehler verursacht?
 
Hä, ich versteh das nicht.:mad:

Ich habe mein ersten nodejs versuche auf einen Pentium 2 gemacht, da ich noch keine anderen Rechner für Debian hatte.
Jedenfalls habe ich den P2 jetzt von Dachboden geholt und meine Streaming Software getestet geht einwandfrei, dann das Raspberry genommen, geht auch.

Nachgesehen was auf den P2 Rechner für einen Gstremaer Version installiert ist siehe da 1.0.2.
Also anderen Rechner geschnappt Debian neu installiert Gstreamer 1.0.2 installiert pcm Daten verschickt … geht mit einer Sampelrate von 44100 da ich aber schon mit einer Rate von 192000 gearbeitet habe, habe ich das auch noch mal probiert.

Auf einmal geht nicht mehr, wider nur ein rauschen. Also eine Ausgabe von den Samples gemacht und siehe da die wert werden nicht kleiner als 0.999902312345 hm... Rate geändert auf 44100 sind die werte 0.00000234 zu klein.

Also ein habe ich via gst ein Sinus erzeugt. Selbst das geht nicht nur ein ticken kommt an. Die Samples sind in Ordnung normale float werte hä???

Reinfolge der TCP Packet falsch,kann nicht sein. Dann habe ich das lokal an einen Rechner getestet also Chrome installiert selbe Problem, dann Chromium installiert auch kein Erfolg. dann habe ich via Taskkill die gespawnte gstreamer Pipeline getötet du siehe da es werden immer noch Daten gesendet was aber nicht sein kann.:confused:

Meine letzte Vermutung ist das Debian ein Update gezogen hat was den Fehler verursacht, und durch die Neuinstallation wird eben auch das Update immer installiert.

Ich mache jetzt noch eins ich installiere Debian 6 (ist auf den P2 drauf) wenn es dann nicht geht, Frage:
Kommt jemand aus der Nähe von Leipzig?
Fahre auch bis Dresden, Magdeburg und wenns gut organisiert ist auch nach Berlin?
Was aber auch geht Teamviewer.
 
Hä, ich versteh das nicht.:mad:
wir(ich jedenfalls) auch nicht, da wir nicht wissen was du genau machst.
also beschreibe mal ausführlich was du genau mit welcher software/hardware anstellst, was ging mal, was geht nicht mehr, was geht noch auf anderer hardware/software aber nicht mehr auf der aktuellen

geht mit einer Sampelrate von 44100 da ich aber schon mit einer Rate von 192000 gearbeitet habe, habe ich das auch noch mal probiert.

Auf einmal geht nicht mehr, wider nur ein rauschen. Also eine Ausgabe von den Samples gemacht und siehe da die wert werden nicht kleiner als 0.999902312345 hm... Rate geändert auf 44100 sind die werte 0.00000234 zu klein.
klingt komisch, erst ging alles, nach wechsel zu 192000 nicht mehr(mag ja noch sein) und dann wieder zurück auf 44100 und es geht nichts mehr?
 
Ok, dann hole ich mal weit aus.

Wie der ein oder andere mitbekommen hat entwickle einen Streaming Plattform für PCM Streaming in RealTime.

Die Situation ist so GstreamerPipeline(source) - > Nodejs(hier wird auch eine GstreasmePipeline gespwant Grund ist eine Datentypen Erkennung und Konvertierung in float) - > binaryjs(websocket), dann stream zum Browser(Input Stream und Play mit web Audio API)

Der nachfolgende Code hat immer funktioniert.
NodeJs:
Code:
var child = require('child_process');
var net = require('net');
var BServer = require('binaryjs').BinaryServer({port: 3000});

//globals
var clients = [];
var cmd = 'gst-launch-1.0';
var options = null;

//Gstreamer spawn um automatische datentypenerknnung durzuführen, audioresample muss zwichen audioparse und audioconvert stehen sonnst Fehler.
var args = ['fdsrc fd=0', '!', 'audioparse', '!', 'audioresample quality=10', '!', 'audio/x-raw, rate=192000', '!', 'audioconvert', '!', 'audio/x-raw, rate=192000, channels=1, format=F32LE', '!','fdsink fd=1'];

var GstLaunch = child.spawn(cmd, args, options);

BServer.on('connection', function(client){
	console.log('WsClient connected');
	clients.push(client);

	client.on('close', function(code, messege){
		for(var i in clients){
			if(clients[i].id == client.id){
				clients.splice(i, 1);
				console.log('Disconnected WebSocket (' + clients.length+' total)' );
			}		
		}
	});
	console.log(clients.length);
});

//TCP Socket Daten an Gstremer senden 
var TcpServer = net.createServer(function (TcpSocket){
	console.log('stream connected');
	TcpSocket.on('data', function(TcpData){
		GstLaunch.stdin.write(TcpData);
	});		
});

//Error callbacks
GstLaunch.on('message', Message);
GstLaunch.stderr.on('data', onSpawnError);
GstLaunch.on('exit', onSpawnExit);

function Message(msg){;
	console.log(msg.toString());
}

function onSpawnError(data){
	console.log(data.toString());
}

function onSpawnExit(code){
	if(code != null){
	console.error('GStreamer error, exit code ' + code);
	}
}



//send with binaryjs
function Send(data){
for(var i in clients){
var MFNormalCW = clients[i].createStream('MF-CW')
				MFNormalCW.write(data);
	}
};


//Data callback form GStreamer
GstLaunch.stdout.on('data', Send);

//tcp Port
TcpServer.listen(5000);
console.log(TcpServer.address().port);
Das Nodejs Skript lauert auf einen TCp Port und schriebt die Daten in einen websocket Verbindung. Es ist sozusagen einen TCP to websocket Bridge. Das Audioparse Element sorg für einen Datentypen erkennung und audioconvert konvertiert das in in Float32 womit auch die web audio api arbeitet. Der rest ist selbst erklärend.

Der Grund warum das nodejs auf einen tcp port lauscht ist einfach erklärt: mein Empfänger lieft die PCM Daten nicht via Soundkarte sondern übe einen tcp Port.
Siehe:Anhang anzeigen weinheim-2005-pa3fwm.pdf

Die nun vorhanden PCM Daten wandern via websocket zu den Clients wo sie via web Audi api abgespielt werden sollen.
Da habe ich 2 Skriptes einen mit Scriptprocessor und das andere mit der createBuffer Methode, beide sind nicht perfekt aber sie liefen bis eben vor ein paar Tagen einwandfrei.

das Scriptprocessor Skript:
Code:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/html">
<head>
    <title>Playing sound with WebAudio API</title>
     <script src="http://cdn.binaryjs.com/0/binary.js"></script>
 </head>
<body>
<div id="ausgabe"></div>
<script type="text/javascript">

window.AudioContext = window.AudioContext || window.webkitAudioContext;
var audioctx = new AudioContext();

//44100Saples/s * 32Bit / 8 = 176400 byte, ein Float32Array Elemet 4 byte groß 176400/4 = 44100 Elemente
var bufferSize = 96000;
var f32= new Float32Array(bufferSize), ratioweight=0, writeoffs=0, outputoffs=40001; bitLength=0
var InRate=44100;

function play(b){
			var output=b.outputBuffer.getChannelData(0),outputLen=b.outputBuffer.length;
			for(var i=0;i<outputLen;i++){
				//Interpolation Sampleratio berechnen 
			var firstSample=f32[outputoffs],ratio=InRate/audioctx.sampleRate;
				ratioweight+=ratio;
				if(1<=ratioweight){
					ratioweight-=1;
					f32[outputoffs]=0;
					outputoffs++;
					bufferSize<=outputoffs&&(outputoffs-=bufferSize);
					var secondSample=f32[outputoffs];
					var Sample=(ratioweight*secondSample+(ratio-ratioweight)*firstSample)/ratio;
					//document.getElementById("ausgabe").innerHTML= (Sample);			
				}
				
				 output[i]=Sample;//document.getElementById("ausgabe").innerHTML= (output[i]);
			}//ende for
}

//Audio Context stuff
audioctx.sampleRate=sr;
var sr=audioctx.sampleRate,Samples=2048;
Processor=audioctx.createScriptProcessor(Samples,0,1)
Processor.onaudioprocess=play;
Processor.connect(audioctx.destination);
console.log(audioctx.sampleRate);


var client = new BinaryClient("ws://192.168.2.104:3000");
client.on('stream', function(s, meta) {
	if (meta === 'MF-CW'){
    	s.on('data', function(data) {		
			var d = new Float32Array(data),c;
					
			for(c=0;c<d.length;c++,writeoffs++){
				document.getElementById("ausgabe").innerHTML= (d[c]);
				f32[writeoffs]=d[c]; 
				bufferSize<=writeoffs&&(writeoffs=0);		
			}	
        });//s.on('data'	
	}
});//client.on('stream'

 </script>
 
</body>
</html>


und das createBuffer Skript.
Code:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/html">
<head>
    <title>Playing sound with WebAudio API</title>
     <script src="http://cdn.binaryjs.com/0.1.4/binary.js"></script>
 </head>
<body>
<script>

window.AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new AudioContext();
var init = 0;
var nextTime = 0;
var audioStack = [];

var client = new BinaryClient("ws://192.168.2.104:3000");
client.on('stream', function(s, meta) {
	if (meta === 'MF-CW') {
	
    	s.on('data', function(data) {	
		console.log(data.byteLength);
		audioStack.push(data);
		if ((init!=0) || (audioStack.length > 10)) { // make sure we put at least 10 chunks in the buffer before starting
			init++;
			scheduleBuffers();
		}
	});
	}
});

function scheduleBuffers() {
	while (audioStack.length) {
		var data	 = audioStack.shift();
		var audData  = new Float32Array(data);

		var sr = 88200;//samplerate		

		var source      = context.createBufferSource();
		var audioBuffer = context.createBuffer(1, audData.length , sr);
		audioBuffer.getChannelData(0).set(audData);
		source.buffer   = audioBuffer;
		source.connect(context.destination);
		if (nextTime == 0)
			nextTime = context.currentTime + 0.05;  /// add 50ms latency to work well across systems - tune this if you like
		source.start(nextTime);
		nextTime+=source.buffer.duration; // Make the next buffer wait the length of the last buffer before being played
	};
}

 </script>
 
 

</body>
</html>

Hier mal einen Hörprobe von der Skriprocessor Version.
Anhang anzeigen aufnahme 1.zip
Diese Aufnahme stammt von den Pentium 2 als stream Server, der PlaybackBrowser war FF. Es “jttert“ zwar aber es ist hörbar. Bei allen anderen Rechner im Haus kommt nur ein Rauschen an, die Skripts sind dieselben auch die Gstremaer Version sind gleich.

Nehme ich einen Modernern Rechner als den Pentium 2 kommt bei den Clients nur ein Rauschen an, gaaaaanz weit weg hört man aber Musik, die Frage ist wo kommt das Rauschen her und warum ist das von der Sample rate abhängig.

Ich kann nur noch mit einer Rate von 44100 streamen. Höher = Rauschen, kleiner = kein Ton, da Samples nur noch 0.00000234.
Außer mit dem P2 oder RPi geht’s mit allen Rates, aber auf beiden Systemen mach das arbeiten keinen spaß.

Rauschen tut aber nur ein Signal von einer Soundkarte, ein Sinus 440Hz wird warum auch immer zerhackt und in ein Trafo ähnliches brummen umgewandelt. Kann ich ja auch mal aufzeichnen.

Ich hatte heute von Gstreamer nach Gstreamer gstreamt, das geht einwandfrei. Das Problem muss also in kombination Nodejs, binaryjs auftreten aber warum ging‘s erst und jetzt nicht mehr ?????
 
Zuletzt bearbeitet:
dann würde ich ja zuerst mal rausfinden, wo das rauschen das 1. mal reinkommt.
ist es hier
GstreamerPipeline(source) - >
schon da? usw.
 
hesst schrieb:
ist es hier GstreamerPipeline(source) - > schon da? usw.

Ausgeschlossen da, das Probleme auch auftritt wenn man die gespawnte Gst_Pipeline als Quelle nimmt, also statt fdsrc(file descriptor), audiotestsrc freq=440. Sprich vorher garn nicht erst mit TCP arbeiten.
So hört sich das 440Hz Signal dann an.
Anhang anzeigen defekt.zip
Aussehen tut das so:
defekt.png

Ändere ich den Datentyp von F32LE auf S16LE, dann ändert sich a die Playback rate und b, stimmen die Frequenzen nicht mehr. Je nach Output Samplerate sind es 220Hz oder 880Hz.

Man könnte meinen:
Die Menge der zu transportierenden Daten entscheidet auf der Client Seite die sample rate.

Ps Wenn ich statt tcp udp nehme ist es dasselbe Problem.

Ohne Scheiß wer das raus findet den schenke ich 50 Euro.
 
Ausgeschlossen da, das Probleme auch auftritt wenn man die gespawnte Gst_Pipeline als Quelle nimmt, also statt fdsrc(file descriptor), audiotestsrc freq=440. Sprich vorher garn nicht erst mit TCP arbeiten.
??? nochmal, wir stecken da nicht drinn, brauchen also eine genaue beschreibung, auch die vorherige hätte ich mir ausführlicher vorgestellt.
du sagst "ausgeschlossen weil <<irgendwas>>" das einzig logische irgendwas, was ich mir hier vorstellen kann, ist wenn du hier
dann stream zum Browser(Input Stream und Play mit web Audio API)
im letzten schritt vor dem letzten glied deiner kette einen sauberen stream an den browser sendest, und es trotzdem rauscht. meintest du das?
 
Hallo hesst, ich habe das jetzt so gemacht wie du gesagt hast, habe mir da web-audio-api Modul von npm Netzwerk heruntergeladen und getestet.

Zuerst habe ich ein Sinus erzeugt ohne Gstreamer rein mit JS und abgespielt das geht problemlos.

Dann habe ich die Child erzeugt Gstreamer Pipeline hinzugeholt und via gstreamer ein sinus erzeugt, da kam dann die Fehlermeldung . “ Value Out of bunds“ in web audio api module.
Daraufhin habe ich gedacht das es an den File Deskriptor liegt also Gstreamer Pipeline weg und die Daten vom TCp socket geholt(das erste Glied in der Kette) . Ebenfalls “ Value Out of bunds“ .
Der Datentyp war immer Float32 darauf habe ich geachtet.

Dann habe ich wider ein Sinus erzeugt was ich via binarjs streamen wollte. Ergebnis es geht nicht entweder kommt kein Ton oder nur Müll.
Entweder Spielt das Buffer Objekt verrückt oder Nodejs in Kombination Debian.

Hir das Skript mit dem zu übertragen Sinus:
Code:
var BServer = require('binaryjs').BinaryServer({port: 3000});

//globals
var bufferSize = 44100;
var Sinus = new Buffer(bufferSize);
var clients = [];

BServer.on('connection', function(client){
	console.log('WsClient connected');
	clients.push(client);

	client.on('close', function(code, messege){
		for(var i in clients){
			if(clients[i].id == client.id){
				clients.splice(i, 1);
				console.log('Disconnected WebSocket (' + clients.length+' total)' );
			}		
		}
	});
	console.log(clients.length);
});

for(var i=0;i<44100;i++){
//Sinus.writeFloatLE(Math.sin(Math.PI*2/44100*i*440)/4, i);//kommt Ton
Sinus[i] = Math.sin(Math.PI*2/44100*i*440)/4;//stille
}

//senden alle 500ms 
setInterval(function(){
	send();
},500);

function send(){
for(var i in clients){
var MFNormalCW = clients[i].createStream('MF-CW')
		

MFNormalCW.write(Sine);	

	}
}
Bei diesem Skript kommt wie gesagt nur Müll an wenn ich die writeFloatLE Methode nutze. Schreibe ich die Daten ohne eine Methode in das Buffer Objekt knackt nur 2 mal alle Sekunde.

Wenn das mal jemand auf einer Windows Maschine testen kann wäre ich sehr dankbar. Wenn‘s da klappt ist zumindest binaryjs nicht für den Fehler verantwortlich
 
kkapsner schrieb:
Hast du denn den Datentyp auch beim Empfänger geändert?
Ja habe ich, via (audoDatia>0)?audioData/32767:audioData/32768;
habe ich 16 bit in Float32 zurück gewandelt.
das alles in den onmessege event (s.on(data) in meinen Bespiel)

kkapsner schrieb:
Ich hab' ja den Verdacht, dass da irgendwas mit den Datentypen (z.B. BE vs. LE) durcheinander geraten ist.
aber warum auf einmal?? hast du das letzte beispiel bei dir mal laufen gelassen??
habe es mit Debian 6 und Ubuntu probiert es funz nicht mehr!!!!!!!!!!!!:mad:


kkapsner schrieb:
Wenn nicht, ändern sich natürlich die Frequenzen, da du ja weniger Daten pro Sekunden sendest.
Asso, wenn das so ist dann ist das setInterval eventuell zu langsam mit 500ms, aber 1 Sekunde 44100 samples kommt mir zu langsam vor(zumindest über tcp der ADC macht das). Vorher wurde der onmessege event alle 5-10ms ausgeführt aber es kamen nur buffer mit einer länge von 16384-ca. 17000
Elementen an.

Aber bei der Gstreamer variante wurde ja die Send Funktion von Gstreamer ausgelöst.
GstLaunch.stdout.on('data', Send);
darauf habe ich kein Einfluss wie schnell oder wann der File-Deskriptor ein event feuert.

PS: Gstreamer ist nicht für den Fehler verantwortlich da ein Stream von Gstreamer nach Gstreamer tadellos funktioniert!!

Was ich auch noch erwähne sollte ist das wen man, die gespawnte Gstreamer Pipeline komplett weglässt, also das tcp direkt in websocket schreibt, dann geht es aber nur noch mit einer sample Rate von 44100 in FF, in Chrome no way. Alle ander SR ebenfalls no way.

Wie gesagt irgendwas passiert mit den Daten innerhalb nodejs aber was?

Habe mir auch überlegt was der Pentium 2 anders macht als neure Rechner... er ist langsamer, aber was hat Geschwindigkeit mit dem Problem zu tun.. ein Rätsel :confused:

Frage könnte wir hesst oder Korbinian oder wer auch immer mit Teamviewer + Skype irgendwas reißen. Das Projekt ist mir sehr wichtig außerdem habe ich schon viel gelernt JS und DSP, will jetzt nicht wegen eines Spukes damit aufhören.:grin:
 
Zuletzt bearbeitet:
Hi, ich habe das Problem gefunden und auch lösen können es lag an den audioparse Element, warum sich nun Gstreamer zu GStrearmer verstehen ist unklar.
Irgendwas in Kombination mit dem File Deskriptor und audioparse geht nicht naja egal.

Allerdings habe ich das nächste Problem auch schwerwiegend.:(

Wie konvertiere ich ein nodejs Buffer zu einen Typedarray (float32):confused:????

Habe ein schon ein paar Dinge versucht aber alle schlugen fehl.
Würde gern erst mal eure Ideen hören bevor ich mit dem Content beginne.

Stdout liefert mir ein Buffer mit float32 Samples, aber audiolib und meine Filter wollen alle ein Float32Array, da man keine for schleife durch ein Buffer Objekt machen kann.
Kann man schon es kommen aber nur oktets als Rückgabe.

PS. :new Float32Array(new Buffer) geht nicht kommen auch nur oktes(uInt‘s) raus.

obwohl es in der API so steht
Creating a typed array from a Buffer works with the following caveats:

The buffer's memory is copied, not shared.

The buffer's memory is interpreted as an array, not a byte array.
That is, new Uint32Array(new Buffer([1,2,3,4])) creates a 4-element Uint32Array with elements [1,2,3,4],
not an Uint32Array with a single element [0x1020304] or [0x4030201].
 
hesst schrieb:
Buffer Node.js v0.10.32 Manual & Documentation


So einfach ist das nicht bzw vielleicht doch ich versteh‘s nur nicht.
Wenn ich eine Schleife durch das buffer Objekt mache dann bricht die genau 4 bytes vorher ab.

bsp:
Code:
var buf = new Buffer(1024); // soll ein stdout buffer darstellen 
var F32 = new Float32array(buf.length);

for(var i=0;i<buf.length;i++){
 F32[i] = buf.readFloatLE(i);// bricht ab bei i 1020
}
Ich habe auch verstanden warum das abbricht, weil ein Float 32 bit groß ist also 4 Byte.


Ich könnte jetzt i*=4 rechnen aber ich weiß nicht ob das der Sinn ist

Äh i+=4 meinte ich. xD
 
Zuletzt bearbeitet:
Code:
var i=0;
var j=0;
var buf = new Buffer(1024); // soll ein stdout buffer darstellen 
var F32 = new Float32array(buf.length/4);
for(;i<buf.length;i+=4,++j)
{
 F32[j] = buf.readFloatLE(i);
}

- - - Aktualisiert - - -

oder du klaust dir die base64 nach uint8array methode
Code:
function b64ToUint6 (nChr) {

  return nChr > 64 && nChr < 91 ?
      nChr - 65
    : nChr > 96 && nChr < 123 ?
      nChr - 71
    : nChr > 47 && nChr < 58 ?
      nChr + 4
    : nChr === 43 ?
      62
    : nChr === 47 ?
      63
    :
      0;

}
function base64DecToArr (sBase64, nBlocksSize) {

  var
    sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""), nInLen = sB64Enc.length,
    nOutLen = nBlocksSize ? Math.ceil((nInLen * 3 + 1 >> 2) / nBlocksSize) * nBlocksSize : nInLen * 3 + 1 >> 2, taBytes = new Uint8Array(nOutLen);

  for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) {
    nMod4 = nInIdx & 3;
    nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4;
    if (nMod4 === 3 || nInLen - nInIdx === 1) {
      for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) {
        taBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255;
      }
      nUint24 = 0;

    }
  }

  return taBytes;
}
dann einfach
Code:
var buf = new Buffer(1024); // soll ein stdout buffer darstellen 
var F32 = new Float32array(base64DecToArr(buf.toString('base64')));
sollte das gleiche machen, ist nicht ganz so performant, finde ich aber schöner(lesbarer)
 
die erste Version läuft nicht.

das Problem ist das der buffer der ankommt nicht immer durch 4 zu teilen geht zb. 15685 ergibt eine Komma zahl. das will das Float32Arry Objekt nicht.
warum das so ist habe ich auch noch nicht verstanden 90% aller fälle passiert das wen man auf den Server was macht.

Die base64 Version rockt:cool:, habe ich auch so am laufen aber über ein Modul

Zur base 64 Version hätte ich noch ne frage:

Habe ich einen Qualitätsverlust wenn ich den Weg über base64 mache??

Kann ich auf diese weiße auch 16bit nach float32 bringen??
 
die erste Version läuft nicht.
die 2te macht n nichts anderes, die fehler werden vermutlich nur ignoriert

das Problem ist das der buffer der ankommt nicht immer durch 4 zu teilen geht
dann hast du ein problem, entweder ist da mehr als floats, oder da fehlen noch daten die später kommen

zb. 15685 ergibt eine Komma zahl. das will das Float32Arry Objekt nicht.
logisch

Die base64 Version rockt:cool:, habe ich auch so am laufen aber über ein Modul
hier werden dann aber die 3-1 restlichen bytes ignoriert, bzw. werden nachfolgende pakete falsch interpretiert, falls die das vorherige ergänzen

Habe ich einen Qualitätsverlust wenn ich den Weg über base64 mache??
nee, base64 transformiert nur bytes in den lesbaren bereich

Kann ich auf diese weiße auch 16bit nach float32 bringen??
wie 16bit? du kannst 16 bit als 2 byte base64 codieren und damit 2 16bitwerte als float interpretieren, falls es sich um floatwerte handelt(nicht jeder 32 bit wert ist ein gültiger float wert)
 
hesst schrieb:
dann hast du ein problem, entweder ist da mehr als floats, oder da fehlen noch daten die später kommen
naja mann könnte vorher die Daten in eine Ringbuffer schreiben und immer 16384 Samples droppen z.B..
Eigentlich will ich ja von der GStremer Pipeline weg.



hesst schrieb:
hier werden dann aber die 3-1 restlichen bytes ignoriert, bzw. werden nachfolgende pakete falsch interpretiert, falls die das vorherige ergänzen
Wie kommst du den darauf??

hesst schrieb:
nee, base64 transformiert nur bytes in den lesbaren bereich
Das gefällt mir gut:cool:

hesst schrieb:
Naja wenn mir der stdout event 16Bit Samples bringt und ich die in base64 Encodiere
und daraus dann Float 32 mache, habe ich doch den Datentyp konvertiert oder??

Praktisch so:
Stdout Buffer (16bit samples) ->base64->Float32

es gibt nämlich 'n menge Datentypen, die da wären:
S8, U8, S16LE, S16BE, U16LE, U16BE, S24_32LE, S24_32BE, U24_32LE,
U24_32BE, S32LE, S32BE, U32LE, U32BE, S24LE, S24BE, U24LE, U24BE,
S20LE, S20BE, U20LE, U20BE, S18LE, S18BE, U18LE, U18BE, F32LE, F32BE, F64LE, F64BE
Diese müssen alle nach float 32 konvertiert werden.
 
Wie kommst du den darauf??
float sind immer 32 bit
hast du jetzt einen buffer aus 4 byte, kannst du den als float interpretieren
|0|1|2|3| <= das ist ein float
hast du 3 buffer aus 5, 5 und 2 byte, die eigentlich zusammengehören, kannst du den 1. als einen float interpretieren, beim 2. auch, der wert ist aber nicht mehr der des 2. floats und den 3. kannst du nicht als float interpretieren.
das sind die eigentlichen werte
|0|1|2|3|4|5|6|7|8|9|A|B|
<float1 ><float2 ><float3 >
lesen tust du:
|0|1|2|3|4|
<float1 >

|5|6|7|8|9|
<float2 > der ist aber falsch

|A|B|
der geht nicht als float zu interpretieren

Naja wenn mir der stdout event 16Bit Samples bringt und ich die in base64 Encodiere
und daraus dann Float 32 mache, habe ich doch den Datentyp konvertiert oder??
nee, dann hast du 2 16bit werte als 1 float interpretiert
 
Zurück
Oben