Skip to content

Instantly share code, notes, and snippets.

@al2o3cr
Last active November 13, 2016 01:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save al2o3cr/81ca52545e51bff85dd4a008bfd03b43 to your computer and use it in GitHub Desktop.
Save al2o3cr/81ca52545e51bff85dd4a008bfd03b43 to your computer and use it in GitHub Desktop.
require 'thwait'
class Voice
BASELINE = %w( there is no - poop ing - on - the bus - )
VOICES = `say -v '?'`.lines.map { |line| line.split.first }
attr_reader :voice_name, :rate
def initialize(voice_name, rate)
@i = 0
@voice_name = voice_name
@rate = rate
end
def perform
mod = word == "there" ? "[[volm +0.2]] " : ""
Thread.new do
if word != "-"
system "say -r #{rate} -v #{voice_name} \"#{mod}#{word}\""
end
advance
end
end
def advance
@i = (@i + 1) % BASELINE.length
end
def word
BASELINE[@i]
end
end
class Beat
attr_reader :time
def initialize(time)
@time = time
end
def perform
Thread.new do
sleep(time)
end
end
end
class Metronome
def perform
Thread.new do
if ENV['METRONOME'] == '1'
system "afplay -v 0.5 /System/Library/Sounds/Tink.aiff"
end
end
end
end
a1 = Voice.new('Kathy', 400)
a2 = Voice.new('Agnes', 400)
beat = Beat.new(0.25)
metronome = Metronome.new
13.times do
(Voice::BASELINE.length * 4).times do
t1 = a1.perform
t2 = a2.perform
t3 = beat.perform
t4 = metronome.perform
ThreadsWait.all_waits(t1, t2, t3, t4)
end
a1.advance
end
@al2o3cr
Copy link
Author

al2o3cr commented Nov 13, 2016

NOTE: the metronome is helpful if you're debugging a voice that can't keep up. For instance, the Cellos voice plays for a minimum length that is too long, so the metronome ticks will not play at a constant tempo. Invoke the script with METRONOME=1 in the environment to enable it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment