Parallel Oscillators
This tutorial provides an example of how waveforms,
other than sine waves, can be tuned to musically (rather than timbrally)
interesting ratios. Techniques shown here are useful for people
interested in exploring intervallic relationships.
View /
Download source - Instrument source code
View /
Download source - Composition source code
Instrument class overview
import jm.audio.Instrument; import jm.audio.io.*; import jm.audio.synth.*; import jm.music.data.Note; import jm.audio.AudioObject;
public final class PulseFifthsInst extends Instrument{ private EnvPoint[] pointArray = new EnvPoint[10]; private int sampleRate;
public PulseFifthsInst(int sampleRate){ this.sampleRate = sampleRate; EnvPoint[] tempArray = { new EnvPoint((float)0.0, (float)0.0), new EnvPoint((float)0.02, (float)1.0), new EnvPoint((float)0.15, (float)0.6), new EnvPoint((float)0.9, (float)0.4), new EnvPoint((float)1.0, (float)0.0) }; pointArray = tempArray; }
public void createChain(){ Oscillator wt = new Oscillator(this, Oscillator.PULSE_WAVE, this.sampleRate, 2); wt.setPulseWidth(0.15); StereoPan span = new StereoPan(wt, (float)0.2); Oscillator wt2 = new Oscillator(this, Oscillator.PULSE_WAVE, this.sampleRate, 2); wt2.setPulseWidth(0.15); wt2.setFrqRatio((float)(3.0/2.0)); StereoPan span2 = new StereoPan(wt2, (float)0.8); AudioObject[] waves = {span, span2}; Add add = new Add(waves); Envelope env = new Envelope(add, pointArray); Volume vol = new Volume(env); SampleOut sout = new SampleOut(vol); } }
|
The creatChain method holds the interesting stuff.
Here we are setting up two pulse wave oscillators.
A pulse wave consists of two parts: a flat
(negative) part and a raised (positive) part - the pulse. The
frequency of the pulse wave increases as the pulses become closer
together. The method setPulseWidth sets the width of the raised area
(the pulse). If the pulse width is set to 0.5 (50%), a square wave is
created.
The first oscillator is "normal" in that it has the
default frequency. It produces the tonic.
The second oscillator has the same frequency, but a
different frequency ratio: 3/2 (1.5)
Q: Why not just make the frequency 1.5 times the
first one?
A: Adjusting the frequency ratio is an easy method for people
interested in intervalic relationships. As well as this, it is easy for
the frequency to be readjusted while maintaining the same ratio.
Here is a table that has the various ratios for the
pythagorean tuning system. Try them out and see what you get!
Interval |
Ratio |
Derivation |
|
Unison |
1:1 |
Unison 1:1 |
Minor Second |
256:243 |
Octave - M7 |
Major Second |
9:8 |
(3:2)^2 |
Minor Third |
32:27 |
Octave - M6 |
Major Third |
81:64 |
(3:2)^4 |
Fourth |
4:3 |
Octave - 5 |
Augmented Fourth |
729:512 |
(3:2)^6 |
Fifth |
3:2 |
(3:2)^1 |
Minor Sixth |
128:81 |
Octave - M3 |
Major Sixth |
27:16 |
(3:2)^3 |
Minor Seventh |
16:9 |
Octave - M2 |
Major Seventh |
243:128 |
(3:2)^5 |
Octave |
2:1 |
Octave 2: |
|
Below is the code that generates the music used in
the example. Usual stuff like adding the Note to the Phrase to the Part
to the Score. The Instrument that was created above (PulseFifthInst) is
used (
new PulseFifthInst(sampleRate); ) to play the score ( Write.au(score,
"PulseFifthsTest.au", inst); )
Musical Example
import jm.JMC; import jm.music.data.*; import jm.audio.*; import jm.util.*; public final class PulseFifthsTest implements JMC{ public static void main(String[] args){ Score score = new Score("JMDemo - Audio test"); Part part = new Part("wave", 0); Phrase phr = new Phrase(0.0); for(int i = 0; i < 65; i++ ) { Note note = new Note((int)(Math.random() * 18) + 60, 0.25, (int)(Math.random() * 75) + 50); phr.addNote(note); } part.addPhrase(phr); score.addPart(part); int sampleRate = 44100; Instrument inst = new PulseFifthsInst(sampleRate); Write.au(score, "PulseFifthsTest.au", inst); View.au("PulseFifthsTest.au"); } }
|
|