From c11fb75ca42c306645d9aa13ecd2b4af37561092 Mon Sep 17 00:00:00 2001 From: Mitya Selivanov Date: Sat, 30 Sep 2023 18:52:22 +0200 Subject: Kick sound; Sheet duplicate --- source/saw/main.c | 97 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 74 insertions(+), 23 deletions(-) diff --git a/source/saw/main.c b/source/saw/main.c index 2a62e80..45ca6cc 100644 --- a/source/saw/main.c +++ b/source/saw/main.c @@ -46,6 +46,7 @@ enum { INSTRUMENT_SAW_DOWN, INSTRUMENT_SQUARE_UP, INSTRUMENT_SQUARE_DOWN, + INSTRUMENT_KICK, INSTRUMENT_COUNT, TRACK_INPUT_NONE = 0, @@ -246,7 +247,8 @@ static void saw_playback(i32 frame_count) { saw_roll_t *roll = saw_rolls + k; if (!roll->enabled || saw_playback_frame + frame_count <= roll->time || - saw_playback_frame >= roll->time + roll->duration) + saw_playback_frame + frame_count > + roll->time + roll->duration) continue; i64 play_frame = roll->loop_duration == 0 @@ -274,15 +276,25 @@ static void saw_playback(i32 frame_count) { saw_playback_frame += frame_count; } -static f64 saw_oscillator(i32 type, f64 t, f64 warp) { - f64 n = t - floor(t); +static f64 saw_oscillator(i32 type, f64 frequency, f64 phase, + f64 warp, f64 t) { + if (type == INSTRUMENT_KICK) { + frequency /= 8.; + f64 q = t * frequency + phase; + frequency /= 8.; + f64 f = frequency * (10. + q) / (1. + q); + return sin(q * f * (M_PI * 2)); + } + + t = t * frequency + phase; + t = t - floor(t); switch (type) { - case INSTRUMENT_SINE: return sin(n * (M_PI * 2)); - case INSTRUMENT_SAW_UP: return -1. + n * 2.; - case INSTRUMENT_SAW_DOWN: return 1. - n * 2.; - case INSTRUMENT_SQUARE_UP: return n < .5 + warp / 2. ? -1. : 1.; - case INSTRUMENT_SQUARE_DOWN: return n < .5 + warp / 2. ? 1. : -1.; + case INSTRUMENT_SINE: return sin(t * (M_PI * 2)); + case INSTRUMENT_SAW_UP: return -1. + t * 2.; + case INSTRUMENT_SAW_DOWN: return 1. - t * 2.; + case INSTRUMENT_SQUARE_UP: return t < .5 + warp / 2. ? -1. : 1.; + case INSTRUMENT_SQUARE_DOWN: return t < .5 + warp / 2. ? 1. : -1.; default:; } @@ -323,13 +335,11 @@ static void saw_audio(ma_device *device, void *void_out_, f64 t = (f64) saw_voices[n].time / (f64) SAW_SAMPLE_RATE; f64 a = amplitude * saw_envelope(t, attack, decay, sustain, duration, release); - out[i * 2] += (f32) (saw_oscillator(wave_type, - t * frequency + phase_l, - warp) * + out[i * 2] += (f32) (saw_oscillator(wave_type, frequency, + phase_l, warp, t) * a); - out[i * 2 + 1] += (f32) (saw_oscillator(wave_type, - t * frequency + phase_r, - warp) * + out[i * 2 + 1] += (f32) (saw_oscillator(wave_type, frequency, + phase_r, warp, t) * a); saw_voices[n].time++; @@ -349,8 +359,8 @@ static void saw_ui_compose(i64 x0, i64 y0, i64 width, i64 height) { i64 frame_height = sapp_height(); i64 track_height = 60; - i64 grid_scale = 40; - i64 grid_rate = 2; + i64 grid_scale = 50; + i64 grid_rate = 3; i64 border = 2; // Time bar @@ -785,8 +795,8 @@ static void saw_ui_track(saw_track_t *track, i64 x0, i64 y0, title.values, title.values + title.size); next_y = header_offset + text_height; - char buf_instr[][100] = { "Sine", "Saw up", "Saw down", "Square up", - "Square down" }; + char buf_instr[][100] = { "Sine", "Saw up", "Saw down", + "Square up", "Square down", "Kick" }; nvgText(saw_nvg, x0 + border * 2, frame_height - y0 - height + next_y - border * 2, "Instrument", 0); @@ -988,7 +998,8 @@ static void saw_ui_roll(saw_roll_t *roll, i64 x0, i64 y0, i64 width, if (!roll->pitch_turned_off[pitch] && (saw_lbutton_click || (saw_lbutton_down && roll->last_index != pitch))) - saw_play_voice(saw_tracks + roll->track, roll, pitch, 2); + saw_play_voice(saw_tracks + roll->track, roll, pitch, + SAW_SAMPLE_RATE / roll->rate); if (saw_rbutton_click) roll->pitch_turned_off[pitch] = @@ -1388,17 +1399,15 @@ static void saw_init(void) { saw_project_file.size = strlen(saw_project_file_buf); saw_project_file.values = saw_project_file_buf; - - printf("Project file: %s\n", saw_project_file_buf); } } + printf("Project file: %s\n", BS(saw_project_file)); + // Load the project from a file // if (path_type(saw_project_file) == PATH_FILE) { - printf("Open project: %s\n", BS(saw_project_file)); - FILE *f = fopen(BS(saw_project_file), "rb"); if (f == NULL) { @@ -1842,6 +1851,48 @@ static void saw_event(sapp_event const *event) { break; + case SAPP_KEYCODE_D: + if (saw_current_roll != -1) { + i64 n = -1; + + saw_roll_t *roll = saw_rolls + saw_current_roll; + + i8 collision = 0; + + for (i64 i = 0; i < ROLL_COUNT; i++) + if (saw_rolls[i].enabled && + saw_rolls[i].track == roll->track && + saw_rolls[i].time >= + roll->time + roll->duration && + saw_rolls[i].time < + roll->time + roll->duration * 2) { + collision = 1; + break; + } + + if (collision) + break; + + for (i64 i = 0; i < ROLL_COUNT; i++) + if (!saw_rolls[i].enabled) { + n = i; + break; + } + + if (n == -1) + break; + + for (i64 i = 0; i < ROLL_COUNT; i++) + if (saw_compose.rolls[i] == -1) { + saw_compose.rolls[i] = n; + break; + } + + saw_rolls[n] = *roll; + saw_rolls[n].time = roll->time + roll->duration; + } + break; + default:; } } -- cgit v1.2.3