Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Sonic Pi script to emulate the tonespace MIDI harmonizer from mucoder.
use_real_time # Preventing latency
use_tuning :just, :c # Just Intonation, chords are diatonic in C major
with_fx :compressor, threshold: 0.1 do # Preventing clipping
with_fx :reverb do # Everything on the same reverb
with_fx :lpf, cutoff_slide: 0.02 do |filtre| # Everything on the same breath-controlled filter
baritone = synth :hoover, note: 0, release: 1000, amp: 0 # “Classic early 90’s rave synth”
tenor = synth :chipbass, note: 0, release: 1000, amp: 0 # “A 16 step triangle wave modelled after the 2A03 chip found in voice 3 of the NES games console.”
alto = synth :beep, note: 0, release: 1000, amp: 0 # Sine wave
soprano = synth :chiplead, note: 0, release: 1000, amp: 0 # “A slightly clipped square (pulse) wave with phases of 12.5%, 25% or 50% modelled after the 2A03 chip found in voices 1 and 2 of the NES games console.”
live_loop :notes do
note_on, velocity = sync "/midi/USB_Midi_Cable/4/1/note_on" # Incoming notes from Yamaha WX-11 wind controller
if velocity > 0 # Only use actual note-ons
tick # Used to rotate chords
deg=note_on % 12 # Which degree in the C major scale?
case deg
when 1, 3, 6, 8, 10 # No chord outside of the C major scale
shord=[0, 0, 0]
when 0 # When the incoming note is a C, any octave, build a chord using the tonespace sequence
shord=(ring
[4, 7, 11], # CM7 [CEGB]
[5, 7, 11], # CM7sus4 [CFGB]
[4, 7, 9], # CM6 [CEGA]
[5, 7, 9], # CM6sus4 [CFGA]
[2, 4, 7], # CMadd9 [CDEG]
[4, 7, 0], # CM [CEG]
[2, 7, 0], # Csus2 [CDG]
[5, 7, 0], # Csus4 [CFG]
[4, 0, 0], # CM3 [CE]
[7, 0, 0], # CP5 [CG]
[5, 0, 0], # CP4 [CF]
[2, 0, 0], # CM2 [CD]
[9, 0, 0], # CM6 [CA]
[11, 0, 0], # C_M7 [CB]
[0, 0, 0], # C
).look
when 2 # When the incoming note is a D…
shord=(ring
[3, 7, 10], # Dm7 [DFAC]
[5, 7, 10], # Dm7sus4 [DGAC]
[5, 7, 9], # DM6sus4 [DGAB]
[3, 7, 9], # Dm6 [DFAB]
[2, 3, 7], # Dmadd9 [DEFA]
[3, 7, 0], # Dm [DFA]
[2, 7, 0], # Dsus2 [DEA]
[5, 7, 0], # Dsus4 [DGA]
[3, 5, 0], # Dadd4no5 [DFG]
[3, 0, 0], # Dm3 [DF]
[7, 0, 0], # DP5 [DA]
[5, 0, 0], # DP4 [DG]
[2, 0, 0], # DM2 [DE]
[9, 0, 0], # DM6 [DB]
[10, 0, 0], # D_m7 [DC]
[0, 0, 0], # D
).look
when 4 # Incoming E
shord=(ring
[3, 7, 10], # Em7 [EGBD]
[3, 8, 10], # Em7#5 [EGCD]
[5, 7, 10], # E7sus4 [EABD]
[3, 7, 0], # Em [EGB]
[5, 7, 0], # Esus4 [EAB]
[5, 8, 0], # Esus4#5 [EAC]
[3, 5, 0], # Eadd4no5 [EGA]
[3, 0, 0], # Em3 [EG]
[7, 0, 0], # EP5 [EB]
[5, 0, 0], # EP4 [EA]
[8, 0, 0], # Em6 [EC]
[10, 0, 0], # Em7 [ED]
[1, 0, 0], # Em2 [EF]
[0, 0, 0], # E
).look
when 5 # Incoming F…
shord=(ring
[4, 7, 11], # FM7 [FACE]
[4, 7, 9], # FM6 [FACD]
[2, 4, 7], # FMadd9 [FGAC]
[4, 7, 0], # FM [FAC]
[4, 6, 0], # Fb5 [FAB]
[2, 7, 0], # Fsus2 [FGC]
[4, 0, 0], # FM3 [FA]
[7, 0, 0], # FP5 [FC]
[2, 0, 0], # FM2 [FG]
[6, 0, 0], # Fd5 [FB]
[9, 0, 0], # FM6 [FD]
[11, 0, 0], # FM7 [FE]
[0, 0, 0], # F
).look
when 7 # Incoming G…
shord=(ring
[4, 7, 10], # G7 [GBDF]
[4, 9, 10], # G7add6 [GBEF]
[5, 7, 10], # G7sus4 [GCDF]
[4, 7, 9], # GM6 [GBDE]
[5, 7, 9], # GM6sus4 [GCDE]
[2, 4, 7], # GMadd9 [GABD]
[4, 7, 0], # GM [GBD]
[2, 7, 0], # Gsus2 [GAD]
[5, 7, 0], # Gsus4 [GCD]
[4, 0, 0], # GM3 [GB]
[7, 0, 0], # GP5 [GD]
[5, 0, 0], # GP4 [GC]
[2, 0, 0], # GM2 [GA]
[9, 0, 0], # GM6 [GE]
[10, 0, 0], # Gm7 [GF]
[0, 0, 0], # G
).look
when 9 # Incoming A…
shord=(ring
[3, 7, 10], # Am7 [ACEG]
[3, 8, 10], # Am7#5 [ACFG]
[5, 7, 10], # A7sus4 [ADEG]
[2, 3, 7], # Amadd9 [ABCE]
[3, 7, 0], # Am [ACE]
[2, 7, 0], # Asus2 [ABE]
[5, 7, 0], # Asus4 [ADE]
[5, 8, 0], # Asus4#5 [ADF]
[3, 5, 0], # Aadd4no5 [ACD]
[3, 0, 0], # Am3 [AC]
[7, 0, 0], # AP5 [AE]
[5, 0, 0], # AP4 [AD]
[2, 0, 0], # AM2 [AB]
[8, 0, 0], # Am6 [AF]
[10, 0, 0], # Am7 [AG]
[0, 0, 0], # A
).look
when 11 # Incoming B…
shord=(ring
[3, 6, 10], # Bm7b5 [BDFA]
[3, 8, 10], # Bm7#5 [BDGA]
[3, 6, 0], # Bdim [BDF]
[5, 7, 0], # Bsus4#5 [BEG]
[3, 5, 0], # Badd4no5 [BDE]
[3, 0, 0], # Bm3 [BD]
[5, 0, 0], # BP4 [BE]
[6, 0, 0], # Bd5 [BF]
[8, 0, 0], # Bm6 [BG]
[10, 0, 0], # Bm7 [BA]
[1, 0, 0], # Bm2 [BC]
[0, 0, 0], # B
).look
end
control baritone, note: note_on, amp: velocity / 127.0 # Incoming note, “hoover” sound
control tenor, note: note_on + shord[0], amp: velocity / 150.0 # Typically a third or fourth above the incoming note, “chipbass” sound
control alto, note: note_on + shord[1], amp: velocity / 150.0 # Typically a fifth above the incoming note, sinewave
control soprano, note: note_on + shord[2], amp: velocity / 127.0 # Typically a seventh above the incoming note, “chiplead” sound
end
end
live_loop :windy do # Use the incoming breath control, MIDI CC#2, to modulate the low-pass filter
control_change, breath = sync "/midi/USB_Midi_Cable/4/1/control_change"
if control_change==2
control filtre, cutoff: breath
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.