summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/saw/main.c162
1 files changed, 110 insertions, 52 deletions
diff --git a/source/saw/main.c b/source/saw/main.c
index fdcda68..77ec5df 100644
--- a/source/saw/main.c
+++ b/source/saw/main.c
@@ -28,7 +28,7 @@ enum {
SAW_SAMPLE_RATE = 44100,
VOICE_COUNT = 16,
- ROLL_SIZE = 60,
+ ROLL_SIZE = 80,
SHEET_SIZE = 200,
ROLL_COUNT = 16,
@@ -40,6 +40,7 @@ typedef struct {
i64 time;
f64 duration;
f64 frequency;
+ f64 amplitude;
} saw_voice_t;
typedef struct {
@@ -61,7 +62,8 @@ typedef struct {
i8 grid_input;
i32 grid_note;
i32 grid_time;
- i8 offset_input;
+ i8 offset_x_input;
+ i8 offset_y_input;
i64 offset_x;
i64 offset_y;
} saw_roll_t;
@@ -135,6 +137,10 @@ static f64 saw_pitch_frequency(i64 pitch) {
return pow(2., 5.5 + pitch / 12.);
}
+static f64 saw_pitch_amplitude(i64 pitch) {
+ return .2 / exp(0.02 * pitch);
+}
+
static void saw_playback(i32 frame_count) {
if (!saw_playback_on)
return;
@@ -167,6 +173,7 @@ static void saw_playback(i32 frame_count) {
.time = 0,
.duration = ((f64) p->duration) / roll->rate,
.frequency = saw_pitch_frequency(p->pitch),
+ .amplitude = saw_pitch_amplitude(p->pitch),
};
}
}
@@ -191,7 +198,7 @@ static void saw_audio(ma_device *device, void *void_out_,
f64 period = M_PI * 2.;
f64 frequency = saw_voices[n].frequency;
- f64 amplitude = .2;
+ f64 amplitude = saw_voices[n].amplitude;
// envelope
f64 attack = .007;
@@ -394,20 +401,21 @@ static void saw_ui_compose(i64 x0, i64 y0, i64 width, i64 height) {
}
saw_rolls[n] = (saw_roll_t) {
- .enabled = 1,
- .track = track,
- .last_index = -1,
- .turned_off = { 0 },
- .rate = 6,
- .notes = { 0 },
- .frame = frame,
- .size = 6 / grid_rate,
- .grid_input = 0,
- .grid_note = 0,
- .grid_time = 0,
- .offset_input = 0,
- .offset_x = 0,
- .offset_y = ROLL_DEFAULT_OFFSET_Y,
+ .enabled = 1,
+ .track = track,
+ .last_index = -1,
+ .turned_off = { 0 },
+ .rate = 6,
+ .notes = { 0 },
+ .frame = frame,
+ .size = 6 / grid_rate,
+ .grid_input = 0,
+ .grid_note = 0,
+ .grid_time = 0,
+ .offset_x_input = 0,
+ .offset_y_input = 0,
+ .offset_x = 0,
+ .offset_y = ROLL_DEFAULT_OFFSET_Y,
};
saw_current_roll = n;
@@ -483,6 +491,23 @@ static void saw_ui_compose(i64 x0, i64 y0, i64 width, i64 height) {
nvgFillColor(saw_nvg, nvgRGBA(240, 240, 80, 180));
nvgFill(saw_nvg);
}
+
+ // Cursor indicator
+ //
+ if (saw_mouse_x >= x0 && saw_mouse_x < x0 + width &&
+ saw_mouse_y >= frame_height - y0 - height &&
+ saw_mouse_y < frame_height - y0) {
+ i32 dx = x0 + saw_compose.offset_x;
+ i32 s = grid_scale / grid_rate;
+ i32 x = dx + ((saw_mouse_x - dx + s / 2) / s) * s;
+ i32 w = border * 4;
+
+ nvgBeginPath(saw_nvg);
+ nvgRect(saw_nvg, x - w / 2, frame_height - y0 - height, w,
+ height);
+ nvgFillColor(saw_nvg, nvgRGBA(80, 80, 240, 160));
+ nvgFill(saw_nvg);
+ }
}
static void saw_ui_roll(saw_roll_t *roll, i64 x0, i64 y0, i64 width,
@@ -561,7 +586,8 @@ static void saw_ui_roll(saw_roll_t *roll, i64 x0, i64 y0, i64 width,
.enabled = 1,
.time = 0,
.duration = .6,
- .frequency = saw_pitch_frequency(pitch)
+ .frequency = saw_pitch_frequency(pitch),
+ .amplitude = saw_pitch_amplitude(pitch),
};
}
@@ -575,12 +601,21 @@ static void saw_ui_roll(saw_roll_t *roll, i64 x0, i64 y0, i64 width,
if (!hover_any)
roll->last_index = -1;
- if (saw_mbutton_click && saw_mouse_x >= x0 &&
- saw_mouse_y >= frame_height - y0 - height &&
- saw_mouse_x < x0 + width && saw_mouse_y < frame_height - y0)
- roll->offset_input = 1;
- if (!saw_mbutton_down && roll->offset_input)
- roll->offset_input = 0;
+ // Offset input
+ if (saw_mbutton_click) {
+ if (saw_mouse_x >= x0 + pianokey_width + sheet_offset &&
+ saw_mouse_y >= frame_height - y0 - height &&
+ saw_mouse_x < x0 + width && saw_mouse_y < frame_height - y0)
+ roll->offset_x_input = 1;
+ if (saw_mouse_x >= x0 &&
+ saw_mouse_y >= frame_height - y0 - height &&
+ saw_mouse_x < x0 + width && saw_mouse_y < frame_height - y0)
+ roll->offset_y_input = 1;
+ }
+ if (!saw_mbutton_down) {
+ roll->offset_x_input = 0;
+ roll->offset_y_input = 0;
+ }
// Draw music sheet
//
@@ -759,21 +794,42 @@ static void saw_ui_roll(saw_roll_t *roll, i64 x0, i64 y0, i64 width,
// Playback indicator
//
+ {
+ i32 x = x0 + pianokey_width + sheet_offset + roll->offset_x -
+ border * 2 +
+ ((saw_playback_frame - roll->frame) * roll->rate *
+ sheet_scale +
+ SAW_SAMPLE_RATE / 2) /
+ SAW_SAMPLE_RATE;
+ i32 w = border * 4;
+
+ if (x >= x0 + pianokey_width + sheet_offset - border * 2 &&
+ x < x0 + width) {
+ nvgBeginPath(saw_nvg);
+ nvgRect(saw_nvg, x, frame_height - y0 - height + text_height, w,
+ height - text_height);
+ nvgFillColor(saw_nvg, nvgRGBA(240, 240, 80, 180));
+ nvgFill(saw_nvg);
+ }
+ }
- i32 x = x0 + pianokey_width + sheet_offset + roll->offset_x -
- border * 2 +
- ((saw_playback_frame - roll->frame) * roll->rate *
- sheet_scale +
- SAW_SAMPLE_RATE / 2) /
- SAW_SAMPLE_RATE;
- i32 w = border * 4;
+ // Cursor indicator
+ //
+ if (saw_mouse_x >= x0 + pianokey_width + sheet_offset &&
+ saw_mouse_x < x0 + width &&
+ saw_mouse_y >= frame_height - y0 - height &&
+ saw_mouse_y < frame_height - y0) {
+ i32 dx = x0 + pianokey_width + sheet_offset + roll->offset_x;
+ i32 x = dx +
+ ((saw_mouse_x - dx + sheet_scale / 2) / sheet_scale) *
+ sheet_scale;
+ i32 w = border * 4;
- if (x >= x0 + pianokey_width + sheet_offset - border * 2 &&
- x < x0 + width) {
nvgBeginPath(saw_nvg);
- nvgRect(saw_nvg, x, frame_height - y0 - height + text_height, w,
+ nvgRect(saw_nvg, x - w / 2,
+ frame_height - y0 - height + text_height, w,
height - text_height);
- nvgFillColor(saw_nvg, nvgRGBA(240, 240, 80, 180));
+ nvgFillColor(saw_nvg, nvgRGBA(80, 80, 240, 160));
nvgFill(saw_nvg);
}
}
@@ -813,20 +869,21 @@ static void saw_init(void) {
saw_compose.rolls[i] = (i == 0 ? 0 : -1);
saw_rolls[i] = (saw_roll_t) {
- .enabled = (i == 0),
- .track = 0,
- .last_index = -1,
- .turned_off = { 0 },
- .rate = 6,
- .notes = { 0 },
- .frame = 0,
- .size = 48,
- .grid_input = 0,
- .grid_note = 0,
- .grid_time = 0,
- .offset_input = 0,
- .offset_x = 0,
- .offset_y = ROLL_DEFAULT_OFFSET_Y,
+ .enabled = (i == 0),
+ .track = 0,
+ .last_index = -1,
+ .turned_off = { 0 },
+ .rate = 6,
+ .notes = { 0 },
+ .frame = 0,
+ .size = 48,
+ .grid_input = 0,
+ .grid_note = 0,
+ .grid_time = 0,
+ .offset_x_input = 0,
+ .offset_y_input = 0,
+ .offset_x = 0,
+ .offset_y = ROLL_DEFAULT_OFFSET_Y,
};
}
}
@@ -880,11 +937,12 @@ static void saw_event(sapp_event const *event) {
saw_mouse_x = event->mouse_x;
saw_mouse_y = event->mouse_y;
- for (i64 i = 0; i < ROLL_COUNT; i++)
- if (saw_rolls[i].offset_input) {
+ for (i64 i = 0; i < ROLL_COUNT; i++) {
+ if (saw_rolls[i].offset_x_input)
saw_rolls[i].offset_x += event->mouse_dx;
+ if (saw_rolls[i].offset_y_input)
saw_rolls[i].offset_y += event->mouse_dy;
- }
+ }
break;