diff --git a/examples/curlywas/tim_ges.cwa b/examples/curlywas/tim_ges.cwa index 7619079..5d276c6 100644 --- a/examples/curlywas/tim_ges.cwa +++ b/examples/curlywas/tim_ges.cwa @@ -1,3 +1,5 @@ +import "env.memory" memory(4); + fn melody(ch: i32, t: i32, T: i32) { let lazy riff_pos = abs(((T&31) - 16) as f32) as i32; let lazy shift = ((1-((T>>5)&3))%2-1) * 2; @@ -7,7 +9,7 @@ fn melody(ch: i32, t: i32, T: i32) { let inline riff_note = 5514 >> (riff_pos % note_count * 4) & 15; let inline melody_note = shift + octave - riff_note; - ch?1 = riff_pos * 10 + 4; + ch?1 = riff_pos * 10 + 63; ch?3 = melody_note + 64; let inline arp_note = shift + ((0x85>>((t/2)%3*4)) & 15) - 1; @@ -36,12 +38,12 @@ export fn upd() { data 80 { i8( - 0, 64, 0, 128, 0, 0x90, - 0, 64, 0, 128, 0, 0x4c, + 0, 80, 0, 128, 0, 0x90, + 0, 80, 0, 128, 0, 0x4c, 5, 128, 0, 128, 0, 0x4c, 5, 128, 0, 128, 0, 0x4c, 0xf8, 0x85, - 0x81, 0x81, 0, 105, 0, 80 + 0x81, 0x81, 0, 110, 0, 80 ) } diff --git a/platform/bin/platform.uw8 b/platform/bin/platform.uw8 index 22136ee..21ac62c 100644 Binary files a/platform/bin/platform.uw8 and b/platform/bin/platform.uw8 differ diff --git a/platform/src/ges.cwa b/platform/src/ges.cwa index 37ec73f..e8476be 100644 --- a/platform/src/ges.cwa +++ b/platform/src/ges.cwa @@ -34,8 +34,9 @@ export fn gesSnd(t: i32) -> f32 { channelState?GesChannelState.Trigger = ctrl; if envState { - envVol = envVol + 8 * pow(1.5625, (15 - channelReg?4 & 15) as f32) as i32; - if envVol >= 65535 { + let lazy attack = channelReg?4 & 15; + envVol = envVol + 12 * pow(1.5625, (15 - attack) as f32) as i32; + if envVol >= 65535 | !attack { envVol = 65535; envState = 0; } @@ -61,25 +62,33 @@ export fn gesSnd(t: i32) -> f32 { let inline pulseWidth = channelReg?1; let phaseShift = (pulseWidth - 128) * 255; + let invPhaseInc = 1 as f32 / phaseInc as f32; i = 0; let wave = ctrl >> 6; if wave < 2 { if wave { + let pulsePhase1 = pulseWidth << 23; + let pulsePhase2 = (511 - pulseWidth) << 23; loop sawLoop { let p = (phase ^ 32768) << 16; - p = ((p ^ (p >> 31)) >> 15) + phaseShift; - p = (p < 0 | p > 65535) * 65535; - i!(GesBufferOffset + 128*4) = (phase ^ p & 65535) - 32768; + let saw = (p >> 16) - polyBlep(phase, invPhaseInc, -32767); + let saw2 = select(p #>= pulsePhase1 & p #< pulsePhase2, -saw, saw); + let saw2 = saw2 - + polyBlep((p - pulsePhase1) >> 16, invPhaseInc, -saw) - + polyBlep((p - pulsePhase2) >> 16, invPhaseInc, saw); + i!(GesBufferOffset + 128*4) = saw2; phase = phase + phaseInc; branch_if (i := i + 4) < 64*4: sawLoop; } } else { + let pulsePhase = 32768 + pulseWidth * 128; loop rectLoop { - let p = (phase & 65535) + phaseShift; - i!(GesBufferOffset + 128*4) = select(p >= 32768, -32768, 32767); + i!(GesBufferOffset + 128*4) = select((phase & 65535) < pulsePhase, -32768, 32767) - + polyBlep(phase, invPhaseInc, -32767) - + polyBlep(phase - pulsePhase, invPhaseInc, 32767); phase = phase + phaseInc; branch_if (i := i + 4) < 64*4: rectLoop; } @@ -163,3 +172,9 @@ export fn gesSnd(t: i32) -> f32 { } (((t & 127) * 4)!GesBufferOffset) as f32 / 32768 as f32 } + +fn polyBlep(transientPhase: i32, invPhaseInc: f32, magnitude: i32) -> i32 { + let lazy t = ((transientPhase << 16) >> 16) as f32 * invPhaseInc; + let lazy x = max(0 as f32, 1 as f32 - abs(t)); + (f32.copysign(x * x, t) * magnitude as f32) as i32 +} \ No newline at end of file diff --git a/src/run-web.html b/src/run-web.html index 8d674ce..11d4b7d 100644 --- a/src/run-web.html +++ b/src/run-web.html @@ -1 +1 @@ -