Created
December 25, 2023 20:57
-
-
Save ejfox/075557d7bb167f6ccd70a653024a151e to your computer and use it in GitHub Desktop.
Sonic Pi + Midi Christmas Medley
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Defining all melodies with their durations in a dictionary-like structure | |
melodies = { | |
silent_night: { | |
notes: [:G, :A, :G, :E, :G, :A, :G, :E, :C, :G, :C, :G, :A, :A, :G], | |
durations: [0.5, 0.5, 1, 1, 0.5, 0.5, 1, 1, 0.5, 0.5, 1, 1, 0.5, 0.5, 1] | |
}, | |
jingle_bells: { | |
notes: [:E, :E, :E, :E, :E, :E, :E, :G, :C, :D, :E, :F, :F, :F, :F, :F, :E, :E, :E, :E, :E, :D, :D, :E, :D, :G], | |
durations: [0.5, 0.5, 1, 0.5, 0.5, 1, 0.5, 0.5, 0.5, 1, 1, 0.5, 0.5, 0.5, 0.5, 1, 0.5, 0.5, 0.5, 0.5, 1, 0.5, 0.5, 0.5, 0.5, 1] | |
}, | |
deck_the_halls: { | |
notes: [:E, :G, :F, :E, :D, :C, :D, :E, :D, :G, :G, :A, :G, :F, :E, :D], | |
durations: [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5] | |
}, | |
o_christmas_tree: { | |
notes: [:C, :C, :D, :C, :F, :E, :C, :C, :D, :C, :G, :F], | |
durations: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] | |
}, | |
we_wish_you_a_merry_christmas: { | |
notes: [:G, :E, :D, :C, :D, :G, :G, :E, :D, :C, :E, :C], | |
durations: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] | |
}, | |
the_first_noel: { | |
notes: [:G, :A, :B, :G, :G, :A, :B, :G, :E, :E, :F, :G], | |
durations: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] | |
}, | |
giant_steps_segment: { | |
notes: [:B, :D, :F, :B, :G, :B, :D, :F, :E, :G, :B, :D], | |
durations: [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5] | |
} | |
} | |
# Function to play a specific melody with MIDI, swapping notes from another melody | |
define :play_melody_with_variation_midi do |channel, primary_melody_name| | |
primary_melody = melodies[primary_melody_name][:notes] | |
primary_durations = melodies[primary_melody_name][:durations] | |
total_duration = primary_durations.sum * [1, 0.5, 1.5].choose # Slowing down the melody | |
primary_melody.each_with_index do |note, i| | |
if one_in(6 ) | |
alternate_melody_name = melodies.keys.reject { |m| m == primary_melody_name }.choose | |
note = melodies[alternate_melody_name][:notes].choose | |
end | |
midi note, channel: channel, sustain: primary_durations[i] | |
sleep total_duration / primary_melody.length | |
end | |
end | |
# Function to play a more harmonious jazzy chord based on the currently active melody | |
define :play_jazzy_chord_midi do |channel, current_melody| | |
if one_in(4) # Adjust the frequency of jazzy chords here | |
melody_notes = melodies[current_melody][:notes] | |
root_note = melody_notes.choose # Choosing a root note from the melody | |
# Selecting chord types that are more likely to harmonize | |
chord_types = [:major7, :minor7, :maj9] | |
chord_type = chord_types.choose | |
chord_notes = chord(root_note, chord_type) | |
chord_notes.each do |note| | |
midi note, channel: channel, sustain: [2,4,6].choose | |
end | |
sleep [2,4,8].choose # Pause between chords | |
end | |
end | |
# Mixing of evolving melodies and occasional jazzy chords over different MIDI channels | |
in_thread do | |
loop do | |
primary_melody = melodies.keys.choose | |
play_melody_with_variation_midi 1, primary_melody | |
play_jazzy_chord_midi 3, primary_melody | |
sleep [1, 2, 4].choose # Adjusting space between melody plays | |
end | |
end | |
in_thread do | |
loop do | |
primary_melody = melodies.keys.choose | |
play_melody_with_variation_midi 2, primary_melody | |
play_jazzy_chord_midi 3, primary_melody | |
sleep [2, 4, 8].choose # Adjusting space between melody plays | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment