javascript - 录制音频、同步循环、偏移延迟和导出部分

标签 javascript html5-audio audio-recording web-audio-api recorder.js

我正在构建一个网络应用程序,允许用户循环聆听器乐,然后在上面录制人声。这一切都可以使用 Recorder.js 进行,但是存在一些问题:

  • 录音存在延迟,因此需要用户在按下录音之前进行设置。
  • 导出的循环长度并不总是相同,因为采样率可能与所需时间不完全匹配

但是从那时起我又回到了绘图板并问:什么对用户来说是最好的?。这给了我一组新的要求:

  • 背景循环在后台持续播放
  • 只要用户选择,录音就会开始和停止
  • 录音然后与循环同步播放(循环之间的死区时间会自动填充空白音频)
  • 用户可以滑动偏移 slider 来调整延迟的小计时问题
  • 用户可以选择保存录音的哪一部分(与原始伴奏循环长度相同)

这是一个图表:

enter image description here

到目前为止我的逻辑:

// backing loop
a.startTime = 5
a.duration = 10
a.loop = true

// recording
b.startTime = 22.5
b.duration = 15
b.loop = false

// fill blank space + loop
fill = a.duration - (b.duration % a.duration) // 5
c = b.buffers + (fill * blankBuffers)
c.startTime = (context.currentTime - a.startTime) % a.duration
c.duration = 20
c.loop = true

// user corrects timing offset
c.startTime = ((context.currentTime - a.startTime) % a.duration) - offset

// user choose favourite loop
? this is where I start to lose the plot!

下面是切碎从 Recorder.js 发送的缓冲区的示例:

// shorten the length of buffers
start = context.sampleRate * 2; // start at 2 seconds
end = context.sampleRate * 3; // end at 3 seconds
buffers.push(buffers.subarray(start, end));

以及我一直在处理的以前版本的更多示例代码: https://github.com/mattdiamond/Recorderjs/issues/105

如果您能帮助解决如何对导出循环的缓冲区进行切片或改进此逻辑,我们将不胜感激!

更新

使用这个示例,我能够找到如何在录音中插入空格:

http://mdn.github.io/audio-buffer/

我现在已经几乎复制了我需要的功能,但是白噪声似乎关闭了。是不是哪里计算错误了?

http://kmturley.github.io/Recorderjs/loop.html

最佳答案

我设法通过编写以下逻辑解决了这个问题

diff = track2.startTime - track1.startTime
before = Math.round((diff % track1.duration) * 44100)
after = Math.round((track1.duration - ((diff + track2.duration) % track1.duration)) * 44100)
newAudio = [before data] + [recording data] + [after data]

在 JavaScript 代码中它看起来像这样:

var i = 0,
    channel = 0,
    channelTotal = 2,
    num = 0,
    vocalsRecording = this.createBuffer(vocalsBuffers, channelTotal),
    diff = this.recorder.startTime - backingInstance.startTime + (offset / 1000),
    before = Math.round((diff % backingInstance.buffer.duration) * this.context.sampleRate),
    after = Math.round((backingInstance.buffer.duration - ((diff + vocalsRecording.duration) % backingInstance.buffer.duration)) * this.context.sampleRate),
    audioBuffer = this.context.createBuffer(channelTotal, before + vocalsBuffers[0].length + after, this.context.sampleRate),
    buffer = null;

// loop through the audio left, right channels
for (channel = 0; channel < channelTotal; channel += 1) {
    buffer = audioBuffer.getChannelData(channel);
    // fill the empty space before the recording
    for (i = 0; i < before; i += 1) {
        buffer[num] = 0;
        num += 1;
    }
    // add the recording data
    for (i = 0; i < vocalsBuffers[channel].length; i += 1) {
        buffer[num] = vocalsBuffers[channel][i];
        num += 1;
    }
    // fill the empty space at the end of the recording
    for (i = 0; i < after; i += 1) {
        buffer[num] = 0;
        num += 1;
    }
}
// now return the new audio which should be the exact same length
return audioBuffer;

您可以在此处查看完整的工作示例:

http://kmturley.github.io/Recorderjs/loop.html

关于javascript - 录制音频、同步循环、偏移延迟和导出部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28867006/

相关文章:

javascript - 右键单击音频被禁用

javascript - 无法暂停 React 音频

ios - 使用 AudioUnit 录制设备音频输出

swift - IOS 8 AVAudioRecorder 更改示例格式

Javax.sound 在 Android 中不可用

javascript - 如何通过从Android应用程序发送一些数据/标志来在网站上显示声音警报

php - mysql ajax更新问题

javascript - 使用 JS 禁用选项

javascript - CSS Flexbox div 自动更改顺序以填充空白

javascript - 将 Audio 对象设置为未定义是否会导致内存泄漏?