1 /*
2 * main.cc
3 * DIN Is Noise is copyright (c) 2006-2021 Jagannathan Sampath
4 * DIN Is Noise is released under GNU Public License 2.0
5 * For more information, please visit https://dinisnoise.org/
6 */
7
8 #include <SDL/SDL.h>
9 #include <string>
10 #include <map>
11 #include <vector>
12 #include <iostream>
13 #include <fstream>
14 #include <list>
15 #include <algorithm>
16 #include <tcl.h>
17 #include "dingl.h"
18 #include "main.h"
19 #include "box.h"
20 #include "utils.h"
21 #include "font.h"
22 #include "ui_list.h"
23 #include "console.h"
24 #include "input.h"
25 #include "viewwin.h"
26 #include "curve.h"
27 #include "multi_curve.h"
28 #include "solver.h"
29 #include "chrono.h"
30 #include "curve_editor.h"
31 #include "font_editor.h"
32 #include "din.h"
33 #include "curve_library.h"
34 #include "console_iterator.h"
35 #include "delay.h"
36 #include "random.h"
37 #include "globals.h"
38 #include "command.h"
39 #include "scalelist.h"
40 #include "morse_code.h"
41 #include "sine_mixer.h"
42 #include "tcl_interp.h"
43 #include "compressor.h"
44 #include "oscilloscope.h"
45 #include "keyboard_keyboard.h"
46 #include "authors_note.h"
47 #include "midi_in.h"
48 #include "menu.h"
49 #include "curve_picker.h"
50 #include "fractaliser.h"
51 #include "rose_milker.h"
52 #include "circler.h"
53 #include "spiraler.h"
54 #include "starrer.h"
55 #include "lissajous.h"
56 #include "superformula.h"
57 #include "warper.h"
58 #include "recorder.h"
59 #include "mondrian.h"
60 #include "instrument.h"
61 #include "countries.h"
62 #include "morpher.h"
63 #include "number.h"
64 #include "binaural_drones.h"
65 #include "fft.h"
66 #include "capturer.h"
67 #include "noiser.h"
68 #include "defvelaccel.h"
69
70 using namespace std;
71
72 ofstream dlog ("log", ios::out); // DIN Is Noise log
73
74 extern const float GOLDEN_RATIO = 1.618033;
75 extern const float PI = 3.1415961;
76 extern const float TWO_PI = 2 * PI;
77 extern const float PI_BY_180 = PI / 180.;
78 extern const char spc = ' ';
79 const string tokenizer::DEFAULT_DELIMITER (" ");
80
81 // for attack, decay and deltas [see keyboard-keyboard.cc, mondrian.cc, triggered_note.cc]
82 extern const float MIN_TIME = 0.01f; // seconds
83
84 #if defined __GPL20__
85 string home = getenv ("HOME");
86 string user_data_dir (home + "/.din/"); // contains defaults, user savings and preferences
87 string country_data_dir (user_data_dir + "country/"); // contains country data used by countries plugin (see countries.cc)
88 #elif defined (__MACOSX_CORE__) || defined (__LINUX_BIN__)
89 string user_data_dir = "user/";
90 string country_data_dir = "user/country/";
91 #elif __WINDOWS_DS__
92 string user_data_dir = "user\\";
93 string country_data_dir = "user\\country\\";
94 #endif
95
96 tcl_interp interpreter; // integrated TCL interpreter
97
98 int quit = DONT;
99
100 struct startup_shutdown {
101
startup_shutdownstartup_shutdown102 startup_shutdown () {
103 dlog << "!!! started DIN Is Noise !!!" << endl;
104 time_t t0 = time(0);
105 seed_rand_gen (t0);
106 dlog << "+++ initialised random number generator @ seed = " << t0 << " +++" << endl;
107 }
108
~startup_shutdownstartup_shutdown109 ~startup_shutdown () {
110 SDL_Quit ();
111 dlog << "!!! cleaned up SDL !!!" << endl;
112 dlog << "*** [Mondrian] box count = " << rect::ref << " ***" << endl;
113 dlog << "*** [Mondrian] ball count = " << ball::ref << " ***" << endl;
114 dlog << "*** [Mondrian] slit count = " << slit::ref << " ***" << endl;
115 dlog << "*** [Microtonal-Keyboard] drone count = " << drone::ref << " ***" << endl;
116 dlog << "\\o/ DIN Is Noise was up for " << interpreter ("uptime 0").result << " \\o/" << endl;
117 }
118
119 } SS ;
120
121 // DIN clocks
122 double TIME_NOW = 0; // in seconds on the audio clock stored in variable timenow on TCL interpreter
123 audio_clock clk; // audio clock
124 ui_clock ui_clk; // UI clock
125
126 // keyboard and mouse state
127 keyboard keybd;
128 int mousex = 0, mousey = 0, mouseyy = 0; // absolute mouse x, y & main viewport y
129 int lmb = 0, rmb = 0; // left & right mouse buttons
130 int wheel = 0; // mouse wheel
131 int wheely = -60; // for moving menu, settings widgets
132 int SHIFT = 0; // shift button
133 int CTRL = 0; // ctrl button
134 int ALT = 0; // alt button
135 is_lmb_t is_lmb; // for acquiring lmb
136
137 // UI
138 int UI_OFF = 0;
139 int widget::HOVER = 0; // mouse hovering on any widget?
140 widget* widget::focus = 0; // widget that has focus
141 widget* widget::next_focus = 0; // widget waiting to have focus
142
143 // see spinner.h, spinner2.h
144 int SPACING = 5;
145 int VAR_MIN = -100, VAR_MAX = 100; // for variance @ spinner.h
146 int VAR_MIN2 = 0, VAR_MAX2 = 100; // for variance @ spinner2.h
147 string VARSTR, VARSTR2;
148
149 // widget defaults
150 // loaded from globals file (see globals.cc)
151 float widget::R, widget::G, widget::B; // default widget color
152 int widget::bb [16] = {0}; // widget bounding box
153 color checkbutton::on_color, checkbutton::off_color; // checkbutton on/off colors
154 const char* field::fmts [] = {"%0.3f", "%0.4f", "%0.6f", "%f"}; // precision formats for field
155
156 int FPS = 0; // requested frames per second
157 double TIME_PER_FRAME; // in seconds, calc @ command.cc
158 double LAST_FRAME_TIME = 0.0;
159
160 int IPS; // keyboard/mouse inputs per second
161 double TIME_PER_INPUT; // in seconds
162
163 int basic_editor::hide_cursor = 0; // to hide cursor when mouse is on a ui control
164 float* basic_editor::gl_pts = 0;
165 int basic_editor::n_pts = 0;
166 int basic_editor::ref = 0;
167
168 int plugin::change_curve_name = 1; // when applying plugin?
169
170 int capturer_t::ref = 0; // see capturer.h
171 int point_modulator::ref = 0; // see point_modulator.h
172
173 list<crvpt> LIST_OF_POINTS; // list of points (see curve.h/cc)
174
175 // see drone.h/cc
176 int drone::UID = 0; // unique id for drones
177 int drone::ref = 0; // for ref counting drones
178 map<drone*, bool> drone::proc_conn; // drone connections
179 float drone::STIFFNESS = 1.0f; // stiffness of inter-drone connections
180 double drone::LIFETIME = 7; // for launched drones (seconds)
181 int drone::HANDLESIZE = 3; // default drone handle size
182 double drone::INSERTTIME = 3; // for launched drones to get into orbit (seconds)
183 double drone::gabt = 1.0f; // for mute/unmute drones
184 float drone::mastervolume = 0.0f; // for all drones
185 point<float> mod_params::horizontal (1.0f,0.0f), mod_params::vertical (0.0f,1.0f); // drone modulation directions
186 int drone::IS = drone::DRONE;
187 drone::wandt drone::wand (5.0); // for wandded drones
188 anglet drone::chuckt::apt; // angle per turn (degrees) for chuck rotation
189 int drone::chuckt::outline = 1; // draw chuck outlines?
190 int drone::chuckt::autoresettrails = 1; // when chuck params changed?
191 int drone::ARE = drone::IMMORTAL; // type of drone
192
193 defvelaccel drone::v0 (" Velocity"), drone::a0 (" Acceleration");
194 int drone::anchored = 0;
195 float drone::arrowt::U = 0.25, drone::arrowt::V = 0.25, drone::arrowt::K = 1.0f, drone::arrowt::CAP = 1;
196
197 // for drone <> noise conversion
198 drone::drone2noise drone::dnl;
199 drone::noise2drone drone::ndl;
200 drone::fin* drone::fins[3] = {0, &drone::dnl, &drone::ndl};
201
202 double drone::posafxvelt::minmag = 3.0f;
203
204 // for trails on drones and mondrian
205 float* trail_t::tpts = 0;
206 int trail_t::n_tpts = 0;
207
208 // drone mesh, see mesh.h/cc
209 int* mesh::gl_pts = 0;
210 float* mesh::clr = 0;
211 int mesh::n_glpts = 0;
212 int proximity_orderer::ROW = 0, proximity_orderer::COL = 0;
213
214 double fader::TIME; // loaded from din_info
215
216 // see curve_mixer.h/cc
217 float curve_mixer::TIME = 1.0f; // curve (waveform/envelope) mixing time in seconds
218 int curve_mixer::SAMPLES = 1024; // curve mixing time in samples, change one, changes the other
219 double curve_mixer::ELAPSEDT = 0.0;
220
221 // for sprintf
222 const int BUFFER_SIZE = 1 << 15;
223 char BUFFER [BUFFER_SIZE] = {0};
224
225 // music constants
226 //
227
228 int NUM_NOTES = 13;
229
230 // notations
231 int NOTATION = WESTERN;
232 const char* WESTERN_SHARP [] = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B", "C"};
233 const char* WESTERN_FLAT [] = {"C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B", "C"};
234 const char* INDIAN_SWAR [] = {"S", "r", "R", "g", "G", "m", "M", "P", "d", "D", "n", "N", "S"};
235
236 // for the octave of Middle-C; from wikipedia - piano key frequencies page.
237 float WIKIPEDIA_KEY_FREQUENCIES [] = {
238 261.626f, 277.183f, 293.665f, 311.127f, 329.628f, 349.228f, 369.994f, 391.995f, 415.305f, 440.0f, 466.164f, 493.883f, 523.251f
239 };
240
241 string NEAREST_NOTE; // note nearest to key of DIN
242 float NEAREST_NOTE_DISTANCE; // distance in Hz of the nearest note from the key of DIN
243 float NEAREST_NOTE_FREQUENCY; // frequency in Hz of the nearest note to the key of DIN
244
245 int SAMPLE_RATE; // sample rate of DIN
246 float SAMPLE_DURATION; // duration of an audio sample in seconds
247
248 string SCALE; // current scale
249 string TUNING; // current tuning
250 int NUM_INTERVALS; // number of intervals in tuning
251 string INTERVALS_FILE; // file name that contains interval info
252 map <string, float> INTERVALS; // interval name -> value
253 map <string, string> INT2IND;
254 vector<string> INTERVAL_NAMES; // sequential interval names (eg., 1 2b 2 3b 3 ... 7b 7 8)
255 vector<float> INTERVAL_VALUES; // sequential interval values (eg., value of 1 2b 3 3b ... 7b 7 8)
256 map <string, int> NOTE_POS; // interval name -> note number (eg., 1 => 0, 2b => 1, 3 => 2, etc)
257
258 scale_info all_notes; // used by change left/right note on range to move to any note
259
260 //
261 // microtonal keyboard
262 //
263 const char* s_drones = " drones";
264 int LEFT = 0, BOTTOM, TOP;
265 int WIDTH, HEIGHT;
266 int TRAILSIZE = 0; // default drone trail size (== number of trail points), mondrian ball trail size
267 int NUM_OCTAVES = 0; // number of octaves
268
269 // random bpm init see range::init_mod()
270 // limits loaded from globals file, see globals.cc
271 rnd<int> RAN_MOD_BPM;
272
273 const char* din_info::cnn_opts [] = {" to scale note", " to any note"};
274 const char* din_info::cnno [] = {"Octave", "Note"};
275
276 // see curve_samples in curve_editor.h
277 float HZ;
278 float curve_samples::dm = 0.0f;
279 float curve_samples::nsec = 2.0f;
280
281 // screens - 1 is instrument; 2 - 8 are editors
282 //
283 const Uint8 ui_list::key [] = {SDLK_2, SDLK_3, SDLK_4, SDLK_5, SDLK_6, SDLK_7, SDLK_8}; // keys 2 - 8
284 ui* ui_list::ed [] = {0};
285 ui* ui::over = 0;
286
287 // solver xhandlers; see solver.cc
288 atmin _atmin;
289 atmax _atmax;
290 tomin _tomin;
291 tomax _tomax;
292 loopmin _loopmin;
293 loopmax _loopmax;
294 pongmin _pongmin;
295 pongmax _pongmax;
296
297 // see multi_curve.cc
298 multi_curve curve_editor::copy;
299 multi_curve mix;
300
301 color curve_editor::vtxlbl; // vertex label color
302 int hit_t::name_only = 0;
303
304 // see sine_mixer.cc
305 int sine_mixer::NUM_SINE_SAMPLES = 100;
306 const int sine_mixer::MIN_SINE_SAMPLES = 4;
307
308 // program
309 //
310 string VERSION_NUMBER;
311 string LOCATION;
312 string APP_NAME;
313
314 int SCREEN_WIDTH, SCREEN_HEIGHT; // initial screen width & height (from user/globals)
315 const int SCREEN_DEPTH = 24; // fixed color depth
316 int FULL_SCREEN = 0; // full screen?
317
318 // see viewwin.cc
319 viewport view; // display - using OpenGL
320 int viewport::handle_radius = 50;
321 float viewport::handle_factor = 0.0f;
322 int window::PAN_RATE = 100, window::ZOOM_RATE = 100;
323 double window::PAN_REPEAT = 1.0 / PAN_RATE, window::ZOOM_REPEAT = 1.0 / ZOOM_RATE;
324 float window::PAN_AMOUNT = 0.1f, window::ZOOM_AMOUNT = 0.1f;
325
326 load_globals lg;
327
328 // 0 init correct for oscilloscope; see oscilloscope.cc
329 float oscilloscope::sample_t::lmin = 0, oscilloscope::sample_t::lmax = 0;
330 float oscilloscope::sample_t::rmin = 0, oscilloscope::sample_t::rmax = 0;
331 oscilloscope scope ("scope.osc");
332
333 // custom vector font
334 #ifdef __SVG_FNT__
335 font fnt ("laser.fnt");
336 #elif __PLOTTER_FNT__
337 font fnt ("plotter.fnt");
338 #else
339 font fnt ("jag.fnt");
340 #endif
341 int line_height; // of text
342
343 // console
344 //
345
346 // possible text colors of console
347 const float cc = 0.50f;
348 const color console::yellow (1, 1, cc);
349 const color console::green (cc, 1, cc);
350 const color console::red (1, cc, cc);
351 const color console::cyan (cc, 1, 1);
352 const color console::white (1, 1, 1);
353
354 string CHARSET [] = { // list of input chars
355 // default is US layout
356 "abcdefghijklmnopqrstuvwxyz0123456789 .=-/;\\,[]'`", // normal
357 "ABCDEFGHIJKLMNOPQRSTUVWXYZ)!@#$%^&*( >+_?:|<{}\"~", // shift
358 };
359 const int CHARSET_LENGTH = CHARSET[0].length ();
360 const char* console::precision = "%.3f";
361 console cons;
362
set_window_caption()363 void set_window_caption () {
364 make_app_name ();
365 SDL_WM_SetCaption (APP_NAME.c_str(), APP_NAME.c_str());
366 }
367
get_typed_char()368 char get_typed_char () { // get char typed on an input area
369 const string& norm = CHARSET[0];
370 const string& shift = CHARSET[1];
371 for (int i = 0; i < CHARSET_LENGTH; ++i) {
372 if (keypressedd (norm[i])) {
373 if (SHIFT || keydown (SDLK_CAPSLOCK))
374 return shift[i];
375 else
376 return norm[i];
377 }
378 }
379 return 0;
380 }
381
382 // audio output
383 //
384 audio_out aout;
385
386 // list of scales
387 scalelist scalelst;
388
389 //
390 // L and R delays
391 //
392 delay left_delay (1000, "feedback-l.crv", "volume-l.crv"), right_delay (1000, "feedback-r.crv", "volume-r.crv");
393 curve_editor delayed ("delay.ed");
394
395 font_editor fed (fnt, "font.ed", "font.hlp");
396 multi_curve dummy ("dummy.crv");
397
398 // vars in Tcl interpreter
399 //
400
401 // midi bpm from external midi clock
402 double MIDI_BPM = 0;
403
404 // tap bpm from computer keyboard
405 double TAP_BPM = 0;
406
407 // microtonal-keyboard height (0 to 1)
408 float VOLUME = 0;
409
410 fft fft0; // FFT of waveform in waveform editors
411
412 cmdlist cmdlst; // list of din commands
413
414 // 1 oscillator / waveform for lead
415 //
416
417 float VOICE_VOLUME = 0.2f;
418
419 //
420 // curve libraries
421 //
422 curve_library wav_lib ("waveforms.lib"); // waveforms
423 curve_library sin_lib ("sin.lib"); // custom sine curves
424 curve_library cos_lib ("cos.lib"); // custom cosine curves
425 curve_library attack_lib ("attack.lib", 1); // attack curves [1 = has_sustain]
426 curve_library decay_lib ("decay.lib"); // decay curves
427
428 // compressor
429 compressor coml ("coml.crv"), comr ("comr.crv");
430 curve_editor comed ("compressor.ed");
431
432 // octave shift
433 //
434 beat2value octave_shift ("os", "octave-shift.crv");
435 curve_editor octed ("octave-shift.ed");
436 curve_library octlib ("octave-shift-patterns.lib");
437 beat2value_listener octlis;
438
439 // drone modulation
440 //
441 multi_curve drone_mod_am_crv ("drone-mod-am.crv");
442 multi_curve drone_mod_fm_crv ("drone-mod-fm.crv");
443 curve_editor drone_mod_ed ("drone-modulation.ed");
444 drone_mod_lis dmlis;
445
446 // range modulation
447 multi_curve ran_mod_width_crv ("range-mod-width.crv");
448 multi_curve ran_mod_height_crv ("range-mod-height.crv");
449 curve_editor ran_mod_ed ("range-modulation.ed");
450
451 // point modulation
452 curve_editor pomo_ed ("point-modulation.ed");
453 multi_curve pomo_x_crv ("pomo-x.crv");
454 multi_curve pomo_y_crv ("pomo-y.crv");
455 pomo_lis pol;
456
457 // range width/height set
458 multi_curve ran_width_crv ("range-width.crv"), ran_height_crv ("range-height.crv");
459 solver sol_ran_width (&ran_width_crv), sol_ran_height (&ran_height_crv);
460 curve_editor ran_wh_ed ("range-width-height.ed");
461 range_wh_lis rwhl;
462
463 // pitch / volume distribution
464 multi_curve pitch_crv ("pitch.crv"), vol_crv ("vol.crv");
465 curve_editor pitch_vol_ed ("pitch-vol.ed");
466 solver warp_pitch (&pitch_crv), warp_vol (&vol_crv);
467 multi_curve* warcrv [] = {&pitch_crv, &vol_crv};
468 solver* warsol_pv [] = {&warp_pitch, &warp_vol};
469 pitch_vol_lis pvl;
470
471 // noise interpolation
472 multi_curve noiser::interp ("noiser.crv");
473 curve_editor noiser::ed ("noiser.ed");
474 noise_interp_lis noiser::lis;
475
476 // drone pendulum depth & bpm
477 multi_curve dp_depth ("dp_depth.crv"), dp_bpm ("dp_bpm.crv");
478 curve_editor drone_pend_ed ("drone-pend.ed");
479 solver warp_depth (&dp_depth), warp_bpm (&dp_bpm);
480 solver* warsol_dp [] = {&warp_depth, &warp_bpm};
481 multi_curve* dp_crv [] = {&dp_depth, &dp_bpm};
482 drone_pend_ed_lis dpel;
483
484 recorder recorder0; // for recording sounds made in DIN
485
486 // microtonal-keyboard see din.cc/.h
487 //
488
489 const string din::PSD = "Please select some drones!";
490 const string din::A2D = "Please select at least 2 drones.";
491 const char* ol_fixed_lbls [] = {" with left fixed", " with center fixed", " with right fixed"};
492 const char* voice_is_lbls [] = {"Noise", "Voice"};
493 din din0 (cmdlst);
494
495 // mondrian (see mondrian.cc/h)
496 //
497 rnd<float> rect::rd (0.0f, 1.0f); // to make box color
498 int rect::ref = 0, ball::ref = 0, slit::ref = 0;
499 const float mondrian::gutter = 2;
500 const float mondrian::gutter2 = mondrian::gutter * mondrian::gutter;
501 float mondrian::min_split_size = 16;
502 float slit::HALF_SIZE = 20;
503 float slit::MIN_HALF_SIZE = 1;
504 float slit::MIN_SIZE = 2 * slit::MIN_HALF_SIZE;
505 const char* ball::types_str [4] = {"bouncer", "wrecker", "healer", "bouncer or wrecker or healer"};
506 float ball::recent_attack_time = 0.01f; // secs
507 float ball::recent_decay_time = 2.0f; // secs
508 float ball::recent_pitch_mult = 1.0f; // modulation
509 const char* mondrian_listener::split_types [3] = {" into 2 boxes", " at notes", " into N boxes"};
510 const char* mondrian_listener::selection_targets [2] = {"Selection target = slits", "Selection target = balls"};
511 const char* mondrian_listener::pick_box_types [5] = {" Pick the oldest box", " Pick a random box", " Pick the biggest box", " Pick the youngest box", " Pick a box that has a ball"};
512 const char* mondrian_listener::auto_split_orient_types [4] = { "", " Split horizontally", " Split vertically", " Split horizontally & vertically"};
513 const char* mondrian_listener::auto_split_at_types [2] = {" Split at notes", " Split anywhere"};
514 const double slit::INITIAL_OPEN_CLOSE_TIME = 2.0;
515
516 // ball operations
517 const char* ball_op::names [] = {"All Ops", "Turn", "Speed", "Teleport", "Clone"};
518 float ball_op::TRIGGERT = 0.1; // seconds
519 float turn::CLOCKWISE = 60.0f, turn::ANTI_CLOCKWISE = 60.0f; // degrees
520 float speed::BRAKE = 1, speed::ACCELERATE = 1;
521 float teleport::MAX_RADIUS = 300.0f;
522 int Clone::max_balls = 64;
523 int Transform::rules [3] = {ball::WRECKER, ball::HEALER, ball::BOUNCER};
524
525 mondrian mondrian0;
526
527 // binaural drones see binaural_drones.cc/h)
528 //
529 i_binaural_drones binaural_drones0;
530 const char* binaural_drones_listener::justs [] = {" Justification = Left", " Justification = Right", " Justification = Center"};
531 gotog _gotomax (1, &mondrian0.attacked);
532
533 // keyboard-keyboard
534 //
535 float NOTE_VOLUME = 0.75f * VOICE_VOLUME;
536
537 int PITCH_BEND; // in Hz
538 float PITCH_BEND_PER_PIXEL;
539
540 // in seconds
541 float ATTACK_TIME = 0.05f;
542 float DECAY_TIME = 5.0f;
543 float DELTA_TIME = 0.025f;
544
545 color keyboard_keyboard::note_color[2]; // midi keybd note color
546 const int keyboard_keyboard::color_index [] = {0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0}; // 0 - white, 1 - black; 1 octave
547 keyboard_keyboard keybd2;
548 gotog _gotog (1, &keybd2.attacked); // default sustain (see keyboard-keyboard.cc)
549
550 // available instruments
551 const char* INSTRUMENTS [] = {"keyboard_keyboard", "microtonal_keyboard", "mondrian", "binaural_drones"};
552 const char* INSTRUMENTS_SHORT [] = {"kkb", "mkb", "mon", "bd"};
553 extern const int NUM_INSTRUMENTS = 4, LAST_INSTRUMENT = NUM_INSTRUMENTS - 1;
554 int CURRENT_INSTRUMENT = 0;
555 string INSTRUMENT = INSTRUMENTS [CURRENT_INSTRUMENT];
556 instrument* INSTRUMENT_PTR [] = {&keybd2, &din0, &mondrian0, &binaural_drones0};
557 checkbutton* LAST_TABS [NUM_INSTRUMENTS] = {0, 0, 0, 0};
558
559 mkb_selector_t mkb_selector; // selector for microtonal keyboard with drone mesh preview
560 box_selector mon_selector; // selector for mondrian
561
562 string style_listener::styles [] = {"loop", "pong"};
563
564 vector<multi_curve*> curve_list;
setup_curve_list()565 void setup_curve_list () {
566 multi_curve* lst [] = {
567 &din0.wave,
568 &keybd2.wave,
569 din0.fm.crv,
570 din0.am.crv,
571 din0.gatr.crv,
572 octave_shift.crv,
573 &din0.drone_wave,
574 &left_delay.fbk_crv,
575 &left_delay.vol_crv,
576 &right_delay.fbk_crv,
577 &right_delay.vol_crv
578 };
579 for (int i = 0; i < 11; ++i) curve_list.push_back (lst[i]);
580 }
581
582 const char* bpm_com::str [bpm_com::NUM] = {"os", "gr", "am", "fm"};
583 beat2value* bpm_com::bv [] = {&octave_shift, &din0.gatr, &din0.am, &din0.fm};
584
585 #define DEFINE_TCL_FUNC(X) inline int (X) (ClientData cd, Tcl_Interp* ti, int objc, Tcl_Obj* CONST objv[]) { return tcl_run (cd, ti, objc, objv);}
586
587 DEFINE_TCL_FUNC(tcl_key)
588 DEFINE_TCL_FUNC(tcl_setv)
589 DEFINE_TCL_FUNC(tcl_getv)
590 DEFINE_TCL_FUNC(tcl_set_delay)
591 DEFINE_TCL_FUNC(tcl_get_delay)
592 DEFINE_TCL_FUNC(tcl_set_bpm)
593 DEFINE_TCL_FUNC(tcl_get_bpm)
594 DEFINE_TCL_FUNC (tcl_set_beat);
595 DEFINE_TCL_FUNC (tcl_get_beat);
596 DEFINE_TCL_FUNC(tcl_set_style)
597 DEFINE_TCL_FUNC(tcl_get_style)
598 DEFINE_TCL_FUNC(tcl_set_kern)
599 DEFINE_TCL_FUNC(tcl_get_kern)
600 DEFINE_TCL_FUNC(tcl_set_font_size)
601 DEFINE_TCL_FUNC(tcl_get_font_size)
602 DEFINE_TCL_FUNC(tcl_note_distance)
603 DEFINE_TCL_FUNC(tcl_chord)
604 DEFINE_TCL_FUNC(tcl_notation)
605 DEFINE_TCL_FUNC(tcl_echo)
606 DEFINE_TCL_FUNC(tcl_curve_value)
607 DEFINE_TCL_FUNC(tcl_curve_name)
608 DEFINE_TCL_FUNC(tcl_curve_library)
609 DEFINE_TCL_FUNC(tcl_morse_code)
610 DEFINE_TCL_FUNC (tcl_set_editor);
611 DEFINE_TCL_FUNC (tcl_set_kb_layout);
612 DEFINE_TCL_FUNC (tcl_set_scope);
613 DEFINE_TCL_FUNC (tcl_get_scope);
614 DEFINE_TCL_FUNC (tcl_get_drone);
615 DEFINE_TCL_FUNC (tcl_set_drone);
616 DEFINE_TCL_FUNC (tcl_text_color);
617 DEFINE_TCL_FUNC (tcl_paste_gater);
618 DEFINE_TCL_FUNC (tcl_get_intervals);
619 DEFINE_TCL_FUNC (tcl_num_octaves);
620 DEFINE_TCL_FUNC (tcl_set_audio);
621 DEFINE_TCL_FUNC (tcl_load_scale);
622 DEFINE_TCL_FUNC (tcl_scale_curve);
623 DEFINE_TCL_FUNC (tcl_binaural_drone);
624 DEFINE_TCL_FUNC (tcl_set_sine_mixer);
625 DEFINE_TCL_FUNC (tcl_change_sine_mixer);
626 DEFINE_TCL_FUNC (tcl_update_sine_mixer);
627 DEFINE_TCL_FUNC (tcl_write_svg);
628 DEFINE_TCL_FUNC (tcl_write_trail);
629
630 // din commands
631 //
632 // format: long name, short name
633
634 // for L and R delays
635 set_delay sd (&left_delay, &right_delay, "set-delay", "sd");
636 get_delay gd (&left_delay, &right_delay, "get-delay", "gd");
637
638 // to load the scale
639 load_scale los (&din0, "load-scale", "los");
640
641 // set and get din variables
642 set_var sv (&din0, "set-var", "sv");
643 get_var gv (&din0, "get-var", "gv");
644
645 // bpm commands
646 //
647 set_bpm sb ("set-bpm", "sb");
648 get_bpm gb ("get-bpm", "gb");
649 set_beat sn ("set-beat", "sbt");
650 get_beat gn ("get-beat", "gbt");
651 set_style ss ("set-style", "ss");
652 get_style gs ("get-style", "gs");
653
654 // set key/tonic
655 key ky (&din0, "key", "key");
656
657 // display notation on the keyboard
658 notation no (&din0, "notation", "no");
659
660 // music utils
661 note_distance nd ("note-distance", "nd");
662 chord ch ("chord", "ch");
663
664 // font cmds
665 set_font_size sfs ("set-font-size", "sfs");
666 get_font_size gfs ("get-font-size", "gfs");
667 set_kern sk ("set-kern", "sk");
668 get_kern gk ("get-kern", "gk");
669
670 // curve cmds
671 curve_name cn ("curve-name", "cn");
672 curve_value cv ("curve-value", "cv");
673 curve__library cl ("curve-library", "cl");
674 set_curve_editor sced ("set-curve-editor", "sced");
675 paste_gater pasg ("paste-gater", "paste-gater");
676 scale_curve scrv ("scale-curve", "scrv");
677
678 // morse code
679 morse_code mc ("morse-code", "mc");
680
681 // to replace curves in a multi curve with a seed curve
682 fractaliser fractaliser_;
683
684 // to generate curve from polar equation R = sin (K * theta)
685 rose_milker rosemilker;
686
687 // to generate a regular polygon
688 circler circler_;
689
690 // to generate a spiral with R = A * theta
691 spiraler spiraler_;
692
693 // to connect dots to make star polygons
694 starrer starrer_;
695
696 // to generate lissajous curve
697 lissajous lissajous_;
698
699 // to generate superformula curve
700 superformula superformula_;
701
702 // to warp XY of segments of a curve
703 warper warper_;
704
705 // to turn country outlines into curves
706 countries countries_;
707
708 // to morph one curve into another
709 morpher morpher_;
710
711 // to convert a number into a curve
712 number number_;
713
714 // sine mixer for waveform edit
715 sine_mixer sinemixer;
716
717 // plugin browser
718 const int plugin_browser::num_plugins = 12;
719 plugin* plugin_browser::plugins [] = {
720 &circler_,
721 &sinemixer,
722 &rosemilker,
723 &spiraler_,
724 &lissajous_,
725 &number_,
726 &fractaliser_,
727 &countries_,
728 &warper_,
729 &morpher_,
730 &superformula_,
731 &starrer_,
732 };
733
734 // unix like echo
735 echo ech ("echo", ".");
736
737 set_kb_layout kbl ("set-kb-layout", "kbl");
738
739 // oscilloscope
740 set_scope ssco ("set-scope", "ssco", &din0, &binaural_drones0);
741 get_scope gsco ("get-scope", "gsco", &din0);
742
743 // drone
744 get_drone gdro ("get-drone", "gdro", din0);
745 set_drone sdro ("set-drone", "sdro", din0);
746
747 // console
748 set_text_color stc ("set-text-color", "stc");
749
750 // get scale intervals
751 get_intervals gint ("get-intervals", "gint");
752
753 // set number of octaves
754 num_octaves noct ("num-octaves", "noct", din0);
755
756 // set audio
757 set_audio sau ("set-audio", "sa");
758
759 #ifdef __SVG__
760 write_svg wsvg ("write-svg", "wsvg"); // write curve into svg file
761 write_trail wtrl ("write-trail", "wtrl"); // write drone trails into svg file
762 #endif
763
764 #ifdef __HPGL__
765 write_hpgl whpgl ("write-hpgl", "hpgl"); // write curve into hp-gl file for output on graphtec plotters
766 #endif
767
768 // used by binaural drones instrument
769 cmd_binaural_drone snd ("binaural-drone", "bd");
770
771 set_sine_mixer ssm ("set-sine-mixer", "ssm");
772 change_sine_mixer csm ("change-sine-mixer", "csm");
773 update_sine_mixer usm ("update-sine-mixer", "usm");
774
add_commands(Tcl_Interp * interp)775 void add_commands (Tcl_Interp* interp) { // add din commands to Tcl interpreter
776
777 unsigned int ncmds = 42;
778 tclcmd cmd_funcs [] = {
779 tcl_key,
780 tcl_setv,
781 tcl_getv,
782 tcl_set_delay,
783 tcl_get_delay,
784 tcl_set_bpm,
785 tcl_get_bpm,
786 tcl_set_beat,
787 tcl_get_beat,
788 tcl_set_style,
789 tcl_get_style,
790 tcl_set_kern,
791 tcl_get_kern,
792 tcl_set_font_size,
793 tcl_get_font_size,
794 tcl_note_distance,
795 tcl_chord,
796 tcl_notation,
797 tcl_echo,
798 tcl_curve_value,
799 tcl_curve_name,
800 tcl_curve_library,
801 tcl_morse_code,
802 tcl_set_editor,
803 tcl_set_scope,
804 tcl_get_scope,
805 tcl_get_drone,
806 tcl_set_drone,
807 tcl_text_color,
808 tcl_paste_gater,
809 tcl_get_intervals,
810 tcl_num_octaves,
811 tcl_set_kb_layout,
812 tcl_set_audio,
813 tcl_load_scale,
814 tcl_scale_curve,
815 tcl_binaural_drone,
816 tcl_set_sine_mixer,
817 tcl_change_sine_mixer,
818 tcl_update_sine_mixer,
819 tcl_write_svg,
820 tcl_write_trail,
821 };
822
823 command* cmds [] = {
824 &ky,
825 &sv,
826 &gv,
827 &sd,
828 &gd,
829 &sb,
830 &gb,
831 &sn,
832 &gn,
833 &ss,
834 &gs,
835 &sk,
836 &gk,
837 &sfs,
838 &gfs,
839 &nd,
840 &ch,
841 &no,
842 &ech,
843 &cv,
844 &cn,
845 &cl,
846 &mc,
847 &sced,
848 &ssco,
849 &gsco,
850 &gdro,
851 &sdro,
852 &stc,
853 &pasg,
854 &gint,
855 &noct,
856 &kbl,
857 &sau,
858 &los,
859 &scrv,
860 &snd,
861 &ssm,
862 &csm,
863 &usm,
864 &wsvg,
865 &wtrl,
866 };
867
868 extern cmdlist cmdlst;
869 for (unsigned int i = 0; i < ncmds; ++i) {
870 command* cmdp = cmds [i];
871 cmdlst.add (cmdp);
872 Tcl_CreateObjCommand (interp, cmdp->longname.c_str(), cmd_funcs[i], (ClientData) i, 0);
873 Tcl_CreateObjCommand (interp, cmdp->shortname.c_str(), cmd_funcs[i], (ClientData) i, 0);
874 }
875
876 dlog << "+++ added " << ncmds << " din commands to the Tcl interpreter +++" << endl;
877
878 }
879
880 authors_note anote;
881 curve_picker_t curve_picker;
882
883 mouse_slider mouse_slider0;
884
885 const char* menu::defvelaccelui::autorotatet::diropts [] = {" Clockwise", " Anti clockwise", " Clockwise or Anti-clockwise"};
886 const char* menu::defvelaccelui::autorotatet::movopts [] = {" Ticked", " Smooth", " Smooth or Ticked"};
887 ui_list uis;
888
modulate_down()889 void modulate_down () {
890 instrument* instr = get_current_instrument ();
891 if (instr->osd.active == 0) {
892 static const string down = "down";
893 start_octave_shift (instr, 0, down);
894 }
895 }
896
modulate_up()897 void modulate_up () {
898 instrument* instr = get_current_instrument ();
899 if (instr->osd.active == 0) {
900 static const string up = "up";
901 start_octave_shift (instr, 1, up);
902 }
903 }
904
start_octave_shift(instrument * instr,int idir,const string & sdir)905 void start_octave_shift (instrument* instr, int idir, const string& sdir) {
906 octave_shift_data& osd = instr->osd;
907 osd.tonic = instr->scaleinfo.tonic;
908 osd.dir = idir;
909 osd.active = 1;
910 osd.now = octave_shift.sol.firstx;
911 }
912
do_octave_shift()913 void do_octave_shift () {
914 for (int i = 0; i < NUM_INSTRUMENTS; ++i) {
915 instrument* instr = INSTRUMENT_PTR [i];
916 octave_shift_data& osd = instr->osd;
917 if (osd.active) {
918 osd.now += (octave_shift.delta * aout.samples_per_channel);
919 static const string octave_shift_str = "Octave Shift ", percent = "%";
920 float now = osd.now - octave_shift.sol.firstx;
921 float delta = octave_shift.sol.lastx - octave_shift.sol.firstx;
922 osd.percent_complete = (int) (now / delta * 100);
923 stringstream ss; ss << octave_shift_str << osd.percent_complete << percent;
924 string txt (ss.str());
925 MENU.l_octave_shift.set_text (txt);
926 uis.l_octave_shift.set_text (txt);
927 if (osd.now > octave_shift.sol.lastx) { // finished
928 osd.now = octave_shift.sol.lastx;
929 osd.active = 0;
930 MENU.l_octave_shift.set_text (octave_shift_str);
931 uis.l_octave_shift.set_text (octave_shift_str);
932 }
933 float shift = octave_shift.sol (osd.now);
934 if (shift != 0) {
935 if (osd.dir) set_tonic (instr, osd.tonic * shift); // go up
936 else set_tonic (instr, osd.tonic / shift); // go down
937 }
938
939 if (!osd.active) {
940 cons << GREEN;
941 cons ("key");
942 }
943
944 }
945 }
946
947 }
948
abort_octave_shift(instrument * inst)949 int abort_octave_shift (instrument* inst) {
950 octave_shift_data& osd = inst->osd;
951 if (osd.active) {
952 osd.active = 0;
953 cons << GREEN;
954 cons ("key");
955
956 static const char* oss = "Octave Shift";
957 MENU.l_octave_shift.set_text (oss);
958 uis.l_octave_shift.set_text (oss);
959 return 1;
960 } else cons << RED << "No octave shift in progress!" << eol;
961 return 0;
962 }
963
esc_octave_shift(instrument * inst)964 int esc_octave_shift (instrument* inst) {
965 if (SHIFT)
966 return abort_octave_shift (inst);
967 return 0;
968 }
969
setup_screens()970 void setup_screens () {
971
972 dlog << "*** setting up screens ***" << endl;
973
974 left_delay.setup ();
975 right_delay.setup ();
976
977 coml.apply (&coml.crv);
978 comr.apply (&comr.crv);
979
980 // in delay editor load feedback & volume curves
981 delayed.add (&left_delay.fbk_crv, &left_delay.fbk_lis);
982 delayed.add (&left_delay.vol_crv, &left_delay.vol_lis);
983 delayed.add (&right_delay.fbk_crv, &right_delay.fbk_lis);
984 delayed.add (&right_delay.vol_crv, &right_delay.vol_lis);
985
986 // add L & R compressor curves to compressor editor
987 comed.add (&coml.crv, &coml.lis);
988 comed.add (&comr.crv, &comr.lis);
989
990 // octave shift
991 octave_shift.setup ();
992 octlis.set (&octave_shift);
993 octave_shift.xmin = &_atmin;
994 octave_shift.xmax = &_atmax;
995 octed.add (octave_shift.crv, &octlis);
996 octed.attach_library (&octlib);
997
998 // drone modulation
999 drone_mod_ed.add (&drone_mod_am_crv, &dmlis);
1000 drone_mod_ed.add (&drone_mod_fm_crv, &dmlis);
1001 drone_mod_ed.attach_library (&wav_lib);
1002
1003 // range modulation
1004 ran_mod_ed.add (&ran_mod_width_crv, MENUP.rml);
1005 ran_mod_ed.add (&ran_mod_height_crv, MENUP.rml);
1006 ran_mod_ed.attach_library (&wav_lib);
1007
1008 // range width+height
1009 ran_wh_ed.add (&ran_width_crv, &rwhl);
1010 ran_wh_ed.add (&ran_height_crv, &rwhl);
1011
1012 // range volume & pitch
1013 pitch_vol_ed.add (warcrv[0], &pvl);
1014 pitch_vol_ed.add (warcrv[1], &pvl);
1015
1016 // drone pendulum amplitude & bpm
1017 drone_pend_ed.add (dp_crv[0], &dpel);
1018 drone_pend_ed.add (dp_crv[1], &dpel);
1019
1020 // point modulation
1021 pomo_ed.add (&pomo_x_crv, &pol);
1022 pomo_ed.add (&pomo_y_crv, &pol);
1023
1024 // noise interpolator
1025 noiser::ed.add (&noiser::interp, &noiser::lis);
1026
1027 // font editor
1028 fed.add (&dummy, 0);
1029
1030 // setup geometry > sound plugins of curve editor
1031 for (int i = 0; i < plugin_browser::num_plugins; ++i) {
1032 plugin* pi = plugin_browser::plugins[i];
1033 dlog << "setting up plugin: " << pi->name << endl;
1034 pi->setup ();
1035 dlog << pi->name << " setup complete." << endl;
1036 }
1037
1038 din0.setup ();
1039 keybd2.setup ();
1040 mondrian0.setup ();
1041
1042 uis.add_widgets ();
1043 uis.setup ();
1044 curve_picker.setup ();
1045 fft0.setup ();
1046 dlog << "+++ setup screens complete +++" << endl;
1047
1048 }
1049
setup_plugin_labels()1050 void setup_plugin_labels () {
1051 fractaliser_.b_edit.set_text ("Edit");
1052 warper_.b_edit.set_text ("Edit");
1053 }
1054
goto_next_instrument()1055 void goto_next_instrument () {
1056 scope.save_current_instrument ();
1057 ++CURRENT_INSTRUMENT;
1058 if (CURRENT_INSTRUMENT >= NUM_INSTRUMENTS) CURRENT_INSTRUMENT = 0;
1059 }
1060
find_instrument()1061 void find_instrument () {
1062 for (int i = 0; i < NUM_INSTRUMENTS; ++i) {
1063 if (INSTRUMENT == INSTRUMENTS[i]) {
1064 CURRENT_INSTRUMENT = i;
1065 break;
1066 }
1067 }
1068 }
1069
is_instrument(ui * u)1070 int is_instrument (ui* u) {
1071 for (int i = 0; i < NUM_INSTRUMENTS; ++i) if ((void *) u == (void *) INSTRUMENT_PTR[i]) return 1;
1072 return 0;
1073 }
1074
find_instrument(const string & inst)1075 instrument* find_instrument (const string& inst) {
1076 for (int i = 0; i < NUM_INSTRUMENTS; ++i) if (inst == INSTRUMENTS[i] || inst == INSTRUMENTS_SHORT[i]) return INSTRUMENT_PTR[i];
1077 return get_current_instrument ();
1078 }
1079
get_current_instrument()1080 instrument* get_current_instrument () {
1081 return INSTRUMENT_PTR [CURRENT_INSTRUMENT];
1082 }
1083
update_window(int wnow,int hnow,int wprev,int hprev)1084 void update_window (int wnow, int hnow, int wprev, int hprev) { // called when main window resized
1085
1086 glViewport (0, 0, wnow, hnow);
1087
1088 view (wnow, hnow);
1089
1090 curve_picker.update ();
1091
1092 int wx = wnow - 1, hy = hnow - 1;
1093
1094 cons.set_window (box<int>(0, 0, wx, hy));
1095
1096 uis.update_widgets (wnow, hnow, wprev, hprev);
1097
1098 keybd2.calc_visual_params ();
1099
1100 din0.window_resized (wx, hy);
1101
1102 mondrian0.calc_visual_params ();
1103
1104 if (uis.crved)
1105 uis.crved->calc_visual_params ();
1106
1107 dlog << "+++ update window complete ++" << endl;
1108
1109 }
1110
setup_sdl_surface(SDL_Surface * surface,int w,int h,int fs=0)1111 void setup_sdl_surface (SDL_Surface* surface, int w, int h, int fs = 0) {
1112 if (surface) SDL_FreeSurface (surface);
1113 if (fs)
1114 surface = SDL_SetVideoMode (w, h, SCREEN_DEPTH, SDL_OPENGL | SDL_FULLSCREEN);
1115 else {
1116 char* sdl_pos = (char *) "SDL_VIDEO_CENTERED=center";
1117 SDL_putenv (sdl_pos);
1118 surface = SDL_SetVideoMode (w, h, SCREEN_DEPTH, SDL_OPENGL | SDL_RESIZABLE);
1119 }
1120 if (surface) dlog << "+++ setup video mode " << w << ' ' << h << ' ' << SCREEN_DEPTH << " +++" << endl; else {
1121 dlog << "!!! couldnt set video mode: " << w << ' ' << h << ' ' << SCREEN_DEPTH << endl;
1122 exit (1);
1123 }
1124 }
1125
save_window()1126 void save_window () {
1127 string fname = user_data_dir + "window";
1128 ofstream file (fname.c_str(), ios::out);
1129 extern viewport view;
1130 if (file) {
1131 file << "view_width " << view.width << endl;
1132 file << "view_height " << view.height << endl;
1133 file << "full_screen " << FULL_SCREEN << endl;
1134 file << "mode " << uis.settings_scr.imode << endl;
1135 file << "win_left " << din0.win.left << endl;
1136 file << "win_bottom " << din0.win.bottom << endl;
1137 } else {
1138 dlog << "!!! couldnt save window in " << fname << " !!!" << endl;
1139 return;
1140 }
1141
1142 dlog << "+++ saved window in " << fname << " +++" << endl;
1143
1144
1145 }
1146
restore_last_window()1147 void restore_last_window () {
1148
1149 dlog << "*** reading last window ***" << endl;
1150
1151 int width = 0, height = 0;
1152
1153 string fname (user_data_dir + "window");
1154 ifstream file (fname.c_str(), ios::in);
1155
1156 string ignore;
1157
1158 // last window size
1159 file >> ignore >> width;
1160 file >> ignore >> height;
1161 file >> ignore >> FULL_SCREEN;
1162 file >> ignore >> uis.settings_scr.imode;
1163 if (FULL_SCREEN == 0) {
1164 uis.settings_scr.add_display_mode (width, height);
1165 uis.settings_scr.imode = uis.settings_scr.num_modes - 1;
1166 } else
1167 uis.settings_scr.add_display_mode (800, 600); // one windowed mode for sanity
1168
1169 // last microtonal board position
1170 file >> ignore >> din0.win.left;
1171 file >> ignore >> din0.win.bottom;
1172
1173 view (width, height);
1174 din0.prev_mousey = view.ymax;
1175
1176 }
1177
1178 SDL_Surface* surface = 0;
1179
setup_video_mode(int w,int h,int vw,int vh,int fs)1180 void setup_video_mode (int w, int h, int vw, int vh, int fs) {
1181 setup_sdl_surface (surface, w, h, fs);
1182 update_window (w, h, vw, vh);
1183 glEnableClientState (GL_VERTEX_ARRAY);
1184 }
1185
try_quit()1186 void try_quit () {
1187 dlog << "*** started to quit DIN Is Noise ***" << endl;
1188 din0.save_scale ();
1189 din0.dinfo.save ();
1190 keybd2.scaleinfo.save_scale ();
1191 mondrian0.scaleinfo.save_scale ();
1192 binaural_drones0.scaleinfo.save_scale ();
1193 save_window ();
1194 interpreter ("src save_settings");
1195 dlog << "+++ saved DIN settings +++ " << endl;
1196 uis.cb_voice.turn_off ();
1197 uis.cb_delay.turn_off ();
1198 din0.delete_all_drones ();
1199 binaural_drones0.save ();
1200 MENU.bdl.clicked (MENU.bbd_select_all);
1201 MENU.bdl.clicked (MENU.bbd_delete);
1202 scope.save_current_instrument ();
1203 quit = SOON;
1204 dlog << "!!! Quitting SOON !!!" << endl;
1205 }
1206
read_input()1207 int read_input () {
1208 // handle window events
1209 wheel = 0;
1210 widget::HOVER = 0;
1211 static SDL_Event event;
1212 while (SDL_PollEvent(&event)) {
1213 switch(event.type) {
1214 case SDL_VIDEORESIZE:
1215 if (FULL_SCREEN == 0) {
1216 setup_video_mode (event.resize.w, event.resize.h, view.width, view.height, FULL_SCREEN);
1217 uis.settings_scr.update_windowed_mode (event.resize.w, event.resize.h);
1218 }
1219 break;
1220
1221 case SDL_MOUSEBUTTONUP:
1222 switch (event.button.button) {
1223 case SDL_BUTTON_WHEELUP:
1224 wheel = 1;
1225 break;
1226 case SDL_BUTTON_WHEELDOWN:
1227 wheel = -1;
1228 break;
1229 }
1230 break;
1231
1232 case SDL_QUIT:
1233 quit = IMMEDIATE;
1234 break;
1235
1236 }
1237 }
1238
1239 // read keyboard
1240 keybd.read ();
1241 SHIFT = shift_down ();
1242 CTRL = ctrl_down ();
1243 ALT = alt_down ();
1244
1245 // read mouse
1246 int buttons = SDL_GetMouseState (&mousex, &mousey);
1247 mouseyy = view.ymax - mousey;
1248 lmb = buttons & SDL_BUTTON_LMASK;
1249 rmb = buttons & SDL_BUTTON_RMASK;
1250
1251 return 1;
1252
1253 }
1254
1255 midi_in midiin;
1256
applyfx(float * out0,float * out1,int do_delay,int do_compress)1257 void applyfx (float* out0, float* out1, int do_delay, int do_compress) {
1258 //
1259 // apply delays
1260 //
1261 float fdr = uis.fdr_delay.amount;
1262 float* outl = out0; left_delay (outl, aout.samples_per_channel, fdr);
1263 float* outr = out1; right_delay (outr, aout.samples_per_channel, fdr);
1264
1265 // apply compression
1266 //
1267 if (do_compress) {
1268 float* outl = out0, *outr = out1;
1269 coml.apply (outl, aout.samples_per_channel);
1270 comr.apply (outr, aout.samples_per_channel);
1271 }
1272
1273 }
1274
1275 int n_pomo_eds = 35;
1276 curve_editor* pomo_eds [] = {
1277 &din0.waved,
1278 &din0.moded,
1279 &din0.gated,
1280 &delayed,
1281 &octed,
1282 &din0.droneed,
1283 &keybd2.waved,
1284 &keybd2.attacked,
1285 &keybd2.decayed,
1286 &keybd2.veled,
1287 &comed,
1288 &mc.ed,
1289 &drone_mod_ed,
1290 &fed,
1291 &fractaliser_.ed,
1292 &warper_.ed,
1293 &mondrian0.waved,
1294 &mondrian0.attacked,
1295 &mondrian0.decayed,
1296 &binaural_drones0.waved,
1297 &spiraler_.scr.sin_ed,
1298 &spiraler_.scr.cos_ed,
1299 &spiraler_.scr.rad_ed,
1300 &rosemilker.scr.sin_ed,
1301 &rosemilker.scr.cos_ed,
1302 &circler_.scr.sin_ed,
1303 &circler_.scr.cos_ed,
1304 &circler_.scr.rad_ed,
1305 &sinemixer.sin_ed,
1306 &ran_mod_ed,
1307 &ran_wh_ed,
1308 &pitch_vol_ed,
1309 &pomo_ed,
1310 &noiser::ed,
1311 &drone_pend_ed,
1312 };
1313
1314 const char* keys_trig_what [] = {" Keys trigger notes", " Keys trigger noise"};
1315
1316 const char* colorer_t::s_schemes [] = {" Top", " Bottom", " Blend", " Random"};
1317 color_data_t get_color::data;
1318
1319 pressedt elsewhere; // see input.h, sine_mixer.cc, basic_editor.cc
1320 pressedt& pressed = elsewhere;
1321
main(int argc,char ** argv)1322 int main (int argc, char** argv) {
1323
1324 // MIDI note colors
1325 keyboard_keyboard::note_color [0] = color (0.9f, 0.9f, 0.9f); // white
1326 keyboard_keyboard::note_color [1] = color (0.2f, 0.2f, 0.2f); // black
1327
1328 dlog << "*** Starting DIN Is Noise " << VERSION_NUMBER << " ***" << endl;
1329
1330
1331 // bring up OpenGL window
1332 //
1333 if (SDL_Init (SDL_INIT_VIDEO) < 0) {
1334 dlog << "!!! couldnt initialise SDL video !!!" << endl;
1335 exit (1);
1336 } else {
1337 dlog << "+++ initialised SDL video +++" << endl;
1338 }
1339
1340 uis.settings_scr.load_fullscreen_modes ();
1341
1342 if (SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1) < 0) {
1343 dlog << "!!! couldnt setup SDL/OpenGL double buffer !!!" << endl;
1344 exit(1);
1345 } else {
1346 dlog << "+++ setup SDL/OpenGL double buffer +++" << endl;
1347 }
1348
1349 restore_last_window ();
1350
1351 setup_screens ();
1352 setup_curve_list ();
1353
1354 interpreter.add_din_specific ();
1355
1356 interpreter ("src init");
1357 dlog << "+++ loaded DIN scripts (init.tcl) +++ " << interpreter.result << endl;
1358
1359 MENU.riset.set_value (din0.dinfo.drone_rise_time);
1360 MENU.fallt.set_value (din0.dinfo.drone_fall_time);
1361
1362 interpreter ("src settings");
1363 dlog << "+++ loaded DIN settings (settings.tcl) +++ " << interpreter.result << endl;
1364
1365 all_notes.load_scale ("all_notes");
1366
1367 midiin.open ();
1368
1369 binaural_drones0.load ();
1370
1371 // init menu items
1372 uis.sp_attack_time.set_value (ATTACK_TIME);
1373 uis.sp_decay_time.set_value (DECAY_TIME);
1374 uis.sp_voices.set_value ((int)(1.0f / NOTE_VOLUME + 0.5f));
1375 uis.sp_pitch_bend.set_value (PITCH_BEND_PER_PIXEL);
1376 uis.cb_show_nearby_notes.set_state (keybd2.show_nearby_notes);
1377 float obpm = octave_shift.bpm;
1378 MENU.sp_octave_shift_bpm.set_value (obpm);
1379 uis.sp_octave_shift_bpm.set_value (obpm);
1380 MENU.sp_gater_bpm.set_value (din0.gatr.bpm);
1381 MENU.sp_voice_volume.set_value (VOICE_VOLUME);
1382 MENU.cb_show_anchors.set_state (din0.dinfo.anchor);
1383 MENU.cb_show_vel.set_state (din0.dinfo.vel);
1384 MENU.cb_show_accel.set_state (din0.dinfo.accel);
1385 MENU.cb_mark_ran.set_state (din0.dinfo.mark_sel_range, 0);
1386 MENU.sp_drone_master_vol.set_value (drone::mastervolume);
1387 MENU.td_tap_display.set_bpm (din0.gatr.bpm);
1388 MENU.mark_tap_target ();
1389 MENU.sp_mesh_rows.set_value (din0.dinfo.rows);
1390 MENU.sp_mesh_cols.set_value (din0.dinfo.cols);
1391 MENU.sp_bounces.set_value (din0.dinfo.bounce.n);
1392 MENU.sp_rebound.set_value (din0.dinfo.bounce.speed);
1393 MENU.picked (MENU.ol_bounce_style.option, 0);
1394 MENU.picked (MENU.ol_drone_is.option, 0);
1395 MENU.sp_snap_left.set_value (din0.dinfo.snap.left);
1396 MENU.sp_snap_right.set_value (din0.dinfo.snap.right);
1397 MENU.sdl.picked (MENU.ol_snap_style.option, 0);
1398 MENU.sp_mondrian_min_voices.set_value (mondrian0.min_voices);
1399 MENU.sp_mondrian_change_attack_time.set_value (0);
1400 MENU.sp_mondrian_change_decay_time.set_value (0);
1401 MENU.sp_mondrian_change_speed.set_delta (mondrian0.delta_speed);
1402 MENU.sp_mondrian_change_note_poly_points.set_value (mondrian0.poly.points);
1403 MENU.sp_mondrian_change_note_poly_radius.set_value (mondrian0.poly.radius);
1404 MENU.sp_mondrian_change_note_poly_radius.set_delta (mondrian0.poly.delta_radius);
1405 MENU.cb_mondrian_auto_adjust_voices.set_state (mondrian0.auto_adjust_voices);
1406 MENU.cb_draw_ball_position.set_state (mondrian0.draw_ball.position);
1407 MENU.cb_draw_ball_heading.set_state (mondrian0.draw_ball.heading);
1408 MENU.cb_draw_ball_trails.set_state (mondrian0.draw_ball.trails);
1409 MENU.cb_draw_boxes.set_state (mondrian0.draw__boxes);
1410 MENU.cb_fill_boxes.set_state (mondrian0.fill_boxes);
1411 MENU.cb_draw_notes.set_state (mondrian0.draw__notes);
1412 MENU.cb_label_hz_vol.set_state (mondrian0.label_hz_vol);
1413 MENU.cb_label_notes.set_state (mondrian0.label_notes);
1414 MENU.ol_ball_types.set_text (ball::types_str[mondrian0.added_ball_type]);
1415 MENU.sp_mondrian_num_boxes.set_value (mondrian0.num_boxes);
1416 MENU.sp_auto_split_time.set_value (mondrian0.auto_split_rect.triggert);
1417 MENU.sp_auto_delete_time.set_value (mondrian0.auto_del_rect.triggert);
1418 MENU.ol_auto_split_at.set_text (mondrian_listener::auto_split_at_types [mondrian0.auto_split_at]);
1419 MENU.ol_auto_split_orient.set_text (mondrian_listener::auto_split_orient_types [mondrian0.auto_split_orient]);
1420 MENU.ol_auto_pick_box_split.set_text (mondrian_listener::pick_box_types [mondrian0.split_leaf]);
1421 MENU.ol_auto_pick_box_delete.set_text (mondrian_listener::pick_box_types [mondrian0.delete_leaf]);
1422 MENU.cb_auto_split_box.set_state (mondrian0.auto_split_rect.active);
1423 MENU.cb_auto_delete_box.set_state (mondrian0.auto_del_rect.active);
1424 MENU.sp_min_split_size.set_value (mondrian::min_split_size);
1425 uis.cb_show_pitch_volume_drones.set_state (din0.dinfo.show_pitch_volume.drones);
1426 uis.cb_show_pitch_volume_board.set_state (din0.dinfo.show_pitch_volume.board);
1427 MENU.lf_master_volume.fld.set_text (int (binaural_drones0.master_volume * 100.0f));
1428 MENU.lf_bd_start_pitch.fld.set_text (binaural_drones0.starting_pitch);
1429 MENU.sp_bd_separation.set_value (binaural_drones0.separation);
1430 MENU.sp_bd_pairs.set_value (binaural_drones0.pairs);
1431 MENU.lf_bd_spacing.fld.set_text (binaural_drones0.spacing);
1432 MENU.cb_close_octave.set_state (binaural_drones0.close_octave);
1433 MENU.cb_resize_separation.set_state (binaural_drones0.resize_separation);
1434 MENU.bdl.picked (MENU.ol_key_note.option, 0);
1435 MENU.bdl.picked (MENU.ol_justification.option, 0);
1436 MENU.lf_vol_fade_time.fld.set_text (binaural_drones0.vol_fader.duration);
1437 MENU.lf_pitch_fade_time.fld.set_text (binaural_drones0.pitch_fader.duration);
1438 MENU.lf_modulation_amount.fld.set_text (binaural_drones0.modulation_amount);
1439 MENU.bdl.picked (MENU.ol_select_what.option, 0);
1440 MENU.update_binaurals_list ();
1441 MENU.load_range (din0.dinfo.sel_range);
1442 MENU.sral.picked (MENU.ol_set_range.option, 0);
1443 MENU.sp_default_width.set_value (WIDTH);
1444 MENU.sp_default_height.set_value (HEIGHT);
1445 MENU.cnsl.set (MENU.ol_change_note_style.option, din0.dinfo.change_note_style);
1446 MENU.picked (MENU.ol_set_unset_toggle.option, 0);
1447 MENU.picked (MENU.ol_drone_order.option, 0);
1448 MENU.picked (MENU.ol_mesh_point.option, 0);
1449 MENU.sp_mesh_dur.set_value (din0.dinfo.mesh_vars.duration);
1450 MENU.cb_sync_rows_cols.set_state (din0.dinfo.mesh_vars.sync);
1451 MENU.cb_am_bpm.set_state (din0.dinfo.mesh_vars.apply_to.am);
1452 MENU.cb_fm_bpm.set_state (din0.dinfo.mesh_vars.apply_to.fm);
1453 MENU.sp_drones_per_pend.set_value (din0.dinfo.mesh_vars.dpp);
1454 MENU.picked (MENU.ol_create_this.option, 0);
1455 MENU.dp_numdrones.set_value (din0.dinfo.drone_pend.n);
1456 MENU.dp_bpm1.set_value (din0.dinfo.drone_pend.bpm);
1457 MENU.picked (MENU.dp_orient.option, 0);
1458 MENU.cb_pitch_dis.set_state (din0.dinfo.dist.pitch);
1459 MENU.cb_vol_dis.set_state (din0.dinfo.dist.vol);
1460 MENU.sp_lev_sz.set_value (din0.dinfo.dist.pix);
1461 MENU.s_phrase_position.set_right (din0.dinfo.phrasor_right);
1462 MENU.seloncre.set_state (din0.dinfo.seloncre);
1463 MENU.cnol.picked (MENU.ol_change_note.option, 0);
1464 set_label (uis.ol_trig_what.option, keys_trig_what, keybd2.trig_what);
1465 MENU.cb_draw_mesh.set_state (din0.meshh.draw, 0);
1466 MENU.cmod.changed (MENU.cb_modulation);
1467 MENU.sp_stiff.set_value (drone::STIFFNESS);
1468 MENU.gabt.set_value (drone::gabt);
1469 uis.dpeu.depth.set_value (50);
1470 uis.dpeu.bpm.set_value (din0.dinfo.drone_pend.bpm);
1471 din0.set_random_color ();
1472 get_color::update_data ();
1473 MENU.ol_color.set_text (MENU.colorer.get_scheme_name());
1474 MENU.handlesize.set_value (drone::HANDLESIZE);
1475 MENU.trailsize.set_value (TRAILSIZE);
1476
1477 din0.dinfo.wand = !din0.dinfo.wand;
1478 MENU.awdl.picked (MENU.ol_add_wand.option, 0); // flipped back here
1479 MENU.sp_wand_dist.set_value (drone::wand.dist);
1480 MENU.darl.picked (MENU.ol_drones_are.option, 0);
1481 MENU.lifetime.set_value (drone::LIFETIME);
1482 MENU.chapt.set_value (drone::chuckt::apt.deg);
1483
1484 MENU.dva.which = din0.dinfo.menu.dva.which;
1485 MENU.dva.load ();
1486
1487 MENU.cb_show_gravity.set_state (din0.dinfo.gravity.visible);
1488 MENU.dcl.changed (MENU.cb_show_gravity);
1489
1490 din0.dinfo.gravity.initui ();
1491
1492 MENU.choutline.set_state (drone::chuckt::outline);
1493 MENU.chautoresettrails.set_state (drone::chuckt::autoresettrails);
1494
1495 MENU.ancl.picked (MENU.anchored.option, 0);
1496
1497 MENU.dronearrowdefaults.cap.set_state (drone::arrowt::CAP, 0);
1498
1499 // finish init menu items
1500
1501 const char* viv = voice_is_lbls[din0.dinfo.voice_is_voice];
1502 uis.cb_voice.set_text (viv);
1503 MENU.handle_voice_tab_items (viv);
1504
1505 uis.settings_scr.lf_mixing_time.fld.set_text (curve_mixer::TIME);
1506 uis.settings_scr.sample_rate_changed ();
1507
1508 options_list* ol [] = {MENUP.ol_bouncer, MENUP.ol_wrecker, MENUP.ol_healer};
1509 for (int i = 0; i < 3; ++i) {
1510 int j = Transform::rules[i];
1511 sprintf (BUFFER, "%s becomes %s", ball::types_str[i], ball::types_str[j]);
1512 ol[i]->set_text (BUFFER);
1513 }
1514
1515 uis.settings_scr.update_mode_display ();
1516
1517 mondrian0.make_notes ();
1518
1519 curve_picker.widget::hide();
1520
1521 cons.home ();
1522
1523 setup_video_mode (view.width, view.height, view.width, view.height, FULL_SCREEN);
1524
1525 glClearColor(0, 0, 0, 0); // black bg
1526
1527 basic_editor::alloc_gl_pts (16);
1528
1529 nagscr ();
1530
1531 // ui loop
1532 double framet = 0;
1533 double inputt = 0;
1534
1535 const string loop ("loop");
1536 const char* timenow = "timenow";
1537 const string s_goodbye ("Goodbye!"), s_drones (" | Drones = "), s_kbkb (" | Keyboard-Keyboard = "), s_mondrian (" | Mondrian = "), s_binaurals (" | Fading Binaurals = ");
1538
1539 const char percent = '%';
1540
1541 aout.start (); // start audio loop in a separate thread. see audio_wanted (..)
1542
1543 framet = TIME_PER_FRAME + ui_clk ();
1544
1545 while (1) {
1546
1547 // try to write audio
1548 if (aout.can_write ()) {
1549
1550 float* out0 = aout.writep; // left channel
1551 float* out1 = out0 + aout.samples_per_channel; // right channel
1552
1553 do_octave_shift ();
1554
1555 memset (aout.writep, 0, aout.samples_buffer_size); // silence everything
1556
1557 interpreter (loop); // run loop on tcl proc
1558
1559 // audio from instruments
1560 din0.render_audio (out0, out1);
1561 keybd2.render_audio (out0, out1);
1562 mondrian0.render_audio (out0, out1);
1563 binaural_drones0.render_audio (out0, out1);
1564
1565 // delay and compressor
1566 applyfx (out0, out1, din0.dinfo.delay, din0.dinfo.compress);
1567
1568 // to oscilloscope
1569 if (scope.visible) scope.add_samples (out0, out1, aout.samples_per_channel);
1570
1571 // record?
1572 if (uis.cb_record.state) {
1573 recorder0.add (aout.writep, aout.samples_buffer_size, aout.samples_per_buffer, uis.cb_record, MENU.cb_record);
1574 }
1575
1576 // stream status
1577 aout.available [aout.writei] = 1;
1578 if (++aout.writei >= aout.num_samples_buffers) {
1579 aout.writep = aout.samples_buffers;
1580 aout.writei = 0;
1581 } else aout.writep += aout.samples_per_buffer;
1582
1583 // store timenow in TCL. timenow is seconds on din audio clock
1584 TIME_NOW = clk.secs;
1585 Tcl_UpdateLinkedVar (interpreter.interp, timenow);
1586
1587 }
1588
1589 if (recorder0.saving_started) { // save recording to disk
1590 if (recorder0.save_some (MENU.cb_record) == 0)
1591 MENU.b_save.set_text ("Overwrite");
1592 }
1593
1594 // draw frame
1595 double T = ui_clk ();
1596 if (T >= framet) {
1597 LAST_FRAME_TIME = TIME_PER_FRAME + (T - framet);
1598 uis.draw ();
1599 SDL_GL_SwapBuffers ();
1600 framet = TIME_PER_FRAME + ui_clk ();
1601 }
1602
1603 // handle input [mouse, keys and midi] and bg
1604 T = ui_clk ();
1605 if (T >= inputt) {
1606 read_input ();
1607 if (quit == DONT) ;
1608 else if (quit == SOON) {
1609 cons << console::yellow << s_goodbye << s_drones << din0.num_drones << s_kbkb << keybd2.num_triggered_notes << s_mondrian << mondrian0.num_triggered_notes;
1610 if (binaural_drones0.num_binaural_drones) cons << s_binaurals << int (binaural_drones0.vol_fader.xt*100+0.5) << percent;
1611 cons << eol;
1612 if (
1613 (din0.num_drones == 0) &&
1614 (uis.fdr_voice.on == 0) &&
1615 (uis.fdr_delay.on == 0) &&
1616 (keybd2.num_triggered_notes == 0) &&
1617 (mondrian0.num_triggered_notes == 0) &&
1618 (binaural_drones0.vol_fader.active == 0)
1619 )
1620 break;
1621 }
1622 else if (quit == IMMEDIATE) break;
1623
1624 uis.handle_input ();
1625 uis.bg ();
1626 for (int i = 0; i < n_pomo_eds; ++i) pomo_eds[i]->pomo.bg (); // update point modulations on curve editors
1627 midiin.handle_input ();
1628 keybd.save ();
1629 inputt = TIME_PER_INPUT + ui_clk ();
1630 }
1631
1632 } // finish
1633
1634 aout.close ();
1635
1636 mesh::destroy ();
1637 trail_t::destroy ();
1638
1639 drone_mod_am_crv.save ("drone-mod-am.crv");
1640 drone_mod_fm_crv.save ("drone-mod-fm.crv");
1641 ran_mod_height_crv.save ("range-mod-height.crv");
1642 ran_mod_width_crv.save ("range-mod-width.crv");
1643 ran_width_crv.save ("range-width.crv");
1644 ran_height_crv.save ("range-height.crv");
1645 vol_crv.save ("vol.crv");
1646 pitch_crv.save ("pitch.crv");
1647 pomo_x_crv.save ("pomo-x.crv");
1648 pomo_y_crv.save ("pomo-y.crv");
1649 noiser::interp.save ("noiser.crv");
1650 dp_depth.save ("dp_depth.crv");
1651 dp_bpm.save ("dp_bpm.crv");
1652
1653 #if defined (__SVG_FNT__) || defined (__PLOTTER_FNT__)
1654 ifstream textf ("text.txt", ios::in);
1655 if (textf) {
1656 int x, y;
1657 textf >> x >> y;
1658 string line;
1659 int lh = line_height;
1660 while (!textf.eof()) {
1661 getline (textf, line);
1662 #ifdef __SVG_FNT__
1663 write_string (line, x, y);
1664 y += lh;
1665 #elif __PLOTTER_FNT__
1666 plot_string (line, x, y);
1667 y -= lh;
1668 #endif
1669 }
1670 }
1671 #endif
1672
1673 return 0;
1674
1675 }
1676
set_tonic(instrument * instr,float f)1677 void set_tonic (instrument* instr, float f) {
1678 instr->scaleinfo.set_tonic (f);
1679 if (instr == get_current_instrument ()) instr->scaleinfo.update_settings ();
1680 }
1681
get_tonic(instrument * instr)1682 float get_tonic (instrument* instr) {
1683 return instr->scaleinfo.tonic;
1684 }
1685
set_notation(int n)1686 void set_notation (int n) {
1687 NOTATION = n;
1688 din0.notate_all_ranges ();
1689 keybd2.setup_notes (0);
1690 mondrian0.calc_visual_params ();
1691 uis.settings_scr.sn_scale_notes.refresh ();
1692 }
1693
set_num_octaves(int n)1694 void set_num_octaves (int n) {
1695 int lno = NUM_OCTAVES;
1696 NUM_OCTAVES = n;
1697 #define DONTLOADFROMDISK 0
1698 din0.setup_ranges (lno, DONTLOADFROMDISK);
1699 din0.update_drone_ranges ();
1700 din0.refresh_all_drones ();
1701 }
1702
hide_menu()1703 int hide_menu () {
1704 if (MENU.show) {
1705 MENU.toggle ();
1706 return 1;
1707 }
1708 return 0;
1709 }
1710
show_menu()1711 void show_menu () {
1712 MENU.show = 0;
1713 MENU.toggle ();
1714 }
1715
hz2step(float & hz,float & step)1716 void hz2step (float& hz, float& step) {
1717 step = hz * 1.0f / SAMPLE_RATE;
1718 }
1719
step2hz(float & step,float & hz)1720 void step2hz (float& step, float& hz) {
1721 hz = step * SAMPLE_RATE;
1722 }
1723
set_snap_drones(int what)1724 void set_snap_drones (int what) {
1725 stringstream ss; ss << "set-var snap_drones " << what;
1726 cons (ss.str());
1727 }
1728
set_snap(int what)1729 void set_snap (int what) {
1730 MENU.set_snap (what);
1731 }
1732
dont_call_listener(checkbutton & cb,int state)1733 void dont_call_listener (checkbutton& cb, int state) {
1734 if (state) cb.turn_on (DONT_CALL_LISTENER); else cb.turn_off (DONT_CALL_LISTENER);
1735 }
1736
find_nearest_note(string & note,float & frequency,float & dist)1737 int find_nearest_note (string& note, float& frequency, float& dist) {
1738
1739 float left = WIKIPEDIA_KEY_FREQUENCIES [0] / 2048, right = 2 * left;
1740 float outf = frequency;
1741 if (outf < left) return 0;
1742
1743 // find octave
1744 while (1) {
1745 if ((left <= outf) && (right > outf)) break;
1746 else {
1747 left*=2;
1748 right*=2;
1749 }
1750 }
1751
1752 float oct = left / WIKIPEDIA_KEY_FREQUENCIES[0];
1753 int id = 0;
1754 float tone = 0, newdist = 0;
1755 dist = outf - left;
1756 for (int i = 0; i < 13; ++i) {
1757 tone = WIKIPEDIA_KEY_FREQUENCIES[i] * oct;
1758 newdist = abs(outf - tone);
1759 if (newdist <= dist) {
1760 dist = newdist;
1761 id = i;
1762 } else {
1763 break;
1764 }
1765 }
1766
1767 note = WESTERN_FLAT[id];
1768 frequency = WIKIPEDIA_KEY_FREQUENCIES[id] * oct;
1769 dist = outf - frequency;
1770 return id;
1771
1772 }
1773
turn_on_ui()1774 void turn_on_ui () {
1775 UI_OFF = 0;
1776 uis.show_hide_widgets (1);
1777 }
1778
turn_off_ui()1779 void turn_off_ui () {
1780 UI_OFF = 1;
1781 uis.show_hide_widgets (0);
1782 }
1783
tween(float * buf1,float * buf2,int n,float amount)1784 void tween (float* buf1, float* buf2, int n, float amount) {// interpolate buf2 -> buf1 and store in buf1
1785 for (int i = 0; i < n; ++i) {
1786 float b1 = buf1 [i], b2 = buf2[i];
1787 buf1[i] = amount * (b1 - b2) + b2;
1788 }
1789 }
1790
tween(float * buf1,float * buf2,int n,float * amount)1791 void tween (float* buf1, float* buf2, int n, float* amount) {
1792 for (int i = 0; i < n; ++i) {
1793 float b1 = buf1 [i], b2 = buf2[i];
1794 buf1[i] = amount[i] * (b1 - b2) + b2;
1795 }
1796 }
1797
fill(float * buf,float start,float end,int n)1798 void fill (float* buf, float start, float end, int n) {
1799 float es = end - start;
1800 float a = 0, da = 1./ (n - 1);
1801 for (int i = 0; i < n; ++i) {
1802 buf[i] = start + a * es;
1803 a += da;
1804 }
1805 }
1806
multiply(float * out,float * mul,int n)1807 void multiply (float* out, float* mul, int n) {
1808 for (int i = 0; i < n; ++i) out[i] *= mul[i];
1809 }
1810
multiply(float * out,int n,float depth)1811 void multiply (float* out, int n, float depth) {
1812 for (int i = 0; i < n; ++i) out[i] *= depth;
1813 }
1814
warp_mouse(int x,int y)1815 void warp_mouse (int x, int y) {
1816 SDL_WarpMouse (x, y);
1817 mousex = x;
1818 mousey = y;
1819 mouseyy = view.ymax - y;
1820 }
1821
can_wheel()1822 int can_wheel () {
1823 return (wheel && !widget::HOVER && !MENU.show);
1824 }
1825
edited(curve_editor * ed,int i)1826 void range_wh_lis::edited (curve_editor* ed, int i) {
1827 if (i) {
1828 sol_ran_height.update ();
1829 din0.all_ranges_height_changed ();
1830 } else {
1831 sol_ran_width.update ();
1832 din0.all_ranges_width_changed ();
1833 }
1834 }
1835
edited(curve_editor * ed,int i)1836 void pitch_vol_lis::edited (curve_editor* ed, int i) {
1837 warsol_pv[i]->update ();
1838 din0.refresh_all_drones ();
1839 }
1840
edited(curve_editor * ed,int i)1841 void drone_pend_ed_lis::edited (curve_editor* ed, int i) {
1842 warsol_dp[i]->update ();
1843 din0.update_drone_pendulums ();
1844 }
1845
edited(curve_editor * ed,int j)1846 void pomo_lis::edited (curve_editor* ed, int j) {
1847 for (int i = 0; i < n_pomo_eds; ++i) pomo_eds[i]->pomo.update_solvers (j);
1848 }
1849
edited(curve_editor * ed,int i)1850 void noise_interp_lis::edited (curve_editor* ed, int i) {
1851 din0.noise_interpolator_changed ();
1852 update_triggered_noises (keybd2.triggered_notes);
1853 update_triggered_noises (mondrian0.triggered_notes);
1854 }
1855
make_good_name(string & name)1856 void make_good_name (string& name) {
1857 for (int i = 0, j = name.length (); i < j; ++i) {
1858 char& ci = name[i];
1859 if (ci == spc) ci = '_';
1860 }
1861 }
1862