为什么振荡器的网络音频输出没有按预期工作?
Why the web audio output from oscillator is not working as expected?
代码如下:
我想创建一个音频程序,可以播放从极低频到高频的音频。
但是,此代码会产生不同的输出(即使使用相同的设备):
- 声音是突然发出来的-预期的结果是逐渐发出来。我确定我的听力没有问题,因为我已经让我的朋友听到了;
- 音频在同一频率上听起来不同。
警告:请将音量调到非常低,以防在 运行 此脚本之前受到任何伤害。
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
// create Oscillator node
var oscillator = audioCtx.createOscillator();
var osc_arr = [];
function purgeSound(){
osc_arr.forEach(function(v){
try {
v.stop();
v.disconnect(audioCtx.destination);
} catch (e) {}
})
}
function playSoundAtFreq(fq){
purgeSound();
var osc = audioCtx.createOscillator();
osc_arr.push(osc);
osc.type = 'square';
osc.frequency.setValueAtTime(fq, audioCtx.currentTime); // value in hertz
$('#fff').val(fq);
osc.connect(audioCtx.destination);
osc.start();
}
$('#stop').click(function(){
purgeSound();
_break = true;
})
var _break = false;
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
var pointer = 0;
var go = appendAttemptAsync(10000);
async function appendAttemptAsync(range) {
if(_break) return;
var target = pointer+range;
for (pointer; pointer<range; pointer++) {
playSoundAtFreq(pointer);
console.log(pointer)
//if(pointer % 1 == 0) {
await sleep(100)
//}
}
return 5221;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id='stop'>stop</button>
<input id="fff" type="text" />
警告:请将音量调到非常低,以防在 运行 此脚本之前受到任何伤害。
感谢您提出任何改进我的代码的建议。
如果您希望振荡器像 中的 YouTube 视频那样扫频,您可以这样做:
let osc = new OscillatorNode(audioCtx);
osc.connect(audioCtx.destination);
osc.frequency.setValueAtTime(20, audioCtx.currentTime);
osc.frequency.linearRampToValueAtTime(audioCtx.sampleRate / 2, audioCtx.currentTime + 300);
osc.start();
将300
更改为音调扫过的适当时间。我随意选了5分钟
我不知道为什么您的示例不起作用,但这段代码是使用 WebAudio 清除音调的典型方法。
代码如下:
我想创建一个音频程序,可以播放从极低频到高频的音频。
但是,此代码会产生不同的输出(即使使用相同的设备):
- 声音是突然发出来的-预期的结果是逐渐发出来。我确定我的听力没有问题,因为我已经让我的朋友听到了;
- 音频在同一频率上听起来不同。
警告:请将音量调到非常低,以防在 运行 此脚本之前受到任何伤害。
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
// create Oscillator node
var oscillator = audioCtx.createOscillator();
var osc_arr = [];
function purgeSound(){
osc_arr.forEach(function(v){
try {
v.stop();
v.disconnect(audioCtx.destination);
} catch (e) {}
})
}
function playSoundAtFreq(fq){
purgeSound();
var osc = audioCtx.createOscillator();
osc_arr.push(osc);
osc.type = 'square';
osc.frequency.setValueAtTime(fq, audioCtx.currentTime); // value in hertz
$('#fff').val(fq);
osc.connect(audioCtx.destination);
osc.start();
}
$('#stop').click(function(){
purgeSound();
_break = true;
})
var _break = false;
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
var pointer = 0;
var go = appendAttemptAsync(10000);
async function appendAttemptAsync(range) {
if(_break) return;
var target = pointer+range;
for (pointer; pointer<range; pointer++) {
playSoundAtFreq(pointer);
console.log(pointer)
//if(pointer % 1 == 0) {
await sleep(100)
//}
}
return 5221;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id='stop'>stop</button>
<input id="fff" type="text" />
警告:请将音量调到非常低,以防在 运行 此脚本之前受到任何伤害。
感谢您提出任何改进我的代码的建议。
如果您希望振荡器像
let osc = new OscillatorNode(audioCtx);
osc.connect(audioCtx.destination);
osc.frequency.setValueAtTime(20, audioCtx.currentTime);
osc.frequency.linearRampToValueAtTime(audioCtx.sampleRate / 2, audioCtx.currentTime + 300);
osc.start();
将300
更改为音调扫过的适当时间。我随意选了5分钟
我不知道为什么您的示例不起作用,但这段代码是使用 WebAudio 清除音调的典型方法。