gpt4 book ai didi

javascript - Web 音频振荡器仅在 Firefox 中点击

转载 作者:数据小太阳 更新时间:2023-10-29 05:29:13 25 4
gpt4 key购买 nike

我正在尝试使用网络音频振荡器创建一个简单的节拍器,这样就不需要外部音频文件了。我通过快速升高和降低振荡器的音量来创建节拍器的声音(因为您不能多次使用 start() 和 stop()),然后以设定的时间间隔重复该功能。它最终听起来像一 block 漂亮的小木 block 。

下面的代码在 Chrome、Safari 和 Opera 中工作/听起来很棒。但在 Firefox 中,当音量增加时会出现令人讨厌的间歇性“咔嗒”声。我试过更改启动/释放时间以消除咔哒声,但它们必须非常非常长才能持续消失。事实上,振荡器听起来就像一个持续的音符。

var audio = new (window.AudioContext || window.webkitAudioContext)();
var tick = audio.createOscillator();
var tickVol = audio.createGain();

tick.type = 'sine';
tick.frequency.value = 1000;
tickVol.gain.value = 0; //setting the volume to 0 before I connect everything
tick.connect(tickVol);
tickVol.connect(audio.destination);
tick.start(0);

var metronome = {
start: function repeat() {
now = audio.currentTime;

//Make sure volume is 0 and that no events are changing it
tickVol.gain.cancelScheduledValues(now);
tickVol.gain.setValueAtTime(0, now);

//Play the osc with a super fast attack and release so it sounds like a click
tickVol.gain.linearRampToValueAtTime(1, now + .001);
tickVol.gain.linearRampToValueAtTime(0, now + .001 + .01);

//Repeat this function every half second
click = setTimeout(repeat, 500);
},
stop: function() {
if(typeof click !== 'undefined') {
clearTimeout(click);
tickVol.gain.value = 0;
}
}
}

$("#start").click(function(){
metronome.start();
});

$("#stop").click(function(){
metronome.stop();
});

Codepen

有没有办法让 FF 听起来像其他 3 种浏览器?

最佳答案

我在最新的 Opera 中遇到了完全相同的问题,发现问题出在各个声音的“十进制时间长度”上。

我写了一个莫尔斯电码翻译器,和你的一样,它只是通过 createOscillator 创建的一系列简单的短声音/蜂鸣声。

使用莫尔斯电码,您可以根据 codex 或 paris 等 5 个字母长的单词计算速度(每分钟单词数)。

为了让每分钟 20 或 30 巴黎准确地在分钟内完成,我必须使用声音时间长度,例如 0.61。在 Opera 中,这会导致“声音点击结束”。将其更改为 0.6 后,所有浏览器中的点击都消失了 - 除了 Firefox。

我已经在声音之间尝试了 freq = 0 和 gain = 0,但在 FF 中仍然在最后听到咔哒声,而且我对网络音频的了解还不够多,无法尝试其他任何方法。

另一方面,我注意到您正在使用循环和超时来到达下一个滴答声。您是否尝试过“Oscillator onended function”?我将它与一个简单的计数器增量和可变长度的空白声音/音符一起使用。想看的话就到我JS的最后吧。

**更新 - 我一直在摆弄 setValueAtTime() 和 linearRampToValueAtTime() 并且似乎已经解决了点击问题。滚动到脚本底部以查看示例。 **

(function(){

/* Morse Code Generator & Translator - Kurt Grigg 2003 (Updated for sound and CSS3) */

var d = document;
d.write('<div class="Mcontainer">'
+'<div class="Mtitle">Morse Code Generator Translator</div>'
+'<textarea id="txt_in" class="Mtxtarea"></textarea>'
+'<div class="Mtxtareatitle">Input</div>'
+'<textarea id="txt_out" class="Mtxtarea" style="top: 131px;"></textarea>'
+'<div class="Mtxtareatitle" style="top: 172px;">Output</div>'
+'<div class="Mbuttonwrap">'
+'<input type="button" class="Mbuttons" id="how" value="!">'
+'<input type="button" class="Mbuttons" id="tra" value="translate">'
+'<input type="button" class="Mbuttons" id="ply" value="play">'
+'<input type="button" class="Mbuttons" id="pau" value="pause">'
+'<input type="button" class="Mbuttons" id="res" value="reset"></div>'
+'<select id="select" class="Mselect">'
+'<option value=0.07 selected="selected">15 wpm</option>'
+'<option value=0.05>20 wpm</option>'
+'<option value=0.03>30 wpm</option>'
+'</select>'
+'<div class="sliderWrap">volume <input id="volume" type="range" min="0" max="1" step="0.01" value="0.05"/></div>'
+'<div class="Mchckboxwrap">'
+'<span style="text-align: right;">separator <input type="checkbox" id="slash" class="Mchckbox"></span>'
+'</div>'
+'<div id="about" class="Minfo">'
+'<b>Input morse</b><br>'
+'<ul><li>Enter morse into input box using full stop (period) and minus sign (hyphen)</li>'
+'<li>Morse letters must be separated by 1 space</li>'
+'<li>Morse words must be separated by 3 or more spaces</li>'
+'<li>You can use / to separate morse words. There must be at least 1 space before and after each separator used</li>'
+'</ul>'
+'<b>Input text</b><br>'
+'<ul class="Mul"><li>Enter text into input box</li>'
+'<li>Characters that cannot be translated will be ignored</li>'
+'<li>If morse and text is entered, the converter will assume morse mode</li></ul>'
+'<input type="button" value="close" id="clo" class="Mbuttons">'
+'</div><div id="mdl" class="modal"><div id="bdy"><div id="modalMsg">A MSG</div><input type="button" value="close" id="cls" class="Mbuttons"></div></div></div>');

var ftmp = d.getElementById('mdl');
var del;

d.getElementById('tra').addEventListener("click", function(){convertToAndFromMorse(txtIn.value);},false);
d.getElementById('ply').addEventListener("click", function(){CancelIfPlaying();},false);
d.getElementById('pau').addEventListener("click", function(){stp();},false);
d.getElementById('res').addEventListener("click", function(){Rst();txtIn.value = '';txtOt.value = '';},false);


d.getElementById('how').addEventListener("click", function(){msgSelect();},false);
d.getElementById('clo').addEventListener("click", function(){fadeOut();},false);

d.getElementById('cls').addEventListener("click", function(){fadeOut();},false);
d.getElementById('bdy').addEventListener("click", function(){errorSelect();},false);

var wpm = d.getElementById('select');
wpm.addEventListener("click", function(){wpMin()},false);

var inc = 0;
var playing = false;
var txtIn = d.getElementById('txt_in');
var txtOt = d.getElementById('txt_out');
var paused = false;
var allowed = ['-','.',' '];
var aud;
var tmp = (window.AudioContext || window.webkitAudioContext)?true:false;
if (tmp) {
aud = new (window.AudioContext || window.webkitAudioContext)();
}
var incr = 0;
var speed = parseFloat(wpm.options[wpm.selectedIndex].value);
var char = [];
var alphabet = [["A",".-"],["B","-..."],["C","-.-."],["D","-.."],["E","."],["F","..-."],["G","--."],["H","...."],["I",".."],["J",".---"],
["K","-.-"],["L",".-.."],["M","--"],["N","-."],["O","---"],["P",".--."],["Q","--.-"],["R",".-."],["S","..."],["T","-"],["U","..-"],
["V","...-"],["W",".--"],["X","-..-"],["Y","-.--"],["Z","--.."],["1",".----"],["2","..---"],["3","...--"],["4","....-"],["5","....."],
["6","-...."],["7","--..."],["8","---.."],["9","----."],["0","-----"],[".",".-.-.-"],[",","--..--"],["?","..--.."],["'",".----."],["!","-.-.--"],
["/","-..-."],[":","---..."],[";","-.-.-."],["=","-...-"],["-","-....-"],["_","..--.-"],["\"",".-..-."],["@",".--.-."],["(","-.--.-"],[" ",""]];

function errorSelect() {
txtIn.focus();
}

function modalSwap(msg) {
d.getElementById('modalMsg').innerHTML = msg;
}

function msgSelect() {
ftmp = d.getElementById('about');
fadeIn();
}

function fadeIn() {
ftmp.removeEventListener("transitionend", freset);
ftmp.style.display = "block";
del = setTimeout(doFadeIn,100);
}

function doFadeIn() {
clearTimeout(del);
ftmp.style.transition = "opacity 0.5s linear";
ftmp.style.opacity = "1";
}

function fadeOut() {
ftmp.style.transition = "opacity 0.8s linear";
ftmp.style.opacity = "0";
ftmp.addEventListener("transitionend",freset , false);
}

function freset() {
ftmp.style.display = "none";
ftmp.style.transition = "";
ftmp = d.getElementById('mdl');
}

function stp() {
paused = true;
}

function wpMin() {
speed = parseFloat(wpm.options[wpm.selectedIndex].value);
}

function Rst(){
char = [];
inc = 0;
playing = false;
paused = false;
}

function CancelIfPlaying(){
if (window.AudioContext || window.webkitAudioContext) {paused = false;
if (!playing) {
IsReadyToHear();
}
else {
return false;
}
}
else {
modalSwap("<p>Your browser doesn't support Web Audio API</p>");
fadeIn();
return false;
}
}

function IsReadyToHear(x){
if (txtIn.value == "" || /^\s+$/.test(txtIn.value)) {
modalSwap('<p>Nothing to play, enter morse or text first</p>');
fadeIn();
txtIn.value = '';
return false;
}
else if (char.length < 1 && (x != "" || !/^\s+$/.test(txtIn.value)) && txtIn.value.length > 0) {
modalSwap('<p>Click Translate button first . . .</p>');
fadeIn();
return false;
}
else{
playMorse();
}
}

function convertToAndFromMorse(x){
var swap = [];
var outPut = "";
x = x.toUpperCase();

/* Is input empty or all whitespace? */
if (x == '' || /^\s+$/.test(x)) {
modalSwap("<p>Nothing to translate, enter morse or text</p>");
fadeIn();
txtIn.value = '';
return false;
}

/* Remove front & end whitespace */
x = x.replace(/\s+$|^\s*/gi, '');
txtIn.value = x;
txtOt.value = "";

var isMorse = (/(\.|\-)\.|(\.|\-)\-/i.test(x));// Good enough.

if (!isMorse){
for (var i = 0; i < alphabet.length; i++){
swap[i] = [];
for (var j = 0; j < 2; j++){
swap[i][j] = alphabet[i][j].replace(/\-/gi, '\\-');
}
}
}

var swtch1 = (isMorse) ? allowed : swap;
var tst = new RegExp( '[^' + swtch1.join('') + ']', 'g' );
var swtch2 = (isMorse)?' ':'';
x = x.replace( tst, swtch2); //remove unwanted chars.
x = x.split(swtch2);

if (isMorse) {
var tidy = [];
for (var i = 0; i < x.length; i++){
if ((x[i] != '') || x[i+1] == '' && x[i+2] != '') {
tidy.push(x[i]);
}
}
}

var swtch3 = (isMorse) ? tidy : x;

for (var j = 0; j < swtch3.length; j++) {
for (var i = 0; i < alphabet.length; i++){
if (isMorse) {
if (tidy[j] == alphabet[i][1]) {
outPut += alphabet[i][0];
}
}
else {
if (x[j] == alphabet[i][0]) {
outPut += alphabet[i][1] + ((j < x.length-1)?" ":"");
}
}
}
}

if (!isMorse) {
var wordDivide = (d.getElementById('slash').checked)?" / ":" ";
outPut = outPut.replace(/\s{3,}/gi, wordDivide);
}

if (outPut.length < 1) {
alert('Enter valid text or morse...');
txtIn.value = '';
}
else {
txtOt.value = outPut;
}

var justMorse = (!isMorse) ? outPut : tidy;

FormatForSound(justMorse);
}

function FormatForSound(s){
var n = [];
var b = '';
if (typeof s == 'object') {
for (var i = 0; i < s.length; ++i) {
var f = (i == s.length-1)?'':' ';
var t = b += (s[i] + f);
}
}
var c = (typeof s == 'object')? t : s;
c = c.replace(/\//gi, '');
c = c.replace(/\s{1,3}/gi, '4');
c = c.replace(/\./gi, '03');
c = c.replace(/\-/gi, '13');
c = c.split('');
for (var i = 0; i < c.length; i++) {
n.push(c[i]);
}
char = n;
}

function vlm() {
return document.getElementById('volume').value;
}

function playMorse() {

if (paused){
playing = false;
return false;
}

playing = true;
if (incr >= char.length) {
incr = 0;
playing = false;
paused = false;
return false;
}

var c = char[incr];
var freq = 550;
var volume = (c < 2) ? vlm() : 0 ;
var flen = (c == 0 || c == 3) ? speed : speed * 3;

var osc = aud.createOscillator();
osc.type = 'sine';
osc.frequency.value = freq;

var oscGain = aud.createGain();
oscGain.gain.value = volume;
osc.connect(oscGain);
oscGain.connect(aud.destination);

var now = aud.currentTime;

osc.start(now);

/*
Sharp volume fade to stop harsh clicks if wave is stopped
at a point other than the (natural zero crossing point)
*/
oscGain.gain.setValueAtTime(volume, now + (flen*0.8));
oscGain.gain.linearRampToValueAtTime(0.0, now + (flen*0.9999));


osc.stop(now + flen);

osc.onended = function() {
incr++;
playMorse();
}
}
})();
body {
text-align: center;
}





.Mcontainer {
display: inline-block;
position: relative;
width: 382px;
height: 302px;
border: 1px solid #000;
border-radius: 6px;
text-align: center;
font: bold 11px sans-serif;
background-color: rgb(203,243,65);
box-shadow: 0px 4px 2px rgba(0,0,0,0.3);
}
.Mtitle {
-webkit-user-select: none;
-moz-user-select: none;
display: inline-block;
position: absolute;
width: 380px;
height: 20px;
margin: auto;
left: 0; right: 0;
font-size: 16px;
line-height: 20px;
color: #666;
}
.Mtxtareatitle {
-webkit-user-select: none;
-moz-user-select: none;
display: block;
position: absolute;
top: 60px;
left: -36px;
height: 22px;
width: 106px;
font-size: 18px;
line-height: 22px;
text-align: center;
color: #555;
transform: rotate(-90deg);
}
.Mtxtarea {
display: block;
position: absolute;
top: 18px;
margin: auto;
left: 0; right: 0;
height: 98px;
width: 344px;
border: 0.5px solid #000;
border-radius: 6px;
padding-top: 6px;
padding-left: 24px;
resize: none;
background-color: #fffff0;
font: bold 10px courier;
color: #555;
text-transform: uppercase;
overflow: auto;
outline: 0; box-shadow: inset 0px 2px 5px rgba(0,0,0,0.5);
}
.Minfo {
display: none;
position: absolute;
top: -6px; left:-6px;
padding: 6px;
height: auto;
width: 370px;
text-align: left;
border: 0.5px solid #000;
border-radius: 6px;
box-shadow: 0px 4px 2px rgba(0,0,0,0.3);
background-color: rgb(203,243,65);
font: 11px sans-serif;
color: #555;
opacity: 0;
}
.Mbuttonwrap {
display: block;
position: absolute;
top: 245px;
margin: auto;
left: 0; right: 0;
height: 26px;
width: 100%;
}
.Mbuttons {
display: inline-block;
width: 69px;
height: 22px;
border: none;
margin: 0px 3.1px 0px 3.1px;
background-color: transparent;
font: bold 11px sans-serif;
color: #555;
border-radius: 20px;
cursor: pointer;
box-shadow: 0px 2px 2px rgba(0,0,0,0.5);
outline: 0;
}
.Mbuttons:hover {
background-color: rgb(213,253,75);
}
.Mbuttons:active {
position: relative;
top: 1px;
box-shadow: 0px 1px 2px rgba(0,0,0,0.8);
}
.Mchckboxwrap {
display: block;
position: absolute;
top: 274px;
left: 289px;
width: 87px;
height: 21px;
line-height: 22px;
border: 0.5px solid #000;
color: #555;
background: #fff;
-webkit-user-select: none;
-moz-user-select: none;
}
.Mselect {
display: block;
position: absolute;
top: 274px;
left: 6px;
width: 88px;
height: 22px;
border: 0.5px solid #000;
padding-left: 5%;
background: #fff;
font: bold 11px sans-serif;
color: #555;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
outline: 0;
}
::selection {
color: #fff;
background: #555;
}
.Mchckbox {
margin-top: 1px;
vertical-align: middle;
cursor: pointer;
outline: 0;
}
.modal {
display: none;
position: absolute;
margin: auto;
top: 0;right: 0;bottom: 0;left: 0;
background: rgba(0,0,0,0.5);
-webkit-user-select: none;
-moz-user-select: none;
opacity: 0;
text-align: center;
}
.modal > div {
display: inline-block;
position: relative;
width: 250px;
height: 70px;
margin: 10% auto;
padding: 10px;
border: 0.5px solid #000;
border-radius:6px;
background-color: rgb(203,243,65);
font: bold 11px sans-serif;
color: #555;
box-shadow: 4px 4px 2px rgba(0,0,0,0.3);
text-align: center;
}
.sliderWrap {
display: block;
position: absolute;
top: 274px;
margin:auto;padding: 0;
left: 0; right: 0;
width: 184px;
height: 21px;
border: 0.5px solid #000;
background: #fff;
font: bold 11px sans-serif;
color: #555;
line-height: 21px;
text-align: center;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
outline: 0;
}
input[type=range] {
-webkit-appearance: none;
width: 50%;
margin: 0;padding: 0;
vertical-align: middle;
}
input[type=range]:focus {
outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
width: 100%;
height: 4px;
cursor: pointer;
background: #666;
}
input[type=range]::-webkit-slider-thumb {
box-shadow: 1px 1px 0.5px rgba(0, 0, 0, 0.5);
border: none;
height: 10px;
width: 20px;
border-radius: 5px;
background: #ffffff;
cursor: pointer;
-webkit-appearance: none;
margin-top: -3px;
}
input[type=range]:focus::-webkit-slider-runnable-track {
background: #666;
}
input[type=range]::-moz-range-track {
width: 100%;
height: 4px;
cursor: pointer;
background: #666;
}
input[type=range]::-moz-range-thumb {
box-shadow: 1px 1px 0.5px rgba(0, 0, 0, 0.5);
height: 10px;
width: 20px;
border: none;
border-radius: 5px;
background: #ffffff;
cursor: pointer;
}
input[type=range]::-ms-thumb {
height: 10px;
width: 20px;
border: none;
border-radius: 5px;
background: #ffffff;
box-shadow: 1px 1px 0.5px rgba(0, 0, 0, 0.5);
cursor: pointer;
}
input[type=range]::-ms-track {
width: 100%;
height: 4px;
cursor: pointer;
background: transparent;
border: 5px solid transparent;
color: transparent;
}
input[type=range]::-ms-fill-lower {
background: #666;
}
input[type=range]::-ms-fill-upper {
background: #666;
}
::-ms-tooltip {
display: none;
}
select::-ms-expand {
display: none;
}

关于javascript - Web 音频振荡器仅在 Firefox 中点击,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35000423/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com