2

我需要即时生成音频(不能从 wav 或 mp3 文件生成)。幸运的是,新的 WebAudio API(FF4 和 Chrome 13)提供了这个功能。

我有一些要移植到 Javascript 的 Java 代码,如下所示:

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

我试图让它与 Web Audio API 一起工作,但它非常失真。这是我在 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);

这是我正在测试的 .java 文件:http: //gwt-nes-port.googlecode.com/svn/wiki/webAudioTests/Main.java

这是我正在测试的 .js 文件:http: //gwt-nes-port.googlecode.com/svn/wiki/webAudioTests/Main.js

关于 javax.sound 和 Web Audio 工作方式之间差异的任何提示,以及导致我的 JS 代码失真的原因是什么?

4

2 回答 2

4

感谢非常乐于助人的 Google Chrome 团队,我想出了这一点。他们是这样说的:

嗨,布拉德,您的样本数据似乎超出了有效范围。对于此 API,全量程浮点 PCM 音频数据应在 -1.0 -> +1.0 范围内

也许您的数据值是 16 位缩放的(-32768 -> +32767)。

因此,当我创建我的字节数组时,我需要确保所有内容都表示为十进制。所以代替这个:

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

我真的需要看起来像这样的东西:

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

所以在我的代码中,我只是添加了一些逻辑来将 16 位缩放值转换为适当的范围,如下所示:

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

现在音频以小数表示,不再听起来像一首失真的重金属歌曲。

于 2011-05-16T22:23:59.663 回答
-1

您可以在没有 Web Audio API 的情况下执行此操作,因为您拥有示例数据。即时生成 .wav 文件并使用类型数组。

幻灯片 23:http ://davidflanagan.com/Talks/jsconf11/BytesAndBlobs.html

于 2011-06-02T01:35:14.087 回答