summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/saw/main.c52
1 files changed, 50 insertions, 2 deletions
diff --git a/source/saw/main.c b/source/saw/main.c
index 02d94c4..f9773c0 100644
--- a/source/saw/main.c
+++ b/source/saw/main.c
@@ -52,6 +52,8 @@
//
#define TIME_EPS 0.0001
+#define REFERENCE_PITCH 440.0 // A_4
+#define EQUAL_TEMPERAMENT_FACTOR 1.05946309436 // 2^(1/12)
enum {
// TODO
@@ -69,6 +71,8 @@ enum {
BUFFER_SIZE = 1024 * 8,
#endif
+ REFERENCE_PITCH_INDEX = 5 * 12, // index of A_4
+
#ifdef __EMSCRIPTEN__
TRACK_COUNT = 8,
ROLL_COUNT = 16,
@@ -146,6 +150,7 @@ typedef struct {
b8 enabled;
i64 track;
b8 pitch_turned_off[PITCH_COUNT];
+ f64 tuning[PITCH_COUNT];
i64 rate;
saw_roll_note_t notes[SHEET_SIZE];
i64 time;
@@ -316,6 +321,18 @@ static f64 saw_ui_input_buffer = 0.;
# pragma GCC optimize("O3")
#endif
+static void saw_tuning_equal_temperament(f64 *tuning) {
+ assert(tuning != NULL);
+ if (tuning == NULL)
+ return;
+
+ for (i64 i = 0; i < PITCH_COUNT; ++i) {
+ tuning[i] = REFERENCE_PITCH *
+ pow(EQUAL_TEMPERAMENT_FACTOR,
+ (f64) (i - REFERENCE_PITCH_INDEX));
+ }
+}
+
static f64 saw_random(f64 min, f64 max) {
if (max - min < .000001)
return min;
@@ -1323,6 +1340,7 @@ static void saw_ui_compose(i64 x0, i64 y0, i64 width, i64 height) {
.enabled = 1,
.track = track,
.pitch_turned_off = { 0 },
+ .tuning = { 0 },
.rate = ROLL_DEFAULT_RATE,
.notes = { 0 },
.time = frame,
@@ -1340,6 +1358,8 @@ static void saw_ui_compose(i64 x0, i64 y0, i64 width, i64 height) {
.loop_input = 0,
};
+ saw_tuning_equal_temperament(saw_rolls[n].tuning);
+
saw_current_roll = n;
saw_current_track = track;
}
@@ -2385,6 +2405,10 @@ static void saw_init(void) {
// Init Saw state
//
+ f64 tuning[PITCH_COUNT];
+
+ saw_tuning_equal_temperament(tuning);
+
for (i32 i = 0; i < ROLL_COUNT; i++) {
saw_compose.rolls[i] = (i == 0 ? 0 : -1);
@@ -2393,6 +2417,7 @@ static void saw_init(void) {
.track = 0,
.last_index = -1,
.pitch_turned_off = { 0 },
+ .tuning = { 0 },
.rate = ROLL_DEFAULT_RATE,
.notes = { 0 },
.time = 0,
@@ -2408,6 +2433,8 @@ static void saw_init(void) {
.ui_offset_y_input = 0,
.loop_input = 0,
};
+
+ memcpy(saw_rolls[i].tuning, tuning, sizeof tuning);
}
for (i32 i = 0; i < TRACK_COUNT; i++)
@@ -2515,12 +2542,29 @@ static void saw_init(void) {
return;
}
- for (i64 pitch = 0; pitch < pitch_count; pitch++) {
+ for (i64 pitch = 0; pitch < pitch_count; ++pitch) {
i32 flag;
SCAN_(" %d", 1, &flag);
roll->pitch_turned_off[pitch] = flag ? 1 : 0;
}
+#if 0
+ SCAN_(" tuning %d", 1, &pitch_count);
+
+ if (pitch_count < 0 || pitch_count > PITCH_COUNT) {
+ printf("Invalid tuning count: %d\n", pitch_count);
+ fflush(stdout);
+ fclose(f);
+ return;
+ }
+
+ for (i64 pitch = 0; pitch < pitch_count; ++pitch) {
+ i64 frequency;
+ SCAN_(" %lld", 1, &frequency);
+ roll->tuning[pitch] = .0001 * frequency;
+ }
+#endif
+
SCAN_(" rate %lld", 1, &roll->rate);
i32 sheet_size;
@@ -2857,8 +2901,12 @@ static void saw_cleanup(void) {
fprintf(f, "enabled %d\n", (i32) roll->enabled);
fprintf(f, "track %lld\n", roll->track);
fprintf(f, "pitch_turned_off %d\n ", PITCH_COUNT);
- for (i64 pitch = 0; pitch < PITCH_COUNT; pitch++)
+ for (i64 pitch = 0; pitch < PITCH_COUNT; ++pitch)
fprintf(f, " %d", (i32) roll->pitch_turned_off[pitch]);
+ fprintf(f, "tuning %d\n ", PITCH_COUNT);
+ for (i64 pitch = 0; pitch < PITCH_COUNT; ++pitch)
+ fprintf(f, " %lld",
+ (i64) floor(roll->tuning[pitch] * 10000 + .5));
fprintf(f, "\n");
fprintf(f, "rate %lld\n", roll->rate);