summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2023-09-30 18:52:22 +0200
committerMitya Selivanov <automainint@guattari.tech>2023-09-30 18:52:22 +0200
commitc11fb75ca42c306645d9aa13ecd2b4af37561092 (patch)
tree7e607b5e7df8ddd171be8418485c5cc05a9fbe7e
parent02a9be36329d161064040387d7b2ef18da4cd7fe (diff)
downloadsaw-c11fb75ca42c306645d9aa13ecd2b4af37561092.zip
Kick sound; Sheet duplicate
-rw-r--r--source/saw/main.c97
1 files 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:;
}
}