3 Commits

7 changed files with 137 additions and 15 deletions

View File

@@ -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, 128, 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
)
}

Binary file not shown.

View File

@@ -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,31 +62,45 @@ 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 {
i!(GesBufferOffset + 128*4) = (phase & 65535) - 32768;
let p = (phase ^ 32768) << 16;
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;
}
}
} else {
if wave == 2 {
let scale = pulseWidth + 256;
loop triLoop {
let s = phase << 16;
s = s ^ (s >> 31);
s = (s ^ (s >> 31));
s = (s >> 8) * scale;
s = (s ^ (s >> 31));
i!(GesBufferOffset + 128*4) = (s >> 15) - 32768;
phase = phase + phaseInc;
branch_if (i := i + 4) < 64*4: triLoop;
@@ -93,9 +108,10 @@ export fn gesSnd(t: i32) -> f32 {
} else {
loop noiseLoop {
let s = (phase >> 12) & 4095;
let pulse = ((phase >> 8) & 255) >= pulseWidth;
s = s * 0x6746ba73;
s = s ^ (s >> 15);
i!(GesBufferOffset + 128*4) = (s * 0x83567a92) >> 16;
s = s ^ (s >> 15) * pulse;
i!(GesBufferOffset + 128*4) = (s * 0x83567a92 + (phase << 16)) >> 16;
phase = phase + phaseInc;
branch_if (i := i + 4) < 64*4: noiseLoop;
}
@@ -124,8 +140,12 @@ export fn gesSnd(t: i32) -> f32 {
let ctrl = filter?0x6a;
let note = i32.load16_u(filter * 2, 0x6c);
let inline freq = 440 as f32 * pow(2.0, (note - 69*256) as f32 / (12*256) as f32);
let F = min(4096 as f32, 8192 as f32 * sin(freq * (3.1415 / 44100.0))) as i32;
let Q = 7350 - ctrl * (6530/255);
let F = (8192 as f32 * sin(min(0.25, freq / 44100 as f32) * 3.1415)) as i32;
let Q = 8192 - (ctrl >> 4) * (7000/15);
let Qlimit = (8192*4096/F - F/2) * 3 / 4;
if Q > Qlimit {
Q = Qlimit;
}
let low_out = ctrl & 1;
let high_out = (ctrl >> 1) & 1;
let band_out = (ctrl >> 2) & 1;
@@ -152,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
}

View File

@@ -0,0 +1,5 @@
import "env.memory" memory(1);
import "env.sin" fn sin(f32) -> f32;
import "env.pow" fn pow(f32, f32) -> f32;
include "ges.cwa"

File diff suppressed because one or more lines are too long

30
test/ges_test.cwa Normal file
View File

@@ -0,0 +1,30 @@
import "env.memory" memory(4);
import "env.pow" fn pow(f32, f32) -> f32;
import "env.sin" fn sin(f32) -> f32;
import "env.cls" fn cls(i32);
import "env.rectangle" fn rectangle(f32, f32, f32, f32, i32);
include "../platform/src/ges.cwa"
export fn snd(t: i32) -> f32 {
gesSnd(t)
}
export fn upd() {
80?0 = 32!32 / 200 & 2 | 0x41;
80?3 = (32!32 / 400)%7*12/7 + 40;
let pulse = (32!32 * 256 / 2000) & 511;
if pulse >= 256 {
pulse = 511 - pulse;
}
80?1 = pulse;
cls(0);
rectangle(0.0, 100.0, (pulse * 320 / 256) as f32, 16.0, 15);
}
data 80 {
i8(
0x41, 0, 0, 80, 0x70, 0
)
}

59
tests/plot_ges.cwa Normal file
View File

@@ -0,0 +1,59 @@
include "../examples/include/microw8-api.cwa"
export fn upd() {
80?0 = (32!32 >> 11 << 6) | 5;
80?1 = (sin(time() * 6 as f32) * 95 as f32) as i32 + 128;
plotGes();
}
data 80 { i8 (
1, 128, 0, 69, 0, 15,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0xff, 0xff,
0xc1, 0, 0, 110, 0, 0
) }
//import "env.gesSnd" fn gesSnd(i32) -> f32;
include "../platform/src/ges.cwa"
export fn snd(t: i32) -> f32 {
gesSnd(t)
}
global mut samplePos: i32 = 0;
const SoundBuffer = 0x30000;
fn plotGes() {
rectangle(0 as f32, 10 as f32, 320 as f32, 320 as f32, 0);
let count = (time() * 44100 as f32) as i32 * 2 - samplePos;
let i: i32;
loop genLoop {
(i*4)$SoundBuffer = gesSnd(samplePos + i);
branch_if (i := i + 1) < count: genLoop;
}
samplePos = samplePos + count;
let ch: i32;
loop channelLoop {
let offset = 159;
i = 0;
loop searchLoop {
offset = offset + 1;
branch_if (offset * 8 + ch - 8)$SoundBuffer < 0 as f32 | (offset * 8 + ch)$SoundBuffer >= 0 as f32 & offset + 160 < count: searchLoop;
}
offset = ch + (offset - 160) * 8;
i = 0;
loop plotLoop {
setPixel(i, floor((i * 8 + offset)$SoundBuffer * 127 as f32) as i32 + 60 + ch * (120/8), 15);
branch_if (i := i + 1) < 320: plotLoop;
}
branch_if (ch := ch + 8) < 16: channelLoop;
}
}