added pulse, fixed phase for basic waveforms, more versatile frontend
This commit is contained in:
parent
c9487762b2
commit
f8206281de
6 changed files with 73 additions and 36 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -4,6 +4,7 @@
|
||||||
# https://www.atlassian.com/git/tutorials/saving-changes/gitignore
|
# https://www.atlassian.com/git/tutorials/saving-changes/gitignore
|
||||||
|
|
||||||
sonnum.prj
|
sonnum.prj
|
||||||
|
sonnum
|
||||||
|
|
||||||
# Node artifact files
|
# Node artifact files
|
||||||
node_modules/
|
node_modules/
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ OPCODES = {
|
||||||
'slidephase': 17,
|
'slidephase': 17,
|
||||||
'slideskew': 18,
|
'slideskew': 18,
|
||||||
'slidepos': 19,
|
'slidepos': 19,
|
||||||
|
'pulse': 20,
|
||||||
}
|
}
|
||||||
|
|
||||||
class Activity:
|
class Activity:
|
||||||
|
|
|
||||||
|
|
@ -65,3 +65,6 @@ class SoundNode:
|
||||||
|
|
||||||
def slidepos(self, start_tick, end_tick, sx, sy, sz, ex, ey, ez):
|
def slidepos(self, start_tick, end_tick, sx, sy, sz, ex, ey, ez):
|
||||||
self.act('slidepos', start_tick, end_tick, self, None, [sx, sy, sz, ex, ey, ez])
|
self.act('slidepos', start_tick, end_tick, self, None, [sx, sy, sz, ex, ey, ez])
|
||||||
|
|
||||||
|
def pulse(self, start_tick, end_tick):
|
||||||
|
self.act('pulse', start_tick, end_tick, self, None, [])
|
||||||
24
sineex.py
24
sineex.py
|
|
@ -1,4 +1,4 @@
|
||||||
ln = s.sec(6)
|
ln = s.sec(2)
|
||||||
|
|
||||||
s.endtick(ln)
|
s.endtick(ln)
|
||||||
|
|
||||||
|
|
@ -9,12 +9,18 @@ left.setpos(0, -0.3, 0, 0)
|
||||||
right.setpos(0, 0.3, 0, 0)
|
right.setpos(0, 0.3, 0, 0)
|
||||||
|
|
||||||
tr1 = s.node()
|
tr1 = s.node()
|
||||||
tr1.setbasefreq(0, s.note("E4"))
|
tr2 = s.node()
|
||||||
tr1.slidebasefreq(s.sec(2), s.sec(4), s.note("E4"), s.note("C4"))
|
|
||||||
tr1.setbasefreq(s.sec(4), s.note("C4"))
|
|
||||||
tr1.sine(0, ln)
|
|
||||||
tr1.setgain(0, 0.3)
|
|
||||||
|
|
||||||
tr1.setpos(0, 100, 0, 0)
|
tr1.setbasefreq(0, s.note("E4"))
|
||||||
s.wire(tr1, [left])
|
tr1.setgain(0, 0.45)
|
||||||
s.wire(tr1, [right])
|
tr1.setskew(0, 0.3)
|
||||||
|
tr1.square(0, ln)
|
||||||
|
|
||||||
|
tr2.setbasefreq(0, s.note("E4"))
|
||||||
|
tr2.setgain(0, 0.4)
|
||||||
|
tr2.setphase(0, 0.4)
|
||||||
|
tr1.setskew(0, 0.3)
|
||||||
|
tr2.square(0, ln)
|
||||||
|
|
||||||
|
s.wire(tr1, left)
|
||||||
|
s.wire(tr2, right)
|
||||||
23
snm.py
23
snm.py
|
|
@ -10,8 +10,9 @@ parser = argparse.ArgumentParser(description="Sonnum - the additive synthesizer.
|
||||||
|
|
||||||
parser.add_argument('input_snm_fn', metavar="INPUT", nargs='?', type=str, help="Input *.snm source file", default='')
|
parser.add_argument('input_snm_fn', metavar="INPUT", nargs='?', type=str, help="Input *.snm source file", default='')
|
||||||
|
|
||||||
parser.add_argument('-t', '--transpile', help="View the transpiled python code", action='store_true')
|
|
||||||
parser.add_argument('-b', '--bytecode', help="View the resulting bytecode", action='store_true')
|
parser.add_argument('-b', '--bytecode', help="View the resulting bytecode", action='store_true')
|
||||||
|
parser.add_argument('-r', '--rebuild', help="Rebuild the executable", action='store_true')
|
||||||
|
parser.add_argument('-z', '--zigrun', help="Zig run instead of executable", action='store_true')
|
||||||
|
|
||||||
parser.add_argument('-o', '--output', metavar='FN', help="Synthesize to given wav filenames", type=str)
|
parser.add_argument('-o', '--output', metavar='FN', help="Synthesize to given wav filenames", type=str)
|
||||||
|
|
||||||
|
|
@ -21,17 +22,17 @@ def run():
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
C = SonnumCompiler()
|
C = SonnumCompiler()
|
||||||
|
|
||||||
|
if args.rebuild:
|
||||||
|
os.system(f'zig build-exe zigsonnum/sonnum.zig -lc -OReleaseFast')
|
||||||
|
|
||||||
|
else:
|
||||||
fn = args.input_snm_fn
|
fn = args.input_snm_fn
|
||||||
|
|
||||||
with open(fn, 'r', encoding = 'utf-8') as fl:
|
with open(fn, 'r', encoding = 'utf-8') as fl:
|
||||||
snm = fl.read()
|
snm = fl.read()
|
||||||
|
|
||||||
if args.transpile:
|
if args.bytecode:
|
||||||
py_snm = C.transpile_snm_to_py(snm)
|
|
||||||
print('TRANSPILED CODE')
|
|
||||||
print(py_snm)
|
|
||||||
|
|
||||||
elif args.bytecode:
|
|
||||||
py_snm = C.transpile_snm_to_py(snm)
|
py_snm = C.transpile_snm_to_py(snm)
|
||||||
C.run_transpiled_code(py_snm)
|
C.run_transpiled_code(py_snm)
|
||||||
C.sort_activities()
|
C.sort_activities()
|
||||||
|
|
@ -39,11 +40,15 @@ def run():
|
||||||
|
|
||||||
elif args.output:
|
elif args.output:
|
||||||
C.compile_to_smnb(snm, 'source.snmb')
|
C.compile_to_smnb(snm, 'source.snmb')
|
||||||
os.system(f'./zigsonnum/sonnum > {args.output}')
|
os.system(f'./sonnum > {args.output}')
|
||||||
|
|
||||||
|
elif args.zigrun:
|
||||||
|
C.compile_to_smnb(snm, 'source.snmb')
|
||||||
|
os.system(f'zig run zigsonnum/sonnum.zig -lc > {fn}.wav')
|
||||||
|
|
||||||
else:
|
else:
|
||||||
C.compile_to_smnb(snm, 'source.snmb')
|
C.compile_to_smnb(snm, 'source.snmb')
|
||||||
os.system(f'zig run zigsonnum/sonnum.zig -lc -OReleaseFast > {fn}.wav')
|
os.system(f'./sonnum > {fn}.wav')
|
||||||
#os.system(f'zig run zigsonnum/sonnum.zig -lc > {fn}.wav')
|
#os.system(f'zig run zigsonnum/sonnum.zig -lc > {fn}.wav')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ pub const Activity = struct {
|
||||||
17 => { try self.slidephase(); },
|
17 => { try self.slidephase(); },
|
||||||
18 => { try self.slideskew(); },
|
18 => { try self.slideskew(); },
|
||||||
19 => { self.slidepos(); },
|
19 => { self.slidepos(); },
|
||||||
|
20 => { self.pulse(); },
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -175,9 +176,9 @@ pub const Activity = struct {
|
||||||
const phase = self.soundnode.g("phase");
|
const phase = self.soundnode.g("phase");
|
||||||
|
|
||||||
const period = 44100 / freq;
|
const period = 44100 / freq;
|
||||||
const tp = current_tick / period;
|
const tp = (current_tick - (period * phase)) / period;
|
||||||
|
|
||||||
const amp = r_amp * (@abs(2 * (2 * ( tp - @floor(tp + 0.5) ) )) - 1 - (phase * utility.tau));
|
const amp = r_amp * (@abs(2 * (2 * ( tp - @floor(tp + 0.5) ) )) - 1);
|
||||||
self.soundnode.fab.add_r_amp(amp);
|
self.soundnode.fab.add_r_amp(amp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -209,9 +210,9 @@ pub const Activity = struct {
|
||||||
const phase = self.soundnode.g("phase");
|
const phase = self.soundnode.g("phase");
|
||||||
|
|
||||||
const period = 44100 / freq;
|
const period = 44100 / freq;
|
||||||
const tp = current_tick / period;
|
const tp = (current_tick - (period * phase)) / period;
|
||||||
|
|
||||||
const amp = r_amp * (2 * (tp - @floor(0.5+tp) - (phase * utility.tau)));
|
const amp = r_amp * (2 * (tp - @floor(0.5+tp)));
|
||||||
self.soundnode.fab.add_r_amp(amp);
|
self.soundnode.fab.add_r_amp(amp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -328,4 +329,24 @@ pub const Activity = struct {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn pulse(self: *Activity) void {
|
||||||
|
|
||||||
|
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
|
||||||
|
|
||||||
|
const freq = self.soundnode.g("basefreq");
|
||||||
|
const r_amp = self.soundnode.g("gain");
|
||||||
|
const phase = self.soundnode.g("phase");
|
||||||
|
|
||||||
|
const period = 44100 / freq;
|
||||||
|
const tp = current_tick / period;
|
||||||
|
const tp_detract = (current_tick - (period * phase)) / period;
|
||||||
|
|
||||||
|
const amp =2 * (tp - @floor(0.5+tp));
|
||||||
|
const amp_detract = 2 * (tp_detract - @floor(0.5+tp_detract));
|
||||||
|
|
||||||
|
const final_amp = r_amp * (amp - amp_detract);
|
||||||
|
|
||||||
|
self.soundnode.fab.add_r_amp(final_amp);
|
||||||
|
|
||||||
|
}
|
||||||
};
|
};
|
||||||
Loading…
Add table
Reference in a new issue