# Lesson 13

# Threads Lesson. In this lesson,
# you will learn how to run multiple
# blocks of code at the same time
# using threads.

# General Instructions:
#
# This lesson contains two examples and
# two exercises (A, B).
#
# To listen to an example, change "comment"
# to "uncomment" on the "comment do" line,
# then click the "Run" menu command at the
# top of the Sonic Pi editor window.
# When you are done with the example, turn
# it off by changing "uncomment" back to
# "comment," and move on to the next section
# of the lesson.
#

# Normally, Sonic Pi runs lines and blocks of
# code one after the other in sequence.
# However, in music we often want to play
# several different things at the same time.
# Threads allow us to do this. Creating a
# thread allows the code within the thread to
# start at exactly the same time as any code
# follows.

# Example 1: Two parts using a thread.

comment do
  use_bpm 100
  use_synth :prophet

  #create a metronome in 3/4
  in_thread do
    loop do
      sample :drum_heavy_kick
      sleep 1
      sample :perc_snap
      sleep 1
      sample :perc_snap
      sleep 1
    end
  end

  scale_ring = (ring :C4, :D4, :E4, :F4, :G4,
                    :A4, :B4, :C5)
  index = 0
  loop do
    note = scale_ring[index]
    play note
    sleep 1
    index += 1
  end
end

# Exercise A
# 1) Change the "metronome" thread in Example 1
#    so that it plays a 4-beat pattern with
#    the strong emphasis on beats 1 and 3.

#  2) Change the loop after the "metronome"
#     so that it repeatedly plays the first
#     seven notes of Twinkle, Twinkle, Little Star.
#     Re-name "scale_ring" as "twinkle_ring".
#     Use the :r (rest) symbol as the 8th
#     member of the twinkle_ring so that the
#     melodic rhythm matches the metronome
#     rhythm.

# Example 2: Three parts using threads.

comment do
  use_bpm 100
  use_synth :prophet

  #create a metronome in 5/4
  in_thread do
    loop do
      sample :drum_heavy_kick
      sleep 1
      2.times do
        sample :perc_snap
        sleep 1
      end
      sample :drum_heavy_kick
      sleep 1
      sample :perc_snap
      sleep 1
    end
  end

  melody_ring = (ring :A3, :G3, :C4, :D4, :G4,
                    :E4)
  index = 0
  loop do
    3.times do
      note = melody_ring[index]
      play note
      sleep 1
      index += 1
    end
    2.times do
      note = melody_ring[index]
      play note
      sleep 0.5
      index += 1
    end
    note = melody_ring[index]
    play note
    sleep 1
    index += 1
  end
end

# Exercise B
# 1) Experiment with the "metronome"
#    thread in Example 1 by changing
#    the meter - try some irregular
#    meters like 7/4 (3+4 or 2+2+3 or 2+3+2)
#    or 8/8 (3+3+2 or 2+3+2 or 3+2+3)
#
#  2) Change melody_ring notes to match the
#     metronome rhythm. Experiment with
#     different rhythmic loops for the melody
#     notes.