Subversion Repositories DIN Is Noise

Rev

Rev 2310 | Details | Compare with Previous | Last modification | View Log | RSS feed

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