The fire of Jerdehl burns.
This commit is contained in:
parent
44643fe4ad
commit
96393f6db0
107
jerdehl.c
107
jerdehl.c
|
@ -32,8 +32,8 @@ typedef struct noise_oscillator
|
|||
|
||||
double generate_noise(noise_osc_t *n)
|
||||
{
|
||||
// A simple pseudo-random noise generator
|
||||
n->seed = (n->seed * 1103515245 + 12345) & 0x7fffffff;
|
||||
// A simple pseudo-random noise generator
|
||||
n->seed = (n->seed * 1235515245 + 12345) & 0x7ffaffff;
|
||||
return (double)n->seed / 0x40000000 - 1.0; // Normalize to range -1.0 to 1.0
|
||||
}
|
||||
|
||||
|
@ -42,36 +42,33 @@ void init_noise_osc(noise_osc_t *n, uint32_t seed)
|
|||
n->seed = seed;
|
||||
}
|
||||
|
||||
|
||||
double update_crackle(noise_osc_t *n)
|
||||
{
|
||||
// Generate the base noise
|
||||
double noise = generate_noise(n);
|
||||
// Apply random volume modulation to simulate the crackling effect
|
||||
double volume = 0 + ((double)rand() / RAND_MAX) * 0.5; // Random volume between 0.2 and 1.0
|
||||
double volume = 0 + ((double)rand() / RAND_MAX) * 0.2; // Random volume between 0.2 and 1.0
|
||||
// Occasionally spike the volume to simulate louder crackles
|
||||
if ((rand() % 100) < 40) // 10% chance for a louder crackle
|
||||
if ((rand() % 100) < 20) // 20% chance for a louder crackle
|
||||
{
|
||||
volume += 0.5; // Increase volume for a louder crackle
|
||||
volume += 15.0; // Increase volume for a louder crackle
|
||||
}
|
||||
// Clamp the volume to avoid clipping
|
||||
volume = (volume > 1.0) ? 1.0 : volume;
|
||||
// volume = (volume > 1.0) ? 1.0 : volume;
|
||||
// Apply the volume to the noise
|
||||
noise *= volume;
|
||||
// Clamp the noise to avoid clipping
|
||||
return noise;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float chordFrequencies[CHORD_TYPES][CHORD_NOTES] = {
|
||||
{65.41, 77.78, 98.00}, // Cm (C, Eb, G)
|
||||
{73.42, 87.31, 97.99}, // Ddim (D, F, Ab)
|
||||
{82.41, 97.99, 123.47}, // Eb (Eb, G, Bb)
|
||||
{87.31, 103.83, 130.81},// Fm (F, Ab, C)
|
||||
{97.99, 116.54, 146.83},// Gm (G, Bb, D)
|
||||
{103.83, 123.47, 155.56},// Ab (Ab, C, Eb)
|
||||
{116.54, 130.81, 155.56},// Bb (Bb, D, F)
|
||||
{65.41, 77.78, 98.00}, // Cm (C, Eb, G)
|
||||
{73.42, 87.31, 97.99}, // Ddim (D, F, Ab)
|
||||
{82.41, 97.99, 123.47}, // Eb (Eb, G, Bb)
|
||||
{87.31, 103.83, 130.81}, // Fm (F, Ab, C)
|
||||
{97.99, 116.54, 146.83}, // Gm (G, Bb, D)
|
||||
{103.83, 123.47, 155.56}, // Ab (Ab, C, Eb)
|
||||
{116.54, 130.81, 155.56}, // Bb (Bb, D, F)
|
||||
};
|
||||
float higherChordFrequencies[CHORD_TYPES][CHORD_NOTES] = {
|
||||
{130.81, 155.56, 196.00}, // Cm (C4, Eb4, G4)
|
||||
|
@ -85,7 +82,7 @@ float higherChordFrequencies[CHORD_TYPES][CHORD_NOTES] = {
|
|||
|
||||
void set_osc_freq(osc_t *o, float f)
|
||||
{
|
||||
o->step = (uint32_t)((f / 16000.0) * UINT32_MAX);
|
||||
o->step = (uint32_t)((f / 16000) * UINT32_MAX);
|
||||
o->phasor = 0; // Reset the phasor to start at the beginning of the sine wave
|
||||
}
|
||||
|
||||
|
@ -94,35 +91,46 @@ void update_osc(osc_t *o)
|
|||
uint16_t index;
|
||||
o->phasor += o->step;
|
||||
index = o->phasor >> (32 - 11); // We are using an 11-bit index for a 2048-entry table
|
||||
o->value = sinetab[index];
|
||||
o->value = sinetab[index] > 0 ? 1.0 : -1.0;
|
||||
}
|
||||
|
||||
void update_piano_osc(PianoOscillator *p, float chordFrequencies[CHORD_TYPES][CHORD_NOTES], int notePlayChance) {
|
||||
if (p->noteDuration > 0) {
|
||||
void update_piano_osc(PianoOscillator *p, float chordFrequencies[CHORD_TYPES][CHORD_NOTES], int notePlayChance)
|
||||
{
|
||||
if (p->noteDuration > 0)
|
||||
{
|
||||
// Continue playing the current chord
|
||||
double fadeOutFactor = 1.0;
|
||||
double fadeOutFactor = 1;
|
||||
int twoThirdsDuration = (2 * p->noteDuration / 3);
|
||||
if (p->noteDuration <= twoThirdsDuration) {
|
||||
if (p->noteDuration <= twoThirdsDuration)
|
||||
{
|
||||
// Calculate fade-out factor
|
||||
fadeOutFactor = (double)p->noteDuration / twoThirdsDuration;
|
||||
}
|
||||
// Update the value for each oscillator in the chord with fade-out
|
||||
for (int i = 0; i < CHORD_NOTES; ++i) {
|
||||
for (int i = 0; i < CHORD_NOTES; ++i)
|
||||
{
|
||||
update_osc(&p->noteOsc[i]);
|
||||
p->noteOsc[i].value *= fadeOutFactor; // Apply fade-out factor
|
||||
}
|
||||
p->noteDuration--; // Decrement the note duration
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// Random chance to play a new chord or not play anything (silence)
|
||||
if (rand() % notePlayChance == 0) {
|
||||
if (rand() % notePlayChance == 0)
|
||||
{
|
||||
int chordIndex = rand() % CHORD_TYPES;
|
||||
for (int i = 0; i < CHORD_NOTES; ++i) {
|
||||
for (int i = 0; i < CHORD_NOTES; ++i)
|
||||
{
|
||||
set_osc_freq(&p->noteOsc[i], chordFrequencies[chordIndex][i]);
|
||||
}
|
||||
p->noteDuration = (rand() % 10 + 1) * 16000; // Set a new random note duration
|
||||
} else {
|
||||
p->noteDuration = (rand() % 20 + 1) * 16000; // Set a new random note duration
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set all oscillator values to zero to represent silence
|
||||
for (int i = 0; i < CHORD_NOTES; ++i) {
|
||||
for (int i = 0; i < CHORD_NOTES; ++i)
|
||||
{
|
||||
p->noteOsc[i].value = 0.0f;
|
||||
}
|
||||
}
|
||||
|
@ -130,6 +138,8 @@ void update_piano_osc(PianoOscillator *p, float chordFrequencies[CHORD_TYPES][CH
|
|||
}
|
||||
int main()
|
||||
{
|
||||
|
||||
int c, d;
|
||||
FILE *fp;
|
||||
PianoOscillator pianoOsc;
|
||||
PianoOscillator highPianoOsc;
|
||||
|
@ -146,15 +156,16 @@ int main()
|
|||
|
||||
srand(time(NULL));
|
||||
|
||||
for (int i = 0; i < SINE_TABLE_SIZE; i++)
|
||||
for (int i = 0; i < SINE_TABLE_SIZE / 2; i++)
|
||||
{
|
||||
sinetab[i] = sin(i * 2 * M_PI / SINE_TABLE_SIZE);
|
||||
sinetab[i] = 1.0;
|
||||
sinetab[i + SINE_TABLE_SIZE / 2] = -1.0;
|
||||
}
|
||||
|
||||
// Initialize the first chord and duration for piano and high piano
|
||||
int chordIndex = rand() % CHORD_TYPES;
|
||||
update_piano_osc(&pianoOsc, chordFrequencies, 10); // Start with a random duration
|
||||
update_piano_osc(&highPianoOsc, higherChordFrequencies, 8); // Start with a random duration
|
||||
update_piano_osc(&pianoOsc, chordFrequencies, 60); // Start with a random duration
|
||||
update_piano_osc(&highPianoOsc, higherChordFrequencies, 25); // Start with a random duration
|
||||
// Set the frequencies for the first chord
|
||||
for (int i = 0; i < CHORD_NOTES; ++i)
|
||||
{
|
||||
|
@ -165,8 +176,13 @@ int main()
|
|||
noise_osc_t fireCrackleOsc;
|
||||
init_noise_osc(&fireCrackleOsc, time(NULL));
|
||||
|
||||
int j = 20000000;
|
||||
while (1)
|
||||
{
|
||||
if (j == 0) {
|
||||
j = 20000000;
|
||||
}
|
||||
|
||||
out = 0.0f; // Reset output each iteration
|
||||
|
||||
// Update the piano and high piano oscillators
|
||||
|
@ -176,15 +192,31 @@ int main()
|
|||
update_piano_osc(&highPianoOsc, higherChordFrequencies, 2); // 2 for a 1 in 2 chance of silence
|
||||
|
||||
// Mix the outputs from all oscillators
|
||||
|
||||
for (int i = 0; i < CHORD_NOTES; ++i)
|
||||
{
|
||||
out += pianoOsc.noteOsc[i].value + (highPianoOsc.noteOsc[i].value * -1.0f);
|
||||
|
||||
if (j % 179 == 0)
|
||||
{
|
||||
out += pianoOsc.noteOsc[i].value + (highPianoOsc.noteOsc[i].value * -0.5f);
|
||||
}
|
||||
else if (j % 150 == 0)
|
||||
{
|
||||
out += pianoOsc.noteOsc[i].value;
|
||||
}
|
||||
else
|
||||
{
|
||||
out += (highPianoOsc.noteOsc[i].value * -0.6f);
|
||||
}
|
||||
}
|
||||
out /= (2 * CHORD_NOTES); // Correctly average the mixed notes, considering both piano and high piano
|
||||
|
||||
// Fire crackling noise
|
||||
double crackle = update_crackle(&fireCrackleOsc);
|
||||
out += crackle * 0.1f;
|
||||
if (j % 2000 == 0)
|
||||
{
|
||||
double crackle = update_crackle(&fireCrackleOsc);
|
||||
out += crackle * 1.0f;
|
||||
}
|
||||
|
||||
// Increase the gain to make the signal louder
|
||||
float gain = 0.5f; // Adjust the gain factor as needed
|
||||
|
@ -197,11 +229,12 @@ int main()
|
|||
out = -1.0f;
|
||||
|
||||
// Scale to 16-bit output value
|
||||
out16 = (uint16_t)((UINT16_MAX / 2) * (0.5 + 0.5 * out));
|
||||
out16 = (uint16_t)((UINT16_MAX / 2) * (0.6 + 1.0 * out));
|
||||
|
||||
// Write output value for stereo channels
|
||||
fwrite(&out16, sizeof(out16), 1, fp);
|
||||
fwrite(&out16, sizeof(out16), 1, fp);
|
||||
j--;
|
||||
}
|
||||
fclose(fp);
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue