Tweak note-change detection
Values have been tuned to ensure samples aren't retriggered during Mario's jump, but are generally retriggered in every other situation where the frequency is changed. Retriggering more often makes the music in games like Pictionary and Rad Gravity sound _way_ better, as well as the sound effects in games with slower music. * do not repeat samples for sustained notes; this never sounds great. * reset after _any_ frequency change if we have been sitting on the same note for longer than a couple of frames. * fix the "reset if the note has jumped by ~2 semitones" logic, which was *wildly* wrong.
This commit is contained in:
parent
9ff9fe2bb8
commit
0f73094113
|
@ -38,14 +38,22 @@ Sample.prototype = {
|
|||
this.index += this.increment / clocksPerPeriod;
|
||||
},
|
||||
reset: function() { this.index = 0; },
|
||||
freqFromTimer: function(timer) {
|
||||
// timer -> frequency
|
||||
// clocksPerPeriodTriangle = 8, clocksPerPeriodPulse = 4
|
||||
// fTriangle = fCPU/(32*(t + 1))
|
||||
// fpulse = fCPU/(16*(t+1)
|
||||
return 1789773 / (4 * this.clocksPerPeriod * (timer + 1));
|
||||
},
|
||||
sample: function(timer, maxTimer, volume) {
|
||||
const timerIncreasing = maxTimer - timer;
|
||||
if (maxTimer !== this.prevMaxTimer) {
|
||||
if (this.prevMaxTimer) {
|
||||
var ratio = this.prevMaxTimer < maxTimer ? maxTimer / this.prevMaxTimer : this.prevMaxTimer / maxTimer;
|
||||
var semitoneInterval = 1.059463;
|
||||
if (ratio >= semitoneInterval * 2 || this.clocksSinceMaxTimerChange > 210000 || this.index >= this.samples.length) {
|
||||
this.index = 0;
|
||||
var ratio = this.freqFromTimer(this.prevMaxTimer) / this.freqFromTimer(maxTimer);
|
||||
if (ratio < 1) { ratio = 1/ratio };
|
||||
var significantNoteChange = 1.1;
|
||||
if ((this.clocksSinceMaxTimerChange > 130000) || ratio >= significantNoteChange) {
|
||||
this.reset();
|
||||
}
|
||||
}
|
||||
this.prevMaxTimer = maxTimer;
|
||||
|
|
Loading…
Reference in a new issue