Hacking session
This commit is contained in:
parent
3189d421d6
commit
36dd52ceed
148
jerdehl.c
148
jerdehl.c
|
@ -11,6 +11,7 @@ typedef struct oscillator {
|
|||
uint32_t phasor;
|
||||
uint32_t step;
|
||||
float value;
|
||||
float saturation;
|
||||
} osc_t;
|
||||
|
||||
typedef struct tape_oscillator {
|
||||
|
@ -19,11 +20,30 @@ typedef struct tape_oscillator {
|
|||
float saturation; // Saturation level
|
||||
} tape_osc_t;
|
||||
|
||||
typedef struct cicada_oscillator {
|
||||
osc_t modOsc; // Modulator for cicada effect
|
||||
float modDepth; // Depth of modulation
|
||||
float saturation; // Saturation level
|
||||
} cicada_osc_t;
|
||||
|
||||
typedef struct piano_oscillator {
|
||||
osc_t noteOsc[3]; // Oscillators for the chord notes
|
||||
int noteDuration; // Duration of the chord
|
||||
} piano_osc_t;
|
||||
|
||||
// Frequencies for chords in the key of C (C, Dm, Em, F, G, Am)
|
||||
float chordFrequencies[6][3] = {
|
||||
{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)
|
||||
};
|
||||
|
||||
float higherChordFrequencies[6][3] = {
|
||||
{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)
|
||||
{87.31, 110.00, 130.81},// F major (F, A, C)
|
||||
{98.00, 123.47, 146.83},// G major (G, B, D)
|
||||
{110.00, 130.81, 164.81}// A minor (A, C, E)
|
||||
};
|
||||
|
||||
void set_osc_freq(osc_t* o, float f) {
|
||||
o->step = (uint32_t) ((f / 16000.0) * UINT32_MAX);
|
||||
|
@ -37,13 +57,6 @@ void update_osc(osc_t* o) {
|
|||
o->value = sinetab[index];
|
||||
}
|
||||
|
||||
void update_rand_osc(osc_t* o) {
|
||||
uint16_t index;
|
||||
o->phasor += o->step + (((rand() % 100) * (2 + (rand() % 5))) * 100); // Size of the wave
|
||||
index = o->phasor >> (32-10);
|
||||
o->value = sinetab[index] * ((rand() % 100) / 85.0 - 1); // Randomness in amplitude
|
||||
}
|
||||
|
||||
void update_tape_osc(tape_osc_t* t, osc_t* audioOsc) {
|
||||
// Update wow and flutter oscillators
|
||||
update_osc(&t->wowOsc);
|
||||
|
@ -57,26 +70,51 @@ void update_tape_osc(tape_osc_t* t, osc_t* audioOsc) {
|
|||
audioOsc->value = tanh(t->saturation * audioOsc->value);
|
||||
}
|
||||
|
||||
void update_cicada_osc(cicada_osc_t* c, osc_t* o, int* timer) {
|
||||
if (*timer > 0) {
|
||||
// Cicada sound is active
|
||||
c->saturation=0.5;
|
||||
update_osc(&c->modOsc); // Update the modulator
|
||||
|
||||
// Modulate frequency and amplitude
|
||||
float modFactor = 1.0 + c->modDepth * c->modOsc.value;
|
||||
o->step = (uint32_t) (((o->step / UINT32_MAX * 16000.0) * modFactor / 16000.0) * UINT32_MAX);
|
||||
o->value *= modFactor;
|
||||
o->value = tanh(c->saturation * o->value);
|
||||
|
||||
(*timer)--;
|
||||
|
||||
void update_piano_osc(piano_osc_t* 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 {
|
||||
c->saturation=0;
|
||||
o->value = tanh(c->saturation * o->value);
|
||||
// Cicada sound is inactive, check if it should start
|
||||
if ((rand() % 8000000) < 5) {
|
||||
*timer = rand() % (16000 * 100);
|
||||
// Check if it's time to play a new chord
|
||||
if (rand() % 100 < 10) { // Very low 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]);
|
||||
}
|
||||
p->noteDuration = 16000 * 20; // Chord duration
|
||||
} else {
|
||||
p->noteOsc[0].value = 0; // Silence
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void update_higher_piano_osc(piano_osc_t* 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 / 3; // Average the chord notes
|
||||
p->noteDuration--;
|
||||
} else {
|
||||
// Check if it's time to play a new chord
|
||||
if (rand() % 10000 < 10) { // Very low chance to start a new chord
|
||||
int chordIndex = rand() % 6;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
set_osc_freq(&p->noteOsc[i], higherChordFrequencies[chordIndex][i]);
|
||||
}
|
||||
p->noteDuration = 16000 * 20; // Chord duration
|
||||
} else {
|
||||
p->noteOsc[0].value = 0; // Silence
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -87,7 +125,6 @@ int main() {
|
|||
osc_t lfobank[4];
|
||||
osc_t lisa[3];
|
||||
osc_t env;
|
||||
osc_t randOsc;
|
||||
float freq;
|
||||
float coldtab[2048];
|
||||
float oddtab[2048];
|
||||
|
@ -124,24 +161,27 @@ int main() {
|
|||
set_osc_freq(&oscbank[3], 1130.813/2);
|
||||
|
||||
set_osc_freq(&env, 1);
|
||||
// env.phasor = 22.3*UINT32_MAX;
|
||||
env.phasor = 22.3*UINT32_MAX;
|
||||
|
||||
set_osc_freq(&randOsc, -0.2);
|
||||
randOsc.phasor = 1;
|
||||
srand(time(NULL));
|
||||
|
||||
// tape osc
|
||||
// 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
|
||||
|
||||
// cicada osc
|
||||
cicada_osc_t cicadaOsc;
|
||||
set_osc_freq(&cicadaOsc.modOsc, 20.0); // Fast modulation for cicada effect
|
||||
cicadaOsc.modDepth = 0.5; // Modulation depth
|
||||
cicadaOsc.saturation = 0.0;
|
||||
int cicadaTimer = 0; // Timer for cicada oscillator
|
||||
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
|
||||
int chordIndex = rand() % 6;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
set_osc_freq(&pianoOsc.noteOsc[i], chordFrequencies[chordIndex][i]);
|
||||
}
|
||||
|
||||
while(1) {
|
||||
update_osc(&lisa[0]);
|
||||
|
@ -151,7 +191,7 @@ int main() {
|
|||
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]);
|
||||
// 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<4; i++) {
|
||||
|
@ -165,19 +205,25 @@ int main() {
|
|||
|
||||
for(int i=0; i<5; i++) {
|
||||
update_osc(&oscbank[i]);
|
||||
update_rand_osc(&randOsc);
|
||||
update_tape_osc(&tapeOsc, &oscbank[i]);
|
||||
}
|
||||
|
||||
update_cicada_osc(&cicadaOsc, &randOsc, &cicadaTimer);
|
||||
update_tape_osc(&tapeOsc, &randOsc);
|
||||
// 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*randOsc.value/2 +
|
||||
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 * randOsc.value;
|
||||
// piano chord
|
||||
update_piano_osc(&pianoOsc);
|
||||
// update_tape_osc(&tapeOsc, &pianoOsc.noteOsc[0]);
|
||||
out += zero_oh_five * pianoOsc.noteOsc[0].value;
|
||||
|
||||
update_higher_piano_osc(&higherPianoOsc);
|
||||
// update_tape_osc(&tapeOsc, &higherPianoOsc.noteOsc[0]);
|
||||
out += zero_oh_five * higherPianoOsc.noteOsc[0].value;
|
||||
|
||||
// output
|
||||
out16 = (uint16_t)(UINT16_MAX / 2) * (zero_five + zero_five * out);
|
||||
fputc(out16 & 0xFF, fp);
|
||||
fputc(out16 >> 8, fp);
|
||||
|
|
Loading…
Reference in New Issue