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>
#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;
}