示例#1
0
int __init new_midi_init(void) {
    printk(KERN_INFO LOGPREFIX "init\n");

    pr_info("myint: %d\n", myint);

    if (alloc_chrdev_region(&template_dev_number, 0, 1, TEMPLATE) < 0) return -EIO;

    driver_object = cdev_alloc();
    if (driver_object == NULL) goto free_device_number;
    driver_object->owner = THIS_MODULE;
    driver_object->ops = &new_midi_fops;

    if (cdev_add(driver_object, template_dev_number, 1)) goto free_cdev;

    template_class = class_create(THIS_MODULE, TEMPLATE);

    dev = device_create(template_class, NULL, template_dev_number, NULL, "%s", TEMPLATE);

    return init_midi();

free_cdev:
    kobject_put(&driver_object->kobj);
free_device_number:
    unregister_chrdev_region(template_dev_number, 1);
    return -EIO;
}
示例#2
0
文件: midi.c 项目: huangjs/cl
int mus_midi_open_write(const char *name)
{
  init_midi();
  if (us == NULL) 
    MIDIClientCreate(CFSTR("MIDI Write"), NULL, NULL, &us);
  if (outp == NULL)
    MIDIOutputPortCreate(us, CFSTR("Output port"), &outp);
  return(1);
}
示例#3
0
文件: midi.c 项目: huangjs/cl
int mus_midi_open_read(const char *name)
{
  init_midi();
  if (us == NULL) 
    MIDIClientCreate(CFSTR("MIDI Read"), NULL, NULL, &us);
  if (inp == NULL)
    MIDIInputPortCreate(us, CFSTR("Input port"), midi_read_callback, NULL, &inp);
  MIDIPortConnectSource(inp, MIDIGetSource(0), NULL);
  return(0);
}
struct nanokontrol2_context *
init_nanokontrol2(char *path) {
	struct nanokontrol2_context *ctx;

	ctx = malloc(sizeof(struct nanokontrol2_context));
	assert(ctx != NULL);

	if(init_midi(&ctx->midictx, path, nanokontrol2_read_data) == NULL) {
		free(ctx);
		return NULL;
	}

	nanokontrol2_switch_mode(ctx, NANOKONTROL2_MODE_NATIVE);

	return ctx;
}
示例#5
0
static rtems_task gui_task(rtems_task_argument argument)
{
	init_fb_mtk(sysconfig_get_autostart_mode() == SC_AUTOSTART_FILE);
	sysconfig_set_mtk_language();
	sysconfig_set_mtk_wallpaper();
	init_input();
	input_add_callback(mtk_input);
	init_shortcuts();
	init_osc();
	init_messagebox();
	init_performance();
	init_renderer();
	init_cp();
	init_keyboard();
	init_ir();
	init_audio();
	init_midi();
	init_oscsettings();
	init_dmxspy();
	init_dmxdesk();
	init_dmx();
	init_videoin();
	init_rsswall();
	init_patcheditor();
	init_monitor();
	init_firstpatch();
	init_filemanager();
#ifdef WITH_PDF
	init_pdfreader();
#endif
	init_sysettings();
	init_about();
	init_flash();
	init_shutdown();

	cp_autostart();
	
	if(sysconfig_is_rescue())
		messagebox("Rescue mode", "You have booted in rescue mode.\n"
			"Your system will function as usual, using back-up software.\n"
			"From there, you can update the main software or perform\nother actions to fix the problem.\n");

	/* FIXME: work around "black screen" bug in MTK */
	mtk_cmd(1, "screen.refresh()");
	
	input_eventloop();
}
示例#6
0
void GlobalInitialize()
{
    InitCommonControls(); 

/*	if(SDL_WasInit(SDL_INIT_AUDIO | SDL_INIT_TIMER | SDL_INIT_VIDEO) == 0)
	{
		if (SDL_InitSubSystem(SDL_INIT_AUDIO | SDL_INIT_TIMER | SDL_VIDEO) < 0)
			report_error("Couldn't init SDL");
	}
*/
		
	if(SDL_Init(SDL_INIT_EVERYTHING)<0) 
        report_error("Couldn't init SDL");
	
   if (!Sound_Init()) report_error("Couldn't init SDL_Sound");


	if(SDLNet_Init()<0)	report_error("Couldn't init SDL_Net");

	GLOBAL.os_version=check_OS();


    TTY.ThreadExitEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (TTY.ThreadExitEvent == NULL)
        report_error("CreateEvent (Thread exit event)");       

	init_devicetype();
	TTY.COMDEV=INVALID_HANDLE_VALUE;
	TTY.CONNECTED=FALSE;
	TTY.read_pause=TRUE;
	TTY.amount_to_write=0;
	TTY.writeMutex=	CreateMutex( NULL, FALSE, NULL ); 

	TTY.FLOW_CONTROL=0;

	PACKET.readstate=0;
	PACKET.info=0;
	PACKET.requestedinfo=0;

	GLOBAL.objects=0;	actobject=NULL; actconnect=NULL;
	GLOBAL.tool_left=400;GLOBAL.tool_top=100;
	GLOBAL.tool_right=800;GLOBAL.tool_bottom=400;
	GLOBAL.anim_left=20;GLOBAL.anim_right=420;
	GLOBAL.anim_top=350;GLOBAL.anim_bottom=700;
	GLOBAL.design_left=20;GLOBAL.design_right=500;
	GLOBAL.design_top=20;GLOBAL.design_bottom=400;
	GLOBAL.startup=0; GLOBAL.autorun=0; GLOBAL.configfile[0]=0;
	GLOBAL.syncloss=0;
	GLOBAL.dialog_interval=DIALOG_UPDATETIME;
	GLOBAL.draw_interval=DRAW_UPDATETIME;
	GLOBAL.neurobit_available=0;
	GLOBAL.emotiv_available=0;
	GLOBAL.use_cv_capture=0;
	strcpy(GLOBAL.emotivpath,"C:\\Program Files (x86)\\Emotiv Development Kit_v1.0.0.3-PREMIUM");

	GLOBAL.loading=false;
	GLOBAL.read_tcp=0;
	GLOBAL.packet_parsed=0;
	GLOBAL.actcolumn=0;
	GLOBAL.running=false;
	GLOBAL.showdesign=TRUE;
	GLOBAL.showtoolbox=-1;
	GLOBAL.session_length=0;
	GLOBAL.session_start=0;
	GLOBAL.session_end=0;
	GLOBAL.session_loop =0 ;
	GLOBAL.session_sliding=0;

	GLOBAL.main_maximized=0;
	GLOBAL.minimized=0;
	GLOBAL.run_exception=0;
	GLOBAL.fly=0;

	GLOBAL.P3ALC1=12;
	GLOBAL.P3ALC2=12;

	TIMING.timerid=0;

	CAPTFILE.filetype=FILE_INTMODE;
	CAPTFILE.filehandle=INVALID_HANDLE_VALUE;
	CAPTFILE.file_action=0;
	CAPTFILE.do_read=0;
	CAPTFILE.do_write=0;
	CAPTFILE.length=0;
	CAPTFILE.start=0;
	strcpy(CAPTFILE.filename,"none");

	ghWndAnimation=NULL;
    ghWndToolbox=NULL;
    ghWndSettings=NULL;
    ghWndDesign=NULL;
	copy_object=NULL;

	init_draw();
	init_midi();

	load_settings();
	
	TIMING.timerid=0;
	TIMING.pause_timer=0;
	init_system_time();

	write_logfile("application init successful.");
    return ;
}
示例#7
0
LRESULT CALLBACK BROWSEDlghandler( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
{
    static int t,port=DEF_MIDIPORT,midichn=1,instrument=11;
	static char szFileName[MAX_PATH];
	static int oldtone=0;


	switch( message )
	{
		case WM_INITDIALOG:
			{
				SCROLLINFO lpsi;

				init_midi();
				strcpy(LOADSCALE.name,"Chromatic1-127");
				for (t=1;t<128;t++)  LOADSCALE.tones[t-1]=t; 
				LOADSCALE.len=127;
				SetDlgItemText(hDlg, IDC_HARMONICNAME, LOADSCALE.name);

				for (t=0;t<255;t++) 
					SendDlgItemMessage(hDlg, IDC_MIDIINSTCOMBO, CB_ADDSTRING, 0,(LPARAM) (LPSTR) midi_instnames[t]) ;
				SendDlgItemMessage( hDlg, IDC_MIDIINSTCOMBO, CB_SETCURSEL, instrument, 0L ) ;

 			    for (t = 0; t < midiports; t++) 
				 if(MIDIPORTS[t].midiout)
				   SendDlgItemMessage(hDlg, IDC_MIDIPORTCOMBO, CB_ADDSTRING, 0, (LPARAM) (LPSTR) MIDIPORTS[t].portname ) ;
				SetDlgItemText(hDlg, IDC_MIDIPORTCOMBO, MIDIPORTS[port].portname);

				lpsi.cbSize=sizeof(SCROLLINFO);
				lpsi.fMask=SIF_RANGE|SIF_POS;
				lpsi.nMin=1; lpsi.nMax=127;
				SetScrollInfo(GetDlgItem(hDlg,IDC_TONEBAR),SB_CTL,&lpsi,TRUE);
 			    SetScrollPos(GetDlgItem(hDlg, IDC_TONEBAR), SB_CTL, 64, 1);
			    SetDlgItemInt(hDlg, IDC_ACTTONE, 64,0);
			    SetDlgItemInt(hDlg, IDC_MIDICHN, midichn,0);
				
				midi_Instrument(&(MIDIPORTS[port].midiout),midichn,instrument);
				update_harmonic(GetDlgItem(hDlg, IDC_HARMONICLIST));

			}
			return TRUE;
	
		case WM_CLOSE:
				midi_NoteOff(&(MIDIPORTS[port].midiout), midichn,oldtone);
			    EndDialog(hDlg, LOWORD(wParam));
				return TRUE;
			break;
		case WM_COMMAND:
			switch (LOWORD(wParam)) 
			{

			case IDC_MIDIPORTCOMBO:
 				 if (HIWORD(wParam)==CBN_SELCHANGE)
				    port=get_listed_midiport(SendMessage(GetDlgItem(hDlg, IDC_MIDIPORTCOMBO), CB_GETCURSEL , 0, 0));
					midi_Instrument(&(MIDIPORTS[port].midiout),midichn,instrument); 
				 break;
			case IDC_MIDIINSTCOMBO:
					instrument=SendMessage(GetDlgItem(hDlg, IDC_MIDIINSTCOMBO), CB_GETCURSEL , 0, 0);
					midi_Instrument(&(MIDIPORTS[port].midiout),midichn,instrument); 
				break;
			case IDC_MIDICHN:
					midichn=GetDlgItemInt(hDlg, IDC_MIDICHN, NULL, 0);
					midi_Instrument(&(MIDIPORTS[port].midiout),midichn,instrument);
				break;
			case IDC_DELTONE:
				{   int select;
					select=SendDlgItemMessage( hDlg, IDC_HARMONICLIST, LB_GETCURSEL , 0, 0L ) ;
					if ((select>=0)&&(select<LOADSCALE.len))
					{
					  SendDlgItemMessage( hDlg, IDC_HARMONICLIST, LB_DELETESTRING , (WPARAM) select, 0L ) ;
					  LOADSCALE.len--;
					  SetFocus(GetDlgItem(hDlg,IDC_HARMONICLIST));
					  SendDlgItemMessage( hDlg, IDC_HARMONICLIST, LB_SETCURSEL , (WPARAM) select, 0L ) ;
					  apply_harmonic(hDlg);
					}
//					else  report("Nothing selected");
				}
				break;
			case IDC_HARMONICNAME:
				  GetDlgItemText(hDlg, IDC_HARMONICNAME, LOADSCALE.name, 256);
				  
				break;
			case IDC_ADDTONE:
				{  int index,dataint,select;
				   char szdata[5];

					if (LOADSCALE.len<MAX_HARMONICTONES-1)
					{
					  select=SendDlgItemMessage( hDlg, IDC_HARMONICLIST, LB_GETCURSEL , 0, 0L )+1 ;
					  if ((select<1)||(select>LOADSCALE.len)) select=LOADSCALE.len;
					  GetDlgItemText(hDlg, IDC_ACTTONE, szdata, 4);
					  dataint=GetDlgItemInt(hDlg, IDC_ACTTONE, 0,0);
					  index=SendDlgItemMessage( hDlg, IDC_HARMONICLIST, LB_INSERTSTRING , (WPARAM) select, (LPARAM) szdata) ;
					  SendDlgItemMessage(hDlg, IDC_HARMONICLIST, LB_SETITEMDATA, (WPARAM)index, (LPARAM)dataint);
					  LOADSCALE.len++;
					  SetFocus(GetDlgItem(hDlg,IDC_HARMONICLIST));
					  apply_harmonic(hDlg);
					} ;
				}
				break;
			case IDC_HARMONICCLEAR:
					SendDlgItemMessage(hDlg, IDC_HARMONICLIST, LB_RESETCONTENT, 0, 0);
					LOADSCALE.len=0;
					apply_harmonic(hDlg);
					break;
			case IDC_LOADHARMONIC:
				{
				strcpy(szFileName,DEFPATH);
 			    strcat(szFileName,"TONESCALES\\default.sc");
				 if (open_file_dlg(hDlg, szFileName, OPEN_LOAD)) 
				 {
					 /*
				 char tmp[256],*p1,*p2,diff=0;
				  strcpy(tmp,DEFPATH);
				  strcat(tmp,"TONESCALES\\"); 
				  for (p1=tmp,p2=szFileName;(*p1) && (*p2) && (!diff);p1++,p2++) 
					  if (tolower(*p1)!=tolower(*p2)) diff=1;
				  if (diff||(strlen(tmp)>strlen(szFileName)))
					report("Please use Tonescales-subfolder of brainbay application to load/store palette files");
				  else*/
				  {

					if (!load_from_file(szFileName, &LOADSCALE, sizeof(struct SCALEStruct)))
						report("Could not load Harmonic Scale");
					else
					{
					    update_harmonic(GetDlgItem(hDlg, IDC_HARMONICLIST));
						SetDlgItemText(hDlg, IDC_HARMONICNAME, LOADSCALE.name);

					}
				  }
				 } else report("Could not load Harmonic Scale");

				}
				break;
			case IDC_SAVEHARMONIC:
				{
					char temp[100];
					strcpy(szFileName,DEFPATH);
					strcat(szFileName,"TONESCALES\\");
					GetDlgItemText(hDlg, IDC_HARMONICNAME, temp, MAX_PATH);
					strcat (szFileName,temp);
					strcat (szFileName,".sc");

					if (open_file_dlg(hDlg, szFileName, OPEN_SAVE))
					{
/*	 				  char tmp[256],*p1,*p2,diff=0;
					  strcpy(tmp,DEFPATH);
					  strcat(tmp,"TONESCALES\\"); 
					  for (p1=tmp,p2=szFileName;(*p1) && (*p2) && (!diff);p1++,p2++) 
						  if (tolower(*p1)!=tolower(*p2)) diff=1;
					  if (diff||(strlen(tmp)>strlen(szFileName)))
						report("Please use Tonescales-subfolder of brainbay application to load/store palette files");
					  else*/
					  {

						 if (!save_to_file(szFileName, &LOADSCALE, sizeof(struct SCALEStruct)))
							report("Could not save Scale");
					  }
					}
				}
				break;

            case IDC_HARMONICLIST:
                if (HIWORD(wParam)==LBN_SELCHANGE)
                {
					int dataint,sel;
					sel=SendDlgItemMessage( hDlg, IDC_HARMONICLIST, LB_GETCURSEL , 0, 0L ) ;
					dataint=SendDlgItemMessage(hDlg, IDC_HARMONICLIST, LB_GETITEMDATA, (WPARAM)sel, 0);
					midi_NoteOff(&(MIDIPORTS[port].midiout), midichn,oldtone);
					oldtone=dataint;
					midi_NoteOn(&(MIDIPORTS[port].midiout), midichn, dataint,127);
					
                }
				break;

			}
			return TRUE;
		case WM_HSCROLL:
		{
			int nNewPos; 
			if ((nNewPos=get_scrollpos(wParam,lParam))>=0)
			{   
			  if (lParam == (long) GetDlgItem(hDlg,IDC_TONEBAR))  { SetDlgItemInt(hDlg, IDC_ACTTONE,nNewPos,0);
																	midi_NoteOff(&(MIDIPORTS[port].midiout), midichn,oldtone);
																	oldtone=nNewPos;
																	midi_NoteOn(&(MIDIPORTS[port].midiout), midichn,nNewPos,127);
																	apply_harmonic(hDlg);
																	}
			}
		
		}
		break;
		case WM_SIZE:
		case WM_MOVE: ;
		break;
		return TRUE;
	}
    return FALSE;
}
示例#8
0
文件: jamrouter.c 项目: EQ4/jamrouter
/*****************************************************************************
 * main()
 *
 * Parse command line, load patch, start midi_tx, midi_rx, and jack threads.
 *****************************************************************************/
int
main(int argc, char **argv)
{
	char            thread_name[16];
	char            opts[NUM_OPTS * 2 + 1];
	struct option   *op;
	char            *cp;
	char            *p;
	char            *term;
	char            *tokbuf;
	int             c;
	int             j                       = 0;
	int             ret                     = 0;
	int             saved_errno;
	int             argcount                = 0;
	char            **argvals               = argv;
	char            **envp                  = environ;
	char            *argvend                = (char *)argv;
	size_t          argsize;
	unsigned char   rx_channel;

	setlocale(LC_ALL, "C");

	jamrouter_instance = get_instance_num();
	fprintf(stderr, "Starting jamrouter instance %d.\n", jamrouter_instance);

	/* Start debug thread.  debug_class is not set until arguemnts are parsed,
	   so use fprintf() until then. */
	if ((ret = pthread_create(&debug_thread_p, NULL, &jamrouter_debug_thread, NULL)) != 0) {
		fprintf(stderr, "***** ERROR:  Unable to start debug thread.\n");
	}

	/* lock down memory (rt hates page faults) */
	if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0) {
		saved_errno = errno;
		fprintf(stderr, "Unable to unlock memory:  errno=%d (%s)\n",
		        saved_errno, strerror(saved_errno));
	}

	/* init lash client */
#ifndef WITHOUT_LASH
	for (j = 0; j < argc; j++) {
		if ((strcmp(argv[j], "-L") == 0) || (strcmp(argv[j], "--disable-lash") == 0) ||
		    (strcmp(argv[j], "-h") == 0) || (strcmp(argv[j], "--help") == 0) ||
		    (strcmp(argv[j], "-l") == 0) || (strcmp(argv[j], "--list") == 0) ||
		    (strcmp(argv[j], "-v") == 0) || (strcmp(argv[j], "--version") == 0) ||
		    (strcmp(argv[j], "-D") == 0) || (strcmp(argv[j], "--session-dir") == 0) ||
		    (strcmp(argv[j], "-u") == 0) || (strcmp(argv[j], "--uuid") == 0)) {
			lash_disabled = 1;
			break;
		}
	}
	if (!lash_disabled) {
		snprintf(thread_name, 16, "jamrouter%c-lash", ('0' + jamrouter_instance));
		pthread_setname_np(pthread_self(), thread_name);
		if (lash_client_init(&argc, &argv) == 0) {
			lash_poll_event();
		}
		snprintf(thread_name, 16, "jamrouter%c-main", ('0' + jamrouter_instance));
		pthread_setname_np(pthread_self(), thread_name);
	}
#endif

	/* startup initializations */
	init_midi_event_queue();
	init_jack_audio_driver();
	select_midi_driver(NULL, DEFAULT_MIDI_DRIVER);

	/* save original command line for session handling */
	if (jamrouter_cmdline[0] == '\0') {
		jamrouter_cmdline[0] = '\0';
		for (j = 0; j < argc; j++) {
			strcat(&(jamrouter_cmdline[0]), argv[j]);
			strcat(&(jamrouter_cmdline[0]), " ");
		}
		jamrouter_cmdline[strlen(jamrouter_cmdline) - 1] = '\0';
		term = get_color_terminal();
		if (term == NULL) {
			strcpy(jamrouter_full_cmdline, jamrouter_cmdline);
		}
		else {
			snprintf(jamrouter_full_cmdline, 512, "%s -e \"%s \"",
			         term, jamrouter_cmdline);
		}
		argcount = argc;
		argvals  = argv;
	}
	/* command line args supplied by session manager */
	else {
		argcount = 0;
		cp = strdup(jamrouter_cmdline);
		p = cp;
		while ((p = index(p, ' ')) != NULL) {
			p++;
			argcount++;
		}
		if ((argvals = malloc(((size_t)(argcount) + 1UL) *
		                      (size_t)sizeof(char *))) == NULL) {
			fprintf(stderr, "Out of Memory!\n");
			return -1;
		}
		if ((tokbuf = alloca(strlen(jamrouter_cmdline) * 4)) == NULL) {
			fprintf(stderr, "Out of Memory!\n");
			return -1;
		}
		while ((p = strtok_r(cp, " ", &tokbuf)) != NULL) {
			cp = NULL;
			argvals[j++] = p;
		}
		argvals[argcount] = NULL;
	}

	/* build the short option string */
	cp = opts;
	for (op = long_opts; op < &long_opts[NUM_OPTS]; op++) {
		*cp++ = (char) op->val;
		if (op->has_arg) {
			*cp++ = ':';
		}
	}

	/* handle options */
	for (;;) {
		c = getopt_long(argcount, argvals, opts, long_opts, NULL);
		if (c == -1) {
			break;
		}

		switch (c) {
		case 'M':   /* MIDI driver */
			select_midi_driver(optarg, -1);
			break;
		case 'D':   /* MIDI Rx/Tx port/device */
			midi_rx_port_name = strdup(optarg);
			midi_tx_port_name = strdup(optarg);
			break;
		case 'r':   /* MIDI Rx port/device */
			midi_rx_port_name = strdup(optarg);
			break;
		case 't':   /* MIDI Tx port/device */
			midi_tx_port_name = strdup(optarg);
			break;
		case 'x':   /* MIDI Rx latency periods */
			rx_latency_periods = atoi(optarg);
			break;
		case 'X':   /* MIDI Tx latency periods */
			tx_latency_periods = atoi(optarg);
			break;
		case 'g':   /* Tx byte guard time in usec */
			byte_guard_time_usec = atoi(optarg);
			break;
		case 'G':   /* Tx event guard time in usec */
			event_guard_time_usec = atoi(optarg);
			break;
		case 'i':   /* JACK MIDI input port */
			jack_input_port_name = strdup(optarg);
			break;
		case 'o':   /* JACK MIDI output port */
			jack_output_port_name = strdup(optarg);
			break;
		case 'j':   /* Jitter correction mode */
			jitter_correct_mode = 1;
			break;
		case 'z':   /* JACK wake phase within MIDI Rx/Tx period */
			setting_midi_phase_lock = (timecalc_t)(atof(optarg));
			if (setting_midi_phase_lock < (timecalc_t)(0.0625)) {
				setting_midi_phase_lock = (timecalc_t)(0.0625);
			}
			else if (setting_midi_phase_lock > (timecalc_t)(0.9375)) {
				setting_midi_phase_lock = (timecalc_t)(0.9375);
			}
			break;
#ifndef WITHOUT_JACK_DLL
		case '4':   /* JACK DLL timing level 4 */
			jack_dll_level = 4;
			break;
		case '3':   /* JACK DLL timing level 3 */
			jack_dll_level = 3;
			break;
		case '2':   /* JACK DLL timing level 2 */
			jack_dll_level = 2;
			break;
		case '1':   /* JACK DLL timing level 1 */
			jack_dll_level = 1;
			break;
#endif
		case 'k':   /* key to controller mapping */
			if (optarg != NULL) {
				if ((tokbuf = alloca(strlen((const char *)optarg) * 4)) == NULL) {
					jamrouter_shutdown("Out of memory!\n");
				}
				if ((p = strtok_r(optarg, ",", &tokbuf)) != NULL) {
					rx_channel = (atoi(p) - 1) & 0x0F;
					if ((p = strtok_r(NULL, ",", &tokbuf)) != NULL) {
						keymap_tx_channel[rx_channel] = (atoi(p) - 1) & 0x0F;
						if ((p = strtok_r(NULL, ",", &tokbuf)) != NULL) {
							keymap_tx_controller[rx_channel] = atoi(p) & 0x7F;
						}
					}
					JAMROUTER_DEBUG(DEBUG_CLASS_INIT, "Key --> Controller Map:  "
					                "rx_channel=%0d  tx_channel=%d  tx_cc=%d\n",
					                rx_channel + 1,
					                keymap_tx_channel[rx_channel] + 1,
					                keymap_tx_controller[rx_channel]);
				}
			}
			break;
		case 'p':   /* key to pitchbend translation */
			if (optarg != NULL) {
				if ((tokbuf = alloca(strlen((const char *)optarg) * 4)) == NULL) {
					jamrouter_shutdown("Out of memory!\n");
				}
				if ((p = strtok_r(optarg, ",", &tokbuf)) != NULL) {
					rx_channel = (atoi(p) - 1) & 0x0F;
					if ((p = strtok_r(NULL, ",", &tokbuf)) != NULL) {
						pitchmap_tx_channel[rx_channel] = (atoi(p) - 1) & 0x0F;
						if ((p = strtok_r(NULL, ",", &tokbuf)) != NULL) {
							pitchmap_center_note[rx_channel] = atoi(p) & 0x7F;
							if ((p = strtok_r(NULL, ",", &tokbuf)) != NULL) {
								pitchmap_bend_range[rx_channel] = atoi(p) & 0x7F;
							}
						}
					}
					JAMROUTER_DEBUG(DEBUG_CLASS_INIT,
					                "Key --> Pitchbend Map:  "
					                "rx_chan=%0d  tx_chan=%d  center=%d  range=%d\n",
					                rx_channel + 1, pitchmap_tx_channel[rx_channel] + 1,
					                pitchmap_center_note[rx_channel],
					                pitchmap_bend_range[rx_channel]);
				}
			}
			break;
		case 'q':   /* pitchbend to controller translation */
			if (optarg != NULL) {
				if ((tokbuf = alloca(strlen((const char *)optarg) * 4)) == NULL) {
					jamrouter_shutdown("Out of memory!\n");
				}
				if ((p = strtok_r(optarg, ",", &tokbuf)) != NULL) {
					rx_channel = (atoi(p) - 1) & 0x0F;
					if ((p = strtok_r(NULL, ",", &tokbuf)) != NULL) {
						pitchcontrol_tx_channel[rx_channel] = (atoi(p) - 1) & 0x0F;
						if ((p = strtok_r(NULL, ",", &tokbuf)) != NULL) {
							pitchcontrol_controller[rx_channel] = atoi(p) & 0x7F;
						}
					}
					JAMROUTER_DEBUG(DEBUG_CLASS_INIT,
					                "Pitchbend --> Controller Map:  "
					                "rx_chan=%0d  tx_chan=%d  controller=%d\n",
					                rx_channel + 1, pitchcontrol_tx_channel[rx_channel] + 1,
					                pitchcontrol_controller[rx_channel]);
				}
			}
			break;
#ifndef WITHOUT_JUNO
		case 'J':   /* Juno-106 sysex controller translation */
			translate_juno_sysex = 1;
			break;
		case 's':   /* echo sysex translations back to originator */
			echosysex = 1;
			break;
#endif
		case 'e':   /* echo pitchbend and controller translations back to originator */
			echotrans = 1;
			break;
		case 'T':   /* alternate sysex terminator byte */
			sysex_terminator = hex_to_byte(optarg);
			break;
		case 'U':   /* alternate sysex terminator byte */
			sysex_extra_terminator = hex_to_byte(optarg);
			break;
		case 'A':   /* Active-Sensing mode */
			if (strcmp(optarg, "on") == 0) {
				active_sensing_mode = ACTIVE_SENSING_MODE_ON;
			}
			else if (strcmp(optarg, "thru") == 0) {
				active_sensing_mode = ACTIVE_SENSING_MODE_THRU;
			}
			else if (strcmp(optarg, "drop") == 0) {
				active_sensing_mode = ACTIVE_SENSING_MODE_DROP;
			}
			break;
		case 'R':   /* Omit running status byte on MIDI Tx */
			use_running_status = 1;
			break;
		case 'n':   /* Note-On Velocity */
			note_on_velocity = hex_to_byte(optarg);
			break;
		case 'N':   /* Note-Off Velocity */
			note_off_velocity = hex_to_byte(optarg);
			break;
		case 'f':   /* Send multiple Note-Off messages as All-Notes-Off */
			tx_prefer_all_notes_off = 1;
			break;
		case 'F':   /* Tx send real Note-Off instead of Velocity-0-Note-On */
			tx_prefer_real_note_off = 1;
			break;
		case '0':   /* Rx queue real Note-Off instead of Velocity-0-Note-On */
			rx_queue_real_note_off = 1;
			break;
		case 'y':   /* MIDI Rx thread priority */
			if ((midi_rx_thread_priority = atoi(optarg)) <= 0) {
				midi_rx_thread_priority = MIDI_RX_THREAD_PRIORITY;
			}
			break;
		case 'Y':   /* MIDI Tx thread priority */
			if ((midi_tx_thread_priority = atoi(optarg)) <= 0) {
				midi_tx_thread_priority = MIDI_TX_THREAD_PRIORITY;
			}
			break;
		case 'd':   /* debug */
			debug = 1;
			for (j = 0; debug_class_list[j].name != NULL; j++) {
				if (strcmp(debug_class_list[j].name, optarg) == 0) {
					debug_class |= debug_class_list[j].id;
				}
			}
			break;
		case 'v':   /* version */
			printf("jamrouter-%s\n", PACKAGE_VERSION);
			return 0;
		case 'L':   /* disable lash */
			lash_disabled = 1;
			break;
		case 'l':   /* list midi devices */
			scan_midi();
			return 0;
		case 'u':   /* jack session uuid */
			jack_session_uuid = strdup(optarg);
			break;
		case '?':
		case 'h':   /* help */
		default:
			showusage(argv[0]);
			return -1;
		}
	}

	/* Rewrite process title */
	argcount = argc;
	argvals  = argv;
	for (j = 0; j <= argcount; j++) {
		if ((j == 0) || ((argvend + 1) == argvals[j])) {
			argvend = argvals[j] + strlen(argvals[j]);
		}
		else {
			continue;
		}
	}

	/* steal space from first environment entry */
	if (envp[0] != NULL) {
		argvend = envp[0] + strlen (envp[0]);
	}

	/* calculate size we have for process title */
	argsize = (size_t)((char *)argvend - (char *)*argvals - 1);
	memset (*argvals, 0, argsize);

	/* rewrite process title */
	argc = 0;
	snprintf((char *)*argvals, argsize, "jamrouter%d", jamrouter_instance);

	/* signal handlers for clean shutdown */
	init_signal_handlers();

	/* init MIDI system based on selected driver */
	JAMROUTER_DEBUG(DEBUG_CLASS_INIT, "Initializing MIDI:  driver=%s.\n",
	                midi_driver_names[midi_driver]);
	init_sync_info(0, 0);
	init_midi();

	/* initialize JACK audio system based on selected driver */
	snprintf(thread_name, 16, "jamrouter%c-clnt", ('0' + jamrouter_instance));
	pthread_setname_np(pthread_self(), thread_name);
	init_jack_audio();
	while (sample_rate == 0) {
		JAMROUTER_DEBUG(DEBUG_CLASS_INIT,
		                "JACK did not set sample rate.  Re-initializing...\n");
		init_jack_audio();
		usleep(125000);
	}

	/* start the JACK audio system */
	start_jack_audio();

	/* wait for JACK audio to start before starting midi. */
	wait_jack_audio_start();

	snprintf(thread_name, 16, "jamrouter%c-main", ('0' + jamrouter_instance));
	pthread_setname_np(pthread_self(), thread_name);

	/* start MIDI Rx/Tx threads. */
	start_midi_rx();
	wait_midi_rx_start();
	start_midi_tx();
	wait_midi_tx_start();

	/* debug thread not needed once watchdog is running */
	debug_done = 1;
	pthread_join(debug_thread_p, NULL);

	/* Jamrouter watchdog handles restarting threads on config changes,
	   runs driver supplied watchdog loop iterations, and handles debug
	   output. */
	jamrouter_watchdog();
	stop_midi_tx();
	stop_midi_rx();
	stop_jack_audio();
	output_pending_debug();

	/* Wait for threads created directly by JAMROUTER to terminate. */
	if (midi_rx_thread_p != 0) {
		pthread_join(midi_rx_thread_p,  NULL);
	}
	if (midi_tx_thread_p != 0) {
		pthread_join(midi_tx_thread_p,  NULL);
	}
	output_pending_debug();

	return 0;
}