Skip to content

Commit

Permalink
added OscOS and ShaperOS help
Browse files Browse the repository at this point in the history
  • Loading branch information
Samuel Pluta committed Jan 17, 2024
1 parent 95ef18b commit e6d53e4
Show file tree
Hide file tree
Showing 3 changed files with 212 additions and 2 deletions.
129 changes: 129 additions & 0 deletions OversamplingOscillators/HelpSource/OscOS.schelp
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
TITLE:: OscOS
summary:: Oversampled Wavetable Oscillator
categories:: Undocumented classes, UGens>Undocumented
related:: BuchlaFoldOS, ShaperOS

DESCRIPTION::
An oversampled wavetable oscillator that interpolates between adjacent tables.


CLASSMETHODS::

METHOD:: ar
audio rate

ARGUMENT:: bufnum
The buffer of the wavetable. This ugen always uses a single buffer, but it can interpolated between adjacent tables that reside in a single buffer.

OscSC uses standard buffers, not specially formatted Wavetable buffers like Osc and VOsc.

ARGUMENT:: phase
Values between 0-1. OscOS does not have its own internal clock. Instead it relies on a phasor lookup.

ARGUMENT:: bufdivs
The number of separate wavetables in the provided buffer.

ARGUMENT:: bufloc
Values between 0-1. Points the current wavetable. Values between wavetables will result in a linearly interpolated output between wavetables.

ARGUMENT:: oversample
OverSampling Index

0 = none, 1 = 2x, 2 = 4x, 3 = 8x, 4 = 16x

ARGUMENT:: mul
amplitude multiplier

ARGUMENT:: add
value added to the signal



INSTANCEMETHODS::


EXAMPLES::

code::
//fill a buffer with 4 different waveforms
(
t = Signal.sineFill(512, [1], [0]);
u = Signal.sineFill(512, 1.0/(1..56));
w = Signal.sineFill(512, 1.0/(1..56)*([1,0]!28).flatten);
x = Signal.sineFill(512, 1.0/((1..56)**2)*([1,0,-1,0]!14).flatten);
v = t.addAll(u).addAll(w).addAll(x);

b = Buffer.loadCollection(s, v);
)

//plot the buffer if you like
b.plot;

(
{
var phase = Phasor.ar(0,100/SampleRate.ir);
var osc = OscOS.ar(b,phase,4,MouseX.kr,4,0.1);
osc
}.scope
)

//LFSaw also works
(
{
var phase = [Phasor.ar(0,100/SampleRate.ir),LFSaw.ar(100,1).range(0,1)];
var osc = OscOS.ar(b,phase,4,MouseX.kr,4,0.1);
osc
}.scope
)

//using a phase input allows for fun wavetable warping
(
{
var phase = LFSaw.ar(100,1);
var osc;
var midpoint = MouseY.kr(0.1,0.9);
phase = Select.ar(phase>0,[
phase.bilin(midpoint.neg,-1,0,-0.5,-1,0),
phase.bilin(midpoint,0,1,0.5,0,1)
])*0.5+0.5;
osc = OscOS.ar(b,phase,4,MouseX.kr,4,0.1);
osc.dup
}.scope
)

(
{
var phase = LFSaw.ar(100,1);
var osc;
var midpoint = MouseY.kr(0.1,0.9);
phase = Select.ar(phase>0,[
phase.bilin(midpoint.neg,-1,0,(1-midpoint).neg,-1,0),
phase.bilin(midpoint,0,1,1-midpoint,0,1)
])*0.5+0.5;
osc = OscOS.ar(b,phase,4,MouseX.kr,4,0.1);
osc.dup
}.scope
)

//LFSaw works best for frequency modulation
(
{
var fm = SinOsc.ar(100,-0.1,MouseY.kr(0,5000));
var phase = LFSaw.ar(50+fm).range(0,1);
var osc = OscOS.ar(b,phase,4,MouseX.kr,4, 0.1);
osc.dup
}.scope
)

//you can also load samples from commercial wavetable oscillators
c = Buffer.read(s, "/Users/spluta1/Music/Vital/Glorkglunk/Wavetables/Granular Upgrade.wav")

(
{
var phase = LFSaw.ar(53.midicps/4).range(0,1);
var osc = OscOS.ar(c,phase,108,MouseX.kr.poll);
osc.dup
}.scope
)

::
67 changes: 67 additions & 0 deletions OversamplingOscillators/HelpSource/ShaperOS.schelp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
class:: ShaperOS
summary:: Wave shaper.
related:: Classes/Index, Classes/WrapIndex, Classes/Wavetable
categories:: UGens>Shaper, BuchlaFoldOS, SergeFoldOS, OscOS

Description::
Performs waveshaping on the input signal by indexing into the table. This

classmethods::
method::ar, kr

argument::bufnum
The number of a buffer containing the transfer function. This differs from Shaper in that ShaperOS takes standard buffers, not wavetable format buffers.

argument::in
The input signal.

argument::oversample
OverSampling Index

0 = none, 1 = 2x, 2 = 4x, 3 = 8x, 4 = 16x

Examples::
code::
s.boot;

//fill a buffer with a Lockhardt wavefolder shaped function
(

e = Env.new([-1,0.66,-0.66,0.66,-0.66,0.66,-0.66,0.66,-0.66,1],[150,100,100,100,100,100,100,100,150]);
e = e.asSignal(5000);

//low pass filter the env
~last = -1;
f = e.collect{|item,i|
var coef = 0.97;
item = (1-coef.abs*item)+(~last*coef); ~last = item;
item
};
f = e.reverse.collect{|item,i|
var coef = 0.97;
item = (1-coef.abs*item)+(~last*coef); ~last = item;
item
}.reverse;
[e,f].plot;
b = Buffer.loadCollection(s, f.as(Signal));
)

(
//read into the table
{
var amp = MouseX.kr(0,8);//.bilin(0.5, 0, 1, 0.9, 0, 2).poll;
c = SinOsc.ar(MouseY.kr(20,300), 0, amp).tanh;
d = ShaperOS.ar(
b,
c,
2,
1
);

((d*2).tanh*0.1).dup

}.scope(bufsize:1600);
)
::


18 changes: 16 additions & 2 deletions OversamplingWavefolders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -380,15 +380,29 @@ namespace OscOS {
float phase1 = sc_clip(phase, 0.f, 1.0f);
float buf_loc1 = sc_clip(buf_loc, 0.f, 1.0f);

float phase_diff = (phase1 - m_last_phase)/oversample.getOversamplingRatio();
float loc_diff = (buf_loc1 - m_last_buf_loc)/oversample.getOversamplingRatio();
float phase_diff = (phase1 - m_last_phase);
float loc_diff = (buf_loc1 - m_last_buf_loc);


//Print("m_last_phase: %f, phase1: %f, phase_diff: %f, m_last_buf_loc: %f, buf_loc1: %f, loc_diff: %f\n", m_last_phase, phase1, phase_diff, m_last_buf_loc, buf_loc1, loc_diff);
//m_last_phase+(k*phase_diff)

//the phase_diff should not be more than 0.5 except when the phase crosses from 1 to 0 or vice versa
//even at the nyquist frequency, the phase_diff should not be more than 0.5
if(abs(phase_diff) > 0.5f)
for (int k = 0; k < oversample.getOversamplingRatio(); k++){
osBuffer[k] = Perform(table0, phase1, buf_divs, buf_loc1, table_size, fmaxindex);
}
else {
phase_diff = phase_diff/oversample.getOversamplingRatio();
for (int k = 0; k < oversample.getOversamplingRatio(); k++){
osBuffer[k] = Perform(table0, m_last_phase+(k*phase_diff), buf_divs, m_last_buf_loc+(k*loc_diff), table_size, fmaxindex);
}
}


m_last_phase = phase1;
m_last_buf_loc = buf_loc1;

if (m_oversamplingIndex != 0)
out = oversample.downsample();
Expand Down

0 comments on commit e6d53e4

Please sign in to comment.