Skip to content

Instantly share code, notes, and snippets.

@Enkerli
Created April 23, 2017 06:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Enkerli/52a0d567924ab5f18cab1e57b594c074 to your computer and use it in GitHub Desktop.
Save Enkerli/52a0d567924ab5f18cab1e57b594c074 to your computer and use it in GitHub Desktop.
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