HTML5 Web Audio API, портирование с javax.sound и получение искажений - PullRequest
2 голосов
/ 15 мая 2011

У меня есть требование генерировать аудио на лету (генерация из файлов wav или mp3 не возможна). К счастью, новый API WebAudio (FF4 и Chrome 13) предоставляет эту функциональность.

У меня есть код Java, который я портирую на Javascript, который выглядит следующим образом:

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

Я пытаюсь заставить это работать с API Web Audio, но оно чрезвычайно искажено. Вот код, который я использую в 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 / СВН / вики / webAudioTests / Main.java

А вот и файл .js, с которым я тестирую: http://gwt -nes-port.googlecode.com / СВН / вики / webAudioTests / Main.js

Какие-нибудь советы о различиях между работой javax.sound и Web Audio и причинах искажения в моем коде JS?

Ответы [ 2 ]

4 голосов
/ 17 мая 2011

Благодаря очень полезной команде 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;
}

Теперь звук представлен в виде десятичной дроби и больше не звучит как искаженная хеви-металлическая песня.

0 голосов
/ 02 июня 2011

Вы можете сделать это без API Web Audio, так как у вас есть пример данных.Создайте файл .wav на лету и используйте массивы типов.

Слайд 23: http://davidflanagan.com/Talks/jsconf11/BytesAndBlobs.html

...