It's so quiet. Let's make music

Preview:

DESCRIPTION

Ruby is used for a lot of things, but for some reason, only a few people are using it for music. In a language that is meant to make programming fun, the lack of such creative code is scary. Let's fix the current landscape by learning how to use the tools available in Ruby (and some not) to let those creative juices flow. We will be focusing on how to build sounds from the ground up (the powerful amplitude, and the majestic waveform), so you don't need any prior audio wizardry. Just bring yourself and a Ruby console and we just might create some beautiful music in a beautiful language.

Citation preview

It’s so quiet.Let’s make music.

Loren Segal RubyConf 2014

@lsegal

WARNING: MUSIC AHEAD🚨 🚨

What ismusic even?

S + R = Mound

hythm

usic

S + R = Mound

hythm

usic

S + R = Mound

uby

usic

S + R =ound

uby

S + R =ound

uby

This talk.

dSoundd boop.

beep.

Analog Audio

Good Vibrations

Continuous Signal

DIGITAL AUDIO

💻 🔊?

Discrete Signal (not continuous)

187 198

-84 -84

not continuous,

Just Samples

Discrete Signal (not continuous)

Discrete Signal (not continuous)

Discrete Signal (sampling)

Discrete Signal (sampling)

Discrete Signal (sampling)

Audio Vocabulary[Sample Rate]⇒

“Number of data values for each second of audio”

Measured in Hertz (Hz)

[0, 214, 231, 35, -193, -245, -72, 167, 252, 105, -139, -255, -137, 107, 252, 165, -74, -246, -192, 38]

20.times.map {|i| (Math.sin(i) * 255).floor }

20 Samples

Common Sample Rates

44,100 Hz 44,800 Hz 96,000 Hz

used by VHS, CDs

💻 🔊

WAVESfundamental

SINEsin(x)

#math

f(t) = A sin(2πΩt)s

f(t) = A sin(2πΩt)Amplitude

Frequency

s

Ampl

itude

Frequency* …ish

Audio Vocabulary[Amplitude]⇒

“Loudness” Measured in Decibels (dB)

Audio Vocabulary[Frequency]⇒

“Pitch” Measured in Hertz (Hz)

s = Sample Rate

Ωs

= e.g., 44100

Frequency?

Ω = 440 Hz [A3]

f(t) = sin(0.0627t)

SQUARE

f(t) = A ((Ωt) < 0.5 ? -1 : 1)s

Triangle

f(t) = A(1 - 4(Ωt - Ωt ))ss

SAW(tooth)

f(t) = 2A (Ωt - Ωt )s s

NOISE

f(t) = A rand()rand() = some evenly distributed random fn

Show, Don’t Tell

Processing Audio

From synthesis

To analysis

Fourier Transform

It’s Complex

Literally.

SIDE VIEW OF f(t)!

thefouriertransform.com

“All waveforms, no matter what you scribble or observe in the universe, are actually just the sum of simple sinusoids of different frequencies.”

Analysis Applications

1. Pitch Detection: Instrument Tuner, Visualization

2. Wave Shaping: Equalizer, Autotune

Let’s see it.

RUBY TIME

ruby-audio$ gem install

libsndfile wrapper

require  'ruby-­‐audio'  include  RubyAudio      sample_rate,  len,  freq,  amp  =  48000,  10,  440,  0.9    buf  =  Buffer.float(sample_rate  *  len)  buf.size.times  do  |i|      sine_rad  =  ((freq  *  Math::PI  *  2)  /  sample_rate)  *  i      buf[i]  =  amp  *  Math.sin(sine_rad)  end      format  =  FORMAT_WAV  |  FORMAT_PCM_16  info  =  SoundInfo.new(channels:  1,  samplerate:  sample_rate,  format:  format)  snd  =  Sound.new('out.wav',  'w',  info)  snd.write(buf)  snd.close

Write a Sine Wave

easy_audio$ gem install

portaudio wrapper

require  'easy_audio'  

EasyAudio.easy_open(&EasyAudio::Waveforms::SINE)  sleep  2  #  play  for  2  seconds

Play a Sine Wave

require  'easy_audio'  

triangle  =  EasyAudio::Waveforms::TRIANGLE  stream  =  EasyAudio.easy_open(freq:  220,  &triangle)  Thread.new  {  loop  {  stream.frequency  +=  50;  sleep  0.2  }  }  sleep  3

Increase Frequency / Time

Audio Plugins

VST

github.com/lsegal/ easy_vst

AudioEffect*  createEffectInstance(audioMasterCallback  audioMaster)  {      ruby_init();      ruby_init_loadpath();      rb_require("drb/drb");      rb_eval_string("DRb.start_service");          return  new  SampleVST(audioMaster);  }      //  ...          server  =  rb_eval_string(          "DRbObject.new_with_uri('druby://localhost:9090')");

Embedding DRb - C++

rb_funcall(      server,                                  //  the  DRb  object      rb_intern(“process”),      //  the  remote  method      1,                                            //  one  argument      INT2FIX(sampleFrames));  //  number  of  samples

Call Distributed Method

Fun Time!

Summary

1. Audio is samples!

2. Making waves!Sine, Square, Saw, Triangle, Noise

3. Fourier = analysis

4. Ruby libraries!ruby-audio

easy_audio easy_vst

5. Music!

💾gnuu.org

github.com/lsegal

@lsegal

Thanks! Questions?

Recommended