Skip to content

Commit

Permalink
Dev wavetable (#11)
Browse files Browse the repository at this point in the history
* Added: Wavetable Oscillator (WAVE)
  • Loading branch information
thomassidor authored Nov 4, 2019
1 parent 9ca7680 commit f560adb
Show file tree
Hide file tree
Showing 14 changed files with 4,873 additions and 3,400 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Currently the following are included:
* Simplex Noise (SN1)
* Simplex Noise x8 (SN8)
* Simplex Oscillator (SN-OSC)
* Wavetable Oscillator (WAVE)

Feel free to join the project, copy source code or panel designs.

Expand All @@ -36,6 +37,9 @@ All the best, Thomas René Sidor


## Changelog
Version 1.4.0
* Added: Wavetable Oscillator (WAVE)

Version 1.3.0
* Added: Simplex Oscillator (SN-OSC)
* Fixed: Sync out of simple and plus oscillators only giving 1v
Expand Down
6,748 changes: 3,661 additions & 3,087 deletions Rack Panels.ai

Large diffs are not rendered by default.

11 changes: 10 additions & 1 deletion plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"slug": "TinyTricks",
"name": "Tiny Tricks",
"brand": "Tiny Tricks",
"version": "1.3.0",
"version": "1.4.0",
"license": "MIT",
"author": "Thomas René Sidor",
"authorEmail": "[email protected]",
Expand Down Expand Up @@ -200,5 +200,14 @@
"oscillator"
]
}
,
{
"slug": "WAVE",
"name": "Wavetable Oscillator",
"description": "A wavetable oscillator where you can record your own waves.",
"tags": [
"oscillator"
]
}
]
}
227 changes: 227 additions & 0 deletions res/panels/WAVE.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
128 changes: 128 additions & 0 deletions src/oscillators/wavetable.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
struct WaveTableOscillator{

static const int WAVEFORM_COUNT = 3;
static const int MAX_SAMPLE_COUNT = 2048;
int TABLE_END = MAX_SAMPLE_COUNT;
float lookuptables[WAVEFORM_COUNT][MAX_SAMPLE_COUNT] = {0};

float currentIndex = 0.f;
float tableDelta = 0.f;

bool isStepEOC = false;

bool mirror = false;
bool reverse = false;

float prevPitch = 90000.f;

float phase = 0.f;
float freq = 0.f;

WaveTableOscillator(){

}

void step(){
isStepEOC = false;

if(mirror){
if(!reverse){
currentIndex += tableDelta;
if (currentIndex >= TABLE_END/2.f)
reverse = true;
}
else{
currentIndex -= tableDelta;
if(currentIndex < 0.f){
reverse = false;
currentIndex = 0.f;
isStepEOC = true;
}
}
}
else{
currentIndex += tableDelta;
if (currentIndex >= TABLE_END){
currentIndex -= TABLE_END;
isStepEOC = true;
}
}
}

bool isEOC(){
return isStepEOC;
}

float getSample(float y){

//Getting indexes for current place in table
int index0 = (int) currentIndex;
int index1 = index0 == (TABLE_END - 1) ? (int) 0 : index0 + 1;

// How far are we from the index
float indexFrac = currentIndex - (float) index0;

//Getting indexes for the levels based on y
float frac = y * (WAVEFORM_COUNT-1);
int level0 = floor(frac);
int level1 = ceil(frac);
float levelFrac = frac - (float) level0;

//Getting the four samples in the table
float Level0Value0 = lookuptables[level0][index0];
float Level0Value1 = lookuptables[level0][index1];

float Level1Value0 = lookuptables[level1][index0];
float Level1Value1 = lookuptables[level1][index1];

//Interpolating between the two
float interpolatedValueForLevel0 = Level0Value0 + indexFrac * (Level0Value1 - Level0Value0);
float interpolatedValueForLevel1 = Level1Value0 + indexFrac * (Level1Value1 - Level1Value0);

float finalValue = interpolatedValueForLevel0 + levelFrac * (interpolatedValueForLevel1 - interpolatedValueForLevel0);

return finalValue;
}

void addSampleToFrame(float sampleValue, float y){
lookuptables[yToLevel(y)][(int)currentIndex] = sampleValue;
}

unsigned int yToLevel(float y){
return floor(y*(WAVEFORM_COUNT-1));
}

void endFrame(){
currentIndex = currentIndex + 1;
}

void startCapture(){
reset();
}

void endCapture(){
TABLE_END = currentIndex;
reset();
}

void setPitch(float pitch, float sampleRate){
if(pitch != prevPitch){
float frequency = dsp::FREQ_C4 * powf(2.0f, pitch);
auto tableSizeOverSampleRate = TABLE_END / sampleRate;
tableDelta = frequency * tableSizeOverSampleRate;
prevPitch = pitch;
}
}

void setMirror(bool _mirror){
mirror = _mirror;
reset();
}


void reset(){
currentIndex = 0.f;
}


};
2 changes: 1 addition & 1 deletion src/plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ void init(Plugin *p) {
p->addModel(modelRX8);
p->addModel(modelSN1);
p->addModel(modelSN8);
//p->addModel(modelSNWAVE);
p->addModel(modelSNOSC);
p->addModel(modelWAVE);



Expand Down
2 changes: 1 addition & 1 deletion src/plugin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@ extern Model *modelTTTRIPLUS;
extern Model *modelRX8;
extern Model *modelSN1;
extern Model *modelSN8;
//extern Model *modelSNWAVE;
extern Model *modelSNOSC;
extern Model *modelWAVE;
23 changes: 14 additions & 9 deletions src/simplex-oscillator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const float SCALE_MIN = 0.5f;
const float DETAIL_MIN = 1.f;
const float DETAIL_MAX = 8.f;

struct SNOSC : Module, ScopedModule {
struct SNOSC : Module {
enum ParamIds {
SCALE_PARAM,
DETAIL_PARAM,
Expand Down Expand Up @@ -40,6 +40,8 @@ struct SNOSC : Module, ScopedModule {
};


MiniScope* scope;

SimplexOscillator oscillator;
float prevPitch = 900000.f; //Crude fix for making sure that oscillators oscillate upon module init
dsp::SchmittTrigger syncTrigger;
Expand Down Expand Up @@ -141,7 +143,7 @@ struct SNOSC : Module, ScopedModule {
oscillator.reset();
forwardSyncReset = true;
if(voltage >= 11.f){
resetScope();
scope->reset();
ticksSinceScopeReset = 0;
}
}
Expand All @@ -157,7 +159,7 @@ struct SNOSC : Module, ScopedModule {
//Setting output
outputs[OSC_OUTPUT].setVoltage(value);
//Updating scope
addFrameToScope(args.sampleRate, value);
scope->addFrame(value);


//TODO: Clean up this logic. It's not pretty.
Expand All @@ -172,7 +174,7 @@ struct SNOSC : Module, ScopedModule {
// Normally we'll reset the scope on EOC,
// but not if sync is connected - unless it's been too long since last sync
if(!inputs[SYNC_INPUT].isConnected() || ticksSinceScopeReset > SimplexOscillator::BUFFER_LENGTH)
resetScope();
scope->reset();
}
else{
outputs[SYNC_OUTPUT].setVoltage(0.f);
Expand All @@ -188,11 +190,14 @@ struct SNOSCWidget : ModuleWidget {
setModule(module);
setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/panels/SNOSC.svg")));

MiniScope *scope = new MiniScope();
scope->module = module;
scope->box.pos = mm2px(Vec(1.571f, 6.0f));
scope->box.size = mm2px(Vec(27.337f, 14.366f));
addChild(scope);
if(module){
MiniScope *scope = new MiniScope();
scope->box.pos = mm2px(Vec(3.571f, 9.0f));
scope->box.size = mm2px(Vec(23.337f, 8.366f));
scope->setGain(1.0f);
addChild(scope);
module->scope = scope;
}

//Screws
addChild(createWidget<ScrewSilver>(Vec(0, 0)));
Expand Down
Loading

0 comments on commit f560adb

Please sign in to comment.