如何提高有问题手机的麦克风采样率
How to increase the microphone sample rate on problematic phones
我正在开发一个基于麦克风样本显示图表的网络应用程序。我每隔 ~15 毫秒从 getByteTimeDomainData 中获取向量 return 的最高值,并将其放在图表上。
问题是,在某些手机(例如小米手机)中,我得到了假的麦克风样本 - return它使用相同的向量 10 次(~150 毫秒),然后才再次对麦克风进行采样并且 return 是另外 10 次的新向量。
标准手机:
从 30 次调用 getByteTimeDomainData 中收集的最高值:
230,237,237,236,236,220,220,232,232,218,218,214,214,217,217,227,227,222,222,224,224,222,222,216,216,202,202,223,223,205
小米手机:
从 30 次调用 getByteTimeDomainData 中收集的最高值:
132,132,132,132,132,132,132,129,129,129,129,129,129,129,129,129,129,130,130,130,130,130,130,130,130,130,13=131,[3=3],[3=3]
我的问题是- 我如何改进它并在小米中获得更多样本?
var start_amp = function () {
'use strict';
var soundAllowed = function (stream) {
window.persistAudioStream = stream;
var audioContext = new AudioContext();
var audioStream = audioContext.createMediaStreamSource(stream);
var analyser = audioContext.createAnalyser();
audioStream.connect(analyser);
analyser.smoothingTimeConstant = 0; // = 1 doesn't fix the samples problem
analyser.fftSize = 1024;
var frequencyArray = new Uint8Array(analyser.frequencyBinCount);
var doDraw = function () {
requestAnimationFrame(doDraw);
analyser.getByteTimeDomainData(frequencyArray);
var max = 0;
for (var i = 0; i < frequencyArray.length; i++) {
if (max < frequencyArray[i]) {
max = frequencyArray[i];
}
}
boardArray.push(max);
if (boardArray.length >= document.body.clientWidth * 0.7) {
boardArray.shift();
totalSamples += 1;
if (totalSamples == 60) {
totalSamples = 0;
}
}
draw(boardArray);
}
doDraw();
}
var soundNotAllowed = function (error) {
alert('Please check your microphone connectivity and allow this site to access it');
console.log(error);
}
navigator.getUserMedia({ audio: true }, soundAllowed, soundNotAllowed);
}
经过一些研究,我发现创建另一个 AudioContext 和 Analyzer 会给我不同的样本。看起来每个节点都有一些采样率限制。
所以我创建了 3 个 AudioContext 并使用它们的平均值:
var start_amp = function () {
'use strict';
var soundAllowed = function (stream) {
window.persistAudioStream = stream;
// Node 1
var audioContext = new AudioContext();
var audioStream = audioContext.createMediaStreamSource(stream);
var analyser = audioContext.createAnalyser();
audioStream.connect(analyser);
analyser.smoothingTimeConstant = 0; // = 1 doesn't fix the samples problem
analyser.fftSize = 1024;
// Node 2
var audioContext2 = new AudioContext();
var audioStream2 = audioContext2.createMediaStreamSource(stream);
var analyser2 = audioContext2.createAnalyser();
audioStream2.connect(analyser2);
analyser2.smoothingTimeConstant = 0; // = 1 doesn't fix the samples problem
analyser2.fftSize = 1024;
// Node 3
var audioContext3 = new AudioContext();
var audioStream3 = audioContext3.createMediaStreamSource(stream);
var analyser3 = audioContext3.createAnalyser();
audioStream3.connect(analyser3);
analyser3.smoothingTimeConstant = 0; // = 1 doesn't fix the samples problem
analyser3.fftSize = 1024;
var frequencyArray = new Uint8Array(analyser.frequencyBinCount);
var frequencyArray2 = new Uint8Array(analyser2.frequencyBinCount);
var frequencyArray3 = new Uint8Array(analyser3.frequencyBinCount);
var doDraw = function () {
requestAnimationFrame(doDraw);
analyser.getByteTimeDomainData(frequencyArray);
analyser2.getByteTimeDomainData(frequencyArray2);
analyser3.getByteTimeDomainData(frequencyArray3);
var max = 0;
for (var i = 0; i < frequencyArray.length; i++) {
if (max < frequencyArray[i]) {
max = frequencyArray[i];
}
}
var max2 = 0;
for (var i = 0; i < frequencyArray2.length; i++) {
if (max2 < frequencyArray2[i]) {
max2 = frequencyArray2[i];
}
}
var max3 = 0;
for (var i = 0; i < frequencyArray3.length; i++) {
if (max3 < frequencyArray3[i]) {
max3 = frequencyArray3[i];
}
}
boardArray.push((max + max2 + max3) / 3);
if (boardArray.length >= document.body.clientWidth * 0.7) {
boardArray.shift();
totalSamples += 1;
if (totalSamples == 60) {
totalSamples = 0;
}
}
draw(boardArray);
}
doDraw();
}
var soundNotAllowed = function (error) {
alert('Please check your microphone connectivity and allow this site to access it');
console.log(error);
}
navigator.getUserMedia({ audio: true }, soundAllowed, soundNotAllowed);
}
我正在开发一个基于麦克风样本显示图表的网络应用程序。我每隔 ~15 毫秒从 getByteTimeDomainData 中获取向量 return 的最高值,并将其放在图表上。
问题是,在某些手机(例如小米手机)中,我得到了假的麦克风样本 - return它使用相同的向量 10 次(~150 毫秒),然后才再次对麦克风进行采样并且 return 是另外 10 次的新向量。
标准手机:
从 30 次调用 getByteTimeDomainData 中收集的最高值: 230,237,237,236,236,220,220,232,232,218,218,214,214,217,217,227,227,222,222,224,224,222,222,216,216,202,202,223,223,205
小米手机:
从 30 次调用 getByteTimeDomainData 中收集的最高值:
132,132,132,132,132,132,132,129,129,129,129,129,129,129,129,129,129,130,130,130,130,130,130,130,130,130,13=131,[3=3],[3=3]
我的问题是- 我如何改进它并在小米中获得更多样本?
var start_amp = function () {
'use strict';
var soundAllowed = function (stream) {
window.persistAudioStream = stream;
var audioContext = new AudioContext();
var audioStream = audioContext.createMediaStreamSource(stream);
var analyser = audioContext.createAnalyser();
audioStream.connect(analyser);
analyser.smoothingTimeConstant = 0; // = 1 doesn't fix the samples problem
analyser.fftSize = 1024;
var frequencyArray = new Uint8Array(analyser.frequencyBinCount);
var doDraw = function () {
requestAnimationFrame(doDraw);
analyser.getByteTimeDomainData(frequencyArray);
var max = 0;
for (var i = 0; i < frequencyArray.length; i++) {
if (max < frequencyArray[i]) {
max = frequencyArray[i];
}
}
boardArray.push(max);
if (boardArray.length >= document.body.clientWidth * 0.7) {
boardArray.shift();
totalSamples += 1;
if (totalSamples == 60) {
totalSamples = 0;
}
}
draw(boardArray);
}
doDraw();
}
var soundNotAllowed = function (error) {
alert('Please check your microphone connectivity and allow this site to access it');
console.log(error);
}
navigator.getUserMedia({ audio: true }, soundAllowed, soundNotAllowed);
}
经过一些研究,我发现创建另一个 AudioContext 和 Analyzer 会给我不同的样本。看起来每个节点都有一些采样率限制。 所以我创建了 3 个 AudioContext 并使用它们的平均值:
var start_amp = function () {
'use strict';
var soundAllowed = function (stream) {
window.persistAudioStream = stream;
// Node 1
var audioContext = new AudioContext();
var audioStream = audioContext.createMediaStreamSource(stream);
var analyser = audioContext.createAnalyser();
audioStream.connect(analyser);
analyser.smoothingTimeConstant = 0; // = 1 doesn't fix the samples problem
analyser.fftSize = 1024;
// Node 2
var audioContext2 = new AudioContext();
var audioStream2 = audioContext2.createMediaStreamSource(stream);
var analyser2 = audioContext2.createAnalyser();
audioStream2.connect(analyser2);
analyser2.smoothingTimeConstant = 0; // = 1 doesn't fix the samples problem
analyser2.fftSize = 1024;
// Node 3
var audioContext3 = new AudioContext();
var audioStream3 = audioContext3.createMediaStreamSource(stream);
var analyser3 = audioContext3.createAnalyser();
audioStream3.connect(analyser3);
analyser3.smoothingTimeConstant = 0; // = 1 doesn't fix the samples problem
analyser3.fftSize = 1024;
var frequencyArray = new Uint8Array(analyser.frequencyBinCount);
var frequencyArray2 = new Uint8Array(analyser2.frequencyBinCount);
var frequencyArray3 = new Uint8Array(analyser3.frequencyBinCount);
var doDraw = function () {
requestAnimationFrame(doDraw);
analyser.getByteTimeDomainData(frequencyArray);
analyser2.getByteTimeDomainData(frequencyArray2);
analyser3.getByteTimeDomainData(frequencyArray3);
var max = 0;
for (var i = 0; i < frequencyArray.length; i++) {
if (max < frequencyArray[i]) {
max = frequencyArray[i];
}
}
var max2 = 0;
for (var i = 0; i < frequencyArray2.length; i++) {
if (max2 < frequencyArray2[i]) {
max2 = frequencyArray2[i];
}
}
var max3 = 0;
for (var i = 0; i < frequencyArray3.length; i++) {
if (max3 < frequencyArray3[i]) {
max3 = frequencyArray3[i];
}
}
boardArray.push((max + max2 + max3) / 3);
if (boardArray.length >= document.body.clientWidth * 0.7) {
boardArray.shift();
totalSamples += 1;
if (totalSamples == 60) {
totalSamples = 0;
}
}
draw(boardArray);
}
doDraw();
}
var soundNotAllowed = function (error) {
alert('Please check your microphone connectivity and allow this site to access it');
console.log(error);
}
navigator.getUserMedia({ audio: true }, soundAllowed, soundNotAllowed);
}