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