Changed frequencies and added noise
This commit is contained in:
parent
565d718049
commit
44643fe4ad
222
jerdehl.c
222
jerdehl.c
|
@ -5,19 +5,17 @@
|
|||
#include <time.h>
|
||||
|
||||
#define SINE_TABLE_SIZE 2048
|
||||
#define ZERO_FIVE 0.5
|
||||
#define ZERO_THREE 0.3
|
||||
#define UINT32_MAX_HALF (UINT32_MAX / 2)
|
||||
#define CHORD_NOTES 3
|
||||
#define CHORD_TYPES 21
|
||||
#define CHORD_TYPES 7
|
||||
|
||||
float sinetab[SINE_TABLE_SIZE];
|
||||
double sinetab[SINE_TABLE_SIZE];
|
||||
|
||||
typedef struct oscillator
|
||||
{
|
||||
uint32_t phasor;
|
||||
uint32_t step;
|
||||
float value;
|
||||
double value;
|
||||
} osc_t;
|
||||
|
||||
typedef struct
|
||||
|
@ -26,54 +24,70 @@ typedef struct
|
|||
int noteDuration;
|
||||
} PianoOscillator;
|
||||
|
||||
// Frequencies for chords in the key of C (C, Dm, Em, F, G, Am)
|
||||
typedef struct noise_oscillator
|
||||
{
|
||||
uint32_t seed;
|
||||
double value;
|
||||
} noise_osc_t;
|
||||
|
||||
double generate_noise(noise_osc_t *n)
|
||||
{
|
||||
// A simple pseudo-random noise generator
|
||||
n->seed = (n->seed * 1103515245 + 12345) & 0x7fffffff;
|
||||
return (double)n->seed / 0x40000000 - 1.0; // Normalize to range -1.0 to 1.0
|
||||
}
|
||||
|
||||
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
|
||||
// Occasionally spike the volume to simulate louder crackles
|
||||
if ((rand() % 100) < 40) // 10% chance for a louder crackle
|
||||
{
|
||||
volume += 0.5; // Increase volume for a louder crackle
|
||||
}
|
||||
// Clamp the volume to avoid clipping
|
||||
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)
|
||||
{87.31, 98.00, 116.54}, // Fm7 (F, G, Bb)
|
||||
{73.42, 87.31, 110.00}, // Ddim (D, F, A)
|
||||
{61.74, 77.78, 92.50}, // G7 (G, B, F)
|
||||
{58.27, 73.42, 87.31}, // BbMaj (Bb, D, F)
|
||||
{65.41, 82.41, 103.83}, // Cm/Ab (Ab, C, Eb)
|
||||
{73.42, 92.50, 116.54}, // D7 (D, F#, A, C)
|
||||
{65.41, 77.78, 98.00}, // Cm (C, Eb, G) repeat
|
||||
{58.27, 73.42, 87.31}, // BbMaj (Bb, D, F) repeat
|
||||
{61.74, 77.78, 92.50}, // G7 (G, B, F) repeat
|
||||
{77.78, 98.00, 123.47}, // EbMaj (Eb, G, Bb)
|
||||
{82.41, 103.83, 130.81}, // AbMaj (Ab, C, Eb)
|
||||
{87.31, 110.00, 130.81}, // FMaj7 (F, A, C, E)
|
||||
{98.00, 123.47, 146.83}, // GMaj (G, B, D)
|
||||
{103.83, 130.81, 155.56}, // AbMaj7 (Ab, C, Eb, G)
|
||||
{110.00, 130.81, 164.81}, // AMaj7 (A, C#, E, G#)
|
||||
{116.54, 146.83, 174.61}, // BbMaj (Bb, D, F)
|
||||
{123.47, 155.56, 185.00}, // EbMaj7 (Eb, G, Bb, D)
|
||||
{130.81, 164.81, 195.00}, // FMaj (F, A, C)
|
||||
{146.83, 174.61, 220.00}, // GMaj7 (G, B, D, F#)
|
||||
{65.41, 77.78, 98.00} // Cm (C, Eb, G)
|
||||
{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)
|
||||
{146.83, 174.61, 195.99}, // Ddim (D4, F4, Ab4)
|
||||
{164.81, 195.99, 246.94}, // Eb (Eb4, G4, Bb4)
|
||||
{174.61, 207.65, 261.63}, // Fm (F4, Ab4, C5)
|
||||
{195.99, 233.08, 293.66}, // Gm (G4, Bb4, D5)
|
||||
{207.65, 246.94, 311.13}, // Ab (Ab4, C5, Eb5)
|
||||
{233.08, 261.63, 311.13}, // Bb (Bb4, D5, F5)
|
||||
};
|
||||
|
||||
float higherChordFrequencies[CHORD_TYPES][CHORD_NOTES] = {
|
||||
{130.82 * 2, 155.56 * 2, 196.00 * 2}, // Cm (C6, Eb6, G6)
|
||||
{174.62 * 2, 196.00 * 2, 233.08 * 2}, // Fm7 (F6, G6, Bb6)
|
||||
{146.84 * 2, 174.62 * 2, 220.00 * 2}, // Ddim (D6, F6, A6)
|
||||
{123.48 * 2, 155.56 * 2, 185.00 * 2}, // G7 (G6, B6, F6)
|
||||
{116.54 * 2, 146.84 * 2, 174.62 * 2}, // BbMaj (Bb6, D6, F6)
|
||||
{130.82 * 2, 164.82 * 2, 207.66 * 2}, // Cm/Ab (Ab6, C6, Eb6)
|
||||
{146.84 * 2, 185.00 * 2, 233.08 * 2}, // D7 (D6, F#6, A6, C6)
|
||||
{130.82 * 2, 155.56 * 2, 196.00 * 2}, // Cm (C6, Eb6, G6) repeat
|
||||
{116.54 * 2, 146.84 * 2, 174.62 * 2}, // BbMaj (Bb6, D6, F6) repeat
|
||||
{123.48 * 2, 155.56 * 2, 185.00 * 2}, // G7 (G6, B6, F6) repeat
|
||||
{155.56 * 2, 196.00 * 2, 246.94 * 2}, // EbMaj (Eb6, G6, Bb6)
|
||||
{164.82 * 2, 207.66 * 2, 261.62 * 2}, // AbMaj (Ab6, C6, Eb6)
|
||||
{174.62 * 2, 220.00 * 2, 261.62 * 2}, // FMaj7 (F6, A6, C6, E6)
|
||||
{196.00 * 2, 246.94 * 2, 293.66 * 2}, // GMaj (G6, B6, D6)
|
||||
{207.66 * 2, 261.62 * 2, 311.12 * 2}, // AbMaj7 (Ab6, C6, Eb6, G6)
|
||||
{220.00 * 2, 261.62 * 2, 329.62 * 2}, // AMaj7 (A6, C#6, E6, G#6)
|
||||
{233.08 * 2, 293.66 * 2, 349.22 * 2}, // BbMaj (Bb6, D6, F6)
|
||||
{246.94 * 2, 311.12 * 2, 369.99 * 2}, // EbMaj7 (Eb6, G6, Bb6, D6)
|
||||
{261.62 * 2, 329.62 * 2, 391.99 * 2}, // FMaj (F6, A6, C6)
|
||||
{293.66 * 2, 349.22 * 2, 440.00 * 2}, // GMaj7 (G6, B6, D6, F#6)
|
||||
{130.82 * 2, 155.56 * 2, 196.00 * 2} // Cm (C6, Eb6, G6)
|
||||
};
|
||||
void set_osc_freq(osc_t *o, float f)
|
||||
{
|
||||
o->step = (uint32_t)((f / 16000.0) * UINT32_MAX);
|
||||
o->phasor = 0; // Reset the phasor to start at the beginning of the sine wave
|
||||
}
|
||||
|
||||
void update_osc(osc_t *o)
|
||||
{
|
||||
|
@ -83,79 +97,37 @@ void update_osc(osc_t *o)
|
|||
o->value = sinetab[index];
|
||||
}
|
||||
|
||||
void set_osc_freq(osc_t *o, float f)
|
||||
{
|
||||
o->step = (uint32_t)((f / 16000.0) * UINT32_MAX);
|
||||
o->phasor = 0; // Reset the phasor to start at the beginning of the sine wave
|
||||
}
|
||||
|
||||
void update_piano_osc(PianoOscillator *p)
|
||||
{
|
||||
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
|
||||
p->noteDuration--; // Decrement the note duration
|
||||
}
|
||||
else
|
||||
{
|
||||
// Time to play a new chord
|
||||
int chordIndex = rand() % CHORD_TYPES;
|
||||
for (int i = 0; i < CHORD_NOTES; ++i)
|
||||
{
|
||||
// Assign a new frequency to each oscillator in the chord
|
||||
set_osc_freq(&p->noteOsc[i], chordFrequencies[chordIndex][i]);
|
||||
double fadeOutFactor = 1.0;
|
||||
int twoThirdsDuration = (2 * p->noteDuration / 3);
|
||||
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) {
|
||||
update_osc(&p->noteOsc[i]);
|
||||
p->noteOsc[i].value *= fadeOutFactor; // Apply fade-out factor
|
||||
}
|
||||
p->noteDuration = (rand() % 5 + 1) * 16000; // Set a new random note duration
|
||||
}
|
||||
|
||||
// Update the value for each oscillator in the chord
|
||||
for (int i = 0; i < CHORD_NOTES; ++i)
|
||||
{
|
||||
update_osc(&p->noteOsc[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void update_high_piano_osc(PianoOscillator *p)
|
||||
{
|
||||
if (p->noteDuration > 0)
|
||||
{
|
||||
// Continue playing the current chord or silence
|
||||
p->noteDuration--; // Decrement the note duration
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Random chance to play a new chord or not play anything (silence)
|
||||
if (rand() % 10 == 0)
|
||||
{ // 50% chance to start a new chord, adjust as needed
|
||||
if (rand() % notePlayChance == 0) {
|
||||
int chordIndex = rand() % CHORD_TYPES;
|
||||
for (int i = 0; i < CHORD_NOTES; ++i)
|
||||
{
|
||||
// Assign a new frequency to each oscillator in the chord
|
||||
set_osc_freq(&p->noteOsc[i], higherChordFrequencies[chordIndex][i]);
|
||||
for (int i = 0; i < CHORD_NOTES; ++i) {
|
||||
set_osc_freq(&p->noteOsc[i], chordFrequencies[chordIndex][i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p->noteDuration = (rand() % 10 + 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;
|
||||
}
|
||||
}
|
||||
// Set a new random note duration
|
||||
p->noteDuration = (rand() % 5 + 1) * 16000; // E.g., between 1 and 5 seconds
|
||||
}
|
||||
|
||||
// Update the value for each oscillator in the chord
|
||||
if (p->noteDuration > 0)
|
||||
{ // Only update oscillators if not in silence
|
||||
for (int i = 0; i < CHORD_NOTES; ++i)
|
||||
{
|
||||
update_osc(&p->noteOsc[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
FILE *fp;
|
||||
|
@ -181,38 +153,48 @@ int main()
|
|||
|
||||
// Initialize the first chord and duration for piano and high piano
|
||||
int chordIndex = rand() % CHORD_TYPES;
|
||||
pianoOsc.noteDuration = (rand() % 100 + 1) * 16000; // Start with a random duration
|
||||
highPianoOsc.noteDuration = (rand() % 5 + 1) * 16000; // Start with a random duration
|
||||
update_piano_osc(&pianoOsc, chordFrequencies, 10); // Start with a random duration
|
||||
update_piano_osc(&highPianoOsc, higherChordFrequencies, 8); // Start with a random duration
|
||||
// Set the frequencies for the first chord
|
||||
for (int i = 0; i < CHORD_NOTES; ++i)
|
||||
{
|
||||
set_osc_freq(&pianoOsc.noteOsc[i], chordFrequencies[chordIndex][i]);
|
||||
set_osc_freq(&highPianoOsc.noteOsc[i], higherChordFrequencies[chordIndex][i]);
|
||||
}
|
||||
|
||||
noise_osc_t fireCrackleOsc;
|
||||
init_noise_osc(&fireCrackleOsc, time(NULL));
|
||||
|
||||
while (1)
|
||||
{
|
||||
out = 0.0f; // Reset output each iteration
|
||||
|
||||
// Update the piano and high piano oscillators
|
||||
update_piano_osc(&pianoOsc);
|
||||
update_high_piano_osc(&highPianoOsc);
|
||||
// Update the piano oscillator
|
||||
update_piano_osc(&pianoOsc, chordFrequencies, 10); // 10 for a 1 in 10 chance of silence
|
||||
// Update the high piano oscillator
|
||||
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;
|
||||
out += pianoOsc.noteOsc[i].value + (highPianoOsc.noteOsc[i].value * -1.0f);
|
||||
}
|
||||
out /= CHORD_NOTES; // Correctly average the mixed notes
|
||||
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;
|
||||
|
||||
// Increase the gain to make the signal louder
|
||||
float gain = 0.2f; // Adjust the gain factor as needed
|
||||
float gain = 0.5f; // Adjust the gain factor as needed
|
||||
out *= gain;
|
||||
|
||||
// Ensure the signal does not exceed the maximum range
|
||||
if (out > 1.0f)
|
||||
out = 1.0f;
|
||||
if (out < -1.0f)
|
||||
out = 0.8f;
|
||||
out = -1.0f;
|
||||
|
||||
// Scale to 16-bit output value
|
||||
out16 = (uint16_t)((UINT16_MAX / 2) * (0.5 + 0.5 * out));
|
||||
|
@ -221,6 +203,6 @@ int main()
|
|||
fwrite(&out16, sizeof(out16), 1, fp);
|
||||
fwrite(&out16, sizeof(out16), 1, fp);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue