Подтвердить что ты не робот

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

Любые подсказки о том, как реализовать форму волны?

4b9b3361

Ответ 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
}