From 6824f180ba2d8908917c645c67c99e9915efb17a Mon Sep 17 00:00:00 2001 From: Mitya Selivanov Date: Sat, 17 Feb 2024 01:52:59 +0100 Subject: Fix disabled voice skipping --- source/saw/main.c | 66 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 15 deletions(-) (limited to 'source') diff --git a/source/saw/main.c b/source/saw/main.c index 7809be3..4f4d2ae 100644 --- a/source/saw/main.c +++ b/source/saw/main.c @@ -54,6 +54,7 @@ #define TIME_EPS 0.0001 #define REFERENCE_PITCH 440.0 // A_4 #define EQUAL_TEMPERAMENT_FACTOR 1.05946309436 // 2^(1/12) +#define GLOBAL_VOLUME 2.0 enum { // TODO @@ -82,9 +83,9 @@ enum { SHEET_SIZE = 200, #else TRACK_COUNT = 16, - ROLL_COUNT = 32, + ROLL_COUNT = 64, PITCH_COUNT = 100, - VOICE_COUNT = 32, + VOICE_COUNT = 64, UNISON_COUNT = 100, SHEET_SIZE = 200, #endif @@ -422,8 +423,11 @@ static f64 saw_pitch_amplitude(i64 pitch) { static void saw_play_voice(saw_track_t *track, saw_roll_t *roll, i64 pitch, i64 duration) { - if (saw_voices[VOICE_COUNT - 1].enabled || pitch < 0 || - pitch >= PITCH_COUNT) + if (pitch < 0 || pitch >= PITCH_COUNT) + return; + + assert(!saw_voices[VOICE_COUNT - 1].enabled); + if (saw_voices[VOICE_COUNT - 1].enabled) return; for (i32 n = VOICE_COUNT - 1; n > 0; --n) @@ -527,6 +531,7 @@ static void saw_audio_render(void) { assert(0); return; } + frame_count -= saw_playback_lookahead; mtx_unlock(&saw_playback_mutex); @@ -573,9 +578,11 @@ static void saw_audio_render(void) { // Sound generation // { + b8 regroup_voices = 0; + for (i32 n = 0; n < VOICE_COUNT; n++) { if (!saw_voices[n].enabled) - continue; + break; saw_track_t *track = saw_tracks + saw_voices[n].track; @@ -607,16 +614,18 @@ static void saw_audio_render(void) { saw_playback_temp[i * CHANNEL_COUNT] += (f32) (saw_oscillator(wave_type, frequency, phase_l, warp, t) * - a); + a * GLOBAL_VOLUME); saw_playback_temp[i * CHANNEL_COUNT + 1] += (f32) (saw_oscillator(wave_type, frequency, phase_r, warp, t) * - a); + a * GLOBAL_VOLUME); saw_voices[n].time++; - if (t > duration + release) + if (t > duration + release) { saw_voices[n].enabled = 0; + regroup_voices = 1; + } } break; case INSTRUMENT_SAMPLER: { @@ -674,10 +683,10 @@ static void saw_audio_render(void) { saw_playback_temp[i * CHANNEL_COUNT] += (f32) (saw_sampler(sam, 0, frequency, k) * a * - u); + u * GLOBAL_VOLUME); saw_playback_temp[i * CHANNEL_COUNT + 1] += (f32) (saw_sampler(sam, 1, frequency, k) * a * - u); + u * GLOBAL_VOLUME); } { @@ -694,10 +703,10 @@ static void saw_audio_render(void) { saw_playback_temp[i * CHANNEL_COUNT] += (f32) (saw_sampler(sam, 0, frequency, k) * a * - u); + u * GLOBAL_VOLUME); saw_playback_temp[i * CHANNEL_COUNT + 1] += (f32) (saw_sampler(sam, 1, frequency, k) * a * - u); + u * GLOBAL_VOLUME); } } @@ -715,20 +724,47 @@ static void saw_audio_render(void) { i64 k = (i64) floor(r * SAMPLE_RATE + .5); saw_playback_temp[i * CHANNEL_COUNT] += - (f32) (saw_sampler(sam, 0, frequency, k) * a * u); + (f32) (saw_sampler(sam, 0, frequency, k) * a * u * + GLOBAL_VOLUME); saw_playback_temp[i * CHANNEL_COUNT + 1] += - (f32) (saw_sampler(sam, 1, frequency, k) * a * u); + (f32) (saw_sampler(sam, 1, frequency, k) * a * u * + GLOBAL_VOLUME); } saw_voices[n].time++; - if (t > duration + release) + if (t > duration + release) { saw_voices[n].enabled = 0; + regroup_voices = 1; + } } break; default:; } } + + if (regroup_voices) + for (i64 i = 0; i < VOICE_COUNT; ++i) { + if (saw_voices[i].enabled) + continue; + + b8 slot_found = 0; + + for (i64 j = VOICE_COUNT - 1; j > i; --j) { + if (!saw_voices[j].enabled) + continue; + + memcpy(saw_voices + i, saw_voices + j, + sizeof *saw_voices); + saw_voices[j].enabled = 0; + + slot_found = 1; + break; + } + + if (!slot_found) + break; + } } } -- cgit v1.2.3