Web Audio для визуализации и взаимодействия с формами сигналов
Как написать программу JavaScript для отображения формы сигнала из аудиофайла? Я хочу использовать веб-аудио и холст.
Я пробовал этот код:
(new window.AudioContext).decodeAudioData(audioFile, function (data) {
var channel = data.getChannelData(0);
for (var i = 0; i < channel; i++) {
canvas.getContext('2d').fillRect(i, 1, 40 - channel[i], 40);
}
});
Но результат далек от того, что я хочу (а именно, изображение не является гладким, так как я рисую прямоугольники). Я хочу, чтобы он выглядел гладко, как этот образ:
![Waveform example]()
Любые подсказки о том, как реализовать форму волны?
Ответы
Ответ 1
Вам может быть интересно AudioJedit. Это проект с открытым исходным кодом размещенный в GitHub. Он имеет небольшую серверную node.js script для загрузки аудиофайлов, но все взаимодействие с аудио реализовано на клиентском JavaScript. Я думаю, что это похоже на то, что вы ищете.
Ответ 2
Вытащил свою собственную библиотеку в конце концов: waveurfer.js.
Он рисует форму волны из данных PCM и ищет области звука, нажимая на нее.
![Imgur]()
Ответ 3
Для (надеюсь) простого использования и интеграции формы сигнала с вашим приложением вам может потребоваться проверить, что мы делаем в IRCAM, особенно в форме сигнала в этом конкретном случае.
Все это с открытым исходным кодом и предназначено для модульности (и незавершенной работы)
Здесь вы можете найти демонстрацию
И соответствующий репозиторий githug
Ответ 4
Ваш код рендеринга крайне неэффективен, потому что он будет отображать 44100 пикселей на каждую секунду аудио. Вы хотите, в лучшем случае, увеличить ширину видового экрана с уменьшенным набором данных.
Диапазон выборки на пиксель, необходимый для соответствия форме сигнала в окне просмотра, может быть рассчитан с помощью audioDurationSeconds * samplerate/viewPortWidthPx. Таким образом, для видового экрана 1000 пикселей и аудиофайла в 2 секунды при 44100 сэмплерируйте выборки на пиксель = (2 * 44100)/1000 = ~ 88.
Для каждого пикселя на экране вы берете минимальное и максимальное значение из этого диапазона выборки, вы используете эти данные для рисования формы волны.
Вот пример алгоритма, который делает это, но позволяет вам давать образцы на пиксель в качестве аргумента, а также позицию прокрутки, чтобы разрешить виртуальную прокрутку и масштабирование. Он включает в себя параметр разрешения, который вы можете настроить для производительности, это указывает, сколько образцов он должен принимать за диапазон выборки пикселей:
Рисование масштабируемой временной шкалы аудиосигнала в Javascript
Метод draw похож на ваш, чтобы сгладить его, вам нужно использовать lineTo вместо fillRect.This разница не должна быть на самом деле огромной, я думаю, вы можете забыть установить атрибуты width и height на холст. Установка этого параметра в css вызывает размытие рисунка, вам нужно установить атрибуты.
let drawWaveform = function(canvas, drawData, width, height) {
let ctx = canvas.getContext('2d');
let drawHeight = height / 2;
// clear canvas incase there is already something drawn
ctx.clearRect(0, 0, width, height);
ctx.beginPath();
ctx.moveTo(0, drawHeight);
for(let i = 0; i < width; i++) {
// transform data points to pixel height and move to centre
let minPixel = drawData[i][0] * drawHeigth + drawHeight;
ctx.lineTo(i, minPixel);
}
ctx.lineTo(width, drawHeight);
ctx.moveTo(0, drawHeight);
for(let i = 0; i < width; i++) {
// transform data points to pixel height and move to centre
let maxPixel = drawData[i][1] * drawHeigth + drawHeight;
ctx.lineTo(i, maxPixel);
}
ctx.lineTo(width, drawHeight);
ctx.closePath();
ctx.fill(); // can do ctx.stroke() for an outline of the waveform
}