Beispiel #1
0
int wsh_cmd_rd(int argc, char **argv)
{
	unsigned long addr;
	unsigned long nr_words;

	if (!argc) {
		wsh_printf("not enough arguments\n");
		wsh_printf("usage: rd ADDR [LENGTH]\n");
		return -1;
	}

	addr = extract_val(argv[0]);
	nr_words = 1;

	addr &= ~0x3;

	if (argc > 1)
		nr_words = extract_val(argv[1]);

	wsh_cache_data_flush((unsigned long *) addr, nr_words * 4);

	for (int i = 0; i < nr_words; i += 4) {
		wsh_printf("[0x%08lx] ", addr);
		for (int j = i; j < i + 4 && j < nr_words; j++) {
			wsh_printf("0x%08lx ", *(unsigned long *) addr);
			addr += 4;
		}
		wsh_printf("\n");
	}

	return 0;
}
Beispiel #2
0
int wsh_cmd_wr(int argc, char **argv)
{
	unsigned long addr;
	unsigned long val;
	unsigned long nr_words;
	unsigned long addr_bak;

	if (argc < 2) {
		wsh_printf("not enough arguments\n");
		wsh_printf("usage: wr ADDR VALUE [LENGTH]\n");
		return -1;
	}

	addr = extract_val(argv[0]);
	val = extract_val(argv[1]);
	nr_words = 1;

	addr &= ~0x3;
	addr_bak = addr;

	if (argc == 3)
		nr_words = extract_val(argv[2]);

	for (int i = 0; i < nr_words; i++) {
		*(unsigned long *) addr = val;
		addr += 4;
	}

	wsh_cache_data_flush((unsigned long *) addr_bak, nr_words * 4);

	return 0;
}
Beispiel #3
0
/*
 * Return the symbolic names of the flags pointed to by BUF which is LEN
 * octets long, using the constant maps MAPS.
 */
static char *
field_debug_mask(u_int8_t *buf, size_t len, struct constant_map **maps)
{
	u_int32_t       val;
	u_int32_t       bit;
	char           *retval, *new_buf, *name;
	size_t          buf_sz;

	if (extract_val(buf, len, &val))
		return 0;

	/* Size for brackets, two spaces and a NUL terminator.  */
	buf_sz = 4;
	retval = malloc(buf_sz);
	if (!retval)
		return 0;

	strlcpy(retval, "[ ", buf_sz);
	for (bit = 1; bit; bit <<= 1) {
		if (val & bit) {
			name = constant_name_maps(maps, bit);
			buf_sz += strlen(name) + 1;
			new_buf = realloc(retval, buf_sz);
			if (!new_buf) {
				free(retval);
				return 0;
			}
			retval = new_buf;
			strlcat(retval, name, buf_sz);
			strlcat(retval, " ", buf_sz);
		}
	}
	strlcat(retval, "]", buf_sz);
	return retval;
}
Beispiel #4
0
/* Return the numeric value of the field F of BUF.  */
u_int32_t
field_get_num(struct field *f, u_int8_t *buf)
{
	u_int32_t       val;

	if (extract_val(buf + f->offset, f->len, &val))
		return 0;
	return val;
}
Beispiel #5
0
/*
 * Return the symbolic name of a constant pointed to by BUF which is LEN
 * octets long, using the constant maps MAPS.
 */
static char *
field_debug_cst(u_int8_t *buf, size_t len, struct constant_map **maps)
{
	u_int32_t       val;

	if (extract_val(buf, len, &val))
		return 0;

	return strdup(constant_name_maps(maps, val));
}
Beispiel #6
0
/*
 * Return a textual representation of the unsigned number pointed to by BUF
 * which is LEN octets long.  MAPS should be zero and is only here because
 * the API requires it.
 */
static char *
field_debug_num(u_int8_t *buf, size_t len, struct constant_map **maps)
{
	char           *retval = NULL;
	u_int32_t       val;

	if (extract_val(buf, len, &val))
		return 0;
	/* 3 decimal digits are enough to represent each byte.  */
	(void)asprintf(&retval, "%u", val);
	return retval;
}
Beispiel #7
0
static int my_cmd_demo(int argc, char **argv)
{
	char *usage[] = { "set   load demo (1 | 2 | 3)",
		"get   print current demo configuration",
		0
	};

	if (check_cmd(argc, "demo", usage))	// check for existing arguments
		return -1;

	if (strcmp("get", argv[0]) == 0) {
		if (check_argc(argc, 1, 1, ""))	// check # of arguments
			return -1;

		// get demo configuration
		printf("demo configuration %d\n", get_demo());

	} else if (strcmp("set", argv[0]) == 0) {
		if (check_argc(argc, 2, 2, "demo set ID"))	// check # of args: 2 required
			return -1;

		// set demo configuration
		unsigned long val = extract_val(argv[1]);	// extract numeric value

		if ((val < 1) || (val > 3)) {
			print_unknown_arg(argv[1]);
			return -1;
		}

		set_demo(val);
		printf("selecting demo %d\n", get_demo());

	} else {
		print_unknown_cmd(argv[0]);
		return -1;
	}
	return 0;
}
Beispiel #8
0
int main(int argc,char *argv[])
{
	extern char *optarg;
	extern int optind;
	int ch;

	struct option long_options[] = {
		{"help", no_argument, 0, 'h'},
		{"version", no_argument, 0, 'V'},
		{"debug", no_argument, 0, 'd'},
		{"quiet", no_argument, 0, 'q'},
		{"log", required_argument, 0, 'l'},
		{"command", required_argument, 0, 'c'},
#ifdef HAVE_LIBMICROHTTPD
		{"port", required_argument, 0, 'p'},
#endif
		{0, 0, 0, 0}
	};

	int contest_offset;

	char *tmp;
	char buf[BUF_SIZE];
	int ttylog,lu,i,q;
	struct winsize ws;

#ifdef HAVE_LIBMICROHTTPD
	unsigned int port = 0;
#endif

	regmatch_t pmatch[2];

	char defcmd[] = "dnetc", logfile[128] = "stdout";
	int pos_cpu[MAX_CPU];
	char p[] = "a";
	int log_fd;

	/* check arguments */
#ifdef HAVE_LIBMICROHTTPD
	while ((ch = getopt_long(argc, argv, "hdVql:c:p:", long_options, NULL)) != -1)
#else
	while ((ch = getopt_long(argc, argv, "hdVql:c:", long_options, NULL)) != -1)
#endif
	{
		switch(ch)
		{
			case 'd':
				dflag = 1;
				break;
			case 'V':
				printf("%s\n",GKRELLDNET_VERSION);
				exit(0);
				break;
#ifdef HAVE_LIBMICROHTTPD
			case 'p':
				port = atoi(optarg);
				break;
#endif
			case 'q':
				qflag = 1;
				break;
			case 'c':
				nargc = get_arg(&nargv,optarg);
				break;
			case 'l':
				strcpy(logfile,optarg);
				break;
			case 'h':
			default:
				usage(argv[0]);
		}
	}
	if(argc - optind != 0)
		usage(argv[0]);

	/* continue in background if in quiet mode */
	if(qflag == 1 && ((new_pid = fork()) != 0))
	{
		if(new_pid < 0)
			clean_and_exit("forking daemon",1);
		else
			exit(0);
	}

	/* default command line */
	if(nargv == NULL)
		nargc = get_arg(&nargv,defcmd);

	/* change output to logfile */
	if(strcmp(logfile,"stdout") != 0)
	{
		if((log_fd = open(logfile, O_CREAT|O_WRONLY|O_APPEND, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1)
			clean_and_exit("opening logfile",1);
		if(dup2(log_fd,1) == -1)
			clean_and_exit("dup2",1);
	}
	ttylog = isatty(1);

	/* creat shared memory segment */
	if((shmid = my_shmcreate(sizeof(struct dnetc_values),IPC_CREAT|IPC_EXCL|0644)) == -1)
		clean_and_exit("shmget",1);
	if((int) (shmem = shmat(shmid,0,0)) == -1)
		clean_and_exit("shmat",1);

	/* init shared memory content */
	shmem->running = TRUE;
	strcpy(shmem->contest,"???");
	shmem->cmode = CRUNCH_RELATIVE;
	shmem->wu_in = shmem->wu_out = 0;
	shmem->n_cpu = 1;
	for(i=0;i<MAX_CPU;i++)
		shmem->val_cpu[i] = 0;
	
	/* precompile regex */
	if(regcomp(&preg_in,"[0-9]+.packets?.+remains?.in",REG_EXTENDED) != 0)
		clean_and_exit(NULL,1);
	if(regcomp(&preg_out,"[0-9]+.packets?(.+in.buff-out|.\\(.+stats?.units?\\).(are|is).in)",REG_EXTENDED) != 0)
		clean_and_exit(NULL,1);
	if(regcomp(&preg_contest,"[A-Z0-9-]{3,6}(.#[a-z])?:.Loaded",REG_EXTENDED) != 0)
		clean_and_exit(NULL,1);
	if(regcomp(&preg_proxy,"((Retrieved|Sent).+(stat..unit|packet)|Attempting.to.resolve|Connect(ing|ed).to)",REG_EXTENDED) !=0)
		clean_and_exit(NULL,1);

	contest_offset = 0;

	if(regcomp(&preg_absolute,"(#[0-9]+: [A-Z0-9-]{3,6}|[A-Z0-9-]{3,6}(.#[a-z])?):.+\\[[,0-9]+\\]",REG_EXTENDED) != 0)
		clean_and_exit(NULL,1);
	if(regcomp(&preg_cruncher,"[0-9]+.cruncher.*started",REG_EXTENDED) != 0)
		clean_and_exit(NULL,1);
	regex_flag = 1;

	/* obtain a pseudo-terminal */
	ws.ws_col = 132; ws.ws_row = 10;
	ws.ws_xpixel = ws.ws_ypixel = 0;
	if((openpty(&fd,&tty_fd,NULL,NULL,&ws)) == -1)
		clean_and_exit("openpty",1);

	/* start dnet client and start reading tty */
	if((fils = fork()) == -1)
		clean_and_exit("fork",1);

	if(fils == 0)
	{
		/* change to dnetc directory */
		change_dir();
		/* start dnet client */
		if(dup2(tty_fd,1) == -1)
			clean_and_exit("dup2",1);
		if(execvp(nargv[0],nargv) == -1)
			clean_and_exit("execvp",1);
	}

#ifdef HAVE_LIBMICROHTTPD
	/* start http server */
	if(port > 0)
	{
		struct sockaddr_in so;
			
		so.sin_family = AF_INET;
		so.sin_port = htons(port);
		so.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
	
	    http_daemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY, port, NULL, NULL, &answer_to_connection, shmem,
					MHD_OPTION_SOCK_ADDR, &so, MHD_OPTION_END);
	    if(http_daemon == NULL)
	        clean_and_exit("MHD_start_daemon",1);
	}
#endif

	/* set signal handler */
	if(signal(SIGHUP,got_signal) == SIG_ERR
	   || signal(SIGINT,got_signal) == SIG_ERR
	   || signal(SIGQUIT,got_signal) == SIG_ERR
	   || signal(SIGCHLD,got_signal) == SIG_ERR
	   || signal(SIGTERM,got_signal) == SIG_ERR)
		clean_and_exit("signal",1);

	/* some more init */
	for(i=0;i<MAX_CPU;i++)
		shmem->val_cpu[i] = 0;

	/* main loop */
	while((lu = mygets(fd,buf,BUF_SIZE)) > 0)
	{
		if(dflag)
			fprintf(stderr,"buf[0] = %x\n<--\n%s\n-->\n",buf[0],buf);

		if(buf[1] == '.' || buf[lu-1] != '\n')
		{
			if(dflag)
				fprintf(stderr,"lu: %02d, ",lu);

			/* fix line with two 0x0d char */
			if((tmp = strchr(&buf[1],0x0d)) != NULL)
				lu = tmp-buf;

			/* skip line with proxy comm. */
			q = regexec(&preg_proxy,buf,1,pmatch,0);
			if(q != 0)
			{
				/* check if line match absolute crunch-o-meter */
				if(regexec(&preg_absolute,buf,1,pmatch,0) == 0)
				{
					/* set crunch-o-meter mode */
					shmem->cmode = CRUNCH_ABSOLUTE;
					/* read CPU num */
					tmp = strchr(&buf[pmatch[0].rm_so],'#');
					if(tmp != NULL)
					{
						if(isdigit(tmp[1]))
							i = strtol(&buf[pmatch[0].rm_so+1],(char **) NULL,10) - 1;
						else if(islower(tmp[1]))
							i = tmp[1] - 'a';
						/* avoid core dump */
						i %= MAX_CPU;
					}
					else
						i = 0;
					/* read k(keys|nodes) */
					shmem->val_cpu[i] = extract_val(&buf[pmatch[0].rm_so]);
					
					if(dflag)
					{
						fprintf(stderr,"\ncpu = %d, %llu nodes|keys\n",i,shmem->val_cpu[i]);
						fprintf(stderr,"found: %s\n",&buf[pmatch[0].rm_so]);
					}
				}
				else
				{
					/* set crunch-o-meter mode */
					shmem->cmode = CRUNCH_RELATIVE;

					for(i=0;i<shmem->n_cpu;i++)
					{
						if(shmem->n_cpu != 1)
						{
							p[0] = 'a' + i;
							if((tmp = strstr(buf,p)) != NULL)
								pos_cpu[i] = tmp - buf;
						}
						else
							pos_cpu[i] = lu - 1;
						
						shmem->val_cpu[i] = (pos_cpu[i] - (pos_cpu[i]/8)*3) * 2;
						if(shmem->val_cpu[i] > 100)
							shmem->val_cpu[i] = 100;
						
						if(dflag)
							fprintf(stderr,"cpu%d: %llu,",i,shmem->val_cpu[i]);
					}
					if(dflag)
						fprintf(stderr,"\n");
				}
			}

			if(!qflag && (ttylog || q == 0))
			{
				printf("%s",buf); fflush(stdout);
			}
		}
		else
		{
			if(regexec(&preg_in,buf,1,pmatch,0) == 0)
				shmem->wu_in = strtol(&buf[pmatch[0].rm_so],NULL,10);
			if(regexec(&preg_out,buf,1,pmatch,0) == 0)
				shmem->wu_out = strtol(&buf[pmatch[0].rm_so],NULL,10);
			if(regexec(&preg_contest,buf,1,pmatch,0) == 0)
				strncpy(shmem->contest,&buf[pmatch[0].rm_so+contest_offset],3);
			if(regexec(&preg_cruncher,buf,1,pmatch,0) == 0)
			{
				shmem->n_cpu = strtol(&buf[pmatch[0].rm_so],NULL,10);
				/* too many crunchers */
				if(shmem->n_cpu > MAX_CPU)
				{
					fprintf(stderr,"dnetw: too many crunchers\n");
					clean_and_exit(NULL,1);
				}
			}

			if(dflag)
				fprintf(stderr,"contest = %s, in = %d, out = %d, n_cpu = %d\n",shmem->contest, shmem->wu_in, shmem->wu_out, shmem->n_cpu);

			if(!qflag)
			{
				printf("%s",buf); fflush(stdout);
			}
		}

	}

	clean_and_exit(NULL,0);

	return 0;
}
Beispiel #9
0
program_t parse(string fn)
{
	int n_osc=0;
	oscillator_t *osc=NULL;
	env_settings_t *env=NULL;
	filter_params_t filter;
	fixed_t sync_factor=0;
	bool sync_factor_const=true;
	
	char buf[2000];
	string line;
	string var;
	string array;
	string strval;
	float val;
	
	parameter_enum p;
	
	int ind,ind2=0;
	
	int state;

	program_t result;

	
	ifstream f;
	f.open(fn.c_str());
	if (f.good())
	{
		state=0;
		while (!f.eof())
		{
			f.getline(buf,sizeof(buf)/sizeof(*buf)-1);
			line=buf;
			line=remove_all_spaces(buf);
			if ((line!="") && (line[0]!='#')) //ignore comments and empty lines
			{
				if (line=="controllers:")
				{
					state=2;
					continue;
				}
				else if (line=="defaults:")
				{
					state=3;
					continue;
				}
				else if (line=="velocity:")
				{
					state=4;
					continue;
				}
				else if (line=="variable:")
				{
					state=5;
					continue;
				}

				var=extract_var(line);
				array=extract_array_name(var);
				strval=extract_val(line);
				val=atof(strval.c_str());
				
				switch (state)
				{
					case 0: //expect and read number of oscillators
						if (var!="oscillators")
							throw string("need to know number of oscillators");
						else
							n_osc=val;
						
						if (n_osc<=0) throw string("invalid number of oscillators");
						
						//init stuff
						env=new env_settings_t[n_osc];
						osc=new oscillator_t[n_osc];
						init_oscs(n_osc, osc);
						init_envs(n_osc, env);
						init_filter(filter);
						
						state=1;
						break;
					
					case 1: //read and set information about oscillator settings
						p=param_to_enum(array);
						
						ind=extract_array_index(var,1);
						if ( param_needs_index(p) &&  (!((ind>=0) && (ind<n_osc))) )
							throw string("out of array bounds");
						
						
						switch (p)
						{
							case MODULATION:						
								ind2=extract_array_index(var,2);
								if (!((ind2>=0) && (ind2<n_osc)))
									throw string("out of array bounds");
							
								osc[ind].fm_strength[ind2]=val*ONE;
								break;
							case OUTPUT:
								osc[ind].output=val*ONE;
								break;
							case WAVEFORM:
								if (isfloat(strval))
								{
									osc[ind].waveform=int(val);
								}
								else
								{
									osc[ind].have_custom_wave=true;
								}
								break;
							case FACTOR:
								osc[ind].factor=val*ONE;
								break;
							case TREMOLO:
								osc[ind].tremolo_depth=int(val);
								break;
							case TREM_LFO:
								if (strval=="snh")
									osc[ind].tremolo_lfo=SNH_LFO;
								else
								{
									osc[ind].tremolo_lfo= int(val);
									if ((val<0) || (val>=N_LFOS))
										throw string("invalid value for tremolo_lfo");
								}
								break;
							case VIBRATO:
								osc[ind].vibrato_depth=val;
								break;
							case VIB_LFO:
								if (strval=="snh")
									osc[ind].vibrato_lfo= SNH_LFO;
								else
								{
									osc[ind].vibrato_lfo= int(val);
									if ((val<0) || (val>=N_LFOS))
										throw string("invalid value for vibrato_lfo");
								}
								break;
							case ATTACK:
								env[ind].attack=val;
								break;
							case DECAY:
								env[ind].decay=val;
								break;
							case SUSTAIN:
								env[ind].sustain=val;
								break;
							case RELEASE:
								env[ind].release=val;
								break;
							case HOLD:
								env[ind].hold=(val!=0);
								break;
							case KSR:
								osc[ind].ksr=val;
								break;
							case KSL:
								osc[ind].ksl=val;
								break;
							case SYNC:
								osc[ind].sync=(val!=0);
								break;
							case FILTER_ENABLED:
								filter.enabled=(val!=0);
								break;
							case FILTER_ENV_AMOUNT:
								filter.env_amount=val;
								break;
							case FILTER_ATTACK:
								filter.env_settings.attack=val;
								break;
							case FILTER_DECAY:
								filter.env_settings.decay=val;
								break;
							case FILTER_SUSTAIN:
								filter.env_settings.sustain=val;
								break;
							case FILTER_RELEASE:
								filter.env_settings.release=val;
								break;
							case FILTER_HOLD:
								filter.env_settings.hold=(val!=0);
								break;
							case FILTER_OFFSET:
								filter.freqfactor_offset=val;
								break;
							case FILTER_RESONANCE:
								filter.resonance=val;
								break;
							case FILTER_TREMOLO:
								filter.trem_strength=int(val);
								break;
							case FILTER_TREM_LFO:
								if (strval=="snh")
									filter.trem_lfo=SNH_LFO;
								else
								{
									filter.trem_lfo=int(val);
									if ((val<0) || (val>=N_LFOS))
										throw string("invalid value for filter_trem_lfo");
								}
								break;
							case SYNC_FACTOR:
								sync_factor=val*ONE;
								break;
							default:
								throw string("unknown variable ('"+array+"')");
						}
						break;
					
					case 5: //read which params shall be variable, even if
					        //there are currently no controllers which change them
					case 4: //read velocity-influence over certain params
					case 2: //read how controllers influence parameters
						p=param_to_enum(array);
						
						ind=extract_array_index(var,1);
						if ( param_needs_index(p) &&  (!((ind>=0) && (ind<n_osc))) )
							throw string("out of array bounds");
						
						if (state==4) //velocity-influence
						{
							switch (p)
							{
								case MODULATION:
								case OUTPUT:
								case FILTER_ENV_AMOUNT:
								case FILTER_RESONANCE:
								case FILTER_OFFSET:
									// everything ok, do nothing
									break;
								
								default: // other params than the above may not be influenced!
									throw string("velocity cannot influence parameter '"+array+"'");
							}
						}
						

						switch (p)
						{
							case MODULATION:						
								ind2=extract_array_index(var,2);
								if (!((ind2>=0) && (ind2<n_osc)))
									throw string("out of array bounds");
							
								osc[ind].fm_strength_const[ind2]=false;
								break;
							case OUTPUT:
								if (state!=4) // not vel.-influence
									osc[ind].output_const=false;
								break;
							case WAVEFORM:
								osc[ind].waveform_const=false; break;
							case FACTOR:
								osc[ind].factor_const=false; break;
							case TREMOLO:
								osc[ind].tremolo_depth_const=false; break;
							case TREM_LFO:
								osc[ind].tremolo_lfo_const=false; break;
							case VIBRATO:
								osc[ind].vibrato_depth_const=false; break;
							case VIB_LFO:
								osc[ind].vibrato_lfo_const=false; break;
							case ATTACK:
								env[ind].attack_const=false; break;
							case DECAY:
								env[ind].decay_const=false; break;
							case SUSTAIN:
								env[ind].sustain_const=false; break;
							case RELEASE:
								env[ind].release_const=false; break;
							case HOLD:
								env[ind].hold_const=false; break;
							case KSR:
								osc[ind].ksr_const=false; break;
							case KSL:
								osc[ind].ksl_const=false; break;
							case SYNC:
								osc[ind].sync_const=false; break;
							case FILTER_ENABLED:
								filter.enabled_const=false; break;
							case FILTER_ENV_AMOUNT:
								filter.env_amount_const=false; break;
							case FILTER_ATTACK:
								filter.env_settings.attack_const=false; break;
							case FILTER_DECAY:
								filter.env_settings.decay_const=false; break;
							case FILTER_SUSTAIN:
								filter.env_settings.sustain_const=false; break;
							case FILTER_RELEASE:
								filter.env_settings.release_const=false; break;
							case FILTER_HOLD:
								filter.env_settings.hold_const=false; break;
							case FILTER_OFFSET:
								filter.freqfactor_offset_const=false; break;
							case FILTER_RESONANCE:
								filter.resonance_const=false; break;
							case FILTER_TREMOLO:
								filter.trem_strength_const=false; break;
							case FILTER_TREM_LFO:
								filter.trem_lfo_const=false; break;
							case SYNC_FACTOR:
								sync_factor_const=false; break;
							default:
								throw string("unknown variable ('"+array+"')");
						}


						
						break;
					
					case 3: //read controller default values
						//ignored						
						break;
				}
			}
		}
		
		
		//some optimizations and checks
		
		for (int i=0;i<n_osc;i++)
			if ((env[i].attack==0) && (env[i].sustain==1.0)
			      && (env[i].release>100))  //TODO FINDMICH besseres kriterium?
				env[i].enabled=false;
		
		if (  ((filter.env_settings.attack==0) && (filter.env_settings.sustain==1.0)
		        && (filter.env_settings.release>100)) //TODO FINDMICH siehe oben
		   || ((filter.env_amount==0) && (filter.env_amount_const==true))  )
		  filter.env_settings.enabled=false;
		
		bool use_sync=false;
		for (int i=0;i<n_osc;i++)
			if ((osc[i].sync==true) || (osc[i].sync_const==false))
			{
				use_sync=true;
				break;
			}
		
		if (!use_sync)
		{
			sync_factor=0;
			sync_factor_const=true;
		}
		
		if ((sync_factor==0) && (sync_factor_const==true))
			for (int i=0;i<n_osc;i++)
			{
				osc[i].sync=false;
				osc[i].sync_const=true;
			}
		
		
		
		for (int i=0;i<n_osc;i++)
			if ( !((osc[i].output==0) && (osc[i].output_const=true)) )
				osc[i].output_const=false;
		
		//end optimizations and checks
		
		result.n_osc=n_osc;
		result.osc=osc;
		result.env=env;
		result.filter=filter;
		result.sync_factor=sync_factor;
		result.sync_factor_const=sync_factor_const;
	}
	else
		throw string ("could not open '"+fn+"'");

	return result;
	//no uninit / free of osc and env here, as it must be done by the caller
}