// Example 5- Amplitude Modulation and Ring Modulation
(
Server.default = s = Server.internal.boot;
s.waitForBoot({
s.scope;
f = FreqScope.new(400, 200, 0);
})
)
// Simple AM instrument as it appears in Dodge's book
// The instrument might clip for high amplitude values
// and modulation index close to 1.0
(
var noteObject, note;
noteObject = CtkSynthDef(\example5a, {arg dur = 1, amp = -6, carfreq = 440,
modfreq = 2, modindex = 0.7;
var car, mod, env;
env = EnvGen.kr(
Env([0.001, 1, 1, 0.001], [dur * 0.1, dur * 0.8, dur * 0.1],
\exp));
amp = amp.dbamp; // convert the value of the amp arg with .dbamp
mod = SinOsc.ar(modfreq, 0, amp * modindex);
car = SinOsc.ar(carfreq, 0, amp + mod);
Out.ar(0, car * env);
});
note = noteObject.new(1.0, 5.0).dur_(5.0);
note.play;
)
// Simple AM instrument with amplitude normalized to 1.0
// to avoid clipping (samples out of range).
// We scale amplitude just before sending the carrier signal
// to the output. The instrument doesn't clip for modulation
// indexes between 0.0 and 1.0
(
var noteObject, note;
noteObject = CtkSynthDef(\example5b, {arg dur = 1, amp = -6, carfreq = 440,
modfreq = 2, modindex = 0.7;
var car, mod, env;
env = EnvGen.kr(
Env([0.001, 1, 1, 0.001], [dur * 0.1, dur * 0.8, dur * 0.1],
\exp));
amp = amp.dbamp; // convert the value of the amp arg with .dbamp
mod = SinOsc.ar(modfreq, 0, amp * modindex);
car = SinOsc.ar(carfreq, 0, (amp + mod) / 2.0 );
Out.ar(0, car * amp * env);
});
note = noteObject.new(1.0, 5.0).dur_(5.0).amp_(-3).carfreq_(440)
.modfreq_(200);
note.play;
)
// Simple Ring Modulation instrument as appears on Dodge's book
// We add the feature of using a harmonic signal as modulator
// instead of a sinusoid. To obtain this harmonic signal, we
// will store a complex waveform in a memory buffer, and read it
// with the Osc UGen.
(
var noteObject, note, score, buffer1, buffer2;
noteObject = CtkSynthDef(\example5c, {arg dur = 1, amp = -6, carfreq = 440,
modfreq = 200, modamp = 0.7, buffer = 1;
var car, mod, env;
env = EnvGen.kr(
Env([0.001, 1, 1, 0.001], [dur * 0.1, dur * 0.8, dur * 0.1],
\exp));
mod = Osc.ar(buffer, modfreq, 0, modamp);
car = SinOsc.ar(carfreq, 0, amp.dbamp);
Out.ar(0, mod * car * env);
});
// first we need to create the waveforms in the memory buffers.
// We will create 2 different buffers.
// This buffer will have 512 frames (or sampled values)
// .. we can fill the buffer with information about individual
// partials using the sine3 method
// here is what the message looks like:
// the command creates a sine wave with a one partial. That partial
// will cycle over the duration of the buffer, with an amplitude of 1,
// and no phase offset.
//one partial - frequency (in relation to buffer length) amp and phase
buffer1 = CtkBuffer.buffer(512).sine3(0.0, 1, 1, 1, 1, 1, 0);
// now we will create a more complex wavetable for buffer 2
// this spectrum will have 6 partials with different amplitudes and
// phase offsets
buffer2 = CtkBuffer.buffer(512).sine3(0.0, 1, 1, 1,
1, 0.75, 0, // partial 1, strength 0.75, phase offset of 0
2, 0.5, 0.5, // partial 2, strength 0.5, phase offset of 0.5
3, 0.25, 0, // partial 3, strength 0.25, phase offset of 0
4, 0.25, 0.0972, // partial 4, strength 0.25, phase offset of 0.0972
5, 0.65, 0, // partial 5, strength 0.65, phase offset of 0
6, 0.06, 0 // partial 6, strength 0.06, phase offset of 0
);
//we create the score add buffer into it
score = CtkScore.new;
score.add(buffer1, buffer2);
//we create a noteObject
score.add(noteObject.new(1.0, 5.0).dur_(5.0).buffer_(buffer1)
.carfreq_(440).modfreq_(200));
score.add(noteObject.new(7.0, 5.0).dur_(5.0).buffer_(buffer2)
.carfreq_(440).modfreq_(200));
//we play the score
score.play;
)
// Same Ring Modulation instrument implemented as signal multiplication
// in this case we modulate two harmonic spectra
(
var noteObject, note, score, buffer;
noteObject = CtkSynthDef(\example5d, {arg dur = 1, amp = -6, carfreq = 440,
modfreq = 200, modamp = 0.7, buffer = 1;
var car, mod, env;
env = EnvGen.kr(
Env([0.001, 1, 1, 0.001], [dur * 0.1, dur * 0.8, dur * 0.1],
\exp));
mod = Osc.ar(buffer, modfreq, 0, modamp);
car = Osc.ar(buffer, carfreq, 0, amp.dbamp);
Out.ar(0, mod * car * env);
});
buffer = CtkBuffer.buffer(512).sine3(0.0, 1, 1, 1,
1, 0.75, 0, // partial 1, strength 0.75, phase offset of 0
2, 0.5, 0.5, // partial 2, strength 0.5, phase offset of 0.5
3, 0.25, 0, // partial 3, strength 0.25, phase offset of 0
4, 0.25, 0.0972, // partial 4, strength 0.25, phase offset of 0.0972
5, 0.65, 0, // partial 5, strength 0.65, phase offset of 0
6, 0.06, 0 // partial 6, strength 0.06, phase offset of 0
);
//we create the score add buffer into it
score = CtkScore.new;
score.add(buffer);
//we create a noteObject
score.add(noteObject.new(1.0, 5.0).dur_(5.0).buffer_(buffer)
.carfreq_(440).modfreq_(140.06));
//we play the score
score.play;
)