1
0
Fork 0

Adding a new modulation Oscillator

This commit is contained in:
Rodrigo Franco 2023-12-06 12:38:35 -03:00
parent fb099110a5
commit 91f3791aa4
1 changed files with 122 additions and 87 deletions

209
jerdehl.c
View File

@ -4,30 +4,41 @@
#include <stdlib.h>
#include <time.h>
float sinetab[2048];
#define SINE_TABLE_SIZE 2048
#define MAX_OSCILLATORS 5
#define MAX_LFO 4
#define CHORD_NOTES 3
#define CHORD_TYPES 6
#define UINT32_MAX_HALF (UINT32_MAX / 2)
#define ZERO_FIVE 0.5
#define ZERO_THREE 0.3
float sinetab[SINE_TABLE_SIZE];
// structs
typedef struct oscillator {
// Oscillator struct
typedef struct {
uint32_t phasor;
uint32_t step;
float value;
float saturation;
} osc_t;
} Oscillator;
typedef struct tape_oscillator {
osc_t wowOsc; // Low-frequency oscillator for wow
osc_t flutterOsc; // Higher-frequency oscillator for flutter
float saturation; // Saturation level
} tape_osc_t;
typedef struct {
Oscillator wowOsc;
Oscillator flutterOsc;
float saturation;
} TapeOscillator;
typedef struct piano_oscillator {
osc_t noteOsc[3]; // Oscillators for the chord notes
int noteDuration; // Duration of the chord
} piano_osc_t;
// Piano Oscillator struct
typedef struct {
Oscillator noteOsc[CHORD_NOTES];
int noteDuration;
} PianoOscillator;
// Frequencies for chords in the key of C (C, Dm, Em, F, G, Am)
float chordFrequencies[6][3] = {
float chordFrequencies[CHORD_TYPES][CHORD_NOTES] = {
{32.70, 41.20, 49.00}, // C major (C, E, G)
{36.71, 43.65, 55.00}, // D minor (D, F, A)
{41.20, 49.00, 61.74}, // E minor (E, G, B)
@ -36,7 +47,7 @@ float chordFrequencies[6][3] = {
{55.00, 65.41, 82.41} // A minor (A, C, E)
};
float higherChordFrequencies[6][3] = {
float higherChordFrequencies[CHORD_TYPES][CHORD_NOTES] = {
{65.41, 82.41, 98.00}, // C major (C, E, G)
{73.42, 87.31, 110.00}, // D minor (D, F, A)
{82.41, 98.00, 123.47}, // E minor (E, G, B)
@ -45,19 +56,20 @@ float higherChordFrequencies[6][3] = {
{110.00, 130.81, 164.81}// A minor (A, C, E)
};
void set_osc_freq(osc_t* o, float f) {
void set_osc_freq(Oscillator* o, float f) {
o->step = (uint32_t) ((f / 16000.0) * UINT32_MAX);
}
// updates
void update_osc(osc_t* o) {
void update_osc(Oscillator* o) {
uint16_t index;
o->phasor += o->step;
index = o->phasor >> (32-11);
o->value = sinetab[index];
}
void update_tape_osc(tape_osc_t* t, osc_t* audioOsc) {
void update_tape_osc(TapeOscillator* t, Oscillator* audioOsc) {
// Update wow and flutter oscillators
update_osc(&t->wowOsc);
update_osc(&t->flutterOsc);
@ -71,7 +83,7 @@ void update_tape_osc(tape_osc_t* t, osc_t* audioOsc) {
}
void update_piano_osc(piano_osc_t* p) {
void update_piano_osc(PianoOscillator* p) {
if (p->noteDuration > 0) {
// Play the current chord
float chordValue = 0;
@ -95,7 +107,7 @@ void update_piano_osc(piano_osc_t* p) {
}
}
void update_higher_piano_osc(piano_osc_t* p) {
void update_higher_piano_osc(PianoOscillator* p) {
if (p->noteDuration > 0) {
// Play the current chord
float chordValue = 0;
@ -119,62 +131,47 @@ void update_higher_piano_osc(piano_osc_t* p) {
}
}
int main() {
FILE *fp;
osc_t oscbank[5];
osc_t lfobank[4];
osc_t lisa[3];
osc_t env;
float freq;
float coldtab[2048];
float oddtab[2048];
float eventab[2048];
uint16_t out16;
float zero_five=0.5;
float zero_three=0.3;
float zero_oh_five=0.25;
float out;//, outA, outB, outC, outD;
fp = fopen("/dev/stdout", "w");
for(int i=0; i<2048; i++) {
coldtab[i] = cos(i*1*M_PI/2048); // is this the cause of the bumps?
eventab[i] = zero_five*cos(i*4*M_PI/2048) + zero_three*cos(i*4*M_PI/2048) + zero_three*cos(i*16*M_PI/2048);
oddtab[i] = zero_five*cos(i*2*M_PI/2048) + zero_three*cos(i*3*M_PI/2048) + zero_three*cos(i*8*M_PI/2048);
sinetab[i] = coldtab[i];
void initialize_tables(float coldtab[], float eventab[], float oddtab[], float sinetab[]) {
for(int i=0; i<SINE_TABLE_SIZE; i++) {
coldtab[i] = cos(i*1*M_PI/SINE_TABLE_SIZE); // is this the cause of the bumps?
eventab[i] = ZERO_FIVE*cos(i*4*M_PI/SINE_TABLE_SIZE) + ZERO_THREE*cos(i*4*M_PI/SINE_TABLE_SIZE) + ZERO_THREE*cos(i*16*M_PI/SINE_TABLE_SIZE);
oddtab[i] = ZERO_FIVE*cos(i*2*M_PI/SINE_TABLE_SIZE) + ZERO_THREE*cos(i*3*M_PI/SINE_TABLE_SIZE) + ZERO_THREE*cos(i*8*M_PI/SINE_TABLE_SIZE);
sinetab[i] = sin(i * 2 * M_PI / SINE_TABLE_SIZE);
}
}
set_osc_freq(&lisa[0], 0.0100);
set_osc_freq(&lisa[1], 0.0550);
set_osc_freq(&lisa[2], 0.746);
lisa[1].phasor = 0.25*UINT32_MAX;
lisa[2].phasor = 0.5*UINT32_MAX;
void initialize_oscillators(Oscillator oscBank[], Oscillator modulationOsc[], Oscillator* envelopeOsc, Oscillator lfoBank[], TapeOscillator tapeOsc, PianoOscillator pianoOsc, PianoOscillator higherPianoOsc) {
// Initialize modulation oscillators (replacing 'lisa')
set_osc_freq(&modulationOsc[0], 0.0100);
set_osc_freq(&modulationOsc[1], 0.0550);
set_osc_freq(&modulationOsc[2], 0.00746);
modulationOsc[1].phasor = 0.25 * UINT32_MAX;
modulationOsc[2].phasor = 0.15 * UINT32_MAX;
set_osc_freq(&lfobank[0], 0.300);
set_osc_freq(&lfobank[1], 0.700);
set_osc_freq(&lfobank[2], 0.800);
set_osc_freq(&lfobank[3], 0.1100);
// Initialize LFOs
set_osc_freq(&lfoBank[0], 0.300);
set_osc_freq(&lfoBank[1], 0.700);
set_osc_freq(&lfoBank[2], 0.800);
set_osc_freq(&lfoBank[3], 0.1100);
set_osc_freq(&oscbank[0], 7469.826/86);
set_osc_freq(&oscbank[1], 1164.814);
set_osc_freq(&oscbank[2], 1195.998);
set_osc_freq(&oscbank[3], 1130.813/2);
// Initialize main oscillator bank
for (int i = 0; i < MAX_OSCILLATORS; i++) {
oscBank[i].phasor = 0; // or some other default value
oscBank[i].step = 0; // or some other default value
oscBank[i].value = 0; // or some other default value
oscBank[i].saturation = 0; // or some other default value
}
set_osc_freq(&env, 1);
env.phasor = 22.3*UINT32_MAX;
srand(time(NULL));
// Initialize envelope oscillator
set_osc_freq(envelopeOsc, 1);
envelopeOsc->phasor = 22.3 * UINT32_MAX_HALF;
// tape oscillator
tape_osc_t tapeOsc;
set_osc_freq(&tapeOsc.wowOsc, 6765464679); // Low frequency for wow
set_osc_freq(&tapeOsc.flutterOsc, 74698268697276); // Higher frequency for flutter
tapeOsc.saturation = 0.4; // Adjust for desired saturation effect
piano_osc_t pianoOsc;
pianoOsc.noteDuration = 0; // Start with silence
piano_osc_t higherPianoOsc; // Higher octave piano oscillator
higherPianoOsc.noteDuration = 0; // Start with silence
// Randomly select the first chord
@ -183,51 +180,89 @@ int main() {
set_osc_freq(&pianoOsc.noteOsc[i], chordFrequencies[chordIndex][i]);
}
// Randomly select the first chord (Higher Piano)
int higherChordIndex = rand() % 6;
for (int i = 0; i < 3; ++i) {
set_osc_freq(&higherPianoOsc.noteOsc[i], higherChordFrequencies[higherChordIndex][i]);
}
}
int main() {
FILE *fp;
Oscillator oscBank[MAX_OSCILLATORS];
Oscillator lfoBank[MAX_LFO];
Oscillator modulationOsc[3];
Oscillator envelopeOsc;
TapeOscillator tapeOsc;
PianoOscillator pianoOsc;
PianoOscillator higherPianoOsc;
float freq;
float coldtab[2048];
float oddtab[2048];
float eventab[2048];
uint16_t out16;
float zero_oh_five=0.25;
float out;//, outA, outB, outC, outD;
fp = fopen("/dev/stdout", "w");
if (!fp) {
perror("Error opening file");
return 1;
}
// Initialization
srand(time(NULL));
initialize_tables(coldtab, eventab, oddtab, sinetab);
initialize_oscillators(oscBank, modulationOsc, &envelopeOsc, lfoBank, tapeOsc, pianoOsc, higherPianoOsc);
while(1) {
update_osc(&lisa[0]);
update_osc(&lisa[1]);
// update_osc(&lisa[2]);
update_osc(&modulationOsc[0]);
update_osc(&modulationOsc[1]);
update_osc(&modulationOsc[2]);
for(int i=0; i<2048; i++) {
sinetab[i] = zero_five * ((zero_five + zero_five * lisa[0].value) * coldtab[i] + (1 - zero_five - zero_five * lisa[0].value) * eventab[i]) +
zero_five * ((zero_five + zero_five * lisa[1].value) * coldtab[i] + (1 - zero_five - zero_five * lisa[1].value) * oddtab[i]);
// zero_five *((zero_five + zero_five * lisa[2].value) * coldtab[i] + (1 - zero_five - zero_five * lisa[2].value) * oddtab[i]);
for(int i=0; i<SINE_TABLE_SIZE; i++) {
sinetab[i] = ZERO_FIVE * ((ZERO_FIVE + ZERO_FIVE * modulationOsc[0].value) * coldtab[i] + (1 - ZERO_FIVE - ZERO_FIVE * modulationOsc[0].value) * eventab[i]) +
ZERO_FIVE * ((ZERO_FIVE + ZERO_FIVE * modulationOsc[1].value) * coldtab[i] + (1 - ZERO_FIVE - ZERO_FIVE * modulationOsc[1].value) * oddtab[i]) +
// THIS IS EXPERIMENTAL
ZERO_FIVE *((ZERO_FIVE + ZERO_FIVE * modulationOsc[2].value) * coldtab[i] + (1 - ZERO_FIVE - ZERO_FIVE * modulationOsc[2].value) * oddtab[i]);
}
for(int i=0; i<4; i++) {
update_osc(&lfobank[i]);
update_osc(&lfoBank[i]);
}
set_osc_freq(&oscbank[0], 22.111 + 0.25*(lfobank[0].value));
set_osc_freq(&oscbank[1], 64.814 - zero_five*(lfobank[1].value));
set_osc_freq(&oscbank[2], 95.998 + zero_three*(lfobank[2].value));
set_osc_freq(&oscbank[3], 30.813/2 - 50*(lfobank[3].value));
set_osc_freq(&oscBank[0], 22.111 + 0.25*(lfoBank[0].value));
set_osc_freq(&oscBank[1], 64.814 - ZERO_FIVE*(lfoBank[1].value));
set_osc_freq(&oscBank[2], 95.998 + ZERO_THREE*(lfoBank[2].value));
set_osc_freq(&oscBank[3], 30.813/2 - 50*(lfoBank[3].value));
for(int i=0; i<5; i++) {
update_osc(&oscbank[i]);
update_tape_osc(&tapeOsc, &oscbank[i]);
update_osc(&oscBank[i]);
update_tape_osc(&tapeOsc, &oscBank[i]);
}
// out = zero_oh_five * randOsc.value / 2 +
out = zero_oh_five * oscbank[0].value +
zero_oh_five * oscbank[1].value +
zero_oh_five * oscbank[2].value +
zero_oh_five * oscbank[3].value * (zero_five + zero_five * env.value);
out = zero_oh_five * oscBank[0].value +
zero_oh_five * oscBank[1].value +
zero_oh_five * oscBank[2].value +
zero_oh_five * oscBank[3].value * envelopeOsc.value;
// piano chord
update_piano_osc(&pianoOsc);
// update_tape_osc(&tapeOsc, &pianoOsc.noteOsc[0]);
out += zero_oh_five * pianoOsc.noteOsc[0].value;
out += 0.5 * pianoOsc.noteOsc[0].value;
update_higher_piano_osc(&higherPianoOsc);
// update_tape_osc(&tapeOsc, &higherPianoOsc.noteOsc[0]);
out += zero_oh_five * higherPianoOsc.noteOsc[0].value;
out += 0.5 * higherPianoOsc.noteOsc[0].value;
// output
out16 = (uint16_t)(UINT16_MAX / 2) * (zero_five + zero_five * out);
out16 = (uint16_t)(UINT16_MAX / 2) * (ZERO_FIVE + ZERO_FIVE * out);
fputc(out16 & 0xFF, fp);
fputc(out16 >> 8, fp);
}
return 1;
return 0;
}