/* Copyright (C) 2010-2012 Florian Jung This file is part of flo's FM synth. flo's FM synth is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. flo's FM synth is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with flo's FM synth. If not, see . */ #include #include #include #include #include "in_synth_cli.h" #include "util.h" #include "communication.h" #include "globals.h" #include "load.h" #include "lfos.h" #ifdef WATCHFILES #include "watch_files.h" #endif using namespace std; #define PROMPT "> " pthread_mutex_t prog_load_mutex; void signal_handler(int sig) { cout << endl << PROMPT << flush; } void lock_and_load_program(int prg_no, string file) { pthread_mutex_lock(&prog_load_mutex); #ifdef WATCHFILES remove_watch(prg_no); #endif do_request(request_t(request_t::SUSPEND_PROGRAM, prg_no)); if (load_program(file,program_settings[prg_no])) { cout << "success" << endl; programfile[prg_no]=file; #ifdef WATCHFILES add_watch(prg_no); #endif } else cout << "failed" << endl; for (int i=0;imaybe_reload_program(prg_no); do_request(request_t(request_t::RESUME_PROGRAM, prg_no)); pthread_mutex_unlock(&prog_load_mutex); } //only use this, if you don't want the file-watches to be updated //i.e., only when reloading a program! void lock_and_load_program_no_watch_updates(int prg_no, string file) { pthread_mutex_lock(&prog_load_mutex); do_request(request_t(request_t::SUSPEND_PROGRAM, prg_no)); if (load_program(file,program_settings[prg_no])) { cout << "success" << endl; programfile[prg_no]=file; } else cout << "failed" << endl; for (int i=0;imaybe_reload_program(prg_no); do_request(request_t(request_t::RESUME_PROGRAM, prg_no)); pthread_mutex_unlock(&prog_load_mutex); } void lock_and_change_lfo(int lfo_no, float freq) { do_request(request_t(request_t::SUSPEND_PROGRAM, -1)); uninit_lfo(lfo_no); lfo_freq_hz[lfo_no]=freq; init_lfo(lfo_no); do_request(request_t(request_t::RESUME_PROGRAM, -1)); } void do_in_synth_cli() { string input; string command; string params; int num; pthread_mutex_init(&prog_load_mutex, NULL); if (signal(2,signal_handler)==SIG_ERR) output_warning("WARNING: failed to set signal handler in the in-synth-cli. pressing ctrl+c will\n" " kill the synth, so be careful. this is not fatal"); fatal_warnings=false; while (cin.good()) { cout << PROMPT << flush; getline(cin,input); input=trim_spaces(input); command=trim_spaces(str_before(input,' ',input)); params=trim_spaces(str_after(input,' ',"")); if ((command=="exit") || (command=="quit")) break; else if (command=="reload") { if ((!isnum(params)) || (params=="")) cout << "error: expected program-number, found '"<=0) && (num<128)) lock_and_load_program(num, programfile[num]); else cout << "error: program-number must be one of 0..127" << endl; } } else if (command=="load") { string prgstr, file; prgstr=trim_spaces(str_before(params,' ',params)); file=trim_spaces(str_after(params,' ',"")); if ((!isnum(prgstr)) || (prgstr=="")) cout << "error: expected program-number, found '"<=0) && (num<128)) { lock_and_load_program(num, file); programfile[num]=file; } else cout << "error: program-number must be one of 0..127" << endl; } } else if (command=="panic") { if ((params=="") || (params=="all")) do_request(request_t(request_t::PANIC, -1)); else if (isnum(params)) { num=atoi(params.c_str()); if ((num>=0) && (num=0) && (num=0) && (num<128)) { if (chanstr=="") for (int i=0;ikill_program(num); else { int num2=atoi(chanstr.c_str()); if ((num2>=0)&&(num2kill_program(num); else cout << "error: channel-number must be one of 0.."<=0) && (num=0) channel[num]->set_n_voices(num2); else cout << "error: limit must be a positive number, zero or 'all'"<reset_controllers(); else if (isnum(params)) { num=atoi(params.c_str()); if ((num>=0) && (numreset_controllers(); else cout << "error: channel-number must be one of 0.."<=0) && (num=0) && (num2<128)) channel[num]->set_program(num2); else cout << "error: program must be one of 0..127"<=0) && (num=0) && (num2<128))) cout << "error: controller must be one of 0..127"<=0) && (val<128))) cout << "error: value must be one of 0..127"<set_controller(num2,val); } else cout << "error: channel-number must be one of 0.."<=0) && (num=0) channel[num]->set_portamento_time_sec(num2); else cout << "error: portamento time must be positive"<=0) && (numset_portamento(127); else //off channel[num]->set_portamento(0); } else cout << "error: channel-number must be one of 0.."<=0) && (num=0) && (num2<128)) channel[num]->set_volume(num2); else cout << "error: volume must be one of 0..127"<=0) && (num=0) && (num2<128)) channel[num]->set_balance(num2); else cout << "error: balance must be one of 0..127"<=0) && (numset_hold_pedal(onstr=="on"); else cout << "error: channel-number must be one of 0.."<=0) && (numset_sostenuto_pedal(onstr=="on"); else cout << "error: channel-number must be one of 0.."<=0) && (numset_soft_pedal(onstr=="on"); else cout << "error: channel-number must be one of 0.."<=0) && (numset_legato_pedal(onstr=="on"); else cout << "error: channel-number must be one of 0.."<=0) && (num0) lock_and_change_lfo(num,freq); else cout << "error: frequency must be a positive number"<=0) { snh_freq_hz=freq; init_snh(); //no uninit necessary, as this only calculates an integer //no lock necessary, as a race-condition would only cause // the snh be calculated some times more } else cout << "error: sample-and-hold-frequency must be greater than zero"<