Your SlideShare is downloading. ×
0
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Ruby, Rock & Roll
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Ruby, Rock & Roll

1,990

Published on

Creating digital music using a Pure Ruby domain specific language

Creating digital music using a Pure Ruby domain specific language

Published in: Technology, Education
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,990
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
0
Comments
0
Likes
3
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Transcript

    • 1. Ruby, Rock and RollChang Sau SheongHP Labs SingaporeMay 2012
    • 2. About
    • 3.  me
    • 4. About
    • 5.  me
    • 6. About
    • 7.  me
    • 8. About
    • 9.  me
    • 10. About
    • 11.  me
    • 12. About
    • 13.  me
    • 14. About
    • 15.  me
    • 16. About
    • 17.  me
    • 18. Musehttp://github.com/sausheong/muse
    • 19. A
    • 20.  (pure)
    • 21.  Ruby
    • 22.  domain- specific
    • 23.  language
    • 24.  for
    • 25.   synthesizing
    • 26.  music
    • 27.  
    • 28. Creating
    • 29.  Muse•Create
    • 30.  sound•Organize
    • 31.  sound
    • 32.  into
    • 33.  music
    • 34.  notes•Write
    • 35.  notes
    • 36.  to
    • 37.  file•Wrap
    • 38.  around
    • 39.  with
    • 40.  a
    • 41.  domain- specific
    • 42.  language
    • 43. About
    • 44.  sound•Sound
    • 45.  is
    • 46.  produced
    • 47.  by
    • 48.  vibration
    • 49.  of
    • 50.  something
    • 51.   (air,
    • 52.  water
    • 53.  etc)•Vibration
    • 54.  produces
    • 55.  waves
    • 56.  •Properties
    • 57.  of
    • 58.  sound
    • 59.  wave
    • 60.  include
    • 61.  amplitude
    • 62.   (volume)
    • 63.  and
    • 64.  frequency
    • 65.  (pitch)
    • 66. Higher
    • 67.  amplitude
    • 68.  means
    • 69.  louder
    • 70.  volume amplitude frequency
    • 71.  =
    • 72.  number
    • 73.  of
    • 74.   cycles
    • 75.  in
    • 76.  1
    • 77.  second cycle More
    • 78.  cycles
    • 79.  in
    • 80.  1
    • 81.  second
    • 82.   mean
    • 83.  higher
    • 84.  frequency,
    • 85.   higher
    • 86.  pitch
    • 87. Make
    • 88.  a
    • 89.  sound•Sine
    • 90.  wave
    • 91.  is
    • 92.  pure
    • 93.  sound,
    • 94.  all
    • 95.  other
    • 96.  sounds
    • 97.  made
    • 98.   by
    • 99.  combining
    • 100.  various
    • 101.  sine
    • 102.  waves•To
    • 103.  make
    • 104.  a
    • 105.  sound,
    • 106.  generate
    • 107.  sine
    • 108.  waves•To
    • 109.  make
    • 110.  a
    • 111.  digital
    • 112.  sound,
    • 113.  generate
    • 114.  digital
    • 115.  sine
    • 116.   waves
    • 117.  and
    • 118.  put
    • 119.  them
    • 120.  into
    • 121.  sound
    • 122.  files
    • 123. The
    • 124.  physics
    • 125.  of
    • 126.  music•Music
    • 127.  is
    • 128.  organized
    • 129.  sound•Music
    • 130.  notes
    • 131.  are
    • 132.  sounds
    • 133.  with
    • 134.  specific
    • 135.  pitches
    • 136.   (frequencies)
    • 137.  and
    • 138.  durations•Each
    • 139.  note
    • 140.  corresponds
    • 141.  to
    • 142.  a
    • 143.  particular
    • 144.   frequency,
    • 145.  expressed
    • 146.  in
    • 147.  hertz
    • 148.  (Hz)•Most
    • 149.  music
    • 150.  use
    • 151.  a
    • 152.  scale
    • 153.  (sequence
    • 154.  of
    • 155.  notes)
    • 156.   with
    • 157.  12
    • 158.  notes
    • 159.  called
    • 160.  the
    • 161.  chromatic
    • 162.  scale
    • 163. same
    • 164.  pitch
    • 165.  class
    • 166.  (octave) C# D# F# G# A#C D E F G A B C 1
    • 167.  octave
    • 168.  =
    • 169.  12
    • 170.  semi-tone
    • 171.  notes
    • 172. The
    • 173.  physics
    • 174.  of
    • 175.  music•The
    • 176.  frequencies
    • 177.  of
    • 178.  the
    • 179.  notes
    • 180.  are
    • 181.  related
    • 182.  to
    • 183.   each
    • 184.  other
    • 185.  in
    • 186.  a
    • 187.  mathematical
    • 188.  formula•The
    • 189.  frequencies
    • 190.  are
    • 191.  defined
    • 192.  around
    • 193.  the
    • 194.   standard
    • 195.  pitch
    • 196.  A4,
    • 197.  which
    • 198.  is
    • 199.  440
    • 200.  Hz
    • 201.  (ISO
    • 202.   16:1975
    • 203.  standard)•Notes
    • 204.  of
    • 205.  the
    • 206.  same
    • 207.  pitch
    • 208.  class
    • 209.  (octave)
    • 210.  are
    • 211.  in
    • 212.   the
    • 213.  ratio
    • 214.  of
    • 215.  a
    • 216.  power
    • 217.  of
    • 218.  2
    • 219.  (1/4,
    • 220.  1/2,
    • 221.  2,
    • 222.  4,
    • 223.  8
    • 224.   etc)
    • 225.  
    • 226. A A7 3520HzA A6 1760HzA A5 880HzA A4 440Hz
    • 227. 12difference
    • 228.  between
    • 229.  12
    • 230.  semi-tones
    • 231.  (1
    • 232.  octave)
    • 233.  is
    • 234.  
    • 235.  2
    • 236.  
    • 237.  
    • 238.  ×
    • 239.  f
    • 240.  
    • 241.  or
    • 242.  2f
    • 243.  
    • 244.  
    • 245.   12 1 difference
    • 246.  between
    • 247.  2
    • 248.  semi-tones
    • 249.  is
    • 250.  
    • 251.  
    • 252.  
    • 253.  2
    • 254.  ×
    • 255.  f
    • 256.  
    • 257.  or
    • 258.   2
    • 259.  
    • 260.   12 12 ×f
    • 261. Getting
    • 262.  the
    • 263.  frequency•Get
    • 264.  the
    • 265.  frequency
    • 266.  of
    • 267.  the
    • 268.  note
    • 269.  (f),
    • 270.  as
    • 271.   compared
    • 272.  to
    • 273.  A4
    • 274.  (440Hz)
    • 275.  using
    • 276.  the
    • 277.  formula n f = 2 × 440Hz 12•where
    • 278.  n
    • 279.  =
    • 280.  distance
    • 281.  from
    • 282.  A4.
    • 283.  For
    • 284.  eg
    • 285.  C5
    • 286.  is
    • 287.  3
    • 288.   notes
    • 289.  (semi-tones)
    • 290.  after
    • 291.  A4,
    • 292.  so
    • 293.  frequency
    • 294.  of
    • 295.   C5
    • 296.  is
    • 297.   3 f = 2 12 × 440Hz = 523.25Hz
    • 298. Create
    • 299.  music
    • 300.  notes•To
    • 301.  get
    • 302.  a
    • 303.  sine
    • 304.  wave
    • 305.  representing
    • 306.  a
    • 307.  note s = sin(2π f )• We
    • 308.  multiple
    • 309.  f
    • 310.  with
    • 311.  2
    • 312.  
    • 313.  
    • 314.  because
    • 315.  we
    • 316.  need
    • 317.  to
    • 318.  
    • 319.   π turn
    • 320.  the
    • 321.  frequency
    • 322.  into
    • 323.  radians
    • 324. Get
    • 325.  note
    • 326.  data
    • 327.  samples 1250 626 0 44100
    • 328.  samples take
    • 329.  samples
    • 330.  at
    • 331.  regular
    • 332.  intervals
    • 333.  (44,100
    • 334.   samples
    • 335.  over
    • 336.  a
    • 337.  period
    • 338.  of
    • 339.  1
    • 340.  second)
    • 341.  and
    • 342.   calculate
    • 343.  the
    • 344.  wave
    • 345.  value
    • 346.  at
    • 347.  that
    • 348.  sample
    • 349. NOTES = %w(a ais b c cis d dis e f fis g gis)FREQUENCIES = { d4:-7, dis4:-6, e4:-5, f4: -4, fis4:-3, g4:-2, gis4:-1, a4: 0, ais4: 1, b4: 2, c5: 3, cis5: 4, d5: 5}# get the frequency of the pitchdef frequency_of(step) 440.0*(2**(step.to_f/12.0))endsample_rate = 44100.0 # 44100 Hzduration = 1 # 1 secstream = [] # data stream for left and right channelsfrequency = frequency_of(FREQUENCIES[:a4])# for the duration of 1 sec, step every 1/44100 times and# write the value(0.0..duration.to_f).step(1/sample_rate) do |i| x = (10000 * Math.sin(2 * Math::PI * frequency * i)).to_i stream [x,x]end
    • 350. [[0, 0], [626, 626], [1250, 1250], [1869, 1869], [2481, 2481], [3083, 3083], [3673, 3673], [4248, 4248], [4807, 4807], [5347, 5347], [5866, 5866], [6362,6362], [6832, 6832], [7276, 7276], [7692, 7692], [8077, 8077], [8431, 8431], [8751, 8751], [9037, 9037], [9287, 9287], [9501, 9501], [9678, 9678], [9816,9816], [9916, 9916], [9978, 9978], [9999, 9999], [9982, 9982], [9925, 9925], [9830, 9830], [9696, 9696], [9523, 9523], [9313, 9313], [9067, 9067], [8785,8785], [8469, 8469], [8119, 8119], [7737, 7737], [7325, 7325], [6884, 6884], [6416, 6416], [5923, 5923], [5407, 5407], [4869, 4869], [4313, 4313], [3739,3739], [3151, 3151], [2550, 2550], [1939, 1939], [1321, 1321], [697, 697], [71, 71], [-555, -555], [-1179, -1179], [-1799, -1799], [-2412, -2412], [-3015,-3015], [-3606, -3606], [-4184, -4184], [-4744, -4744], [-5287, -5287], [-5808, -5808], [-6307, -6307], [-6780, -6780], [-7227, -7227], [-7646, -7646], stream[-8035, -8035], [-8392, -8392], [-8716, -8716], [-9006, -9006], [-9261, -9261], [-9479, -9479], [-9660, -9660], [-9803, -9803], [-9907, -9907], [-9973,-9973], [-9999, -9999], [-9986, -9986], [-9934, -9934], [-9843, -9843], [-9713, -9713], [-9545, -9545], [-9339, -9339], [-9097, -9097], [-8819, -8819],[-8506, -8506], [-8160, -8160], [-7782, -7782], [-7373, -7373], [-6936, -6936], [-6471, -6471], [-5981, -5981], [-5467, -5467], [-4931, -4931], [-4377,-4377], [-3805, -3805], [-3218, -3218], [-2619, -2619], [-2009, -2009], [-1391, -1391], [-768, -768], [-142, -142], [484, 484], [1109, 1109], [1729, 1729],[2343, 2343], [2947, 2947], [3540, 3540], [4119, 4119], [4682, 4682], [5226, 5226], [5750, 5750], [6251, 6251], [6728, 6728], [7178, 7178], [7600, 7600],[7992, 7992], [8353, 8353], [8681, 8681], [8975, 8975], [9234, 9234], [9456, 9456], [9641, 9641], [9788, 9788], [9897, 9897], [9967, 9967], [9998, 9998],[9989, 9989], [9942, 9942], [9855, 9855], [9729, 9729], [9566, 9566], [9364, 9364], [9126, 9126], [8852, 8852], [8544, 8544], [8201, 8201], [7827, 7827],[7421, 7421], [6987, 6987], [6525, 6525], [6038, 6038], [5526, 5526], [4993, 4993], [4441, 4441], [3871, 3871], [3285, 3285], [2687, 2687], [2079, 2079],[1462, 1462], [839, 839], [213, 213], [-413, -413], [-1038, -1038], [-1659, -1659], [-2273, -2273], [-2879, -2879], [-3473, -3473], [-4054, -4054], [-4619,-4619], [-5165, -5165], [-5691, -5691], [-6195, -6195], [-6675, -6675], [-7128, -7128], [-7554, -7554], [-7949, -7949], [-8314, -8314], [-8645, -8645],[-8943, -8943], [-9206, -9206], [-9432, -9432], [-9622, -9622], [-9774, -9774], [-9887, -9887], [-9961, -9961], [-9996, -9996], [-9992, -9992], [-9949,-9949], [-9867, -9867], [-9746, -9746], [-9586, -9586], [-9389, -9389], [-9155, -9155], [-8885, -8885], [-8580, -8580], [-8242, -8242], [-7871, -7871],[-7469, -7469], [-7038, -7038], [-6579, -6579], [-6094, -6094], [-5586, -5586], [-5055, -5055], [-4504, -4504], ...]
    • 351. [[0, 0], [626, 626], [1250, 1250], [1869, 1869], [2481, 2481], [3083, 3083], [3673, 3673], [4248, 4248], [4807, 4807], [5347, 5347], [5866, 5866], [6362,6362], [6832, 6832], [7276, 7276], [7692, 7692], [8077, 8077], [8431, 8431], [8751, 8751], [9037, 9037], [9287, 9287], [9501, 9501], [9678, 9678], [9816,9816], [9916, 9916], [9978, 9978], [9999, 9999], [9982, 9982], [9925, 9925], [9830, 9830], [9696, 9696], [9523, 9523], [9313, 9313], [9067, 9067], [8785,8785], [8469, 8469], [8119, 8119], [7737, 7737], [7325, 7325], [6884, 6884], [6416, 6416], [5923, 5923], [5407, 5407], [4869, 4869], [4313, 4313], [3739,3739], [3151, 3151], [2550, 2550], [1939, 1939], [1321, 1321], [697, 697], [71, 71], [-555, -555], [-1179, -1179], [-1799, -1799], [-2412, -2412], [-3015,-3015], [-3606, -3606], [-4184, -4184], [-4744, -4744], [-5287, -5287], [-5808, -5808], [-6307, -6307], [-6780, -6780], [-7227, -7227], [-7646, -7646], stream[-8035, -8035], [-8392, -8392], [-8716, -8716], [-9006, -9006], [-9261, -9261], [-9479, -9479], [-9660, -9660], [-9803, -9803], [-9907, -9907], [-9973,-9973], [-9999, -9999], [-9986, -9986], [-9934, -9934], [-9843, -9843], [-9713, -9713], [-9545, -9545], [-9339, -9339], [-9097, -9097], [-8819, -8819],[-8506, -8506], [-8160, -8160], [-7782, -7782], [-7373, -7373], [-6936, -6936], [-6471, -6471], [-5981, -5981], [-5467, -5467], [-4931, -4931], [-4377,-4377], [-3805, -3805], [-3218, -3218], [-2619, -2619], [-2009, -2009], [-1391, -1391], [-768, -768], [-142, -142], [484, 484], [1109, 1109], [1729, 1729],[2343, 2343], [2947, 2947], [3540, 3540], [4119, 4119], [4682, 4682], [5226, 5226], [5750, 5750], [6251, 6251], [6728, 6728], [7178, 7178], [7600, 7600],[7992, 7992], [8353, 8353], [8681, 8681], [8975, 8975], [9234, 9234], [9456, 9456], [9641, 9641], [9788, 9788], [9897, 9897], [9967, 9967], [9998, 9998],[9989, 9989], [9942, 9942], [9855, 9855], [9729, 9729], [9566, 9566], [9364, 9364], [9126, 9126], [8852, 8852], [8544, 8544], [8201, 8201], [7827, 7827],[7421, 7421], [6987, 6987], [6525, 6525], [6038, 6038], [5526, 5526], [4993, 4993], [4441, 4441], [3871, 3871], [3285, 3285], [2687, 2687], [2079, 2079],[1462, 1462], [839, 839], [213, 213], [-413, -413], [-1038, -1038], [-1659, -1659], [-2273, -2273], [-2879, -2879], [-3473, -3473], [-4054, -4054], [-4619,-4619], [-5165, -5165], [-5691, -5691], [-6195, -6195], [-6675, -6675], [-7128, -7128], [-7554, -7554], [-7949, -7949], [-8314, -8314], [-8645, -8645],[-8943, -8943], [-9206, -9206], [-9432, -9432], [-9622, -9622], [-9774, -9774], [-9887, -9887], [-9961, -9961], [-9996, -9996], [-9992, -9992], [-9949,-9949], [-9867, -9867], [-9746, -9746], [-9586, -9586], [-9389, -9389], [-9155, -9155], [-8885, -8885], [-8580, -8580], [-8242, -8242], [-7871, -7871],[-7469, -7469], [-7038, -7038], [-6579, -6579], [-6094, -6094], [-5586, -5586], [-5055, -5055], [-4504, -4504], ...]
    • 352. Harmonics•Sine
    • 353.  wave
    • 354.  is
    • 355.  the
    • 356.  most
    • 357.  basic
    • 358.  waveform
    • 359.  and
    • 360.   produces
    • 361.  the
    • 362.  fundamental
    • 363.  frequency,
    • 364.  a
    • 365.  pure
    • 366.   sound•Any
    • 367.  other
    • 368.  sounds
    • 369.  can
    • 370.  be
    • 371.  created
    • 372.  by
    • 373.  adding
    • 374.   other
    • 375.  waves
    • 376.  at
    • 377.  different
    • 378.  frequencies
    • 379.  and
    • 380.   amplitudes
    • 381.  (called
    • 382.  harmonics)•Adding
    • 383.  sine
    • 384.  waves
    • 385.  at
    • 386.  different
    • 387.  multiples
    • 388.  of
    • 389.   the
    • 390.  same
    • 391.  frequency
    • 392.  changes
    • 393.  how
    • 394.  the
    • 395.  same
    • 396.  note
    • 397.   sounds
    • 398. y=sin(x)y
    • 399.  =
    • 400.  sin(2x) y
    • 401.  =
    • 402.  sin(x)
    • 403.  +
    • 404.  sin(2x)
    • 405. def harmonics(input) Math.sin(2 * Math::PI * input) + Math.sin(2 * Math::PI * input * 2)end# for the duration of 1 sec, step every 1/44100 times and# write the value(0.0..duration.to_f).step(1/sample_rate) do |i| x = (10000 * harmonics(frequency * i)).to_i stream [x,x]end
    • 406. def harmonics(input) Math.sin(2 * Math::PI * input) + Math.sin(2 * Math::PI * input * 2)end# for the duration of 1 sec, step every 1/44100 times and# write the value(0.0..duration.to_f).step(1/sample_rate) do |i| x = (10000 * harmonics(frequency * i)).to_i stream [x,x]end
    • 407. Envelopes•Changing
    • 408.  the
    • 409.  volume
    • 410.  of
    • 411.  the
    • 412.  note
    • 413.  over
    • 414.  the
    • 415.   duration
    • 416.  also
    • 417.  changes
    • 418.  how
    • 419.  the
    • 420.  note
    • 421.  sounds def envelope(input, duration) Math.cos((Math::PI*input)/(2*duration.to_f)) end # for the duration of 1 sec, step every 1/44100 times and # write the value (0.0..duration.to_f).step(1/sample_rate) do |i| x = (10000 * Math.sin(2 * Math::PI * frequency * i) * envelope(i, duration)).to_i stream [x,x] end
    • 422. input
    • 423.  x
    • 424.  sin(duration)input
    • 425.  x
    • 426.  cos(duration)
    • 427. input
    • 428.  x
    • 429.  sin(duration)input
    • 430.  x
    • 431.  cos(duration)
    • 432. input
    • 433.  x
    • 434.  sin(duration)input
    • 435.  x
    • 436.  cos(duration)
    • 437. Digital
    • 438.  sound•Digital
    • 439.  sound
    • 440.  stored
    • 441.  in
    • 442.  compressed
    • 443.  or
    • 444.   uncompressed
    • 445.  formats•Main
    • 446.  uncompressed
    • 447.  format
    • 448.  is
    • 449.  PCM
    • 450.  (Pulse
    • 451.  Code
    • 452.   Modulation),
    • 453.  stored
    • 454.  as
    • 455.  WAV
    • 456.  (Windows)
    • 457.  or
    • 458.   AIFF
    • 459.  (Mac)
    • 460.  files•Standard
    • 461.  form
    • 462.  for
    • 463.  all
    • 464.  digital
    • 465.  audio,
    • 466.  digital
    • 467.   representation
    • 468.  of
    • 469.  an
    • 470.  analog
    • 471.  signal
    • 472. The
    • 473.  WAV
    • 474.  format•Audio
    • 475.  file
    • 476.  format
    • 477.  for
    • 478.  Windows,
    • 479.  derived
    • 480.  from
    • 481.   RIFF
    • 482.  (Resource
    • 483.  Interchange
    • 484.  File
    • 485.  Format)•Bitstream
    • 486.  format
    • 487.  store
    • 488.  data
    • 489.  in
    • 490.  chunks•Linear
    • 491.  PCM
    • 492.  encoded,
    • 493.  2
    • 494.  channels
    • 495.  of
    • 496.  44,100
    • 497.   samples
    • 498.  per
    • 499.  second,
    • 500.  16
    • 501.  bits
    • 502.  per
    • 503.  sample
    • 504. Create
    • 505.  WAV
    • 506.  files•Write
    • 507.  manually
    • 508.  using
    • 509.  Array#pack
    • 510.  (read
    • 511.   manually
    • 512.  using
    • 513.  String#unpack)•Use
    • 514.  the
    • 515.  BinData
    • 516.  library
    • 517.  (http:// bindata.rubyforge.org)
    • 518.  to
    • 519.  represent
    • 520.  WAV
    • 521.   format
    • 522.  and
    • 523.  stuff
    • 524.  data
    • 525.  in•Data
    • 526.  is
    • 527.  just
    • 528.  integers
    • 529.  representing
    • 530.  the
    • 531.  sample
    • 532. require bindataclass RiffChunk BinData::Record int32be :chunk_id int32le :chunk_size int32be :formatendclass FormatChunk BinData::Record int32be :chunk_id int32le :chunk_size int16le :audio_format int16le :num_channels int32le :sample_rate int32le :byte_rate int16le :block_align int16le :bits_per_sampleendclass DataChunk BinData::Record int32be :chunk_id int32le :chunk_size array :stream do int16le :left int16le :right endendclass WavFormat BinData::Record riff_chunk :riff_chunk format_chunk :format_chunk data_chunk :data_chunkend
    • 533. class Wav SAMPLE_RATE = 44100 attr :wav, :file, :sample_rate, :format_chunk, :riff_chunk, :data_chunk def initialize(filename) @sample_rate = SAMPLE_RATE @file = File.open(filename, wb) @riff_chunk = RiffChunk.new @riff_chunk.chunk_id = RIFF.unpack(N).first @riff_chunk.format = WAVE.unpack(N).first @format_chunk = FormatChunk.new @format_chunk.chunk_id = fmt .unpack(N).first @format_chunk.chunk_size = 16 @format_chunk.audio_format = 1 @format_chunk.num_channels = 2 @format_chunk.bits_per_sample = 16 @format_chunk.sample_rate = @sample_rate @format_chunk.byte_rate = @format_chunk.sample_rate * @format_chunk.num_channels * @format_chunk.bits_per_sample/2 @format_chunk.block_align = @format_chunk.num_channels * @format_chunk.bits_per_sample/2 @data_chunk = DataChunk.new @data_chunk.chunk_id = data.unpack(N).first end
    • 534. def write(stream_data) stream_data.each_with_index do |s,i| @data_chunk.stream[i].left = s[0] @data_chunk.stream[i].right = s[1] end @data_chunk.chunk_size = stream_data.length * @format_chunk.num_channels * @format_chunk.bits_per_sample/8 @riff_chunk.chunk_size = 36 + @data_chunk.chunk_size @wav = WavFormat.new @wav.riff_chunk = @riff_chunk @wav.format_chunk = @format_chunk @wav.data_chunk = @data_chunk @wav.write(@file) end def close @file.close endendwav_file = Wav.new(sine.wav)wav_file.write(stream)wav_file.close
    • 535. Putting
    • 536.  it
    • 537.  all
    • 538.   together
    • 539. NOTES = %w(a ais b c cis d dis e f fis g gis)FREQUENCIES = { d4:-7, dis4:-6, e4:-5, f4:-4, fis4:-3, g4:-2, gis4:-1, a4: 0, ais4: 1, b4: 2, c5: 3, cis5: 4, d5: 5}# get the frequency of the pitchdef frequency_of(step) 440.0*(2**(step.to_f/12.0))endsample_rate = 44100.0 # 44100 Hzduration = 1 # 1 secstream = [] # data stream for left and right channelsfrequency = frequency_of(FREQUENCIES[:a4])# for the duration of 1 sec, step every 1/44100 times and# write the value(0.0..duration.to_f).step(1/sample_rate) do |i| x = (10000 * Math.sin(2 * Math::PI * frequency * i)).to_i stream [x,x]endwav_file = Wav.new(sine.wav)wav_file.write(stream)wav_file.close
    • 540. Domain
    • 541.  specific
    • 542.  language•Designed
    • 543.  for
    • 544.  a
    • 545.  specific
    • 546.  domain•Captures
    • 547.  concepts
    • 548.  of
    • 549.  the
    • 550.  domain
    • 551.  including
    • 552.   jargon•Is
    • 553.  still
    • 554.  Ruby!
    • 555. Techniques
    • 556.  used
    • 557.  in
    • 558.  Muse•DSL
    • 559.  are
    • 560.  methods
    • 561.  in
    • 562.  Song
    • 563.  and
    • 564.  Bar•Use
    • 565.  instance_eval
    • 566.  to
    • 567.  evaluate
    • 568.  music
    • 569.  score•Use
    • 570.  method_missing
    • 571.  to
    • 572.  catch
    • 573.  names
    • 574.  of
    • 575.  notes
    • 576.   and
    • 577.  chords
    • 578. class Song DSL
    • 579.  are
    • 580.  methods def self.record(name, options ={}, block) ... def bar(id, options={}) ... @bars[id] Bar.new(id, options) @bars[id].last end end class Bar def notes(block) ... end end endrequire museinclude MuseSong.record hotel_california, harmonic: guitar, bpm: 100 do bar(1).notes { d4 b:2; e4; fis4;} ...end
    • 581. instance_evalclass Bar ... def notes(block) instance_eval block endendrequire museinclude MuseSong.record hotel_california, harmonic: guitar, bpm: 100 do bar(1).notes { d4 b:2; e4; fis4;} ...end
    • 582. method_missingclass Bar ... def method_missing(name, *args, block) name = name.to_s if name.start_with? *NOTES ... end endendrequire museinclude MuseSong.record hotel_california, harmonic: guitar, bpm: 100 do ... bar(3).notes { a3_d4_fis4; fis4; fis4 b:0.5;} ...end
    • 583. Turk!h March
    • 584. Wait,
    • 585.  there’s
    • 586.   more
    • 587.  ...
    • 588. Ottothe Algorithmic Composer
    • 589. Algorithmic composition is thetechnique of using algorithms to create music - Wikipedia
    • 590. Grab tweet from Twitter, create music from it
    • 591. Scan a pictureGrab tweet from Twitter, create music from it
    • 592. Get today’s weather report Scan a picture Grab tweet from Twitter, create music from it
    • 593. The algorithm
    • 594. Melody + Chords = Music
    • 595. Grab tweet from Twittertext = Twitter.search(#reddot).last.text
    • 596. Split tweet into wordswords = text.split
    • 597. Convert each word into anumber using the touch tone keypad algorithm
    • 598. KEYPAD = {a:2,b:2,c:2, d:3,e:3,f:3, g:4,h:4,i:4, j:5,k:5,l:5, m:6,n:6,o:6, p:7,q:7,r:7,s:7, t:8,u:8,v:8, w:9,x:9,y:9,z:9}def word_to_num(a_word) a_word.downcase.chars.inject() { |memo,obj| memo + KEYPAD[obj.to_sym].to_s }end
    • 599. Find the 7 most frequently found notesmusic = []words.each do |w| music NOTES[note(w)]endsorted = music.counts.sort_by {|obj| obj[1]}.reversemost_frequent_7_notes = sorted.map {|obj| obj[0]}.first(7)
    • 600. Determine the musical scale from the 7 notesMAJOR = { 0 = %w(c d e f g a b c d), 1 = %w(g a b c d e fis g a), 2 = %w(d e fis g a b cis d e), 3 = %w(a b cis d e fis gis a b), 4 = %w(e fis gis a b cis dis e fis), 5 = %w(b cis dis e fis gis ais b cis), 6 = %w(fis gis ais b cis dis f fis gis) }num_of_sharps = most_frequent_7_notes.inject(0) { |memo, obj| obj.end_with?(is) ? memo + 1 : memo }scale = MAJOR[num_of_sharps]
    • 601. Get the chord progression for the scale (using I-IV-V)scale_chords = {}scale_chords[0] = [#{scale[0]}, #{scale[2]}, #{scale[4]}]scale_chords[1] = [#{scale[3]}, #{scale[5]}, #{scale[7]}]scale_chords[2] = [#{scale[4]}, #{scale[6]}, #{scale[8]}]
    • 602. ✓Melody + Chords = Music
    • 603. Start with the first note of the scale
    • 604. Calculate the ‘distance’ between the current note and the nextdef distance(a_word) word_to_num(a_word).to_i % 5end
    • 605. Determine if the next note goes ‘up’ or ‘down’ the scaledef direction(a_word) (word_to_num(a_word).to_i % 2) == 0 ? 1 : -1end
    • 606. Get number of syllables for each word, each syllable is 1 beatdef syllables(a_word) word = a_word.downcase return 1 if word.length = 3 word.sub!(/(?:[^laeiouy]es|ed|[^laeiouy]e)$/, ) word.sub!(/^y/, ) word.scan(/[aeiouy]{1,2}/).sizeend
    • 607. Move from current note to next noteif direction(word) 0 bar_notes scale.next(distance(word))else bar_notes scale.previous(distance(word))end
    • 608. ✓ ✓Melody + Chords = Music
    • 609. Break down into 4 words perbar, use Muse to write to WAV file
    • 610. quadruplets.reverse.each_with_index do |quad, index| beats = 0.0 bar(index).notes { beats, bar_notes = [], [] quad.each do |word| beats syllables(word).to_f/2 if direction(word) 0 bar_notes scale.next(distance(word)) else bar_notes scale.previous(distance(word)) end end total_beats = beats.inject(:+) bar_notes.each_with_index do |n,i| note = n.chop octave = n[n.size-1] b = (beats[i]*4.0)/total_beats add_to_stream note_data(note, octave, b:b) end } bar(index, v:1.5).notes { ch = scale_chords[index % 3] chord = [ch[1], ch[2], ch[0]] add_to_stream note_data(ch[0].chop, 3, b:1) add_to_stream chord(chord, b:1) add_to_stream chord(chord, b:1) add_to_stream chord(chord, b:1) }
    • 611. Demo
    • 612. @sausheong+Sau Sheong Changsausheong@gmail.comsausheong@hp.comhttp://blog.saush.com

    ×