Skip to content

Commit

Permalink
Merge pull request #19 from zynthian/master
Browse files Browse the repository at this point in the history
Fix #17 & #18:  Reduce loading time and add a basic console interface
  • Loading branch information
sampov2 authored Sep 2, 2020
2 parents b99d4a3 + 6d2d4a2 commit 30e924b
Show file tree
Hide file tree
Showing 5 changed files with 331 additions and 32 deletions.
6 changes: 6 additions & 0 deletions include/yc20-precalc.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ _yc20_get_sample(dsp *x, float phase, int note, int div)
void
yc20_destroy_oscillators(yc20_precalc_osc *osc);

int
yc20_save_precalc_osc(yc20_precalc_osc *p, const char *fpath);

yc20_precalc_osc *
yc20_load_precalc_osc(float samplerate, const char *fpath);

#ifdef __cplusplus
}
#endif
Expand Down
11 changes: 10 additions & 1 deletion src/lv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ ADVISEDOF THE POSSIBILITY OF SUCH DAMAGE.
#include <lv2/lv2plug.in/ns/ext/urid/urid.h>

#include <foo-yc20.h>
#include <foo-yc20-os.h>
#include <yc20-precalc.h>

#ifdef __cplusplus
Expand Down Expand Up @@ -83,7 +84,15 @@ static LV2_Handle instantiate_FooYC20 (
handle->yc20 = new YC20Processor();
handle->yc20->setDSP(tmp);

getUserData(tmp)->osc = yc20_precalc_oscillators(sample_rate);
//Try loading oscillator data from cache file...
std::string fpath=DEFAULT_CONFIG_DIR + "/.precalc_osc.dat";
getUserData(tmp)->osc=yc20_load_precalc_osc(sample_rate,fpath.c_str());

//If not, precalculate and save to cache ...
if (!getUserData(tmp)->osc) {
getUserData(tmp)->osc = yc20_precalc_oscillators(sample_rate);
yc20_save_precalc_osc(getUserData(tmp)->osc,fpath.c_str());
}

return (LV2_Handle)handle;
}
Expand Down
163 changes: 148 additions & 15 deletions src/main-cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ ADVISEDOF THE POSSIBILITY OF SUCH DAMAGE.

#include <signal.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>

#include <yc20-jack.h>
#include <foo-yc20-os.h>
Expand All @@ -52,20 +54,47 @@ void exit_cli(int sig)
std::cerr << "Exiting" << std::endl;
}

int main(int argc, char **argv)
{
std::string get_version() {
std::string version(VERSION_STR);
std::string svn_revision("$Revision: 106 $");

if (version == "") {
version = svn_revision.substr(11, svn_revision.find(" $", 11));
version = "svn-" + version;
}


#define L << std::endl <<
std::cerr << "Foo-YC20 (CLI) " << version
L "Copyright 2010-2011 Sampo Savolainen ([email protected]). All rights reserved."
return version;
}

void print_usage() {
#define L << std::endl <<
std::cerr << "Usage: foo-yc20-cli [OPTION] [PRESET_FILE_PATH]"
L ""
L "Run foo-yc20 combo-organ emulator in headless mode. The following options are accepted:"
L ""
L " -c Enable console"
L " -f Force regeneration of oscillator data cache"
L " -g Generate oscillators data cache and exit"
L " -h Display this help and exit"
L " -l Display license info and exit"
L "" << std::endl;
#undef L
}

void print_command_help() {
#define L << std::endl <<
std::cerr << "Available Commands:"
L " + get_presets : Print preset list"
L " + set_preset [PRESET_FILE_PATH] : Load preset from file"
L " + help : Print command help"
L " + exit : Exit"
L "" << std::endl;
#undef L
}

void print_license() {
#define L << std::endl <<
std::cerr << "Copyright 2010-2011 Sampo Savolainen ([email protected]). All rights reserved."
L "Redistribution and use in source and binary forms, with or without modification,"
L "are permitted provided that the following conditions are met:"
L " 1. Redistributions of source code must retain the above copyright notice,"
Expand All @@ -85,33 +114,137 @@ int main(int argc, char **argv)
L "PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF"
L "LIABILITY, WHETHERIN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE"
L "OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF"
L "ADVISEDOF THE POSSIBILITY OF SUCH DAMAGE." << std::endl;
#undef L
L "ADVISEDOF THE POSSIBILITY OF SUCH DAMAGE."
L "" << std::endl;
#undef L
}

void print_presets() {
DIR *dir;
struct dirent *ent;
std::string dirName(DEFAULT_CONFIG_DIR);
if ((dir = opendir (dirName.c_str())) != NULL) {
while ((ent = readdir (dir)) != NULL) {
if (ent->d_name[0]=='.') continue;
std::cout << ent->d_name << std::endl;
}
closedir (dir);
} else {
std::cerr << "Could not open presets directory!" << std::endl;
}
}

void process_command(YC20Jack &processor, char *command) {
char arg1[128];

if (strcmp(command, "get_presets\n") == 0) {
print_presets();
}
else if (sscanf(command, "set_preset %127[a-zA-Z0-9_:.#&%%()+-]\n", arg1) == 1) {
std::string dirName(DEFAULT_CONFIG_DIR);
std::string fname(arg1);
std::string fpath=dirName + "/" + fname;
std::cerr << "Loading preset <" << fpath << ">" << std::endl;
processor.loadConfiguration(fpath);
}
else if (strcmp(command, "help\n") == 0) {
print_command_help();
}
else if (strcmp(command, "exit\n") == 0) {
exit_cli(0);
}
else {
std::cerr << "Invalid command: Type 'help'." << std::endl;
}
}

int main(int argc, char **argv)
{
//CLI message: program name and version
std::cerr << "Foo-YC20 (CLI) " << get_version() << " (c)Sampo Savolainen 2010" << std::endl << std::endl;

//Process command line options
int force_precalc_osc=0;
int exit_after_precalc_osc=0;
int enable_console=0;
std::string config_fpath;
if (argc > 1) {
std::string arg1(argv[1]);
if (arg1=="-h") {
print_usage();
return 0;
} else if (arg1=="-l") {
print_license();
return 0;
} else if (arg1=="-f") {
force_precalc_osc=1;
} else if (arg1=="-g") {
force_precalc_osc=1;
exit_after_precalc_osc=1;
} else if (arg1=="-c") {
enable_console=1;
} else {
config_fpath=arg1;
}
if (config_fpath.empty() and argc > 2) {
config_fpath=argv[2];
}
}

YC20Jack processor;
processor.connect();

dsp *yc20 = createDSP();
yc20_precalc_osc *osc = yc20_precalc_oscillators(processor.getSamplerate());

yc20_precalc_osc *osc=NULL;
//Try loading oscillator data from cache file...
std::string fpath=DEFAULT_CONFIG_DIR + "/.precalc_osc.dat";
if (!force_precalc_osc) {
osc=yc20_load_precalc_osc(processor.getSamplerate(),fpath.c_str());
}
//If not, precalculate and save to cache ...
if (!osc) {
osc = yc20_precalc_oscillators(processor.getSamplerate());
yc20_save_precalc_osc(osc,fpath.c_str());
}
//If only cache regeneration option => exit
if (exit_after_precalc_osc) {
yc20_destroy_oscillators(osc);
return 0;
}

yc20->init(processor.getSamplerate());

processor.setDSP(yc20);
getUserData(yc20)->osc = osc;

if (argc > 1) {
std::string conf(argv[1]);
std::cerr << "using configuration file '" << conf << "'" << std::endl;
processor.loadConfiguration(conf);
// Load configuration
if (!config_fpath.empty()) {
std::cerr << "Using configuration file '" << config_fpath << "'" << std::endl;
processor.loadConfiguration(config_fpath);
} else {
processor.loadConfiguration();
}

processor.activate();

run = true;
signal(SIGINT, exit_cli);

while(run) {
sleep(100); // ctrl-C interrupts sleep and runs exit_cli() which sets run to false
if (enable_console) {
while (run) {
char line[128];
std::cout << "> " << std::flush;
if (fgets(line, sizeof(line), stdin)) {
process_command(processor, line);
} else {
break;
}
}
} else {
while(run) {
sleep(100); // ctrl-C interrupts sleep and runs exit_cli() which sets run to false
}
}

processor.deactivate();
Expand Down
Loading

0 comments on commit 30e924b

Please sign in to comment.