I am making an application where I am taking mic data from the inputBuffer and I want to stream to another client and play it. However, I cannot get it wokring.
My recording/capturing works fine so I will skip to relevant parts of the code
function recorderProcess(e) {
var left = e.inputBuffer.getChannelData(0);
var convert = convertFloat32ToInt16(left);
window.stream.write(convert);
var src = window.URL.createObjectURL(lcm);
playsound(convert);
ss(socket).emit('file',convert, {size: src.size},currentgame);
ss.createBlobReadStream(convert).pipe(window.stream);
//ss.createReadStream(f).pipe(widnow.stream);
}
function playsound(raw) {
console.log("now playing a sound, that starts with", new Uint8Array(raw.slice(0, 10)));
context.decodeAudioData(raw, function (buffer) {
if (!buffer) {
console.error("failed to decode:", "buffer null");
return;
}
var source = context.createBufferSource();
source.buffer = buffer;
source.connect(context.destination);
source.start(0);
console.log("started...");
}, function (error) {
console.error("failed to decode:", error);
});
}
I am able to successfully create an array buffer using the float32toint16 function, however when I use the init sound function I get an error "null" meaning that the arraybuffer will not decode into an audio stream? Has anyone else had this issue? I have scoured the internet with no answer on how to do this. I am trying to play it this way because ultimately I will be streaming from client to client so I will be sending arraybufers via sockets.
thanks in advance.
If I'm understanding this correctly (there are some missing pieces in your code sample)...
decodeAudioData
can only decode things like MP3 or WAV. It looks like you're passing it a raw Int16Array
or Uint16Array
. Because the underlying ArrayBuffer
isn't a format that decodeAudioData
understands, it gives up.
I think what you want to do is something like this:
function playsound( raw ) {
// i'll assume you know how to convert in this direction
// since you have convertFloat32ToInt16
var buffer = convertInt16ToFloat32( raw ),
src = context.createBufferSource(),
audioBuffer = context.createBuffer( 1, buffer.length, context.sampleRate );
audioBuffer.getChannelData( 0 ).set( buffer );
src.buffer = audioBuffer;
src.connect( context.destination );
src.start( 0 );
}
Basically, you already have a way to create the raw Float32Array
that the Web Audio API likes, so there's no need to decode (and you can't decode anyway, since your data isn't a valid file format). So you just convert back to Float32Array
, create your own AudioBuffer
, write in the data from buffer
, and go from there.
For converting from float32 to unsigned int 16 you can multiply each float32 value with 0xffff(which is 16 bit max value). and for int16 to float32 do this reversely which means divide by 0xffff. audio should be fine now.
I am new in stackoverflow. I should write this as a comment but due to lack of reputation point i can't. Thats why i have to write it as a answer. sorry for inconvenience.
来源:https://stackoverflow.com/questions/25775704/html5-audio-api-inputbuffer-getchanneldata-to-audio-array-buffer