2013-12-14 6 views

risposta

9

Quel ragazzo di Chris Wilson, un tale problema. :)

setTargetAtTime è un decremento esponenziale. Il parametro è una costante di tempo:

"timeConstant è il tempo necessario a un sistema lineare invariabile tempo-continuo del primo ordine per raggiungere il valore 1 - 1/e (circa 63,2%) in base a una risposta di ingresso graduale (transizione da Da 0 a 1 valore). "

Quindi, per ogni "secondo tempo", il livello scenderà di un po 'più di 2/3 (presumendo che il guadagno fosse 1, e si sta impostando un obiettivo di 0. Ad un certo punto, il falloff diventa così vicino allo zero, è al di sotto della soglia del rumore, e non devi preoccuparti di questo, non riuscirà mai a "raggiungere il valore target" - lo approssura successivamente, anche se ovviamente a un certo punto la differenza scende sotto la precisione è possibile rappresentare in un galleggiante

io suggerirei di sperimentare un po ', ma ecco un rapido indovinare per iniziare:.

// only setting this up as a var to multiply it later - you can hardcode. 
// initial value is 1 millisecond - experiment with this value if it's not fading 
// quickly enough. 
var timeConstant = 0.001; 

gain = ctx.createGain(); 
// connect up the node in place here 
gain.gain.setTargetAtTime(0, ctx.currentTime, timeConstant); 

// by my quick math, 8x TC should take you to around 2.5% of the original level 
// - more than enough to smooth the envelope off. 
myBufferSourceNode.stop(ctx.currentTime + (8 * timeConstant)); 
+1

timeConstant è molto intuitivo per me, proveniente da transizioni css in cui si controlla la durata di una transizione. Capisco che lo zero non sarà mai raggiunto. Un amico ha suggerito l'approccio pragmatico per moltiplicare la funzione esponenziale con una funzione lineare molto lentamente decrescente - come y = 1- (x/10000) - per ottenere infine un passaggio a zero. – mrflix

+0

Puoi anche usare linearRampToValueAtTime o exponentialRampToValueAtTime, anche quelli che hanno endpoint, come penso che tu stia cercando. – cwilso

+0

Ciao Chris, grazie per il tuo post che mi ha chiarito come funziona setTargetAtTime, ma .. Voglio creare un enveloppe con un decadimento esponenziale da 1 a 0.1 per 500ms e quindi una versione lineare da 0.1 a 0 per 500ms . Per quanto ho capito, non c'è modo di dire all'API di procedere con la rampa lineare dal valore dopo il decadimento a 0. Devo calcolare manualmente il valore previsto, chiamare setValueAtTime (500ms, valore calcolato) e quindi chiamare linearRampToValue ? Mi scuso per essere fuori tema dalla domanda principale. grazie per il feedback. –

1

se mi rendo conto esimo è potrebbe non essere tecnicamente corretto (data la natura esponenziale della costante di tempo), ma ho usato questa formula di "convertire" da secondi a "costante di tempo"

function secondsToTimeConstant(sec){ 
    return (sec * 2)/10; 
} 

... questo era solo tramite processo e errore, ma più o meno ha funzionato per me

+0

@cwilso sto trascurando qualcosa che potrebbe rovinare le cose in modi che non ho previsto?o (come è stata la mia esperienza fino ad ora) funzionerà abbastanza bene? – Nick