如何使用网络音频获得音轨样本的正确振幅(不播放)api
How to get right amplitudes (without playing) of the audiotrack samples with web audio api
我用网络音频 api 提供给我的样本体积数据做了一些实验,看起来它们与从其他程序(例如 audasity)获得的数据不同。如果我们将采样数组长度除以采样率(在我的例子中是 leftChannel.length/44100),它显示音频的持续时间更长,约为 40 秒,并且在大胆显示音频中的响亮样本的情况下,我的脚本显示安静(几乎有时沉默)。而且我演奏的曲子被我的剧本报告为大胆而安静,而且声音肯定很大。
所以问题是:我找到音频样本幅度的方法是否正确?我的代码有什么问题?
我已阅读有关为音轨创建波形的帖子 Create a waveform of the full track with Web Audio API
并且有我使用的很好的例子,所以这是我的代码:
(function($) {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new window.AudioContext(); // Create audio container
var audioData;
var checkPoint = 21; //this is point in seconds just for debugging, remove later!!
function decode(audioData) {
try{
context.decodeAudioData(audioData,
function(decoded){
drawSound(decoded);
playAudio(decoded);
},
function(){ // do nothing here
});
} catch(e) {
console.log('decode exception',e.message);
}
}
function drawSound(buffer) {
var leftChannel = buffer.getChannelData(0);
console.log('audio duration: ' + leftChannel.length/44100 + ' sec');
for (var i = 0; i < leftChannel.length; i++) {
var volume = leftChannel[i];
//draw(volume, i);
//this is just for debugging, remove later!!
if (Math.abs(i - checkPoint * 44100) < 100) {
console.log(leftChannel[i]);
}
}
}
function playAudio(buffer) {
console.log('start playing audio');
var audioTrack = context.createBufferSource();
audioTrack.connect(context.destination);
audioTrack.buffer = buffer;
audioTrack.start();
}
$(document).ready(function() {
$('body').append($('<input type="text" id="checkpoint" />'));
$('#checkpoint').change(function() {
checkPoint = $(this).val();
});
$('body').append($('<input type="file" id="audiofile" />'));
$('input[type="file"]').change(function() {
var reader = new FileReader();
reader.onload = function(e) {
audioData = this.result;
decode(audioData);
};
reader.readAsArrayBuffer(this.files[0]);
});
});
})(jQuery);
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
</body>
</html>
我做了更彻底的测量和更多的测试,发现我的脚本没有错误,但是!!网络音频 api 在我的一台计算机上(在 Chrome 和 Firefox 中)给出的结果等于 audasity 的音轨长度和振幅,而在另一台计算机上(再次独立于浏览器)给出错误的结果,所以我得出结论,网络音频 api 使用了一些低级处理器相关的功能,因为我的两台计算机上都有相同的 OS (windows 7),唯一的区别是硬件。
我的 post 中提供的代码按预期工作。
如果您认为这是 Chrome 中的错误,请在 crbug.com/new 中提交错误。并提供一个音轨,产生不同的结果和关于不同机器的细节。
另请注意,在 chrome 中,ffmpeg 用于解码文件。解码文件的长度可能与 audacity 不同。
感谢 Raymond Toy 我设法解决了这个问题。 buffer.getChannelData(0) 返回的结果似乎取决于计算机声卡的采样率(您可以从 context.sampleRate 中找到)。如果你想找到轨道的长度,你应该这样做:
var samples = buffer.getChannelData(0);
var duration = samples/context.sampleRate;
样本从开始的偏移量(以秒为单位)为:
var sample = samples[i];
var offsetInSeconds = i/context.sampleRate
我的错误是我在公式中使用了 mp3 音轨的采样率,这导致在具有不同声卡采样率的计算机上出现错误。
正如 Raymond Toy 所注意到的,如果您只需要音频的持续时间,您可以像这样更简单:
var duration = buffer.duration;
我用网络音频 api 提供给我的样本体积数据做了一些实验,看起来它们与从其他程序(例如 audasity)获得的数据不同。如果我们将采样数组长度除以采样率(在我的例子中是 leftChannel.length/44100),它显示音频的持续时间更长,约为 40 秒,并且在大胆显示音频中的响亮样本的情况下,我的脚本显示安静(几乎有时沉默)。而且我演奏的曲子被我的剧本报告为大胆而安静,而且声音肯定很大。
所以问题是:我找到音频样本幅度的方法是否正确?我的代码有什么问题?
我已阅读有关为音轨创建波形的帖子 Create a waveform of the full track with Web Audio API 并且有我使用的很好的例子,所以这是我的代码:
(function($) {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new window.AudioContext(); // Create audio container
var audioData;
var checkPoint = 21; //this is point in seconds just for debugging, remove later!!
function decode(audioData) {
try{
context.decodeAudioData(audioData,
function(decoded){
drawSound(decoded);
playAudio(decoded);
},
function(){ // do nothing here
});
} catch(e) {
console.log('decode exception',e.message);
}
}
function drawSound(buffer) {
var leftChannel = buffer.getChannelData(0);
console.log('audio duration: ' + leftChannel.length/44100 + ' sec');
for (var i = 0; i < leftChannel.length; i++) {
var volume = leftChannel[i];
//draw(volume, i);
//this is just for debugging, remove later!!
if (Math.abs(i - checkPoint * 44100) < 100) {
console.log(leftChannel[i]);
}
}
}
function playAudio(buffer) {
console.log('start playing audio');
var audioTrack = context.createBufferSource();
audioTrack.connect(context.destination);
audioTrack.buffer = buffer;
audioTrack.start();
}
$(document).ready(function() {
$('body').append($('<input type="text" id="checkpoint" />'));
$('#checkpoint').change(function() {
checkPoint = $(this).val();
});
$('body').append($('<input type="file" id="audiofile" />'));
$('input[type="file"]').change(function() {
var reader = new FileReader();
reader.onload = function(e) {
audioData = this.result;
decode(audioData);
};
reader.readAsArrayBuffer(this.files[0]);
});
});
})(jQuery);
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
</body>
</html>
我做了更彻底的测量和更多的测试,发现我的脚本没有错误,但是!!网络音频 api 在我的一台计算机上(在 Chrome 和 Firefox 中)给出的结果等于 audasity 的音轨长度和振幅,而在另一台计算机上(再次独立于浏览器)给出错误的结果,所以我得出结论,网络音频 api 使用了一些低级处理器相关的功能,因为我的两台计算机上都有相同的 OS (windows 7),唯一的区别是硬件。 我的 post 中提供的代码按预期工作。
如果您认为这是 Chrome 中的错误,请在 crbug.com/new 中提交错误。并提供一个音轨,产生不同的结果和关于不同机器的细节。
另请注意,在 chrome 中,ffmpeg 用于解码文件。解码文件的长度可能与 audacity 不同。
感谢 Raymond Toy 我设法解决了这个问题。 buffer.getChannelData(0) 返回的结果似乎取决于计算机声卡的采样率(您可以从 context.sampleRate 中找到)。如果你想找到轨道的长度,你应该这样做:
var samples = buffer.getChannelData(0);
var duration = samples/context.sampleRate;
样本从开始的偏移量(以秒为单位)为:
var sample = samples[i];
var offsetInSeconds = i/context.sampleRate
我的错误是我在公式中使用了 mp3 音轨的采样率,这导致在具有不同声卡采样率的计算机上出现错误。
正如 Raymond Toy 所注意到的,如果您只需要音频的持续时间,您可以像这样更简单:
var duration = buffer.duration;