shithub: orca

Download patch

ref: fd0c4b9b42bfd84b791b1b61d87d1382e5e1cc40
parent: 86dd6be4f4edc4fadf253eba3a7baded145cdef5
author: Bequa La Froth <bequa@eelfroth.com>
date: Wed Apr 17 23:16:00 EDT 2019

Add --bpm option (#19)

* Add --bpm option

* Fix bpm bounds, and formatting

* Prevent int overflow on bpm adjust

* Prevent int overflow in overflow-guard

--- a/README.md
+++ b/README.md
@@ -69,6 +69,11 @@
                            If you plan to work with large files,
                            set this to a low number.
                            Default: 100
+    --initial-size <nxn>   When creating a new grid file, use these
+                           starting dimensions.
+                           Default: 57x25
+    --bpm <number>         Set the tempo (beats per minute).
+                           Default: 120
     -h or --help           Print this message and exit.
 
 OSC/MIDI options:
--- a/tui_main.c
+++ b/tui_main.c
@@ -33,9 +33,11 @@
 "                           If you plan to work with large files,\n"
 "                           set this to a low number.\n"
 "                           Default: 100\n"
-"    --initial-size <nxn>   When creating a new grid file, use these\n" 
+"    --initial-size <nxn>   When creating a new grid file, use these\n"
 "                           starting dimensions.\n"
 "                           Default: 57x25\n"
+"    --bpm <number>         Set the tempo (beats per minute).\n"
+"                           Default: 120\n"
 "    -h or --help           Print this message and exit.\n"
 "\n"
 "OSC/MIDI options:\n"
@@ -768,7 +770,7 @@
   bool is_hud_visible : 1;
 } Ged;
 
-void ged_init(Ged* a, Usz undo_limit) {
+void ged_init(Ged* a, Usz undo_limit, Usz init_bpm) {
   field_init(&a->field);
   field_init(&a->scratch_field);
   field_init(&a->clipboard_field);
@@ -783,7 +785,7 @@
   a->ruler_spacing_y = 8;
   a->ruler_spacing_x = 8;
   a->input_mode = Ged_input_mode_normal;
-  a->bpm = 120;
+  a->bpm = init_bpm;
   a->clock = 0;
   a->accum_secs = 0.0;
   a->time_to_next_note_off = 1.0;
@@ -1225,11 +1227,13 @@
 }
 
 void ged_adjust_bpm(Ged* a, Isz delta_bpm) {
-  Isz new_bpm = (Isz)a->bpm + delta_bpm;
+  Isz new_bpm = (Isz)a->bpm;
+  if (delta_bpm < 0 || new_bpm < INT_MAX - delta_bpm)
+    new_bpm += delta_bpm;
+  else
+    new_bpm = INT_MAX;
   if (new_bpm < 1)
     new_bpm = 1;
-  else if (new_bpm > 3000)
-    new_bpm = 3000;
   if ((Usz)new_bpm != a->bpm) {
     a->bpm = (Usz)new_bpm;
     a->is_draw_dirty = true;
@@ -1838,6 +1842,7 @@
   Argopt_osc_port,
   Argopt_osc_midi_bidule,
   Argopt_strict_timing,
+  Argopt_bpm,
 #ifdef FEAT_PORTMIDI
   Argopt_portmidi_list_devices,
   Argopt_portmidi_output_device,
@@ -1854,6 +1859,7 @@
       {"osc-port", required_argument, 0, Argopt_osc_port},
       {"osc-midi-bidule", required_argument, 0, Argopt_osc_midi_bidule},
       {"strict-timing", no_argument, 0, Argopt_strict_timing},
+      {"bpm", required_argument, 0, Argopt_bpm},
 #ifdef FEAT_PORTMIDI
       {"portmidi-list-devices", no_argument, 0, Argopt_portmidi_list_devices},
       {"portmidi-output-device", required_argument, 0,
@@ -1866,6 +1872,7 @@
   char const* osc_hostname = NULL;
   char const* osc_port = NULL;
   bool strict_timing = false;
+  int init_bpm = 120;
   int init_grid_dim_y = 25;
   int init_grid_dim_x = 57;
   Midi_mode midi_mode;
@@ -1903,6 +1910,16 @@
         exit(1);
       }
     } break;
+    case Argopt_bpm: {
+      init_bpm = atoi(optarg);
+      if (init_bpm < 1) {
+        fprintf(stderr,
+                "Bad bpm argument %s.\n"
+                "Must be positive integer.\n",
+                optarg);
+        exit(1);
+      }
+    } break;
     case Argopt_init_grid_size: {
       enum {
         Max_dim_arg_val_y = ORCA_Y_MAX,
@@ -1987,7 +2004,7 @@
 
   qnav_init();
   Ged ged_state;
-  ged_init(&ged_state, (Usz)undo_history_limit);
+  ged_init(&ged_state, (Usz)undo_history_limit, (Usz)init_bpm);
 
   if (osc_hostname != NULL && osc_port == NULL) {
     fprintf(stderr,