Skip to content

Commit d22e7ff

Browse files
committed
Add minim examples
1 parent 4156867 commit d22e7ff

File tree

11 files changed

+369
-0
lines changed

11 files changed

+369
-0
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# frozen_string_literal: true
2+
3+
require 'picrate'
4+
5+
# ADSRExample is an example of using the ADSR envelope within an instrument.
6+
# For more information about Minim and additional features,
7+
# visit http://code.compartmental.net/minim/
8+
# author: Anderson Mills<br/>
9+
# Anderson Mills's work was supported by numediart (www.numediart.org)
10+
class ADSRExample < Processing::App
11+
load_libraries :minim, :tone_instrument
12+
java_import 'ddf.minim.Minim'
13+
14+
attr_reader :out
15+
16+
def setup
17+
sketch_title 'ADSR Example'
18+
minim = Minim.new(self)
19+
@out = minim.get_line_out(Minim::MONO, 2048)
20+
# pause time when adding a bunch of notes at once
21+
out.pause_notes
22+
# make four repetitions of the same pattern
23+
4.times do |i|
24+
# add some low notes
25+
out.play_note(1.25 + i * 2.0, 0.3, ToneInstrument.new(out, 75, 0.49))
26+
out.play_note(2.50 + i * 2.0, 0.3, ToneInstrument.new(out, 75, 0.49))
27+
28+
# add some middle notes
29+
out.play_note(1.75 + i * 2.0, 0.3, ToneInstrument.new(out, 175, 0.4))
30+
out.play_note(2.75 + i * 2.0, 0.3, ToneInstrument.new(out, 175, 0.4))
31+
32+
# add some high notes
33+
out.play_note(1.25 + i * 2.0, 0.3, ToneInstrument.new(out, 3750, 0.07))
34+
out.play_note(1.5 + i * 2.0, 0.3, ToneInstrument.new(out, 1750, 0.02))
35+
out.play_note(1.75 + i * 2.0, 0.3, ToneInstrument.new(out, 3750, 0.07))
36+
out.play_note(2.0 + i * 2.0, 0.3, ToneInstrument.new(out, 1750, 0.02))
37+
out.play_note(2.25 + i * 2.0, 0.3, ToneInstrument.new(out, 3750, 0.07))
38+
out.play_note(2.5 + i * 2.0, 0.3, ToneInstrument.new(out, 5550, 0.09))
39+
out.play_note(2.75 + i * 2.0, 0.3, ToneInstrument.new(out, 3750, 0.07))
40+
end
41+
# resume time after a bunch of notes are added at once
42+
out.resumeNotes
43+
end
44+
45+
# draw is run many times
46+
def draw
47+
# erase the window to black
48+
background(0)
49+
# draw using a white stroke
50+
stroke(255)
51+
# draw the waveforms
52+
(0...(out.bufferSize - 1)).each do |i|
53+
# find the x position of each buffer value
54+
x1 = map1d(i, 0..out.bufferSize, 0..width)
55+
x2 = map1d(i + 1, 0..out.bufferSize, 0..width)
56+
# draw a line from one buffer position to the next for both channels
57+
line(x1, 50 + out.left.get(i) * 50, x2, 50 + out.left.get(i + 1) * 50)
58+
line(x1, 150 + out.right.get(i) * 50, x2, 150 + out.right.get(i + 1) * 50)
59+
end
60+
end
61+
62+
def settings
63+
size(512, 200, P2D)
64+
end
65+
end
66+
67+
ADSRExample.new
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# frozen_string_literal: true
2+
3+
require 'picrate'
4+
# This sketch demonstrates how to create synthesized sound with Minim
5+
# using an AudioOutput and an Instrument we define. By using the
6+
# playNote method you can schedule notes to played at some point in the
7+
# future, essentially allowing to you create musical scores with code.
8+
# Because they are constructed with code, they can be either
9+
# deterministic or different every time. This sketch creates a
10+
# deterministic score, meaning it is the same every time you run the
11+
# sketch. For more complex examples of using playNote check out
12+
# algorithmicCompExample and compositionExample. For more information
13+
# about Minim and additional features, visit
14+
# http://code.compartmental.net/minim/
15+
class CreateInstrument < Processing::App
16+
load_libraries :minim, :sine_instrument
17+
java_import 'ddf.minim.Minim'
18+
19+
attr_reader :out
20+
21+
def settings
22+
size(512, 200, P2D)
23+
end
24+
25+
def setup
26+
sketch_title 'Create Instrument'
27+
minim = Minim.new(self)
28+
@out = minim.getLineOut
29+
# when providing an Instrument, we always specify start time and duration
30+
out.playNote(0.0, 0.9, SineInstrument.new(97.99))
31+
out.playNote(1.0, 0.9, SineInstrument.new(123.47))
32+
# we can use the Frequency class to create frequencies from pitch names
33+
out.playNote(2.0, 2.9, SineInstrument.new(Frequency.ofPitch('C3').asHz))
34+
out.playNote(3.0, 1.9, SineInstrument.new(Frequency.ofPitch('E3').asHz))
35+
out.playNote(4.0, 0.9, SineInstrument.new(Frequency.ofPitch('G3').asHz))
36+
end
37+
38+
def draw
39+
background(0)
40+
stroke(255)
41+
# draw the waveforms
42+
(out.bufferSize - 1).times do |i|
43+
line(i, 50 + out.left.get(i) * 50, i + 1, 50 + out.left.get(i + 1) * 50)
44+
line(i, 150 + out.right.get(i) * 50, i + 1, 150 + out.right.get(i + 1) * 50)
45+
end
46+
end
47+
end
48+
49+
CreateInstrument.new
5.91 KB
Binary file not shown.
8.03 KB
Binary file not shown.
424 KB
Binary file not shown.
22 KB
Binary file not shown.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# frozen_string_literal: true
2+
3+
java_import 'ddf.minim.Minim'
4+
5+
%w[Frequency Instrument Line Oscil Waves].each do |klass|
6+
java_import "ddf.minim.ugens.#{klass}"
7+
end
8+
9+
# to make an Instrument we must define a class
10+
# that includes Instrument interface (as a module).
11+
class SineInstrument
12+
include Instrument
13+
include Processing::Proxy
14+
15+
attr_reader :wave, :amp_env
16+
17+
def initialize(frequency)
18+
# make a sine wave oscillator
19+
# the amplitude is zero because
20+
# we are going to patch a Line to it anyway
21+
@wave = Oscil.new(frequency, 0, Waves::SINE)
22+
@amp_env = Line.new
23+
amp_env.patch(wave.amplitude)
24+
end
25+
26+
# this is called by the sequencer when this instrument
27+
# should start making sound. the duration is expressed in seconds.
28+
def noteOn(duration)
29+
# start the amplitude envelope
30+
amp_env.activate(duration, 0.5, 0)
31+
# attach the oscil to the output so it makes sound
32+
wave.patch(out)
33+
end
34+
35+
# this is called by the sequencer when the instrument should
36+
# stop making sound
37+
def noteOff
38+
wave.unpatch(out)
39+
end
40+
end
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# frozen_string_literal: true
2+
3+
# java_import 'ddf.minim.Minim'
4+
5+
%w[ADSR Instrument Oscil Waves].each do |klass|
6+
java_import "ddf.minim.ugens.#{klass}"
7+
end
8+
9+
# Every instrument must implement the Instrument interface so
10+
# playNote can call the instrument's methods.
11+
class ToneInstrument
12+
include Instrument
13+
attr_reader :adsr, :out
14+
15+
# constructor for this instrument NB: includes line_out
16+
def initialize(out, frequency, amplitude)
17+
# create new instances of any UGen objects as necessary
18+
sineOsc = Oscil.new(frequency, amplitude, Waves::TRIANGLE)
19+
@adsr = ADSR.new(0.5, 0.01, 0.05, 0.5, 0.5)
20+
@out = out
21+
# patch everything together up to the final output
22+
sineOsc.patch(adsr)
23+
end
24+
25+
# every instrument must have a noteOn method
26+
def noteOn(dur)
27+
# turn on the ADSR
28+
adsr.noteOn
29+
# patch to the output
30+
adsr.patch(out)
31+
end
32+
33+
# every instrument must have a noteOff method
34+
def noteOff
35+
# tell the ADSR to unpatch after the release is finished
36+
adsr.unpatchAfterRelease(out)
37+
# call the noteOff
38+
adsr.noteOff
39+
end
40+
end
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# frozen_string_literal: true
2+
3+
require 'picrate'
4+
# This sketch demonstrates how to use the loop method of a Playable class.
5+
# The class used here is AudioPlayer, but you can also loop an AudioSnippet.
6+
# When you call loop() it will make the Playable playback in an infinite loop.
7+
# If you want to make it stop looping you can call play() and it will finish the
8+
# current loop and then stop. Press 'l' to start the player looping.
9+
class Loop < Processing::App
10+
load_library :minim
11+
java_import 'ddf.minim.Minim'
12+
13+
attr_reader :groove
14+
15+
def settings
16+
size(512, 200, P2D)
17+
end
18+
19+
def setup
20+
minim = Minim.new(self)
21+
@groove = minim.load_file(data_path('groove.mp3'), 2048)
22+
end
23+
24+
def draw
25+
background(0)
26+
stroke(255)
27+
(0...groove.buffer_size - 1).each do |i|
28+
line(i, 50 + groove.left.get(i) * 50, i + 1, 50 + groove.left.get(i + 1) * 50)
29+
line(i, 150 + groove.right.get(i) * 50, i + 1, 150 + groove.right.get(i + 1) * 50)
30+
end
31+
end
32+
33+
def key_pressed
34+
return unless key == 'l'
35+
36+
groove.loop
37+
end
38+
end
39+
40+
Loop.new
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# frozen_string_literal: true
2+
3+
require 'picrate'
4+
5+
# This sketch demonstrates how to play a file with Minim using an
6+
# AudioPlayer. It's also a good example of how to draw the waveform of
7+
# the audio. Full documentation for AudioPlayer can be found at
8+
# http://code.compartmental.net/minim/audioplayer_class_audioplayer.html
9+
# For more information about Minim and additional features,
10+
# visit http://code.compartmental.net/minim/
11+
class Player < Processing::App
12+
load_library :minim
13+
java_import 'ddf.minim.Minim'
14+
15+
PLAYING = 'Press any key to pause playback.'
16+
NOT = 'Press any key to start playback.'
17+
attr_reader :player
18+
19+
def settings
20+
size(512, 200, P2D)
21+
end
22+
23+
def setup
24+
sketch_title 'Playing A File'
25+
minim = Minim.new(self)
26+
@player = minim.load_file(data_path('groove.mp3'))
27+
end
28+
29+
def draw
30+
background(0)
31+
stroke(255)
32+
(0...player.buffer_size - 1).each do |i|
33+
x1 = map1d(i, 0..player.bufferSize, 0..width)
34+
x2 = map1d(i + 1, 0..player.bufferSize, 0..width)
35+
line(
36+
x1,
37+
50 + player.left.get(i) * 50,
38+
x2,
39+
50 + player.left.get(i + 1) * 50
40+
)
41+
line(
42+
x1,
43+
150 + player.right.get(i) * 50,
44+
x2,
45+
150 + player.right.get(i + 1) * 50
46+
)
47+
end
48+
# draws a vertical line where playback is up to
49+
posx = map1d(player.position, 0..player.length, 0..width)
50+
stroke(0, 200, 0)
51+
line(posx, 0, posx, height)
52+
message = player.playing? ? PLAYING : NOT
53+
text(message, 10, 20)
54+
end
55+
56+
def key_pressed
57+
if player.playing?
58+
player.pause
59+
# if finished, rewind and call play again
60+
elsif player.position == player.length
61+
player.rewind
62+
player.play
63+
else
64+
player.play
65+
end
66+
end
67+
end
68+
69+
Player.new

0 commit comments

Comments
 (0)