Rev 298 |
Rev 336 |
Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* settings.cc
* DIN Is Noise is copyright (c) 2006-2017 Jagannathan Sampath
* For more information, please visit http://dinisnoise.org/
*/
#include "settings.h"
#include "viewwin.h"
#include "console.h"
#include "font.h"
#include "ui_list.h"
#include "tcl_interp.h"
#include "midi_in.h"
#include "audio.h"
#include "delay.h"
#include "main.h"
#include "instrument.h"
#include "curve_mixer.h"
#include <sstream>
#include "log.h"
extern string NEAREST_NOTE;
extern float NEAREST_NOTE_FREQUENCY;
extern float NEAREST_NOTE_DISTANCE;
extern int NUM_OCTAVES;
extern int MILLION;
settings::settings () : ol_display_modes (1) {
name = "settings";
//ed = 1; // treat as editor to disable SDLK_1 from switching current instrument
// assign colors
b_go_back.set_color (0.5f, 1.0f, 1.0f);
unsigned char kr1 = 0xeb, kg1 = 0x95, kb1 = 0x60;
s_key.set_color (kr1, kg1, kb1);
ol_nearest_note.set_color (kr1, kg1, kb1);
unsigned char r1 = 0xff, g1 = 0x89, b1 = 0;
sn_scale_notes.set_color (r1, g1, b1);
ol_notation.set_color (r1, g1, b1);
ol_tuning.set_color (r1, g1, b1);
sp_num_octaves.set_color (r1, g1, b1);
unsigned char dr1 = 0xa1, dg1 = 0xd6, db1 = 0x36;
l_delay_dur.set_color (dr1, dg1, db1);
r_delay_dur.set_color (dr1, dg1, db1);
unsigned char ar = 0xd2, ag = 0x73, ab = 0xff;
ol_audio_devices.set_color (ar, ag, ab);
ol_sample_rates.set_color (ar, ag, ab);
ol_buffer_sizes.set_color (ar, ag, ab);
b_refresh_audio_devices.set_color (ar, ag, ab);
unsigned char mr = 0x40, mg = 0x83, mb = 0xff;
ol_midi_devices.set_color (mr, mg, mb);
b_refresh_midi_devices.set_color (mr, mg, mb);
unsigned char dr2 = 0xaf, dg2 = 0xaf, db2 = 0xff;
ol_display_modes.set_color (dr2, dg2, db2);
ol_display_modes.apply.set_listener (this);
unsigned char sr1 = 0xba, sg1 = 0x00, sb1 = 0x00;
scroll_up.set_color (sr1, sg1, sb1);
scroll_down.set_color (sr1, sg1, sb1);
scroll_up.set_direction (arrow_button::top);
scroll_down.set_direction (arrow_button::bottom);
int scroll_arrow_size = 32;
scroll_up.set_size (scroll_arrow_size);
scroll_down.set_size (scroll_arrow_size);
scroll_up.click_repeat = scroll_down.click_repeat = 1;
scroll_up.first_repeat_time = scroll_down.first_repeat_time = 0.0f;
scroll_up.subsequent_repeat_time = scroll_down.subsequent_repeat_time = 0.0f;
imode = -1;
b_factory_reset.set_color (1.0f, 0.5f, 0.5f);
num_widgets = 0;
}
void settings::setup () {
s_key.set_listener (this);
s_key.set_limits (0, 1000000); // 0 to 1 million hz
sp_num_octaves.set_delta (1);
sp_num_octaves.set_limits (1, 15);
//sp_num_octaves.set_moveable (1);
sp_num_octaves.set_listener (this);
sp_num_octaves.set_label ("Number of Octaves");
scroll_up.set_listener (this);
scroll_down.set_listener (this);
// setup separators
separator* seps [] = {&h_separator1, &h_separator2, &h_separator3, &h_separator4, &h_separator5, &h_separator6, &h_separator7, &h_separator8};
for (int i = 0; i < 8; ++i) {
seps[i]->set_color (0.5f, 0.5f, 0.5f);
seps[i]->set_extents (480);
}
// install into widget array
widgets.push_back (&b_go_back);
widgets.push_back (&h_separator1);
widgets.push_back (&s_key);
widgets.push_back (&ol_nearest_note);
widgets.push_back (&h_separator2);
widgets.push_back (&sn_scale_notes);
widgets.push_back (&sp_num_octaves);
widgets.push_back (&ol_notation);
widgets.push_back (&ol_tuning);
widgets.push_back (&h_separator3);
widgets.push_back (&l_delay_dur);
widgets.push_back (&r_delay_dur);
widgets.push_back (&h_separator4);
widgets.push_back (&ol_audio_devices);
widgets.push_back (&ol_sample_rates);
widgets.push_back (&ol_buffer_sizes);
widgets.push_back (&b_refresh_audio_devices);
widgets.push_back (&h_separator5);
widgets.push_back (&ol_midi_devices);
widgets.push_back (&b_refresh_midi_devices);
widgets.push_back (&cb_show_midi_messages);
widgets.push_back (&h_separator6);
widgets.push_back (&ol_display_modes);
widgets.push_back (&h_separator7);
widgets.push_back (&b_factory_reset);
widgets.push_back (&h_separator8);
widgets.push_back (&sp_fps);
widgets.push_back (&sp_ips);
widgets.push_back (&sp_mixing_time);
num_widgets = widgets.size ();
lnspc.resize (num_widgets);
// setup widget listeners
b_go_back.set_listener (this);
b_factory_reset.set_listener (this);
ol_notation.set_listener (this);
ol_tuning.set_listener (this);
ol_midi_devices.set_listener (this);
cb_show_midi_messages.set_listener (this);
b_refresh_midi_devices.set_listener (this);
ol_audio_devices.set_listener (this);
ol_sample_rates.set_listener (this);
ol_buffer_sizes.set_listener (this);
b_refresh_audio_devices.set_listener (this);
l_delay_dur.fld.change_lsnr = this;
r_delay_dur.fld.change_lsnr = this;
ol_nearest_note.set_listener (this);
sp_num_octaves.set_listener (this);
ol_display_modes.set_listener (this);
spinner<int>* spn[] = {&sp_fps, &sp_ips};
const char* lspn[] = {"Frames Per Second", "Inputs Per Second"};
for (int i = 0; i < 2; ++i) {
spinner<int>* si = spn[i];
si->set_limits (1, MILLION);
si->set_delta (1);
si->set_listener (this);
si->set_label (lspn[i]);
}
sp_mixing_time.set_limits (0, MILLION);
sp_mixing_time.set_delta (0.1f);
sp_mixing_time.set_listener (this);
sp_mixing_time.set_label ("Curve mixing time");
cb_show_midi_messages.set_state (0);
i_current_tuning = 0;
i_current_midi = 0;
// build audio buffer sizes list
int bs = 64;
for (int j = 0; j < 7; ++j) {
buffer_sizes.push_back (bs);
bs *= 2;
}
i_buffer_size = 0;
}
void settings::enter () {
// called b4 settings page is displayed
// refresh settings
get_current_instrument ()->scaleinfo.update_settings ();
if (prev_mousex == -1) {
prev_mousex = view.xmax / 2;
prev_mousey = view.ymax / 2;
}
// get current notation
extern string NOTATION;
ol_notation.option.set_text (" notation = " + NOTATION);
// get current tuning
tunings.clear ();
interpreter ("tuning list");
tokenizer tz (interpreter.result);
while (1) {
string name; tz >> name;
if (name == "") break;
tunings.push_back (name);
}
num_tunings = tunings.size ();
interpreter ("tuning get");
s_current_tuning = interpreter.result;
find_current_tuning ();
ol_tuning.option.set_text (" tuning = " + s_current_tuning + " ");
// number of octaves
//
sp_num_octaves.set_value (NUM_OCTAVES);
// load l & r delay durations
const char* const chan [] = {"left", "right"};
label_field* flds [] = {&l_delay_dur, &r_delay_dur};
for (int i = 0; i < 2; ++i) {
stringstream ss_gd;
ss_gd << "get-delay " << chan[i];
interpreter (ss_gd.str());
stringstream ss_res; ss_res << interpreter.result;
int msecs; ss_res >> msecs;
flds[i]->fld.set_text (msecs / 1000.0f);
}
ui::enter ();
cons.rollup (1);
}
void settings::update_widgets () {
int lh = (int)(1.25f * get_line_height ());
int x1 = (int)(0.25f * view.xmax), y1 = view.ymax - 2.3 * lh;
int x2 = (int)(0.1f * view.xmax), y2 = view.ymax / 2, sepy = 7;
scroll_up.set_pos (x2, y2);
scroll_down.set_pos (x2, y2 - scroll_up.extents.height - sepy);
for (int i = 0; i < num_widgets; ++i) lnspc [i] = lh;
lnspc[0]=lnspc[3]=lnspc[8]=lnspc[11]=lnspc[16]=lnspc[20]=lnspc[22]=lnspc[24]=10;
sn_scale_notes.update ();
b_go_back.set_label ("Go back");
b_factory_reset.set_label ("Reset to Factory Settings!");
sp_num_octaves.update ();
cb_show_midi_messages.set_label ("Show incoming MIDI messages");
b_refresh_midi_devices.set_label ("Refresh MIDI devices");
b_refresh_audio_devices.set_label ("Refresh Audio Devices");
l_delay_dur.lbl.set_text ("L delay duration (seconds) ");
r_delay_dur.lbl.set_text ("R delay duration (seconds) ");
sp_fps.update ();
sp_ips.update ();
float t = get_tonic (get_current_instrument());
s_key.set_label ("Key (Hz) ");
s_key.set_value (t);
s_key.by.set_text ("by");
s_key.set_delta (1.0);
NEAREST_NOTE_FREQUENCY = t;
find_nearest_note (NEAREST_NOTE, NEAREST_NOTE_FREQUENCY, NEAREST_NOTE_DISTANCE);
sprintf (sbuf, " nearest note = %s @ %0.3f Hz", NEAREST_NOTE.c_str(), NEAREST_NOTE_FREQUENCY);
ol_nearest_note.set_text (sbuf);
ol_nearest_note.set_click_repeat (1);
for (int i = 0; i < num_widgets; ++i) {
widgets[i]->set_pos (x1, y1);
y1 -= lnspc[i];
}
i_current_midi = midiin.input_port;
ol_midi_devices.option.set_text (" midi = " + midiin.get_name (i_current_midi));
i_current_device = aout.current_device;
ol_audio_devices.option.set_text (" audio = " + aout.get_name (aout.current_device));
sprintf (sbuf, " sample rate = %d", aout.sample_rate);
ol_sample_rates.option.set_text (sbuf);
set_buffer_size (aout.samples_per_channel);
}
void settings::set_buffer_size (int bs) {
for (size_t i = 0, j = buffer_sizes.size (); i < j; ++i) {
if (buffer_sizes[i] == bs) {
i_buffer_size = i;
break;
}
}
sprintf (sbuf, " buffer size = %d", buffer_sizes [i_buffer_size]);
ol_buffer_sizes.option.set_text (sbuf);
}
void settings::find_current_tuning () {
for (int i = 0; i < num_tunings; ++i) {
if (s_current_tuning == tunings[i]) {
i_current_tuning = i;
}
}
}
int settings::handle_input () {
for (int i = 0; i < num_widgets; ++i) if (widgets[i]->handle_input ()) return 1;
if (scroll_up.handle_input () || scroll_down.handle_input ()) return 1;
return 0;
}
void settings::draw () {
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho (0, view.xmax, 0, view.ymax, -1, 1);
for (int i = 0; i < num_widgets; ++i) widgets[i]->draw ();
scroll_up.draw ();
scroll_down.draw ();
}
void settings::clicked (button& b) {
static const int delta_height = 7;
if (&b == &b_factory_reset) {
cons ("factory-reset");
} else if (&b == &b_go_back) {
//uis.set_current (uis.uis[0], 0, 1);
//uis.set_current (uis.uis[0]);
uis.set_current (uis.prev);
} else if (&b == &b_refresh_midi_devices) {
midiin.probe ();
ol_midi_devices.option.set_text (" midi = " + midiin.get_name (i_current_midi));
midiin.open (i_current_midi);
} else if (&b == &b_refresh_audio_devices) {
aout.close ();
aout.probe ();
aout.open ();
aout.start ();
ol_audio_devices.option.set_text (" audio = " + aout.get_name (i_current_device));
sprintf (sbuf, " sample rate = %d", aout.sample_rate);
ol_sample_rates.option.set_text (sbuf);
set_buffer_size (aout.samples_per_channel);
} else if (&b == &scroll_up) {
for (int i = 0; i < num_widgets; ++i) widgets[i]->move (0, -delta_height);
} else if (&b == &scroll_down) {
for (int i = 0; i < num_widgets; ++i) widgets[i]->move (0, +delta_height);
} else if (&b == &ol_display_modes.apply) {
display_mode& dm = display_modes [imode];
extern int FULL_SCREEN; FULL_SCREEN = dm.fullscreen;
setup_video_mode (dm.w, dm.h, dm.w, dm.h, dm.fullscreen);
}
}
void settings::picked (label& l, int d) {
static const float TWELFTH_ROOT_OF_2 = 1.0594630943f;
if (&l == &ol_nearest_note.option) {
float tonic = get_tonic (get_current_instrument ());
if (d > 0) {
tonic *= TWELFTH_ROOT_OF_2;
} else {
tonic /= TWELFTH_ROOT_OF_2;
}
set_tonic (get_current_instrument (), tonic);
} else if (&l == &ol_notation.option) {
extern string NOTATION;
if (NOTATION == "western") {
set_notation ("numeric");
} else {
set_notation ("western");
}
ol_notation.option.set_text (" notation = " + NOTATION);
} else if (&l == &ol_tuning.option) {
i_current_tuning += d;
if (i_current_tuning < 0) i_current_tuning = num_tunings - 1; else
if (i_current_tuning >= num_tunings) i_current_tuning = 0;
s_current_tuning = tunings[i_current_tuning];
interpreter ("tuning set " + s_current_tuning);
ol_tuning.option.set_text (" tuning = " + s_current_tuning + " ");
} else if (&l == &ol_midi_devices.option) {
if (midiin.num_ports) {
i_current_midi += d;
if (i_current_midi < 0) i_current_midi = midiin.num_ports - 1;
else if (i_current_midi >= midiin.num_ports) i_current_midi = 0;
midiin.open (i_current_midi);
ol_midi_devices.option.set_text (" midi = " + midiin.get_name (i_current_midi));
}
} else if (&l == &ol_audio_devices.option) {
aout.goto_next_device (d);
sprintf (sbuf, "set-audio device %d", aout.current_device);
cons (sbuf);
ol_audio_devices.option.set_text (" audio = " + aout.get_name (aout.current_device));
} else if (&l == &ol_sample_rates.option) {
int srate = aout.goto_next_sample_rate_id (d);
sprintf (sbuf, " sample rate = %d", srate);
ol_sample_rates.option.set_text (sbuf);
sprintf (sbuf, "set-audio sample_rate %d", srate);
cons (sbuf);
} else if (&l == &ol_buffer_sizes.option) {
i_buffer_size += d;
int n = buffer_sizes.size ();
if (i_buffer_size < 0) i_buffer_size = n - 1; else if (i_buffer_size >= n) i_buffer_size = 0;
int bs = buffer_sizes [i_buffer_size];
sprintf (sbuf, " buffer size = %d", bs);
ol_buffer_sizes.option.set_text (sbuf);
sprintf (sbuf, "set-audio samples_per_channel %d", bs);
cons (sbuf);
} else if (&l == &ol_display_modes.option) {
imode += d;
if (imode >= num_modes) imode = 0; else if (imode < 0) imode = num_modes - 1;
update_mode_display ();
}
}
void settings::changed (checkbutton& cb) {
int state = cb_show_midi_messages.state;
if (state) interpreter ("load-patch midimap 1"); else interpreter ("unload_midimap");
}
void settings::changed (field& f) {
float value = f;
if (&f == &l_delay_dur.fld || &f == &r_delay_dur.fld) {
static float MAX_DURATION = 60; // seconds
if (value <= 0 || value > MAX_DURATION) {
if (&f == &l_delay_dur.fld)
left_delay.get (value);
else
right_delay.get (value);
value /= 1000.0;
f.set_text (value);
}
string cmd ("set-delay ");
if (&f == &l_delay_dur.fld) cmd += "left "; else cmd += "right ";
float msecs = value * 1000.0f;
stringstream ss; ss << msecs;
cmd += ss.str();
cons (cmd);
} else if (&f == &s_key.f_value) {
set_tonic (get_current_instrument (), value);
} else if (&f == &sp_num_octaves.f_value) {
set_num_octaves (f);
} else if (&f == &sp_fps.f_value) {
extern int FPS;
extern double TIME_PER_FRAME;
FPS = int (f);
TIME_PER_FRAME = 1.0 / FPS;
} else if (&f == &sp_ips.f_value) {
extern int IPS;
extern double TIME_PER_INPUT;
IPS = (int) f;
TIME_PER_INPUT = 1.0 / IPS;
} else if (&f == &sp_mixing_time.f_value) {
float mixt = f;
if (mixt <= 0) {
cons << console::red << "Bad mix time ie <= 0" << eol;
return;
}
curve_mixer::TIME = f;
}
}
void settings::load_fullscreen_modes () {
dlog << "*** loading fullscreen modes ***" << endl;
SDL_Rect **modes;
// get available full screen modes
modes = SDL_ListModes (0, SDL_FULLSCREEN | SDL_OPENGL | SDL_HWSURFACE);
// Check is there are any modes available
if (modes == (SDL_Rect **) 0){
dlog << "No full-screen modes available" << endl;
return;
}
// Check if our resolution is restricted
if (modes == (SDL_Rect **) -1) {
} else {
static const int fullscreen = 1;
static const int min_width = 1024;
for(int i =0; modes[i]; ++i) {
SDL_Rect* moder = modes[i];
if (moder->w >= min_width) {
display_modes.push_back (display_mode(moder->w, moder->h, fullscreen));
dlog << " found mode: " << moder->w << 'x' << moder->h << endl;
}
}
}
num_modes = display_modes.size ();
dlog << "number of fullscreen modes = " << num_modes << endl;
dlog << "+++ loaded all full screen modes +++" << endl;
}
void settings::add_display_mode (int w, int h) {
display_mode dm (w, h);
display_modes.push_back (dm);
num_modes = display_modes.size ();
}
void settings::update_windowed_mode (int w, int h) {
int last_mode = num_modes - 1;
display_mode& dm = display_modes [last_mode];
dm.w = w; dm.h = h;
if (last_mode == imode) update_mode_display ();
}
void settings::update_mode_display () {
display_mode& dm = display_modes [imode];
static const char* const fs_str[] = {"windowed", "full screen"};
sprintf (sbuf, " display = %d x %d, %s", dm.w, dm.h, fs_str[dm.fullscreen]);
ol_display_modes.set_text (sbuf);
}