Exemplo n.º 1
0
Arquivo: bank.c Projeto: EQ4/phasex
/*****************************************************************************
 * get_patch_name_from_filename()
 *****************************************************************************/
char *
get_patch_name_from_filename(char *filename)
{
	char    *f;
	char    *tmpname;
	char    *name = NULL;

	/* missing filename gets name of "Untitled" */
	if ((filename == NULL) || (strcmp(filename, user_patchdump_file[0]) == 0)) {
		name = strdup("Untitled");
	}
	else {
		/* strip off leading directory components */
		if ((f = rindex(filename, '/')) == NULL) {
			tmpname = filename;
		}
		else {
			tmpname = f + 1;
		}

		/* make a copy that can be modified and freed safely */
		if ((name = strdup(tmpname)) == NULL) {
			phasex_shutdown("Out of memory!\n");
		}

		/* strip off the .phx */
		if ((f = strstr(name, ".phx\0")) != NULL) {
			*f = '\0';
		}
	}

	/* send name back to caller */
	return name;
}
Exemplo n.º 2
0
/*****************************************************************************
 *
 * JACK_SAMPLERATE_HANDLER()
 *
 * Gets called when jack sets or changes sample rate.
 *
 *****************************************************************************/
int 
jack_samplerate_handler(jack_nframes_t nframes, void *arg) {

    if (debug) {
	fprintf (stderr, "JACK requested sample rate:  %d\n", nframes);
    }

    /* if jack requests a zero value, just use what we already have */
    if (nframes == 0) {
	return 0;
    }

    /* scale sample rate depending on mode */
    switch (sample_rate_mode) {
    case SAMPLE_RATE_UNDERSAMPLE:
	nframes /= 2;
	break;
    case SAMPLE_RATE_NORMAL:
	break;
    case SAMPLE_RATE_OVERSAMPLE:
	nframes *= 2;
	break;
    }

    pthread_mutex_lock (&sample_rate_mutex);
    if (nframes == sample_rate) {
	pthread_mutex_unlock (&sample_rate_mutex);
	return 0;
    }

    /* Changing sample rate currently not supported */
    if ((sample_rate > 0) && (sample_rate != nframes)) {
	/* TODO: rebuild _all_ samplerate dependent tables and vars here */
	phasex_shutdown ("Unable to change sample rate.  Exiting...\n");
    }

    /* First time setting sample rate */
    if (sample_rate == 0) {
	sample_rate    = nframes;
	f_sample_rate  = (sample_t)sample_rate;
	nyquist_freq   = (sample_t)(sample_rate / 2);
	wave_period    = (sample_t)(F_WAVEFORM_SIZE / (double)sample_rate);

	if (debug) {
	    fprintf (stderr, "Internal sample rate:  %d\n", nframes);
	}

	/* now that we have the sample rate, signal anyone else who needs to know */
	pthread_cond_broadcast (&sample_rate_cond);
    }

    pthread_mutex_unlock (&sample_rate_mutex);
    return 0;
}
Exemplo n.º 3
0
Arquivo: bank.c Projeto: EQ4/phasex
/*****************************************************************************
 * load_patch_list()
 *
 * Loads a comma separated list of patches, one for each part.
 *****************************************************************************/
void
load_patch_list(char *patch_list)
{
	PATCH           *patch;
	char            filename[PATH_MAX];
	char            *patch_name;
	char            *tokbuf;
	char            *p;
	unsigned int    part_num = 0;
	int             prog = 0;

	/* Get a comma separated client:port list from command line,
	   or a '-' (or no -p arg) for open subscription. */
	if (patch_list != NULL) {
		if ((tokbuf = alloca(strlen(patch_list) * 4)) == NULL) {
			phasex_shutdown("Out of memory!\n");
		}
		p = patch_list;
		while ((part_num < MAX_PARTS) && ((patch_name = strtok_r(p, ",", &tokbuf)) != NULL)) {
			p = NULL;
			patch = get_patch_from_bank(part_num, 0);
			/* read in patchdump for part num if patch is '-' */
			if (strcmp(patch_name, "-") == 0) {
				read_patch(user_patchdump_file[part_num], patch);
			}
			/* if patch is numeric and within range 0-127, treat it
			   as a program number */
			else if (((prog = atoi(patch_name)) > 0) && (prog <= PATCH_BANK_SIZE)) {
				session_bank[visible_sess_num].prog_num[part_num] =
					(unsigned int)(prog - 1);
			}
			/* default to reading in named patch */
			else {
				/* TODO: if user patch exists (in any directory) load it and
				   skip system patch. */
				snprintf(filename, sizeof(char) * PATH_MAX, "%s/%s.phx",
				         PATCH_DIR, patch_name);
				read_patch(filename, patch);
				snprintf(filename, sizeof(char) * PATH_MAX, "%s/%s.phx",
				         user_patch_dir, patch_name);
				read_patch(filename, patch);
				session_bank[visible_sess_num].prog_num[part_num] = (unsigned int) prog - 1;
			}
			part_num++;
		}
	}
}
Exemplo n.º 4
0
/*****************************************************************************
 *
 * JACK_BUFSIZE_HANDLER()
 *
 * Gets called when jack sets or changes buffer size.
 *
 *****************************************************************************/
int 
jack_bufsize_handler(jack_nframes_t nframes, void *arg) {
    /* Begin buffer critical section */
    pthread_mutex_lock (&buffer_mutex);

    /* Make sure buffer doesn't get overrun */
    if (nframes > (PHASEX_MAX_BUFSIZE / 2)) {
	fprintf (stderr, "JACK requested buffer size:  %d.  Max is:  %d.\n",
		 nframes, (PHASEX_MAX_BUFSIZE / 2));
	phasex_shutdown ("Buffer size exceeded.  Exiting...\n");
    }
    buffer_size   = nframes * 2;
    buffer_full   = buffer_size;

    pthread_mutex_unlock (&buffer_mutex);
    /* End buffer critical section */

    if (debug) {
	fprintf (stderr, "JACK requested buffer size:  %d\n", nframes);
    }

    return 0;
}
Exemplo n.º 5
0
Arquivo: bank.c Projeto: EQ4/phasex
/*****************************************************************************
 * load_patch_bank()
 *****************************************************************************/
void
load_patch_bank(void)
{
	PATCH           *patch;
	FILE            *bank_f;
	char            *p;
	char            *filename;
	char            *tmpname;
	char            buffer[256];
	int             part_num    = 0;
	int             prog        = 0;
	unsigned int    line        = 0;
	int             once        = 1;
	int             result;

	/* open the bank file */
	if ((bank_f = fopen(user_bank_file, "rt")) == NULL) {
		if ((bank_f = fopen(sys_bank_file, "rt")) == NULL) {
			return;
		}
	}

	/* read bank entries */
	while (fgets(buffer, sizeof(buffer), bank_f) != NULL) {
		line++;

		/* discard comments and blank lines */
		if ((buffer[0] == '\n') || (buffer[0] == '#')) {
			continue;
		}

		/* get part number */
		if ((p = get_next_token(buffer)) == NULL) {
			while (get_next_token(buffer) != NULL);
			continue;
		}
		part_num = atoi(p) - 1;
		if ((part_num < 0) || (part_num >= MAX_PARTS)) {
			part_num = 0;
		}

		/* make sure there's a comma */
		if ((p = get_next_token(buffer)) == NULL) {
			while (get_next_token(buffer) != NULL);
			continue;
		}
		if (*p != ',') {
			while (get_next_token(buffer) != NULL);
			continue;
		}

		/* get program number */
		if ((p = get_next_token(buffer)) == NULL) {
			while (get_next_token(buffer) != NULL);
			continue;
		}
		prog = atoi(p) - 1;
		if ((prog < 0) || (prog >= PATCH_BANK_SIZE)) {
			prog = 0;
		}
		patch = & (patch_bank[part_num][prog]);

		/* make sure there's an '=' */
		if ((p = get_next_token(buffer)) == NULL) {
			while (get_next_token(buffer) != NULL);
			continue;
		}
		if (*p != '=') {
			while (get_next_token(buffer) != NULL);
			continue;
		}

		/* get patch name */
		if ((tmpname = get_next_token(buffer)) == NULL) {
			while (get_next_token(buffer) != NULL);
			continue;
		}
		if (*tmpname == ';') {
			while (get_next_token(buffer) != NULL);
			continue;
		}
		if ((filename = strdup(tmpname)) == NULL) {
			phasex_shutdown("Out of memory!\n");
		}

		/* make sure there's a ';' */
		if ((p = get_next_token(buffer)) == NULL) {
			while (get_next_token(buffer) != NULL);
			continue;
		}
		if (*p != ';') {
			while (get_next_token(buffer) != NULL);
			continue;
		}

		/* flush remainder of line */
		while (get_next_token(buffer) != NULL);

		/* load patch into bank */
		result = 0;

		/* handle bare patch names from 0.10.x versions */
		if (filename[0] != '/') {
			snprintf(buffer, sizeof(buffer), "%s/%s.phx", user_patch_dir, filename);
			result = read_patch(buffer, patch);
			if (result != 0) {
				snprintf(buffer, sizeof(buffer), "%s/%s.phx", PATCH_DIR, filename);
				result = read_patch(buffer, patch);
			}
		}

		/* handle fully qualified filenames */
		else {
			result = read_patch(filename, patch);
		}

		/* initialize on failure and set name based on program number */
		if (result != 0) {
			if (read_patch(user_default_patch, patch) != 0) {
				read_patch(sys_default_patch, patch);
			}
			snprintf(buffer, sizeof(buffer), "Untitled-%04d", (prog + 1));
			tmpname = patch->name;
			patch->name = strdup(buffer);
			if (tmpname != NULL) {
				free(tmpname);
			}
			if (patch->directory != NULL) {
				free(patch->directory);
			}
			patch->directory = strdup(user_patch_dir);
		}

		/* free up memory used to piece filename together */
		free(filename);

		/* Lock some global parameters after the first patch is read */
		if (once) {
			get_param_info_by_id(PARAM_MIDI_CHANNEL)->locked = 1;
			get_param_info_by_id(PARAM_BPM)->locked          = 1;

			once = 0;
		}
	}

	/* done parsing */
	fclose(bank_f);

	/* now fill the empty bank slots with the default patch */
	for (prog = 0; prog < PATCH_BANK_SIZE; prog++) {
		patch = & (patch_bank[part_num][prog]);
		if (patch->name == NULL) {
			if (read_patch(user_default_patch, patch) != 0) {
				read_patch(sys_default_patch, patch);
			}
			snprintf(buffer, sizeof(buffer), "Untitled-%04d", (prog + 1));
			patch->name = strdup(buffer);
			patch->directory = strdup(user_patch_dir);
		}
		patch->modified = 0;
	}
}
Exemplo n.º 6
0
Arquivo: wave.c Projeto: EQ4/phasex
int
load_waveform_sample(int wavenum, int num_cycles, double octaves)
{
	float           *in_buf;
	float           *out_buf;
	char            filename[PATH_MAX];
	struct stat     statbuf;
	SRC_DATA        src_data;
	FILE            *rawfile;
	unsigned int    sample;
	unsigned int    input_len;
	float           pos_max;
	float           neg_max;
	float           offset;
	float           scalar;
	size_t          sample_t_size = sizeof(sample_t);

	if ((in_buf = malloc(2 * WAVEFORM_SIZE * sizeof(float))) == NULL) {
		phasex_shutdown("Out of Memory!\n");
	}
	if ((out_buf = malloc(WAVEFORM_SIZE * sizeof(float))) == NULL) {
		phasex_shutdown("Out of Memory!\n");
	}

	/* get file size */
	snprintf(filename, PATH_MAX, "%s/%s.raw", SAMPLE_DIR, wave_names[wavenum]);
	if (stat(filename, &statbuf) != 0) {
		PHASEX_ERROR("Unable to load raw sample file '%s'\n", filename);
	}
	input_len = (unsigned int)((unsigned int) statbuf.st_size / sizeof(float));
	PHASEX_DEBUG(DEBUG_CLASS_INIT, "Loading raw waveform '%s': %d samples\n",
	             filename, input_len);

	/* open raw sample file */
	if ((rawfile = fopen(filename, "rb")) != 0) {

		/* read sample data */
		if (fread(in_buf, sizeof(float), input_len, rawfile) == input_len) {
			fclose(rawfile);

			/* normalize sample to [-1,1] */
			pos_max = neg_max = 0;
			for (sample = 0; sample < input_len; sample++) {
				if (in_buf[sample] > pos_max) {
					pos_max = in_buf[sample];
				}
				if (in_buf[sample] < neg_max) {
					neg_max = in_buf[sample];
				}
			}
			offset = (pos_max + neg_max) / -2.0;
			scalar = 1.0 / (float)((pos_max - neg_max) / 2.0);
			for (sample = 0; sample < input_len; sample++) {
				in_buf[sample] = (in_buf[sample] + offset) * scalar;
			}

			/* resample to fit WAVEFORM_SIZE */
			src_data.input_frames  = (long int) input_len;
			src_data.output_frames = WAVEFORM_SIZE;
			src_data.src_ratio     = F_WAVEFORM_SIZE / (double) input_len;
			src_data.data_in       = in_buf;
			src_data.data_out      =
				(sample_t_size == 4) ? (float *) & (wave_table[wavenum][0]) : & (out_buf[0]);

			src_simple(&src_data, SRC_SINC_BEST_QUALITY, 1);

			if (sample_t_size != 4) {
				for (sample = 0; sample < input_len; sample++) {
					wave_table[wavenum][sample] = (sample_t)(out_buf[sample]);
				}
			}

			/* filter resampled data */
			filter_wave_table_24dB(wavenum, num_cycles, octaves);

			/* all done */
			return 0;
		}
		fclose(rawfile);
	}

	/* copy sine data on failure */
	PHASEX_ERROR("Error reading '%s'!\n", filename);
	for (sample = 0; sample < WAVEFORM_SIZE; sample++) {
		wave_table[wavenum][sample] = wave_table[WAVE_SINE][sample];
	}

	return -1;
}