1
0
Fork 0

Simplified version of jerdehl.c

This commit is contained in:
Rodrigo Franco 2023-12-10 12:07:26 -03:00
parent dee799484f
commit ab15cf0d5a
1 changed files with 63 additions and 99 deletions

162
jerdehl.c
View File

@ -10,6 +10,7 @@
#define UINT32_MAX_HALF (UINT32_MAX / 2)
#define CHORD_NOTES 3
#define CHORD_TYPES 6
#define GUITAR_HARMONICS 6
float sinetab[SINE_TABLE_SIZE];
@ -20,7 +21,6 @@ float clamp(float value, float min, float max) {
return value;
}
typedef struct oscillator {
uint32_t phasor;
uint32_t step;
@ -39,6 +39,16 @@ typedef struct {
int noteDuration;
} PianoOscillator;
// Frequencies for chords in the key of C (C, Dm, Em, F, G, Am)
float lowerChordFrequencies[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)
{43.65, 55.00, 65.41}, // F major (F, A, C)
{49.00, 61.74, 73.42}, // G major (G, B, D)
{55.00, 65.41, 82.41} // A minor (A, C, E)
};
// Frequencies for chords in the key of C (C, Dm, Em, F, G, Am)
float chordFrequencies[CHORD_TYPES][CHORD_NOTES] = {
{32.70, 41.20, 49.00}, // C major (C, E, G)
@ -58,6 +68,7 @@ float higherChordFrequencies[CHORD_TYPES][CHORD_NOTES] = {
{110.00, 130.81, 164.81}// A minor (A, C, E)
};
void update_osc(osc_t* o) {
uint16_t index;
o->phasor += o->step;
@ -69,20 +80,30 @@ void set_osc_freq(osc_t* o, float f) {
o->step = (uint32_t) ((f / 16000.0) * UINT32_MAX);
}
void update_tape_osc(TapeOscillator* t, osc_t* audioOsc) {
// Update wow and flutter oscillators
update_osc(&t->wowOsc);
update_osc(&t->flutterOsc);
// Apply wow and flutter as pitch modulation
float pitchMod = 1.0 + 0.002 * t->wowOsc.value + 0.0005 * t->flutterOsc.value;
set_osc_freq(audioOsc, audioOsc->step * pitchMod);
// Apply saturation (simple non-linear function)
audioOsc->value = tanh(t->saturation * audioOsc->value);
void update_lower_piano_osc(PianoOscillator* p) {
if (p->noteDuration > 0) {
// Play the current chord
float chordValue = 0;
for (int i = 0; i < 3; ++i) {
update_osc(&p->noteOsc[i]);
chordValue += p->noteOsc[i].value;
}
p->noteOsc[0].value = chordValue / 5; // Average the chord notes
p->noteDuration--;
} else {
// Check if it's time to play a new chord
if (rand() % 100 < 10) { // chance to start a new chord
int chordIndex = rand() % 6;
for (int i = 0; i < 3; ++i) {
set_osc_freq(&p->noteOsc[i], lowerChordFrequencies[chordIndex][i]);
}
p->noteDuration = 16000 * 300; // Chord duration
} else {
p->noteOsc[0].value = 0; // Silence
}
}
}
void update_piano_osc(PianoOscillator* p) {
if (p->noteDuration > 0) {
// Play the current chord
@ -95,7 +116,7 @@ void update_piano_osc(PianoOscillator* p) {
p->noteDuration--;
} else {
// Check if it's time to play a new chord
if (rand() % 100 < 10) { // Very low chance to start a new chord
if (rand() % 1000 < 10) { // chance to start a new chord
int chordIndex = rand() % 6;
for (int i = 0; i < 3; ++i) {
set_osc_freq(&p->noteOsc[i], chordFrequencies[chordIndex][i]);
@ -134,122 +155,65 @@ void update_higher_piano_osc(PianoOscillator* p) {
int main() {
FILE *fp;
osc_t oscbank[5];
osc_t lfobank[4];
osc_t lisa[2];
TapeOscillator tapeOsc;
PianoOscillator pianoOsc;
PianoOscillator higherPianoOsc;
PianoOscillator lowerPianoOsc;
PianoOscillator pianoOsc;
PianoOscillator higherPianoOsc;
osc_t env;
float freq;
float coldtab[2048];
float oddtab[2048];
float eventab[2048];
uint16_t out16;
float out;//, outA, outB, outC, outD;
float out;
fp = fopen("/dev/stdout", "w");
// Initialization
srand(time(NULL));
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);
sinetab[i] = cos(i * 2 * M_PI / SINE_TABLE_SIZE);
}
set_osc_freq(&lisa[0], 0.0100);
set_osc_freq(&lisa[1], 0.0746);
lisa[0].phasor = 0.25 * UINT32_MAX;
lisa[1].phasor = 0.15 * UINT32_MAX;
// 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(&lisa[0], 0.0015);
set_osc_freq(&lisa[1], 0.0025);
lisa[1].phasor = 0.25*UINT32_MAX;
set_osc_freq(&lfobank[0], 0.010);
set_osc_freq(&lfobank[1], 0.050);
set_osc_freq(&lfobank[2], 0.030);
set_osc_freq(&lfobank[3], 0.070);
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 envelope oscillator
set_osc_freq(&env, 1);
env.phasor = 22.3 * UINT32_MAX_HALF;
// tape oscillator
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
lowerPianoOsc.noteDuration = 0; // Start with silence
pianoOsc.noteDuration = 0; // Start with silence
higherPianoOsc.noteDuration = 0; // Start with silence
// Randomly select the first chord
int chordIndex = rand() % 6;
// Lower Piano -- Randomly select the first chord
int chordIndex2 = rand() % 15;
for (int i = 0; i < 3; ++i) {
set_osc_freq(&pianoOsc.noteOsc[i], chordFrequencies[chordIndex][i]);
set_osc_freq(&pianoOsc.noteOsc[i], lowerChordFrequencies[chordIndex2][i]);
}
// Randomly select the first chord (Higher Piano)
int higherChordIndex = rand() % 6;
// Piano -- Randomly select the first chord
int chordIndex3 = rand() % 15;
for (int i = 0; i < 3; ++i) {
set_osc_freq(&pianoOsc.noteOsc[i], chordFrequencies[chordIndex3][i]);
}
// Piano -- Randomly select the first chord (Higher Piano)
int higherChordIndex = rand() % 15;
for (int i = 0; i < 3; ++i) {
set_osc_freq(&higherPianoOsc.noteOsc[i], higherChordFrequencies[higherChordIndex][i]);
}
while(1) {
update_osc(&lisa[0]);
update_osc(&lisa[1]);
for(int i=0; i<2048; i++) {
sinetab[i] = 0.5*((0.5+0.5*lisa[0].value)*coldtab[i] + (1 - 0.5 - 0.5*lisa[0].value)*eventab[i]) +
0.5*((0.5+0.5*lisa[1].value)*coldtab[i] + (1 - 0.5 - 0.5*lisa[1].value)*oddtab[i]);
}
for(int i=0; i<4; i++) {
update_osc(&lfobank[i]);
update_tape_osc(&tapeOsc, &oscbank[i]);
}
set_osc_freq(&oscbank[0], 130.813 + 0.1*(lfobank[0].value));
set_osc_freq(&oscbank[1], 164.814 - 0.5*(lfobank[1].value));
set_osc_freq(&oscbank[2], 195.998 + 0.3*(lfobank[2].value));
set_osc_freq(&oscbank[3], 130.813/2 - 5*(lfobank[3].value));
for(int i=0; i<5; i++) {
update_osc(&oscbank[i]);
}
out = 0.25*oscbank[0].value +
0.25*oscbank[1].value +
0.25*oscbank[2].value +
0.25*oscbank[3].value*(0.5 + 0.5*env.value);
// piano chord
update_lower_piano_osc(&lowerPianoOsc);
// update_tape_osc(&tapeOsc, &pianoOsc.noteOsc[0]);
out += 0.2 * lowerPianoOsc.noteOsc[0].value;
// piano chord
update_piano_osc(&pianoOsc);
update_tape_osc(&tapeOsc, &pianoOsc.noteOsc[0]);
// update_tape_osc(&tapeOsc, &pianoOsc.noteOsc[0]);
out += 0.5 * pianoOsc.noteOsc[0].value;
update_higher_piano_osc(&higherPianoOsc);
update_tape_osc(&tapeOsc, &higherPianoOsc.noteOsc[0]);
out += 0.5 * higherPianoOsc.noteOsc[0].value;
// update_tape_osc(&tapeOsc, &higherPianoOsc.noteOsc[0]);
out += 0.3 * higherPianoOsc.noteOsc[0].value;
out = clamp(out, -1.0f, 1.0f);
out = clamp(out, -1.0f, 0.1f);
out16 = (uint16_t) (UINT16_MAX/2)*(0.5 + 0.5*out);
out16 = (uint16_t) (UINT16_MAX/2)*(0.3 + 0.3*out);
fputc(out16 & 0xFF, fp);
fputc(out16 >> 8, fp);
}
return 1;
return 0;
}