E-Guitar synthesizer in 50 lines of Spin 2
Wuerfel_21
Posts: 5,107
CON SAMPLE_RATE = 44_100 _CLKFREQ = SAMPLE_RATE * 256 * 24 AUDIO_LEFT = 24+6 ' this pin and the next one will have audio MAX_PERIOD = 16_000 VAR long string_length long buffer_ptr long exciter_on long retrigger_ctr long note_cnt word string_buffer[MAX_PERIOD] PUB main() | sample, filter,seed, lpf, hpf pinstart(AUDIO_LEFT addpins 1,P_DAC_124R_3V|P_DAC_DITHER_PWM|P_OE,CLKFREQ/SAMPLE_RATE,$7F80) repeat repeat until pinr(AUDIO_LEFT) ' wait for DAC ready wypin(AUDIO_LEFT addpins 1,(sample sar 4)+$7F80) ' set sample if --retrigger_ctr < 0 ' trigger new notes retrigger_ctr := SAMPLE_RATE /4 ' time to next note string_length := (SAMPLE_RATE / getnote()) <# MAX_PERIOD ' tune string buffer_ptr := 0 exciter_on := 1 if exciter_on sample := getrnd() signx 15 ' during first period, generate noise else sample := (string_buffer[buffer_ptr] signx 15) ' afterwards, read from buffer sample := (sample + filter) sar 1 ' incrementally filter sample filter := sample sample := clamp(sample) string_buffer[buffer_ptr] := sample if ++buffer_ptr > string_length ' wrap buffer around exciter_on := buffer_ptr := 0 ' also turn exciter off if 1 ' E-Guitar amplifier simulation - disable for very dry sound sample *= 3 ' gain knob hpf += (sample-=hpf) sar 3 ' pre-amp AC coupling sample := waveshape(sample) lpf += (sample-lpf) sar 2 ' just an LPF to make it less harsh sample := lpf PRI getnote() : r case (note_cnt+/12)+//3 ' simple arpeggio 0: r := lookupz(note_cnt+//3 : 262, 311, 392) ' C4 - Eb4 - G4 1: r := lookupz(note_cnt+//3 : 207, 262, 311) ' A3 - C4 - Eb4 2: r := lookupz(note_cnt+//3 : 233, 294, 349) ' Bb3 - D4 - F4 r >>= 1 ' transpose one octave down note_cnt++ PRI waveshape(x) : r ' wave shaping using arctan transfer function _,r := xypol($2000,x) return clamp(r sar 15) PRI clamp(x) : r ' clamp to valid 16 bit range return x <# $7FFF #> -$7FFF
Something I wrote to pass an hour or so. It's a basic Karplus-Strong synth with a rudimentary tube amp simulation. It'd probably sound better if there were multiple channels and the decay of the previous note was allowed to continue. Or to play chords, of course.
Comments
This looks interesting. Is that complete? Looks like it needs some note data somewhere to play something?
Seems could be warped into MIDI player...
Yea, it just plays a little sequence of notes
Nice!
Once again cordic shines!
I am a great fan of asymmetric overdrive. So perhaps you might want to add some offset before the arctan, which will add 2nd harmonics and therefore enrich the sound in a nice way.
Also a little bit of even a very simple reverb can do much....
Christof