Skip to content

Commit

Permalink
minim examples
Browse files Browse the repository at this point in the history
  • Loading branch information
monkstone committed Dec 20, 2019
1 parent a914ff1 commit c8043d7
Show file tree
Hide file tree
Showing 21 changed files with 525 additions and 77 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# JRubyArt-examples for JRubyArt-1.7.0+
# JRubyArt-examples for JRubyArt-2.2.0+
Replaces `AppRender` with `GfxRender`, and removal of bashisms in autorun Rakefiles

Description
Expand Down
2 changes: 1 addition & 1 deletion external_library/gem/geomerative/hello_world.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def setup
background(255)
fill(255, 102, 0)
stroke(0)
@grp = RG.getText('Hola Mundo!', data_path('FreeSans.ttf'), 72, CENTER)
@grp = RG.get_text('Hola Mundo!', data_path('FreeSans.ttf'), 72, CENTER)
end

def draw
Expand Down
62 changes: 62 additions & 0 deletions external_library/java/minim/adsr_example.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# frozen_string_literal: true

# ADSRExample is an example of using the ADSR envelope within an instrument.
# For more information about Minim and additional features,
# visit http://code.compartmental.net/minim/
# author: Anderson Mills<br/>
# Anderson Mills's work was supported by numediart (www.numediart.org)

load_libraries :minim, :tone_instrument
java_import 'ddf.minim.Minim'

attr_reader :out

def setup
sketch_title 'ADSR Example'
minim = Minim.new(self)
@out = minim.get_line_out(Minim::MONO, 2048)
# pause time when adding a bunch of notes at once
out.pause_notes
# make four repetitions of the same pattern
4.times do |i|
# add some low notes
out.play_note(1.25 + i * 2.0, 0.3, ToneInstrument.new(out, 75, 0.49))
out.play_note(2.50 + i * 2.0, 0.3, ToneInstrument.new(out, 75, 0.49))

# add some middle notes
out.play_note(1.75 + i * 2.0, 0.3, ToneInstrument.new(out, 175, 0.4))
out.play_note(2.75 + i * 2.0, 0.3, ToneInstrument.new(out, 175, 0.4))

# add some high notes
out.play_note(1.25 + i * 2.0, 0.3, ToneInstrument.new(out, 3750, 0.07))
out.play_note(1.5 + i * 2.0, 0.3, ToneInstrument.new(out, 1750, 0.02))
out.play_note(1.75 + i * 2.0, 0.3, ToneInstrument.new(out, 3750, 0.07))
out.play_note(2.0 + i * 2.0, 0.3, ToneInstrument.new(out, 1750, 0.02))
out.play_note(2.25 + i * 2.0, 0.3, ToneInstrument.new(out, 3750, 0.07))
out.play_note(2.5 + i * 2.0, 0.3, ToneInstrument.new(out, 5550, 0.09))
out.play_note(2.75 + i * 2.0, 0.3, ToneInstrument.new(out, 3750, 0.07))
end
# resume time after a bunch of notes are added at once
out.resumeNotes
end

# draw is run many times
def draw
# erase the window to black
background(0)
# draw using a white stroke
stroke(255)
# draw the waveforms
(0...(out.bufferSize - 1)).each do |i|
# find the x position of each buffer value
x1 = map1d(i, 0..out.bufferSize, 0..width)
x2 = map1d(i + 1, 0..out.bufferSize, 0..width)
# draw a line from one buffer position to the next for both channels
line(x1, 50 + out.left.get(i) * 50, x2, 50 + out.left.get(i + 1) * 50)
line(x1, 150 + out.right.get(i) * 50, x2, 150 + out.right.get(i + 1) * 50)
end
end

def settings
size(512, 200, P2D)
end
45 changes: 45 additions & 0 deletions external_library/java/minim/create_instrument.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# frozen_string_literal: true

# This sketch demonstrates how to create synthesized sound with Minim
# using an AudioOutput and an Instrument we define. By using the
# playNote method you can schedule notes to played at some point in the
# future, essentially allowing to you create musical scores with code.
# Because they are constructed with code, they can be either
# deterministic or different every time. This sketch creates a
# deterministic score, meaning it is the same every time you run the
# sketch. For more complex examples of using playNote check out
# algorithmicCompExample and compositionExample. For more information
# about Minim and additional features, visit
# http://code.compartmental.net/minim/

load_libraries :minim, :sine_instrument
java_import 'ddf.minim.Minim'

attr_reader :out

def settings
size(512, 200, P2D)
end

def setup
sketch_title 'Create Instrument'
minim = Minim.new(self)
@out = minim.getLineOut
# when providing an Instrument, we always specify start time and duration
out.playNote(0.0, 0.9, SineInstrument.new(out, 97.99))
out.playNote(1.0, 0.9, SineInstrument.new(out, 123.47))
# we can use the Frequency class to create frequencies from pitch names
out.playNote(2.0, 2.9, SineInstrument.new(out, Frequency.ofPitch('C3').asHz))
out.playNote(3.0, 1.9, SineInstrument.new(out, Frequency.ofPitch('E3').asHz))
out.playNote(4.0, 0.9, SineInstrument.new(out, Frequency.ofPitch('G3').asHz))
end

def draw
background(0)
stroke(255)
# draw the waveforms
(out.bufferSize - 1).times do |i|
line(i, 50 + out.left.get(i) * 50, i + 1, 50 + out.left.get(i + 1) * 50)
line(i, 150 + out.right.get(i) * 50, i + 1, 150 + out.right.get(i + 1) * 50)
end
end
Binary file added external_library/java/minim/data/BD.mp3
Binary file not shown.
Binary file added external_library/java/minim/data/BD.wav
Binary file not shown.
Binary file added external_library/java/minim/data/CHH.wav
Binary file not shown.
Binary file added external_library/java/minim/data/SD.wav
Binary file not shown.
Binary file added external_library/java/minim/data/groove.mp3
Binary file not shown.
Binary file added external_library/java/minim/data/serif.vlw
Binary file not shown.
64 changes: 64 additions & 0 deletions external_library/java/minim/drum_machine.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# frozen_string_literal: true

# This sketch is a more involved use of AudioSamples to create a simple drum machine.
# Click on the buttons to toggle them on and off. The buttons that are on will trigger
# samples when the beat marker passes over their column. You can change the tempo by
# clicking in the BPM box and dragging the mouse up and down.
# We achieve the timing by using AudioOutput's playNote method and a cleverly written Instrument.
# For more information about Minim and additional features,
# visit http://code.compartmental.net/minim/

load_libraries :minim, :tick
java_import 'ddf.minim.Minim'
java_import 'ddf.minim.ugens.Sampler'
attr_reader :minim, :out, :kick, :snare, :hat, :bpm, :buttons
attr_reader :kikRow, :snrRow, :hatRow
attr_accessor :beat
def setup
sketch_title 'Drum Machine'
minim = Minim.new(self)
@out = minim.getLineOut
@hatRow = Array.new(16, false)
@snrRow = Array.new(16, false)
@kikRow = Array.new(16, false)
@buttons = []
@bpm = 120
@beat = 0
# load all of our samples, using 4 voices for each.
# this will help ensure we have enough voices to handle even
# very fast tempos.
@kick = Sampler.new(data_path('BD.wav'), 4, minim)
@snare = Sampler.new(data_path('SD.wav'), 4, minim)
@hat = Sampler.new(data_path('CHH.wav'), 4, minim)
# patch samplers to the output
kick.patch(out)
snare.patch(out)
hat.patch(out)
16.times do |i|
buttons << Rect.new(10 + i * 24, 50, hatRow, i)
buttons << Rect.new(10 + i * 24, 100, snrRow, i)
buttons << Rect.new(10 + i * 24, 150, kikRow, i)
end
# start the sequencer
out.setTempo(bpm)
out.playNote(0, 0.25, Tick.new)
end

def draw
background(0)
fill(255)
# text(frameRate, width - 60, 20)
buttons.each(&:draw)
stroke(128)
(beat % 4).zero? ? fill(200, 0, 0) : fill(0, 200, 0)
# beat marker
rect(10 + beat * 24, 35, 14, 9)
end

def mouse_pressed
buttons.each(&:mouse_pressed)
end

def settings
size(395, 200)
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# frozen_string_literal: true

%w[Frequency Instrument Line Oscil Waves].each do |klass|
java_import "ddf.minim.ugens.#{klass}"
end

# to make an Instrument we must define a class
# that includes Instrument interface (as a module).
class SineInstrument
include Instrument

attr_reader :wave, :amp_env, :out, :tone_instrument

def initialize(out, frequency)
# make a sine wave oscillator
# the amplitude is zero because
# we are going to patch a Line to it anyway
@out = out
@wave = Oscil.new(frequency, 0, Waves::SINE)
@amp_env = Line.new
amp_env.patch(wave.amplitude)
end

# this is called by the sequencer when this instrument
# should start making sound. the duration is expressed in seconds.
def noteOn(duration)
# start the amplitude envelope
amp_env.activate(duration, 0.5, 0)
# attach the oscil to the output so it makes sound
wave.patch(out)
end

# this is called by the sequencer when the instrument should
# stop making sound
def noteOff
wave.unpatch(out)
end
end
27 changes: 27 additions & 0 deletions external_library/java/minim/library/tick/lib/rect.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true

# simple class for drawing the gui
class Rect
include Processing::Proxy
attr_reader :x, :y, :w, :h, :steps, :stepId

def initialize(_x, _y, _steps, _id)
@x = _x
@y = _y
@w = 14
@h = 30
@steps = _steps
@stepId = _id
end

def draw
steps[stepId] ? fill(0, 255, 0) : fill(255, 0, 0)
rect(x, y, w, h)
end

def mouse_pressed
if mouse_x >= x && mouse_x <= x + w && mouse_y >= y && mouse_y <= y + h
steps[stepId] = !steps[stepId]
end
end
end
24 changes: 24 additions & 0 deletions external_library/java/minim/library/tick/lib/tick.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# frozen_string_literal: true

java_import 'ddf.minim.ugens.Instrument'
# class Tick can access app variables by including Processing::App module
# But we must use instance variable to set the beat
class Tick
include Instrument
include Processing::Proxy

def noteOn(_dur)
hat.trigger if hatRow[beat]
snare.trigger if snrRow[beat]
kick.trigger if kikRow[beat]
end

def noteOff
# next beat
Processing.app.beat = (beat + 1) % 16
# set the new tempo
out.setTempo(bpm)
# play this again right now, with a sixteenth note duration
out.playNote(0, 0.25, self)
end
end
2 changes: 2 additions & 0 deletions external_library/java/minim/library/tick/tick.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
require_relative 'lib/tick'
require_relative 'lib/rect'
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# frozen_string_literal: true

# java_import 'ddf.minim.Minim'

%w[ADSR Instrument Oscil Waves].each do |klass|
java_import "ddf.minim.ugens.#{klass}"
end

# Every instrument must implement the Instrument interface so
# playNote can call the instrument's methods.
class ToneInstrument
include Instrument
attr_reader :adsr, :out

# constructor for this instrument NB: includes line_out
def initialize(out, frequency, amplitude)
# create new instances of any UGen objects as necessary
sineOsc = Oscil.new(frequency, amplitude, Waves::TRIANGLE)
@adsr = ADSR.new(0.5, 0.01, 0.05, 0.5, 0.5)
@out = out
# patch everything together up to the final output
sineOsc.patch(adsr)
end

# every instrument must have a noteOn method
def noteOn(dur)
# turn on the ADSR
adsr.noteOn
# patch to the output
adsr.patch(out)
end

# every instrument must have a noteOff method
def noteOff
# tell the ADSR to unpatch after the release is finished
adsr.unpatchAfterRelease(out)
# call the noteOff
adsr.noteOff
end
end
37 changes: 37 additions & 0 deletions external_library/java/minim/loop.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# frozen_string_literal: true

# This sketch demonstrates how to use the loop method of a Playable class.
# The class used here is AudioPlayer, but you can also loop an AudioSnippet.
# When you call loop() it will make the Playable playback in an infinite loop.
# If you want to make it stop looping you can call play() and it will finish the
# current loop and then stop. Press 'l' to start the player looping.

load_library :minim
java_import 'ddf.minim.Minim'

attr_reader :groove

def settings
size(512, 200, P2D)
end

def setup
sketch_title "Press \'l\' key to loop"
minim = Minim.new(self)
@groove = minim.load_file(data_path('groove.mp3'), 2048)
end

def draw
background(0)
stroke(255)
(0...groove.buffer_size - 1).each do |i|
line(i, 50 + groove.left.get(i) * 50, i + 1, 50 + groove.left.get(i + 1) * 50)
line(i, 150 + groove.right.get(i) * 50, i + 1, 150 + groove.right.get(i + 1) * 50)
end
end

def key_pressed
return unless key == 'l'

groove.loop
end
Loading

0 comments on commit c8043d7

Please sign in to comment.