void initSynth(struct b_instance *inst, double rate) { // equivalent to ../src/main.c main() unsigned int defaultPreset[9] = {8,8,6, 0,0,0,0, 0,0}; /* initAll() */ initToneGenerator (inst->synth, inst->midicfg); initVibrato (inst->synth, inst->midicfg); initPreamp (inst->preamp, inst->midicfg); initReverb (inst->reverb, inst->midicfg, rate); initWhirl (inst->whirl, inst->midicfg, rate); initRunningConfig(inst->state, inst->midicfg); /* end - initAll() */ initMidiTables(inst->midicfg); setDrawBars (inst, 0, defaultPreset); #if 0 setDrawBars (inst, 1, defaultPreset); setDrawBars (inst, 2, defaultPreset); #endif #ifdef DEBUGPRINT if (walkProgrammes(inst->progs, 0)) { listProgrammes (inst->progs, stderr); } listCCAssignments(inst->midicfg, stderr); #endif }
/** * This is the routine called by the MIDI parser when it detects * a Program Change message. */ void installProgram (void *instance, unsigned char uc) { int p = (int) uc; b_instance * inst = (b_instance*) instance; p += inst->progs->MIDIControllerPgmOffset; if ((0 < p) && (p < MAXPROGS)) { Programme * PGM = &(inst->progs->programmes[p]); unsigned int flags0 = PGM->flags[0]; #ifdef DEBUG_MIDI_PROGRAM_CHANGES char display[128]; #endif if (flags0 & FL_INUSE) { #ifdef DEBUG_MIDI_PROGRAM_CHANGES strcpy (display, PGM->name); #endif if (flags0 & FL_DRWRND) { char buf [32]; if (flags0 & FL_DRAWBR) { randomizeDrawbars (PGM->drawbars, buf); #ifdef DEBUG_MIDI_PROGRAM_CHANGES strcat (display, "UPR:"); strcat (display, buf); #endif } if (flags0 & FL_LOWDRW) { randomizeDrawbars (PGM->lowerDrawbars, buf); #ifdef DEBUG_MIDI_PROGRAM_CHANGES strcat (display, "LOW:"); strcat (display, buf); #endif } if (flags0 & FL_PDLDRW) { randomizeDrawbars (PGM->pedalDrawbars, buf); #ifdef DEBUG_MIDI_PROGRAM_CHANGES strcat (display, "PDL:"); strcat (display, buf); #endif } } #ifdef DEBUG_MIDI_PROGRAM_CHANGES /* this is not RT safe */ //fprintf (stdout, "\rPGM: %s \r", display); fflush (stdout); fprintf (stdout, "PGM: %s\n", display); #endif if (flags0 & FL_DRAWBR) { setDrawBars (inst, 0, PGM->drawbars); } if (flags0 & FL_LOWDRW) { setDrawBars (inst, 1, PGM->lowerDrawbars); } if (flags0 & FL_PDLDRW) { setDrawBars (inst, 2, PGM->pedalDrawbars); } if (flags0 & FL_SCANNR) { //setVibrato (inst->synth, PGM->scanner & 0x00FF); assert((PGM->scanner & 0xff) > 0); int knob = ((PGM->scanner & 0xf) << 1) - ((PGM->scanner & CHO_) ? 1 : 2); callMIDIControlFunction(inst->midicfg, "vibrato.knob", knob * 23); } if (flags0 & FL_VCRUPR) { //setVibratoUpper (inst->synth, PGM->scanner & 0x200); int rt = getVibratoRouting(inst->synth) & ~0x2; rt |= (PGM->scanner & 0x200) ? 2 : 0; callMIDIControlFunction(inst->midicfg, "vibrato.routing", rt << 5); } if (flags0 & FL_VCRLWR) { //setVibratoLower (inst->synth, PGM->scanner & 0x100); int rt = getVibratoRouting(inst->synth) & ~0x1; rt |= (PGM->scanner & 0x100) ? 1 : 0; callMIDIControlFunction(inst->midicfg, "vibrato.routing", rt << 5); } if (flags0 & FL_PRCENA) { setPercussionEnabled (inst->synth, PGM->percussionEnabled); callMIDIControlFunction(inst->midicfg, "percussion.enable", PGM->percussionEnabled ? 127 : 0); } if (flags0 & FL_PRCVOL) { //setPercussionVolume (inst->synth, PGM->percussionVolume); callMIDIControlFunction(inst->midicfg, "percussion.volume", PGM->percussionVolume ? 127 : 0); } if (flags0 & FL_PRCSPD) { //setPercussionFast (inst->synth, PGM->percussionSpeed); callMIDIControlFunction(inst->midicfg, "percussion.decay", PGM->percussionSpeed ? 127 : 0); } if (flags0 & FL_PRCHRM) { //setPercussionFirst (inst->synth, PGM->percussionHarmonic); callMIDIControlFunction(inst->midicfg, "percussion.harmonic", PGM->percussionHarmonic ? 127 : 0); } if (flags0 & FL_OVRSEL) { //setClean (inst->preamp, PGM->overdriveSelect); callMIDIControlFunction(inst->midicfg, "overdrive.enable", PGM->overdriveSelect ? 0 : 127); } if (flags0 & FL_ROTENA) { /* Rotary enabled */ } if (flags0 & FL_ROTSPS) { // setRevSelect (inst->whirl, (int) (PGM->rotarySpeedSelect)); callMIDIControlFunction(inst->midicfg, "rotary.speed-preset", PGM->rotarySpeedSelect * 32); } if (flags0 & FL_RVBMIX) { //setReverbMix (inst->reverb, PGM->reverbMix); callMIDIControlFunction(inst->midicfg, "reverb.mix-preset", (PGM->reverbMix * 127.0)); } /* TODO -- keyboard split & transpose are not yet saved */ if (flags0 & (FL_KSPLTL|FL_KSPLTP|FL_TRA_PD|FL_TRA_LM|FL_TRA_UM)) { int b; b = (flags0 & FL_KSPLTP) ? 1 : 0; b |= (flags0 & FL_KSPLTL) ? 2 : 0; b |= (flags0 & FL_TRA_PD) ? 4 : 0; b |= (flags0 & FL_TRA_LM) ? 8 : 0; b |= (flags0 & FL_TRA_UM) ? 16 : 0; setKeyboardSplitMulti (inst->midicfg, b, PGM->keyboardSplitPedals, PGM->keyboardSplitLower, PGM->transpose[TR_CHA_PD], PGM->transpose[TR_CHA_LM], PGM->transpose[TR_CHA_UM]); } if (flags0 & FL_TRANSP) { setKeyboardTranspose (inst->midicfg, PGM->transpose[TR_TRANSP]); } if (flags0 & FL_TRCH_A) { setKeyboardTransposeA (inst->midicfg, PGM->transpose[TR_CHNL_A]); } if (flags0 & FL_TRCH_B) { setKeyboardTransposeB (inst->midicfg, PGM->transpose[TR_CHNL_B]); } if (flags0 & FL_TRCH_C) { setKeyboardTransposeC (inst->midicfg, PGM->transpose[TR_CHNL_C]); } } } }
/* * Main program. */ int main (int argc, char * argv []) { int i,c,k; int doDefaultConfig = TRUE; int doDefaultProgram = TRUE; int printCCTable = FALSE; int doDefaultCC = TRUE; char * configOverride [NOF_CFG_OVERS]; int configOverEnd = 0; int loadProgram = -1; unsigned int randomPreset[9]; unsigned int defaultPreset[9] = {8,8,8, 0,0,0,0, 0,0}; unsigned int * presetSelect = defaultPreset; char *midnam = NULL; char * alternateProgrammeFile = NULL; char * alternateConfigFile = NULL; memset(&inst, 0, sizeof(b_instance)); srand ((unsigned int) time (NULL)); for (i=0;i<AUDIO_CHANNELS; i++) jack_port[i] = NULL; jack_ports = strdup("system:playback_"); const char *optstring = "c:CdDhHl:M:p:PrU:V"; const struct option long_options[] = { { "help", no_argument, 0, 'H' }, { "program", required_argument, 0, 'p' }, { "config", required_argument, 0, 'c' }, { "noconfig", no_argument, 0, 'C' }, { "dumpcc", no_argument, 0, 'd' }, { "noCC", no_argument, 0, 'D' }, { "midnam", required_argument, 0, 'M' }, { "noprogram", no_argument, 0, 'P' }, { "randomize", no_argument, 0, 'r' }, { "upper", required_argument, 0, 'U' }, { "version", no_argument, 0, 'V' }, { 0, 0, 0, 0 } }; while ((c = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) { switch (c) { case 'c': alternateConfigFile = optarg; break; case 'C': doDefaultConfig = FALSE; break; case 'd': printCCTable = TRUE; break; case 'D': doDefaultCC = FALSE; break; case 'h': Usage(0); return (0); break; case 'H': Usage(1); return (0); break; case 'l': loadProgram = atoi(optarg); break; case 'M': midnam = optarg; break; case 'r': for (k = 0; k < 9; k++) randomPreset[k] = rand () % 9; fprintf (stderr, "Random Preset: " "%d%d %d%d%d%d %d%d%d\n", randomPreset[0], randomPreset[1], randomPreset[2], randomPreset[3], randomPreset[4], randomPreset[5], randomPreset[6], randomPreset[7], randomPreset[8]); presetSelect = randomPreset; break; case 'p': alternateProgrammeFile = optarg; break; case 'P': doDefaultProgram = FALSE; break; case 'U': parse_preset(defaultPreset, optarg); break; case 'V': PrintVersion(); return(0); default: fprintf(stderr, "invalid argument.\n"); Usage(0); return(1); } } for (i = optind; i < argc; ++i) { char * av = argv[i]; if (strchr (av, '=') != NULL) { /* Remember this as a config parameter */ if (configOverEnd < NOF_CFG_OVERS) { configOverride[configOverEnd++] = av; } else { fprintf (stderr, "Too many configuration parameters (%d), please consider using a\n" "configuration file instead of the commandline.\n", NOF_CFG_OVERS); return(1); } } } /* * allocate data structures, instances. */ allocAll(); /* * evaluate configuration */ if (getenv("XDG_CONFIG_HOME")) { size_t hl = strlen(getenv("XDG_CONFIG_HOME")); defaultConfigFile=(char*) malloc(hl+32); defaultProgrammeFile=(char*) malloc(hl+32); sprintf(defaultConfigFile, "%s/setBfree/default.cfg", getenv("XDG_CONFIG_HOME")); sprintf(defaultProgrammeFile, "%s/setBfree/default.pgm", getenv("XDG_CONFIG_HOME")); } else if (getenv("HOME")) { size_t hl = strlen(getenv("HOME")); defaultConfigFile=(char*) malloc(hl+30); defaultProgrammeFile=(char*) malloc(hl+30); sprintf(defaultConfigFile, "%s/.config/setBfree/default.cfg", getenv("HOME")); sprintf(defaultProgrammeFile, "%s/.config/setBfree/default.pgm", getenv("HOME")); } /* * Here we call modules that need to execute code in order to arrange * static initializations that is not practical to achieve in source code. */ initControllerTable (inst.midicfg); if (doDefaultCC) { midiPrimeControllerMapping (inst.midicfg); } /* * Commandline arguments are parsed. If we are of a mind to try the * default configuration file we do that now. */ if (doDefaultConfig == TRUE && defaultConfigFile) { if (access (defaultConfigFile, R_OK) == 0) { fprintf(stderr, "loading cfg: %s\n", defaultConfigFile); parseConfigurationFile (&inst, defaultConfigFile); } } if (alternateConfigFile) { if (access (alternateConfigFile, R_OK) == 0) { fprintf(stderr, "loading cfg: %s\n", alternateConfigFile); parseConfigurationFile (&inst, alternateConfigFile); } } /* * Then apply any configuration parameters collected from the commandline. * These must be applied last so that they can override the parameters * read from the files (if any). */ for (i = 0; i < configOverEnd; i++) { parseConfigurationLine (&inst, "commandline argument", 0, configOverride[i]); } /* * Having configured the initialization phase we can now actually do it. */ #ifndef _WIN32 if (mlockall (MCL_CURRENT | MCL_FUTURE)) { fprintf(stderr, "Warning: Can not lock memory.\n"); } #endif initAll (); /* * We are initialized and now load the programme file. */ if (doDefaultProgram == TRUE && defaultProgrammeFile) { if (access (defaultProgrammeFile, R_OK) == 0) loadProgrammeFile (inst.progs, defaultProgrammeFile); } else { walkProgrammes(inst.progs, 1); // clear built-in default program } if (alternateProgrammeFile != NULL) loadProgrammeFile (inst.progs, alternateProgrammeFile); if (walkProgrammes(inst.progs, 0)) { listProgrammes (inst.progs, stderr); } initMidiTables(inst.midicfg); if (printCCTable) { listCCAssignments(inst.midicfg, stderr); } if (midnam) { FILE *fp = fopen(midnam, "w"); if (fp) { save_midname(&inst, fp); fclose(fp); } else { fprintf(stderr, "failed to write midnam to '%s'\n", midnam); } } /* * With the programmes eager and ready to go, we spawn off the MIDI * listener thread. The thread will initialize the MIDI device. */ #ifdef HAVE_ASEQ pthread_t t_midi; if (!use_jack_midi) { if (!aseq_open(midi_port)) { k = pthread_create(&t_midi, NULL, aseq_run, &inst); if (k != 0) { fprintf (stderr, "%d : %s\n", k, "pthread_create : MIDIInReader thread"); return (1); } } else { return (1); } } #endif setMIDINoteShift (inst.midicfg, 0); setDrawBars (&inst, 0, presetSelect); #if 0 // initial values are assigned in tonegen.c initToneGenerator() setDrawBars (&inst, 1, presetSelect); /* 838 000 000 */ setDrawBars (&inst, 2, presetSelect); /* 86 - */ #endif const int pgm_off = inst.progs->MIDIControllerPgmOffset; if (loadProgram >= 0 && loadProgram >= pgm_off) { installProgram(&inst, (loadProgram - pgm_off)); } #ifndef _WIN32 signal (SIGHUP, catchsig); signal (SIGINT, catchsig); #endif connect_jack_ports(); synth_ready = 1; fprintf(stderr,"All systems go. press CTRL-C, or send SIGINT or SIGHUP to terminate\n"); while (j_client) /* jack callback is doing this the work now */ #ifdef _WIN32 Sleep (1000); #else sleep (1); #endif /* shutdown and cleanup */ #ifdef HAVE_ASEQ if (!use_jack_midi) { aseq_stop=1; pthread_join(t_midi, NULL); aseq_close(); } #endif free(defaultConfigFile); free(defaultProgrammeFile); free(j_output_bufferptrs); free(j_output_port); free(midi_port); free(jack_ports); for (i=0;i<AUDIO_CHANNELS; i++) free(jack_port[i]); freeAll(); #ifndef _WIN32 munlockall(); #endif fprintf(stderr, "bye\n"); return 0; }