转换Web音频API中的采样率

Convert Sample Rate in Web Audio API

本文关键字:采样率 API Web 音频 转换      更新时间:2024-03-27

如何在浏览器中将缓冲区的采样率从44100 Hz转换为48000 Hz?

我找到了一个图书馆https://github.com/taisel/XAudioJS/blob/master/resampler.js这应该允许我这样做,但不知道如何使用它。

使用离线音频上下文。以下内容可能有效:

var c = new OfflineAudioContext(1, len, 48000);
var b = c.createBuffer(1, len, 44100);
b.copyToChannel(yourSourceBuffer, 0);
var s = c.createBufferSource();
s.buffer = b;
s.connect(context.destination);
s.start();
c.startRendering().then(function (result) {
  // result contains the new buffer resampled to 48000
});

根据实现方式,重新采样的信号的质量可以有相当大的变化。

当音频上下文的采样率与音频文件的采样率不同时,mobile safari中似乎存在一个错误,无法正确解码加载的音频。此外,音频上下文的采样率从44100随机变化到48000,通常但并不总是取决于网站是在打开还是关闭iPhone声音的情况下加载的

这个问题的解决方法是读取音频上下文的采样率,然后为每个采样率加载不同的音频文件,如下所示:

window.AudioContext = window.AudioContext || window.webkitAudioContext;
var audio_context = new AudioContext();
var actual_sample_rate = audio_context.sampleRate;
if (actual_sample_rate != 48000) {
    actual_sample_rate = 44100;
}
function finished_loading_sounds(sounds) {
    buffers['piano_do'] = {
        buffer: sounds.piano,
        rate: 1
    };
    // ...do something when the sounds are loaded...
}
var buffer_loader = new BufferLoader(
    audio_context,
    {
        piano: "audio/" + actual_sample_rate + "/piano.m4a",
    },
    finished_loading_sounds
);
buffer_loader.load();

缓冲区加载程序的定义与本教程类似。

要更改音频文件的采样率,可以使用Audacity。


更新

似乎即使你试图以正确的采样率加载文件,iOS设备上的声音偶尔也会失真。

为了解决这个问题,我发现了一个破解你的AudioContext:

function createAudioContext(desiredSampleRate) {
    var AudioCtor = window.AudioContext || window.webkitAudioContext;
    desiredSampleRate = typeof desiredSampleRate === 'number'
        ? desiredSampleRate
        : 44100;
    var context = new AudioCtor();
    // Check if hack is necessary. Only occurs in iOS6+ devices
    // and only when you first boot the iPhone, or play a audio/video
    // with a different sample rate
    if (/(iPhone|iPad)/i.test(navigator.userAgent) && context.sampleRate !== desiredSampleRate) {
        var buffer = context.createBuffer(1, 1, desiredSampleRate);
        var dummy = context.createBufferSource();
        dummy.buffer = buffer;
        dummy.connect(context.destination);
        dummy.start(0);
        dummy.disconnect();
        context.close(); // dispose old context
        context = new AudioCtor();
    }
    return context;
}

然后使用它,创建如下音频上下文:

var audio_context = createAudioContext(44100);