diff --git a/jerdehl.c b/jerdehl.c index d75e973..b3d9afe 100644 --- a/jerdehl.c +++ b/jerdehl.c @@ -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> 8, fp); } - return 1; + return 0; } \ No newline at end of file