开发者

HTML5 Web Audio API, porting from javax.sound and getting distortion

开发者 https://www.devze.com 2023-03-05 21:28 出处:网络
I have a requirement to generate audio on the fly (generating from wav or mp3 files is not an option). Luckily the new WebAudio API (FF4 and Chrome 13) provides this functionality.

I have a requirement to generate audio on the fly (generating from wav or mp3 files is not an option). Luckily the new WebAudio API (FF4 and Chrome 13) provides this functionality.

I have some Java code i'm porting to Javascript that looks like this:

byte[] buffer = new byte[]{ 56, -27, 88, -29, 88, -29, 88, -29 ............ };
AudioFormat af = new AudioFormat(44100, 16, 1, true, false);
SourceDataLine sdl = AudioSystem.getSourceDataLine(af);
sdl.open(af, 1470 * 4); //create 4 frame audio buffer
sdl.start();
sdl.write(buffer, 0, buffer.length);

I'm trying to get this working with the Web Audio API, but it is extremely distorted. Here is the code i'm using in JS:

var buffer = [ 56, -27, 88, -29, 88, -29, 88, -29 .........开发者_开发问答... ];
var ctx = new webkitAudioContext();
var src = ctx.createBufferSource();
src.buffer = ctx.createBuffer(1, buffer.length, 44100);
src.buffer.getChannelData(0).set(buffer);
src.connect(ctx.destination);
src.looping = false;
src.noteOn(0);

Here is a .java file that i'm testing with: http://gwt-nes-port.googlecode.com/svn/wiki/webAudioTests/Main.java

And here is the .js file that i'm testing with: http://gwt-nes-port.googlecode.com/svn/wiki/webAudioTests/Main.js

Any tips on the differences between how javax.sound and Web Audio work, and what is causing the distortion in my JS code?


Thanks to the very helpful Google Chrome team, I figured this one out. Here is what they said:

Hi Brad, it looks like your sample-data is outside of the valid range. For this API, the full-scale floating-point PCM audio data should be within the range -1.0 -> +1.0

Perhaps your data values are 16bit scaled (-32768 -> +32767).

So when I create my byte array, I need to make sure everything is represented as a decimal. So instead of this:

byte[] buffer = new byte[]{ 56, -27, 88, -29, 88, ............ };

I really needed something that looked like this:

byte[] buffer = new byte[]{ 0.023, -0.1, 0.125, -0.045, ............ };

So in my code I just added some logic to convert the 16bit scaled values to the appropriate range like this:

for(var i=0;i<buffer.length;i++) {
   var b = buffer[i];
   b = (b>0)?b/32767:b/-32768;
   buffer[i] = b;
}

Now the audio is represented as a decimal and no longer sounds like a distorted heavy metal song.


You can do this without the Web Audio API since you have the sample data. Generate a .wav file on the fly and use type arrays.

Slide 23: http://davidflanagan.com/Talks/jsconf11/BytesAndBlobs.html

0

精彩评论

暂无评论...
验证码 换一张
取 消