Javascript 网络音频 API 使用 AudioBufferSource 时 AnalyserNode 不工作
Javascript Web Audio API AnalyserNode Not Working when using AudioBufferSource
我正在尝试构建我正在研究的 VAD 算法的 "offline" 基准版本。
在在线版本中,我使用 createMediaStreamSource 来输入到分析器节点,它工作得很好。
在离线版本中,我想加载和拆分录制的音频文件,所以我使用 xhr 将文件加载为 ArrayBuffer,然后拆分它(这样它将模拟音频流)并将其用作源 createBufferSource.
这是分割audioBuffer的代码:
let audio_dur = audioBuffer.duration;
let segments_num = Math.ceil(audio_dur / segment_dur);
let segment_length = Math.ceil(audioBuffer.length / segments_num);
segmentsArr = new Array(segments_num);
let AudioData = new Float32Array(audioBuffer.length);
AudioData = audioBuffer.getChannelData(0);
for (let i = 0; i <= segments_num-1; i++){
segmentsArr[i] = AudioData.slice(i*segment_length,(i+1)*segment_length-1);
}
然后是连接分析仪的部分:
const analyser = audioCtx.createAnalyser();
analyser.minDecibels = min_decibels;
analyser.fftSize = fft_size;
const T_data = new Float32Array(analyser.fftSize);
const F_data = new Uint8Array(analyser.frequencyBinCount);
let segments_num = segmentsArr.length;
let segment_length = segmentsArr[1].length;
var cur_Buffer = audioCtx.createBuffer(1, segment_length, audioCtx.sampleRate);
for (let segment_ind = 0; segment_ind <= segments_num-1; segment_ind++) {
let cur_segment = segmentsArr[segment_ind];
cur_Buffer.copyToChannel(cur_segment,0,0);
let cur_source = audioCtx.createBufferSource();
cur_source.loop = false;
cur_source.buffer = newBuffer;
cur_source.connect(analyser);
analyser.getByteFrequencyData(F_data); // get current data
analyser.getFloatTimeDomainData(T_data); // get current data
...
代码继续。
问题是:从分析仪返回的时间数据和频率数据总是空的。
之前问:
1. minDecibels 为 -100Db(最低可能)。
2. segmentsArr 不为空,我可以逐段播放,使用与创建 AudioBufferSource 完全相同的方式,然后将其连接到音频目的地。
已回答:感谢@cwilso,问题是我还没有为每个新来源使用 cur_source.start
,
非常感谢。
从这段代码中很难看出这是如何连接的以及代码是如何开始的。
1) 您是在缓冲区源节点上调用 start() ,对吗?
2) 你在启动之后调用 getByteFrequencyData() 等?
3) 你确实听到了通过目的地播放的缓冲区块?
我正在尝试构建我正在研究的 VAD 算法的 "offline" 基准版本。 在在线版本中,我使用 createMediaStreamSource 来输入到分析器节点,它工作得很好。 在离线版本中,我想加载和拆分录制的音频文件,所以我使用 xhr 将文件加载为 ArrayBuffer,然后拆分它(这样它将模拟音频流)并将其用作源 createBufferSource.
这是分割audioBuffer的代码:
let audio_dur = audioBuffer.duration;
let segments_num = Math.ceil(audio_dur / segment_dur);
let segment_length = Math.ceil(audioBuffer.length / segments_num);
segmentsArr = new Array(segments_num);
let AudioData = new Float32Array(audioBuffer.length);
AudioData = audioBuffer.getChannelData(0);
for (let i = 0; i <= segments_num-1; i++){
segmentsArr[i] = AudioData.slice(i*segment_length,(i+1)*segment_length-1);
}
然后是连接分析仪的部分:
const analyser = audioCtx.createAnalyser();
analyser.minDecibels = min_decibels;
analyser.fftSize = fft_size;
const T_data = new Float32Array(analyser.fftSize);
const F_data = new Uint8Array(analyser.frequencyBinCount);
let segments_num = segmentsArr.length;
let segment_length = segmentsArr[1].length;
var cur_Buffer = audioCtx.createBuffer(1, segment_length, audioCtx.sampleRate);
for (let segment_ind = 0; segment_ind <= segments_num-1; segment_ind++) {
let cur_segment = segmentsArr[segment_ind];
cur_Buffer.copyToChannel(cur_segment,0,0);
let cur_source = audioCtx.createBufferSource();
cur_source.loop = false;
cur_source.buffer = newBuffer;
cur_source.connect(analyser);
analyser.getByteFrequencyData(F_data); // get current data
analyser.getFloatTimeDomainData(T_data); // get current data
...
代码继续。
问题是:从分析仪返回的时间数据和频率数据总是空的。
之前问: 1. minDecibels 为 -100Db(最低可能)。 2. segmentsArr 不为空,我可以逐段播放,使用与创建 AudioBufferSource 完全相同的方式,然后将其连接到音频目的地。
已回答:感谢@cwilso,问题是我还没有为每个新来源使用 cur_source.start
,
非常感谢。
从这段代码中很难看出这是如何连接的以及代码是如何开始的。
1) 您是在缓冲区源节点上调用 start() ,对吗? 2) 你在启动之后调用 getByteFrequencyData() 等? 3) 你确实听到了通过目的地播放的缓冲区块?