From a5e76114954b8189a10e21ba15f78fcf58b51577 Mon Sep 17 00:00:00 2001 From: sandyx Date: Tue, 24 Sep 2024 14:56:53 -0500 Subject: [PATCH] note stack --- src/main.c | 207 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 139 insertions(+), 68 deletions(-) diff --git a/src/main.c b/src/main.c index baed5a6..49ab362 100644 --- a/src/main.c +++ b/src/main.c @@ -6,7 +6,7 @@ #include #include -#define MAX_NOTES 26 +#define MAX_NOTES 16 const int window_width = 640; const int window_height = 480; @@ -34,7 +34,45 @@ typedef struct note { bool released; } note; -note scale[MAX_NOTES]; +note scale[26]; + +typedef struct keymap { + int key; + int idx; +} keymap; + +typedef struct note_stack { + int nsp; //stack pointer + note notes[MAX_NOTES]; + keymap keys[MAX_NOTES]; +} note_stack; + +//so the stack can be accessed in the callback +note_stack *nsptr; + +static inline void push_note(note_stack *ns, note n) { + ns->nsp = ns->nsp % MAX_NOTES; + //printf("%s: %d\n", "push_note", ns->nsp); + ns->notes[ns->nsp] = n; + ns->nsp++; +} + +//must come before push_note +static inline void push_key(note_stack *ns, int k) { + ns->keys[ns->nsp % MAX_NOTES].key = k; + ns->keys[ns->nsp % MAX_NOTES].idx = ns->nsp % MAX_NOTES; //might not need + //printf("%s: %d %d %d\n", "push_key", ns->nsp % MAX_NOTES, ns->keys[ns->nsp % MAX_NOTES].key, ns->keys[ns->nsp % MAX_NOTES].idx); +} + +static inline void release_note(note_stack *ns, int k) { + for (int i = 0; i < MAX_NOTES; i++) { + if (ns->keys[i].key == k) { + //printf("%s %d %d\n", "release note", k, i); + ns->notes[i].released = true; //try i first + ns->keys[i].key = 0; + } + } +} float sine_wave(float idx) { return sinf(2 * PI * idx); @@ -48,43 +86,61 @@ float square_wave(float idx) { return -0.5f; } -static inline int count_active_notes(void) { +float saw_wave(float idx) { + return idx - 0.5f; +} + +float reverse_saw_wave(float idx) { + return -idx + 0.5f; +} + +float semisine_wave(float idx) { + return (idx * idx)/2; +} + +//not needed? +static inline int count_active_notes(note_stack *ns) { int active = 0; for (size_t i = 0; i < MAX_NOTES; i++) { - if (scale[i].volume > 0.0f) + if (ns->notes[i].volume > 0.0f) { + //printf("%s %f\n", "wtf?:", ns->notes[i].volume); active++; + } } + //printf("%s: %d\n", "active notes", active); return active; } -static inline float add_notes(void) { - //add each notes index - float m = 0; - int active = count_active_notes(); +static inline float add_notes(note_stack *ns) { + float m = 0.0f; + //int active = count_active_notes(ns); + float compress = 0.0f; for (size_t i = 0; i < MAX_NOTES; i++) { - m += square_wave(scale[i].index) * scale[i].volume; + m += sine_wave(ns->notes[i].index) * ns->notes[i].volume; + m += square_wave(ns->notes[i].index) * ns->notes[i].volume; + compress += scale[i].volume; } //don't divide by zero - - m = active ? m/active : 0.0f; //compression - //m = m + (1.0f - m) * 0.95f; - return m; + m = compress ? m/compress : 0.0f; //compression + + //m = (m - (-1.0f*active)) / (1.0f*active) - (-1.0f*active); + return m * 5; } static inline float calc_note_step(note *n) { return n->frequency/sample_rate; } -static inline void reset_index(void) { +static inline void reset_index(note_stack *ns) { for (size_t i = 0; i < MAX_NOTES; i++) { - scale[i].index += scale[i].step; - if (scale[i].index > 1.0f && scale[i].volume > 0.0f) { - scale[i].index -= 1.0f; + ns->notes[i].index += ns->notes[i].step; + if (ns->notes[i].index > 1.0f && ns->notes[i].volume > 0.0f) { + ns->notes[i].index -= 1.0f; } } } @@ -94,26 +150,24 @@ void AudioInputCallback2(void *buffer, uint32_t frames) { short *d = (short *)buffer; for (size_t i = 0; i < frames; i++) { - d[i] = (signed short)(pcm_volume * add_notes());; - reset_index(); + d[i] = (signed short)(pcm_volume * add_notes(nsptr)); + reset_index(nsptr); } } -const float volume_release_step = 0.01f; - -void key_press(int key, note *n) { +void key_press(int key, note_stack *ns, note n) { if (IsKeyPressed(key)) { - //keys_pressed++; - n->released = false; + push_key(ns, key); + push_note(ns, n); + //n->released = false; } if (IsKeyReleased(key)) { - //keys_pressed--; - n->released = true; + //ns->notes[/*saved idx*/].released = true; + release_note(ns, key); + //n->released = true; } - - //printf("%s\n", "wow"); } int main(int argc, char *argv[]) { @@ -128,61 +182,78 @@ int main(int argc, char *argv[]) { PlayAudioStream(stream); - const float volume_attack_step = 0.08f; - const float volume_release_step = 0.08f; + note_stack ns; + ns.nsp = 0; - //init scale for (int i = 0; i < MAX_NOTES; i++) { + ns.notes[i] = (note){ + .volume = 0.0f, + .released = true, + .index = 0.0f, + }; + ns.keys[i] = (keymap){0}; + } + + nsptr = &ns; + + const float volume_attack_step = 0.04f; + const float volume_release_step = 0.04f; + + //init scale + for (int i = 0; i < 26; i++) { scale[i].frequency = semitone(i-24); scale[i].index = 0.0f; - scale[i].volume = 0.0f; + scale[i].volume = 1.0f; scale[i].step = calc_note_step(&scale[i]); - scale[i].released = true; + scale[i].released = false; } while(!WindowShouldClose()) { - key_press(KEY_Z, &scale[0]); - key_press(KEY_X, &scale[1]); - key_press(KEY_C, &scale[2]); - key_press(KEY_V, &scale[3]); - key_press(KEY_B, &scale[4]); - key_press(KEY_N, &scale[5]); - key_press(KEY_M, &scale[6]); - key_press(KEY_A, &scale[7]); - key_press(KEY_S, &scale[8]); - key_press(KEY_D, &scale[9]); - key_press(KEY_F, &scale[10]); - key_press(KEY_G, &scale[11]); - key_press(KEY_H, &scale[12]); - key_press(KEY_J, &scale[13]); - key_press(KEY_K, &scale[14]); - key_press(KEY_L, &scale[15]); - key_press(KEY_Q, &scale[16]); - key_press(KEY_W, &scale[17]); - key_press(KEY_E, &scale[18]); - key_press(KEY_R, &scale[19]); - key_press(KEY_T, &scale[20]); - key_press(KEY_Y, &scale[21]); - key_press(KEY_U, &scale[22]); - key_press(KEY_I, &scale[23]); - key_press(KEY_O, &scale[24]); - key_press(KEY_P, &scale[25]); + key_press(KEY_Z, &ns, scale[0]); + key_press(KEY_X, &ns, scale[1]); + key_press(KEY_C, &ns, scale[2]); + key_press(KEY_V, &ns, scale[3]); + key_press(KEY_B, &ns, scale[4]); + key_press(KEY_N, &ns, scale[5]); + key_press(KEY_M, &ns, scale[6]); + key_press(KEY_A, &ns, scale[7]); + key_press(KEY_S, &ns, scale[8]); + key_press(KEY_D, &ns, scale[9]); + key_press(KEY_F, &ns, scale[10]); + key_press(KEY_G, &ns, scale[11]); + key_press(KEY_H, &ns, scale[12]); + key_press(KEY_J, &ns, scale[13]); + key_press(KEY_K, &ns, scale[14]); + key_press(KEY_L, &ns, scale[15]); + key_press(KEY_Q, &ns, scale[16]); + key_press(KEY_W, &ns, scale[17]); + key_press(KEY_E, &ns, scale[18]); + key_press(KEY_R, &ns, scale[19]); + key_press(KEY_T, &ns, scale[20]); + key_press(KEY_Y, &ns, scale[21]); + key_press(KEY_U, &ns, scale[22]); + key_press(KEY_I, &ns, scale[23]); + key_press(KEY_O, &ns, scale[24]); + key_press(KEY_P, &ns, scale[25]); for (int i = 0; i < MAX_NOTES; i++) { - if (scale[i].released) { - scale[i].volume -= volume_release_step; - if (scale[i].volume < 0.0f) { - scale[i].volume = 0.0f; - scale[i].index = 0.0f; + if (ns.notes[i].released) { + //printf("lowering volume: %f\n", ns.notes[i].volume); + ns.notes[i].volume -= volume_release_step; + //printf("lowering volume: %f\n", ns.notes[i].volume); + if (ns.notes[i].volume < 0.0f) { + ns.notes[i].volume = 0.0f; + ns.notes[i].index = 0.0f; } } } for (int i = 0; i < MAX_NOTES; i++) { - if (!scale[i].released) { - scale[i].volume += volume_attack_step; - if (scale[i].volume > 1.0f) { - scale[i].volume = 1.0f; + if (!ns.notes[i].released) { + //printf("%s\n", "bugs?"); + ns.notes[i].volume += volume_attack_step; + if (ns.notes[i].volume > 1.0f) { + ns.notes[i].volume = 1.0f; } } }