1
0
Fork 0

Changed frequencies and added noise

This commit is contained in:
Rodrigo Franco 2023-12-14 10:54:26 -03:00
parent 565d718049
commit 44643fe4ad
1 changed files with 102 additions and 120 deletions

222
jerdehl.c
View File

@ -5,19 +5,17 @@
#include <time.h> #include <time.h>
#define SINE_TABLE_SIZE 2048 #define SINE_TABLE_SIZE 2048
#define ZERO_FIVE 0.5
#define ZERO_THREE 0.3
#define UINT32_MAX_HALF (UINT32_MAX / 2) #define UINT32_MAX_HALF (UINT32_MAX / 2)
#define CHORD_NOTES 3 #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 typedef struct oscillator
{ {
uint32_t phasor; uint32_t phasor;
uint32_t step; uint32_t step;
float value; double value;
} osc_t; } osc_t;
typedef struct typedef struct
@ -26,54 +24,70 @@ typedef struct
int noteDuration; int noteDuration;
} PianoOscillator; } 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] = { float chordFrequencies[CHORD_TYPES][CHORD_NOTES] = {
{65.41, 77.78, 98.00}, // Cm (C, Eb, G) {65.41, 77.78, 98.00}, // Cm (C, Eb, G)
{87.31, 98.00, 116.54}, // Fm7 (F, G, Bb) {73.42, 87.31, 97.99}, // Ddim (D, F, Ab)
{73.42, 87.31, 110.00}, // Ddim (D, F, A) {82.41, 97.99, 123.47}, // Eb (Eb, G, Bb)
{61.74, 77.78, 92.50}, // G7 (G, B, F) {87.31, 103.83, 130.81},// Fm (F, Ab, C)
{58.27, 73.42, 87.31}, // BbMaj (Bb, D, F) {97.99, 116.54, 146.83},// Gm (G, Bb, D)
{65.41, 82.41, 103.83}, // Cm/Ab (Ab, C, Eb) {103.83, 123.47, 155.56},// Ab (Ab, C, Eb)
{73.42, 92.50, 116.54}, // D7 (D, F#, A, C) {116.54, 130.81, 155.56},// Bb (Bb, D, F)
{65.41, 77.78, 98.00}, // Cm (C, Eb, G) repeat };
{58.27, 73.42, 87.31}, // BbMaj (Bb, D, F) repeat float higherChordFrequencies[CHORD_TYPES][CHORD_NOTES] = {
{61.74, 77.78, 92.50}, // G7 (G, B, F) repeat {130.81, 155.56, 196.00}, // Cm (C4, Eb4, G4)
{77.78, 98.00, 123.47}, // EbMaj (Eb, G, Bb) {146.83, 174.61, 195.99}, // Ddim (D4, F4, Ab4)
{82.41, 103.83, 130.81}, // AbMaj (Ab, C, Eb) {164.81, 195.99, 246.94}, // Eb (Eb4, G4, Bb4)
{87.31, 110.00, 130.81}, // FMaj7 (F, A, C, E) {174.61, 207.65, 261.63}, // Fm (F4, Ab4, C5)
{98.00, 123.47, 146.83}, // GMaj (G, B, D) {195.99, 233.08, 293.66}, // Gm (G4, Bb4, D5)
{103.83, 130.81, 155.56}, // AbMaj7 (Ab, C, Eb, G) {207.65, 246.94, 311.13}, // Ab (Ab4, C5, Eb5)
{110.00, 130.81, 164.81}, // AMaj7 (A, C#, E, G#) {233.08, 261.63, 311.13}, // Bb (Bb4, D5, F5)
{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)
}; };
float higherChordFrequencies[CHORD_TYPES][CHORD_NOTES] = { void set_osc_freq(osc_t *o, float f)
{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) o->step = (uint32_t)((f / 16000.0) * UINT32_MAX);
{146.84 * 2, 174.62 * 2, 220.00 * 2}, // Ddim (D6, F6, A6) o->phasor = 0; // Reset the phasor to start at the beginning of the sine wave
{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 update_osc(osc_t *o) void update_osc(osc_t *o)
{ {
@ -83,79 +97,37 @@ void update_osc(osc_t *o)
o->value = sinetab[index]; o->value = sinetab[index];
} }
void set_osc_freq(osc_t *o, float f) void update_piano_osc(PianoOscillator *p, float chordFrequencies[CHORD_TYPES][CHORD_NOTES], int notePlayChance) {
{ if (p->noteDuration > 0) {
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)
{
// Continue playing the current chord // Continue playing the current chord
p->noteDuration--; // Decrement the note duration double fadeOutFactor = 1.0;
} int twoThirdsDuration = (2 * p->noteDuration / 3);
else if (p->noteDuration <= twoThirdsDuration) {
{ // Calculate fade-out factor
// Time to play a new chord fadeOutFactor = (double)p->noteDuration / twoThirdsDuration;
int chordIndex = rand() % CHORD_TYPES; }
for (int i = 0; i < CHORD_NOTES; ++i) // Update the value for each oscillator in the chord with fade-out
{ for (int i = 0; i < CHORD_NOTES; ++i) {
// Assign a new frequency to each oscillator in the chord update_osc(&p->noteOsc[i]);
set_osc_freq(&p->noteOsc[i], chordFrequencies[chordIndex][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 p->noteDuration--; // Decrement the note duration
} } else {
else
{
// Random chance to play a new chord or not play anything (silence) // Random chance to play a new chord or not play anything (silence)
if (rand() % 10 == 0) if (rand() % notePlayChance == 0) {
{ // 50% chance to start a new chord, adjust as needed
int chordIndex = rand() % CHORD_TYPES; 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]);
// Assign a new frequency to each oscillator in the chord
set_osc_freq(&p->noteOsc[i], higherChordFrequencies[chordIndex][i]);
} }
} p->noteDuration = (rand() % 10 + 1) * 16000; // Set a new random note duration
else } else {
{
// Set all oscillator values to zero to represent silence // 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; 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() int main()
{ {
FILE *fp; FILE *fp;
@ -181,38 +153,48 @@ int main()
// Initialize the first chord and duration for piano and high piano // Initialize the first chord and duration for piano and high piano
int chordIndex = rand() % CHORD_TYPES; int chordIndex = rand() % CHORD_TYPES;
pianoOsc.noteDuration = (rand() % 100 + 1) * 16000; // Start with a random duration update_piano_osc(&pianoOsc, chordFrequencies, 10); // Start with a random duration
highPianoOsc.noteDuration = (rand() % 5 + 1) * 16000; // 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) for (int i = 0; i < CHORD_NOTES; ++i)
{ {
set_osc_freq(&pianoOsc.noteOsc[i], chordFrequencies[chordIndex][i]); set_osc_freq(&pianoOsc.noteOsc[i], chordFrequencies[chordIndex][i]);
set_osc_freq(&highPianoOsc.noteOsc[i], higherChordFrequencies[chordIndex][i]); set_osc_freq(&highPianoOsc.noteOsc[i], higherChordFrequencies[chordIndex][i]);
} }
noise_osc_t fireCrackleOsc;
init_noise_osc(&fireCrackleOsc, time(NULL));
while (1) while (1)
{ {
out = 0.0f; // Reset output each iteration out = 0.0f; // Reset output each iteration
// Update the piano and high piano oscillators // Update the piano and high piano oscillators
update_piano_osc(&pianoOsc); // Update the piano oscillator
update_high_piano_osc(&highPianoOsc); 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 // Mix the outputs from all oscillators
for (int i = 0; i < CHORD_NOTES; ++i) 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 // 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; out *= gain;
// Ensure the signal does not exceed the maximum range // Ensure the signal does not exceed the maximum range
if (out > 1.0f) if (out > 1.0f)
out = 1.0f; out = 1.0f;
if (out < -1.0f) if (out < -1.0f)
out = 0.8f; out = -1.0f;
// Scale to 16-bit output value // Scale to 16-bit output value
out16 = (uint16_t)((UINT16_MAX / 2) * (0.5 + 0.5 * out)); 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);
fwrite(&out16, sizeof(out16), 1, fp); fwrite(&out16, sizeof(out16), 1, fp);
} }
fclose(fp);
return 0; return 0;
} }