void radix_sort(int* a,int n)
{
    int* bucket=(int*)malloc(sizeof(int)*n);
    int count[radix];

    for(int i=0;i<2;++i)
    {
        memset(count,0,sizeof(int)*radix);

        for(int j=0;j<n;++j)
        {
            count[get_part(a[j],i)]++;
        }

        for(int j=1;j<radix;++j)
        {
            count[j]+=count[j-1];
        }

        for(int j=n-1;j>=0;--j)
        {
            int k=get_part(a[j],i);
            bucket[count[k]-1]=a[j];
            count[k]--;
        }

        memcpy(a,bucket,sizeof(int)*n);
    }

    free(bucket);
}
Beispiel #2
0
/*
 * Given a font name this function returns the part used in the second scroll list.
 */
    static void
style_part(char *font, char *buf)
{
    char    buf2[TEMP_BUF_SIZE];
    char    buf3[TEMP_BUF_SIZE];

    get_part(font, 3, buf3);
    get_part(font, 5, buf2);

    if (!strcmp(buf2, "normal") && !strcmp(buf2, "Normal")
						   && !strcmp(buf2, "NORMAL"))
	vim_snprintf(buf, TEMP_BUF_SIZE, "%s %s", buf3, buf2);
    else
	strcpy(buf, buf3);

    get_part(font, 6, buf2);

    if (buf2[0] != '\0')
	vim_snprintf(buf3, TEMP_BUF_SIZE, "%s %s", buf, buf2);
    else
	strcpy(buf3, buf);

    get_part(font, 4, buf2);

    if (!strcmp(buf2, "o") || !strcmp(buf2, "O"))
	vim_snprintf(buf, TEMP_BUF_SIZE, "%s oblique", buf3);
    else if (!strcmp(buf2, "i") || !strcmp(buf2, "I"))
	vim_snprintf(buf, TEMP_BUF_SIZE, "%s italic", buf3);

    if (!strcmp(buf, " "))
	strcpy(buf, "-");
}
Beispiel #3
0
/*
 * Given a font name this function returns the part used in the third
 * scroll list.
 */
    static void
size_part(char *font, char *buf, int inPixels)
{
    int	    size;
    float   temp;

    *buf = '\0';

    if (inPixels)
    {
	get_part(font, 7, buf);
	if (*buf != NUL)
	{
	    size = atoi(buf);
	    sprintf(buf, "%3d", size);
	}
    }
    else
    {
	get_part(font, 8, buf);
	if (*buf != NUL)
	{
	    size = atoi(buf);
	    temp = (float)size / 10.0;
	    size = temp;
	    if (buf[strlen(buf) - 1] == '0')
		sprintf(buf, "%3d", size);
	    else
		sprintf(buf, "%4.1f", temp);
	}
    }
}
Beispiel #4
0
/*
 * Given a font name this function returns the part used in the first
 * scroll list.
 */
    static void
name_part(char *font, char *buf)
{
    char    buf2[TEMP_BUF_SIZE];
    char    buf3[TEMP_BUF_SIZE];

    get_part(font, 2, buf2);
    get_part(font, 1, buf3);

    if (*buf3 != NUL)
	vim_snprintf(buf, TEMP_BUF_SIZE, "%s (%s)", buf2, buf3);
    else
	vim_snprintf(buf, TEMP_BUF_SIZE, "%s", buf2);
}
Beispiel #5
0
/*****************************************************************************
 * process_all_notes_off()
 *
 * Process all notes off for a single channel.  The events for each channel
 * should have been queued once for each engine already.
 *****************************************************************************/
void
process_all_notes_off(MIDI_EVENT *event, unsigned int part_num)
{
	PART            *part = get_part(part_num);
	VOICE           *voice;
	unsigned int    voice_num;
	int             j;

	PHASEX_DEBUG(DEBUG_CLASS_MIDI_EVENT, "*** All notes off!  Part %d:  event_type=0x%02x\n",
	             (part_num + 1), event->type);

	/* let engine shut off notes gracefully */
	for (voice_num = 0; voice_num < (unsigned int) setting_polyphony; voice_num++) {
		voice = get_voice(part_num, voice_num);
		voice->keypressed = -1;
	}

	/* re-initialize this part's keylists */
	part->head     = NULL;
	part->cur      = NULL;
	part->prev     = NULL;
	part->midi_key = -1;
	part->prev_key = -1;

	/* re-initialize this part's keylist nodes */
	for (j = 0; j < 128; j++) {
		part->keylist[j].midi_key = (short) j;
		part->keylist[j].next     = NULL;
	}
}
Beispiel #6
0
/*
 * Given a font name this function returns the part used in the choice menu.
 */
    static void
encoding_part(char *font, char *buf)
{
    char    buf1[TEMP_BUF_SIZE];
    char    buf2[TEMP_BUF_SIZE];

    *buf = '\0';

    get_part(font, 13, buf1);
    get_part(font, 14, buf2);

    if (*buf1 != NUL && *buf2 != NUL)
	vim_snprintf(buf, TEMP_BUF_SIZE, "%s-%s", buf1, buf2);
    if (!strcmp(buf, " "))
	strcpy(buf, "-");
}
Beispiel #7
0
/*****************************************************************************
 * init_gui_patch() {
 *
 * Initializes the gui patch data, with parameters copied from the patch
 * that is marked as currently visible.  Patch and param data structures
 * are established as well.
 *****************************************************************************/
void
init_gui_patch(void)
{
	PATCH           *patch = get_visible_patch();
	PARAM           *param;
	PARAM           *gui_param;
	unsigned int    param_num;

	gp = &gui_patch;
	memset(gp, 0, sizeof(PATCH));
	memset(&gui_dummy_patch_state, 0, sizeof(PATCH_STATE));
	gp->state     = &gui_dummy_patch_state;
	gp->name      = NULL;
	gp->filename  = NULL;
	gp->directory = NULL;
	gp->sess_num  = 0;
	gp->part_num  = 0;
	gp->prog_num  = 0;
	gp->part      = get_part(0);
	for (param_num = 0; param_num < NUM_HELP_PARAMS; param_num++) {
		param                    = & (patch->param[param_num]);
		gui_param                = & (gp->param[param_num]);
		gui_param->info          = get_param_info_by_id(param_num);
		gui_param->patch         = gp;
		gui_param->value.cc_val  = param->value.cc_val;
		gui_param->value.int_val = param->value.int_val;
		gui_param->value.cc_prev = param->info->cc_default;
	}
}
Beispiel #8
0
Datei: bank.c Projekt: EQ4/phasex
/*****************************************************************************
 * init_patch_bank()
 *****************************************************************************/
void
init_patch_bank(void)
{
	PATCH           *patch;
	int             part_num;
	unsigned int    prog_num;

	/* initialize patchbank memory */
	for (part_num = 0; part_num < MAX_PARTS; part_num++) {
		visible_prog_num[part_num] = 0;
		get_part(part_num)->midi_channel = part_num;
		for (prog_num = 0; prog_num < PATCH_BANK_SIZE; prog_num++) {
			patch            = & (patch_bank[part_num][prog_num]);
			patch->name      = NULL;
			patch->filename  = NULL;
			patch->directory = NULL;
			init_patch_data_structures(patch, SESSION_BANK_SIZE, (unsigned int) part_num, prog_num);
			patch->param[PARAM_MIDI_CHANNEL].value.cc_prev = part_num;
			patch->param[PARAM_MIDI_CHANNEL].value.cc_val  = part_num;
			patch->param[PARAM_MIDI_CHANNEL].value.int_val = part_num +
				patch->param[PARAM_MIDI_CHANNEL].info->cc_offset;
		}
		patch = set_active_patch(0, (unsigned int) part_num, 0);
	}

	/* load the bank for all parts */
	load_patch_bank();
}
Beispiel #9
0
int main(void)
{
	int n;
	printf("Please input a #: ");
	scanf("%d", &n);
	get_part(n);
	return 0;
}
Beispiel #10
0
    static Boolean
proportional(char *font)
{
    char buf[TEMP_BUF_SIZE];

    get_part(font, 11, buf);

    return !strcmp(buf, "p") || !strcmp(buf, "P");
}
Beispiel #11
0
part_t *mt_part_get_partition(char *name)
{
    if (!strcmp(name, "PRELOADER") || !strcmp(name, "preloader")) {
        tempart.start_sect = 0x0;
        tempart.nr_sects = 0x200;
        tempart.part_id = 1;
        return &tempart;
    }
    return get_part(name);
}
Beispiel #12
0
/*****************************************************************************
 * process_hold_pedal()
 *
 * Process a Hold Pedal controller message.
 *****************************************************************************/
void
process_hold_pedal(MIDI_EVENT *event, unsigned int part_num)
{
	PART    *part = get_part(part_num);

	part->hold_pedal = (event->value > 64) ? 1 : 0;

	if (!part->hold_pedal || (part->head == NULL)) {
		part->midi_key = -1;
	}
}
Beispiel #13
0
static int arg_off(const char *arg, int *idx, loff_t *off, loff_t *maxsize)
{
	if (!str2off(arg, off))
		return get_part(arg, idx, off, maxsize);

	if (*off >= nand_info[*idx].size) {
		puts("Offset exceeds device limit\n");
		return -1;
	}

	*maxsize = nand_info[*idx].size - *off;
	return 0;
}
Beispiel #14
0
unsigned int get_message(int client, char *text, struct info *info)
{
	unsigned int sum = 0;

	unsigned int parts     = info->parts;
	unsigned int part_size = info->part_size;

	// XXX
	//size_t retransmit_size = ceil(MAX_MESSAGE_SIZE, part_size) >> 3;
	//char *retransmit = (char *)malloc(retransmit_size);

	//ret_init(retransmit, part_size);

	//int write_length = write(client, retransmit, retransmit_size);
	//if (write_length != retransmit_size) {
	//	LOG(INFO, "Could not send retranstmit bits to client");
	//	// XXX Message could contain garbage
	//}

	//free(retransmit);


	int tries = 1;

	int index;
	int got;

	while (sum < parts) {
		got = get_part(client, text, &index, part_size);

		if (got > 0) {
			//sum += got;
			//ret_clear(retransmit, index);
			++sum;
		} else if (got == 0) {
			LOG(DEBUG, "got 0 (try %i)", tries);
			sleep(1);
			if (tries++ == 5)
				break;
		} else {
			errno = -got;
			LOG(DEBUG, "got < 0 (%i)", errno);
			errno = -got;
			perror("didn't read");
		}
	}

	return sum;
}
Beispiel #15
0
/*****************************************************************************
 * process_pitchbend()
 *****************************************************************************/
void
process_pitchbend(MIDI_EVENT *event, unsigned int part_num)
{
	PART            *part = get_part(part_num);
	unsigned int    bend_value;

	bend_value = ((unsigned int)(event->lsb & 0x7F) |
	              ((unsigned int)(event->msb & 0x7F) << 7));

	PHASEX_DEBUG(DEBUG_CLASS_MIDI_EVENT,
	             "Received pitchbend event:  2-byte value = %d  (lsb=%d msb=%d)\n",
	             bend_value, event->lsb, event->msb);

	part->pitch_bend_target = ((sample_t)(bend_value) - 8192) * 0.0001220703125; /* 1/8192 */
}
Beispiel #16
0
int mtd_arg_off(const char *arg, int *idx, loff_t *off, loff_t *size,
		loff_t *maxsize, int devtype, uint64_t chipsize)
{
	if (!str2off(arg, off))
		return get_part(arg, idx, off, size, maxsize, devtype);

	if (*off >= chipsize) {
		puts("Offset exceeds device limit\n");
		return -1;
	}

	*maxsize = chipsize - *off;
	*size = *maxsize;
	return 0;
}
Beispiel #17
0
/*****************************************************************************
 * init_midi_processor()
 *
 * initialize keylist nodes and round-robin voice selectors
 *****************************************************************************/
void
init_midi_processor()
{
	PART            *part;
	unsigned int    part_num;
	int             j;

	/* initialize keylist nodes and round-robin voice selectors */
	for (part_num = 0; part_num < MAX_PARTS; part_num++) {
		part = get_part(part_num);
		/* initialize keylist nodes */
		for (j = 0; j < 128; j++) {
			part->keylist[j].midi_key = j & 0x7F;
			part->keylist[j].next = NULL;
		}
		/* initialize round robin voice indices */
		vnum[part_num] = 0;

		/* initialize per-part midi event buffer */
		init_midi_event_queue(part_num);
	}
}
Beispiel #18
0
/*****************************************************************************
 * process_polypressure()
 *****************************************************************************/
void
process_polypressure(MIDI_EVENT *event, unsigned int part_num)
{
	PART            *part  = get_part(part_num);
	PATCH_STATE     *state = get_active_state(part_num);
	VOICE           *voice;
	int             voice_num;

	PHASEX_DEBUG(DEBUG_CLASS_MIDI_EVENT,
	             "Event Channel Pressure:  part=%d  value=%d\n",
	             (part_num + 1), event->polypressure);

	part->velocity_target = (sample_t) event->polypressure * 0.01;
	for (voice_num = 0; voice_num < setting_polyphony; voice_num++) {
		voice = get_voice(part_num, voice_num);
		if (voice->active) {
			voice->velocity               = event->polypressure;
			voice->velocity_target_linear = (sample_t) event->polypressure * 0.01;
			voice->velocity_target_log    =
				velocity_gain_table[state->amp_velocity_cc][event->polypressure];
		}
	}
}
/*=====================================================================*/
GData &GData::operator ()(int i,int j )
{
    return get_part(i,j);
}
/*
 * Returns pointer to an ASCII character string that contains the name of the
 * selected font (in X format for naming fonts); it is the users responsibility
 * to free the space allocated to this string.
 */
    char_u *
gui_xm_select_font(char_u *current)
{
    static SharedFontSelData	_data;

    Widget		parent;
    Widget		form;
    Widget		separator;
    Widget		sub_form;
    Widget		size_toggle;
    Widget		name;
    Widget		disp_frame;
    Widget		frame;
    Arg			args[64];
    int			n;
    XmString		str;
    char		big_font[MAX_FONT_NAME_LEN];
    SharedFontSelData	*data;

    data = &_data;

    parent = vimShell;
    data->names = XListFonts(XtDisplay(parent), "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
						       MAX_FONTS, &data->num);

    /*
     * Find the name of the biggest font less than the given limit
     * MAX_DISPLAY_SIZE used to set up the initial height of the display
     * widget.
     */

    {
	int	i;
	int	max;
	int	index = 0;
	int	size;
	char	str[128];

	for (i = 0, max = 0; i < data->num; i++)
	{
	    get_part(fn(data, i), 7, str);
	    size = atoi(str);
	    if ((size > max) && (size < MAX_DISPLAY_SIZE))
	    {
		index = i;
		max = size;
	    }
	}
	strcpy(big_font, fn(data, index));
    }
    data->old = XLoadQueryFont(XtDisplay(parent), big_font);
    data->old_list = gui_motif_create_fontlist(data->old);

    /* Set the title of the Dialog window. */
    data->dialog = XmCreateDialogShell(parent, "fontSelector", NULL, 0);
    str = XmStringCreateLocalized(_("Vim - Font Selector"));

    /* Create form popup dialog widget. */
    form = XtVaCreateWidget("form",
	    xmFormWidgetClass, data->dialog,
	    XmNdialogTitle, str,
	    XmNautoUnmanage, False,
	    XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL,
	    NULL);
    XmStringFree(str);

    sub_form = XtVaCreateManagedWidget("subForm",
	    xmFormWidgetClass, form,
	    XmNbottomAttachment, XmATTACH_FORM,
	    XmNbottomOffset, 4,
	    XmNrightAttachment, XmATTACH_FORM,
	    XmNrightOffset, 4,
	    XmNtopAttachment, XmATTACH_FORM,
	    XmNtopOffset, 4,
	    XmNorientation, XmVERTICAL,
	    NULL);

    data->ok = XtVaCreateManagedWidget(_("OK"),
	    xmPushButtonGadgetClass, sub_form,
	    XmNleftAttachment, XmATTACH_FORM,
	    XmNrightAttachment, XmATTACH_FORM,
	    XmNtopAttachment, XmATTACH_FORM,
	    XmNtopOffset, 4,
	    NULL);
    apply_fontlist(data->ok);

    data->cancel = XtVaCreateManagedWidget(_("Cancel"),
	    xmPushButtonGadgetClass, sub_form,
	    XmNrightAttachment, XmATTACH_FORM,
	    XmNleftAttachment, XmATTACH_FORM,
	    XmNtopAttachment, XmATTACH_WIDGET,
	    XmNtopWidget, data->ok,
	    XmNtopOffset, 4,
	    XmNshowAsDefault, True,
	    NULL);
    apply_fontlist(data->cancel);

    /* Create the separator for beauty. */
    n = 0;
    XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
    XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
    XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
    XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++;
    XtSetArg(args[n], XmNrightWidget, sub_form); n++;
    XtSetArg(args[n], XmNrightOffset, 4); n++;
    separator = XmCreateSeparatorGadget(form, "separator", args, n);
    XtManageChild(separator);

    /* Create font name text widget and the corresponding label. */
    data->name = XtVaCreateManagedWidget("fontName",
	    xmTextWidgetClass, form,
	    XmNbottomAttachment, XmATTACH_FORM,
	    XmNbottomOffset, 4,
	    XmNleftAttachment, XmATTACH_FORM,
	    XmNleftOffset, 4,
	    XmNrightAttachment, XmATTACH_WIDGET,
	    XmNrightWidget, separator,
	    XmNrightOffset, 4,
	    XmNeditable, False,
	    XmNeditMode, XmSINGLE_LINE_EDIT,
	    XmNmaxLength, MAX_FONT_NAME_LEN,
	    XmNcolumns, 60,
	    NULL);

    str = XmStringCreateLocalized(_("Name:"));
    name = XtVaCreateManagedWidget("fontNameLabel",
	    xmLabelGadgetClass, form,
	    XmNlabelString, str,
	    XmNuserData, data->name,
	    XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
	    XmNleftWidget, data->name,
	    XmNbottomAttachment, XmATTACH_WIDGET,
	    XmNbottomWidget, data->name,
	    XmNtopOffset, 1,
	    NULL);
    XmStringFree(str);
    apply_fontlist(name);

    /* create sample display label widget */
    disp_frame = XtVaCreateManagedWidget("sampleFrame",
	    xmFrameWidgetClass, form,
	    XmNshadowType, XmSHADOW_ETCHED_IN,
	    XmNleftAttachment, XmATTACH_FORM,
	    XmNleftOffset, 4,
	    XmNbottomAttachment, XmATTACH_WIDGET,
	    XmNbottomWidget, name,
	    XmNrightAttachment, XmATTACH_WIDGET,
	    XmNrightWidget, separator,
	    XmNrightOffset, 4,
	    XmNalignment, XmALIGNMENT_BEGINNING,
	    NULL);

    data->sample = XtVaCreateManagedWidget("sampleLabel",
	    xmLabelWidgetClass, disp_frame,
	    XmNleftAttachment, XmATTACH_FORM,
	    XmNtopAttachment, XmATTACH_FORM,
	    XmNbottomAttachment, XmATTACH_FORM,
	    XmNrightAttachment, XmATTACH_FORM,
	    XmNalignment, XmALIGNMENT_BEGINNING,
	    XmNrecomputeSize, False,
	    XmNfontList, data->old_list,
	    NULL);

    /* create toggle button */
    str = XmStringCreateLocalized(_("Show size in Points"));
    size_toggle = XtVaCreateManagedWidget("sizeToggle",
	    xmToggleButtonGadgetClass, form,
	    XmNlabelString, str,
	    XmNleftAttachment, XmATTACH_FORM,
	    XmNleftOffset, 4,
	    XmNbottomAttachment, XmATTACH_WIDGET,
	    XmNbottomWidget, disp_frame,
	    XmNbottomOffset, 4,
	    NULL);
    XmStringFree(str);
    apply_fontlist(size_toggle);
    XtManageChild(size_toggle);

    /* Encoding pulldown menu.
     */

    data->encoding_pulldown = XmCreatePulldownMenu(form,
						 "encodingPulldown", NULL, 0);
    str = XmStringCreateLocalized(_("Encoding:"));
    n = 0;
    XtSetArg(args[n], XmNsubMenuId, data->encoding_pulldown); ++n;
    XtSetArg(args[n], XmNlabelString, str); ++n;
    XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
    XtSetArg(args[n], XmNleftOffset, 4); ++n;
    XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n;
    XtSetArg(args[n], XmNbottomWidget, size_toggle); ++n;
    XtSetArg(args[n], XmNbottomOffset, 4); ++n;
    XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); ++n;
    XtSetArg(args[n], XmNrightWidget, separator); ++n;
    XtSetArg(args[n], XmNrightOffset, 4); ++n;
    data->encoding_menu = XmCreateOptionMenu(form, "encodingMenu", args, n);
    XmStringFree(str);
    XmAddTabGroup(data->encoding_menu);

    /*
     * Create scroll list widgets in a separate subform used to manage the
     * different sizes of the lists.
     */

    sub_form = XtVaCreateManagedWidget("subForm",
	    xmFormWidgetClass, form,
	    XmNbottomAttachment, XmATTACH_WIDGET,
	    XmNbottomWidget, data->encoding_menu,
	    XmNbottomOffset, 4,
	    XmNleftAttachment, XmATTACH_FORM,
	    XmNleftOffset, 4,
	    XmNrightAttachment, XmATTACH_WIDGET,
	    XmNrightWidget, separator,
	    XmNrightOffset, 4,
	    XmNtopAttachment, XmATTACH_FORM,
	    XmNtopOffset, 2,
	    XmNorientation, XmVERTICAL,
	    NULL);

    /* font list */
    frame = XtVaCreateManagedWidget("frame", xmFrameWidgetClass, sub_form,
	    XmNshadowThickness, 0,
	    XmNtopAttachment, XmATTACH_FORM,
	    XmNbottomAttachment, XmATTACH_FORM,
	    XmNleftAttachment, XmATTACH_FORM,
	    XmNrightAttachment, XmATTACH_POSITION,
	    XmNrightPosition, 50,
	    NULL);

    str = XmStringCreateLocalized(_("Font:"));
    name = XtVaCreateManagedWidget("nameListLabel", xmLabelGadgetClass, frame,
	    XmNchildType, XmFRAME_TITLE_CHILD,
	    XmNchildVerticalAlignment, XmALIGNMENT_CENTER,
	    XmNchildHorizontalAlignment, XmALIGNMENT_BEGINNING,
	    XmNlabelString, str,
	    NULL);
    XmStringFree(str);
    apply_fontlist(name);

    n = 0;
    XtSetArg(args[n], XmNvisibleItemCount, 8); ++n;
    XtSetArg(args[n], XmNresizable, True); ++n;
    XtSetArg(args[n], XmNlistSizePolicy, XmCONSTANT); ++n;
    XtSetArg(args[n], XmNvisualPolicy, XmVARIABLE); ++n;
#ifdef LESSTIF_VERSION
    XtSetArg(args[n], XmNscrollBarDisplayPolicy, XmSTATIC); ++n;
#endif
    data->list[NAME] = XmCreateScrolledList(frame, "fontList", args, n);
    XtVaSetValues(name, XmNuserData, data->list[NAME], NULL);

    /* style list */
    frame = XtVaCreateManagedWidget("frame", xmFrameWidgetClass, sub_form,
	    XmNshadowThickness, 0,
	    XmNtopAttachment, XmATTACH_FORM,
	    XmNbottomAttachment, XmATTACH_FORM,
	    XmNleftAttachment, XmATTACH_POSITION,
	    XmNleftPosition, 50,
	    XmNleftOffset, 4,
	    XmNrightAttachment, XmATTACH_POSITION,
	    XmNrightPosition, 80,
	    NULL);

    str = XmStringCreateLocalized(_("Style:"));
    name = XtVaCreateManagedWidget("styleListLabel", xmLabelWidgetClass, frame,
	    XmNchildType, XmFRAME_TITLE_CHILD,
	    XmNchildVerticalAlignment, XmALIGNMENT_CENTER,
	    XmNchildHorizontalAlignment, XmALIGNMENT_BEGINNING,
	    XmNlabelString, str,
	    NULL);
    XmStringFree(str);
    apply_fontlist(name);

    n = 0;
    XtSetArg(args[n], XmNvisibleItemCount, 8); ++n;
    XtSetArg(args[n], XmNresizable, True); ++n;
    XtSetArg(args[n], XmNlistSizePolicy, XmCONSTANT); ++n;
    XtSetArg(args[n], XmNvisualPolicy, XmVARIABLE); ++n;
#ifdef LESSTIF_VERSION
    XtSetArg(args[n], XmNscrollBarDisplayPolicy, XmSTATIC); ++n;
#endif
    data->list[STYLE] = XmCreateScrolledList(frame, "styleList", args, n);
    XtVaSetValues(name, XmNuserData, data->list[STYLE], NULL);

    /* size list */
    frame = XtVaCreateManagedWidget("frame", xmFrameWidgetClass, sub_form,
	    XmNshadowThickness, 0,
	    XmNtopAttachment, XmATTACH_FORM,
	    XmNbottomAttachment, XmATTACH_FORM,
	    XmNleftAttachment, XmATTACH_POSITION,
	    XmNleftPosition, 80,
	    XmNleftOffset, 4,
	    XmNrightAttachment, XmATTACH_FORM,
	    NULL);

    str = XmStringCreateLocalized(_("Size:"));
    name = XtVaCreateManagedWidget("sizeListLabel", xmLabelGadgetClass, frame,
	    XmNchildType, XmFRAME_TITLE_CHILD,
	    XmNchildVerticalAlignment, XmALIGNMENT_CENTER,
	    XmNchildHorizontalAlignment, XmALIGNMENT_BEGINNING,
	    XmNlabelString, str,
	    NULL);
    XmStringFree(str);
    apply_fontlist(name);

    n = 0;
    XtSetArg(args[n], XmNvisibleItemCount, 8); ++n;
    XtSetArg(args[n], XmNresizable, True); ++n;
    XtSetArg(args[n], XmNlistSizePolicy, XmCONSTANT); ++n;
    XtSetArg(args[n], XmNvisualPolicy, XmVARIABLE); ++n;
#ifdef LESSTIF_VERSION
    XtSetArg(args[n], XmNscrollBarDisplayPolicy, XmSTATIC); ++n;
#endif
    data->list[SIZE] = XmCreateScrolledList(frame, "sizeList", args, n);
    XtVaSetValues(name, XmNuserData, data->list[SIZE], NULL);

    /* update form widgets cancel button */
    XtVaSetValues(form, XmNcancelButton, data->cancel, NULL);

    XtAddCallback(size_toggle, XmNvalueChangedCallback,
	    (XtCallbackProc)stoggle_callback, (XtPointer)data);
    XtAddCallback(data->list[NAME], XmNbrowseSelectionCallback,
	    (XtCallbackProc)name_callback, (XtPointer)data);
    XtAddCallback(data->list[STYLE], XmNbrowseSelectionCallback,
	    (XtCallbackProc)style_callback, (XtPointer)data);
    XtAddCallback(data->list[SIZE], XmNbrowseSelectionCallback,
	    (XtCallbackProc)size_callback, (XtPointer)data);
    XtAddCallback(data->ok, XmNactivateCallback,
	    (XtCallbackProc)ok_callback, (XtPointer)data);
    XtAddCallback(data->cancel, XmNactivateCallback,
	    (XtCallbackProc)cancel_callback, (XtPointer)data);

    XmProcessTraversal(data->list[NAME], XmTRAVERSE_CURRENT);

    /* setup tabgroups */

    XmAddTabGroup(data->list[NAME]);
    XmAddTabGroup(data->list[STYLE]);
    XmAddTabGroup(data->list[SIZE]);
    XmAddTabGroup(size_toggle);
    XmAddTabGroup(data->name);
    XmAddTabGroup(data->ok);
    XmAddTabGroup(data->cancel);

    add_cancel_action(data->dialog, (XtCallbackProc)cancel_callback, data);

    /* Preset selection data. */

    data->exit = False;
    data->in_pixels= True;
    data->sel[ENCODING] = NULL;
    data->sel[NAME] = NULL;
    data->sel[STYLE] = NULL;
    data->sel[SIZE] = NULL;
    data->font_name = NULL;

    /* set up current font parameters */
    if (current && current[0] != '\0')
    {
	int	    i;
	char	    **names;

	names = XListFonts(XtDisplay(form), (char *) current, 1, &i);

	if (i != 0)
	{
	    char name[TEMP_BUF_SIZE];
	    char style[TEMP_BUF_SIZE];
	    char size[TEMP_BUF_SIZE];
	    char encoding[TEMP_BUF_SIZE];
	    char *found;

	    found = names[0];

	    name_part(found, name);
	    style_part(found, style);
	    size_part(found, size, data->in_pixels);
	    encoding_part(found, encoding);

	    if (strlen(name) > 0
		    && strlen(style) > 0
		    && strlen(size) > 0
		    && strlen(encoding) > 0)
	    {
		data->sel[NAME] = XtNewString(name);
		data->sel[STYLE] = XtNewString(style);
		data->sel[SIZE] = XtNewString(size);
		data->sel[ENCODING] = XtNewString(encoding);
		data->font_name = XtNewString(names[0]);
		display_sample(data);
		XmTextSetString(data->name, data->font_name);
	    }
	    else
	    {
		/* We can't preset a symbolic name, which isn't a full font
		 * description. Therefore we just behave the same way as if the
		 * user didn't have selected anything thus far.
		 *
		 * Unfortunately there is no known way to expand an abbreviated
		 * font name.
		 */

		data->font_name = NULL;
	    }
	}
	XFreeFontNames(names);
    }

    fill_lists(NONE, data);

    /* Unfortunately LessTif doesn't align the list widget's properly.  I don't
     * have currently any idea how to fix this problem.
     */
    XtManageChild(data->list[NAME]);
    XtManageChild(data->list[STYLE]);
    XtManageChild(data->list[SIZE]);
    XtManageChild(data->encoding_menu);
    manage_centered(form);

    /* modal event loop */
    while (!data->exit)
	XtAppProcessEvent(XtWidgetToApplicationContext(data->dialog),
							(XtInputMask)XtIMAll);

    XtDestroyWidget(data->dialog);

    if (data->old)
    {
	XFreeFont(XtDisplay(data->dialog),  data->old);
	XmFontListFree(data->old_list);
    }

    gui_motif_synch_fonts();

    return (char_u *) data->font_name;
}
Beispiel #21
0
int
nametodisk(int *disk, long *offset, long *length)
{
	int err, fstype, subdisk;
	struct part_desc pl[16];
	char env[80], *envp, *pos1, *pos2, *cp;

	/* Decode E2CWD environment */
	envp=getenv("E2CWD");
	
	if (!envp)
		return E2E_NOCWD;

	strcpy(env,envp);			/* We are going to modify it, so we make a copy */

	pos1=strchr(env,':');

	if (!pos1)
		return E2E_BADCWD;

	pos2=strchr(pos1+1,':');

	*pos1 = 0;
	pos1++;

	for (cp=env; *cp; cp++)
		if (!isdigit(*cp))
			return E2E_BADCWD;

	*disk = atoi(env);

	if (pos2) {
		*pos2 = 0;
		pos2++;
	}

	for (cp=pos1; *cp; cp++)
		if (!isdigit(*cp))
			return E2E_BADCWD;

	subdisk = atoi(pos1)-1;

	if (pos2) {
		for (cp=pos2; *cp; cp++)
			if (!isdigit(*cp))
				return E2E_BADCWD;

		cwdino = atoi(pos2);
	}
	else
		cwdino = EXT2_ROOT_INO;


	/* Check that disk contains an ext2 file system */

	if (!(*disk & 0x80)) {
		/* Floppy disk */
		*offset = 0;
		*length = 1440*2; /* TBD */
		fstype=getfstype(*disk, 0, 0);

		if (fstype<0)
			return -fstype;

		if (fstype!=EXT2FS)
			return E2E_BADFS;
		
		return 0;
	}
	
	err=get_part(*disk, pl);
	if (err)
		return err;

	if (pl[subdisk].is_extended)
		return E2E_BADFS;

	fstype=getfstype(*disk, pl[subdisk].parttype, pl[subdisk].start);
	if (fstype<0)
		return -fstype;
	if (fstype!=EXT2FS)
		return E2E_BADFS;

	*offset = pl[subdisk].start;
	*length = pl[subdisk].length;

	return 0;
}
Beispiel #22
0
int mmc_get_dl_info(void)
{
    struct dl_status download_info;
    u64 dl_addr;
    u8 *dl_buf;

    part_dev_t *dev;
    part_t *part;

    int i, err, loglevel;

    dev = mt_part_get_device();
    if (!dev) {
        dprintf(CRITICAL, "[DL_INFO]fail to get device\n");
        err = -ENODEV;
        goto out;
    }

    part = get_part("flashinfo");
    if (!part) {
        dprintf(CRITICAL, "[DL_INFO]fail to find partition flashinfo\n");
        err = -ENODEV;
        goto out;
    }

    dl_addr = (u64)(part->start_sect + part->nr_sects) * 512ULL - DL_INFO_SIZE;
    dprintf(ALWAYS, "[DL_INFO]get dl info from 0x%llx\n", dl_addr);

    dl_buf = (u8 *)calloc(1, DL_INFO_SIZE);
    if (!dl_buf) {
        dprintf(CRITICAL, "[DL_INFO]fail to calloc buffer(count=%d)\n", DL_INFO_SIZE);
        err = -ENOMEM;
        goto fail_malloc;
    }

    err = dev->read(dev, dl_addr, dl_buf, DL_INFO_SIZE, part->part_id);
    if (err != DL_INFO_SIZE) {
        dprintf(CRITICAL, "[DL_INFO]fail to read data(%d)\n", err);
        err = -EIO;
        goto fail_read;
    }

    memcpy(&download_info, dl_buf, sizeof(download_info));

    if (memcmp(download_info.magic_num, "DOWNLOAD INFORMATION!!", 22)) {
        dprintf(CRITICAL, "[DL_INFO]fail to find DL INFO magic\n");
        err = DL_NOT_FOUND;
        goto fail_read;
    }

    if (!memcmp(download_info.download_status, "DL_DONE", 7) ||
        !memcmp(download_info.download_status, "DL_CK_DONE", 10)) {
        loglevel = INFO;
        loglevel = CRITICAL;
        err = DL_PASS;
    } else {
        loglevel = CRITICAL;
        err = DL_FAIL;
    }

    dprintf(loglevel, "[DL_INFO]version: %s\n", download_info.version);	
    dprintf(loglevel, "[DL_INFO]dl_status: %s\n", download_info.download_status);	
    dprintf(loglevel, "[DL_INFO]dram_checksum: %s\n", download_info.ram_checksum);
    for (i = 0; i < PART_MAX_COUNT; i++) {
        if (download_info.cs_info[i].image_index != 0) {
            dprintf(loglevel, "[DL_INFO]image:[%02d]%-12s, checksum: %s\n", 
                    download_info.cs_info[i].image_index,
                    download_info.img_info[i].image_name,
                    download_info.cs_info[i].checksum_status);
        }
    }

fail_read:
    free(dl_buf);
fail_malloc:
    //put_part(part);
out:
    return err;
}
Beispiel #23
0
/*****************************************************************************
 * process_phase_sync()
 *
 * Process a phase sync internal MIDI message.  Currently used for syncing
 * JACK Transport, this function performs phase correction for a given voice.
 *****************************************************************************/
void
process_phase_sync(MIDI_EVENT *event, unsigned int part_num)
{
	PART            *part              = get_part(part_num);
	PATCH_STATE     *state             = get_active_state(part_num);
	DELAY           *delay             = get_delay(part_num);
	CHORUS          *chorus            = get_chorus(part_num);
	VOICE           *voice;
	int             voice_num;
	int             osc;
	int             lfo;
	int             phase_correction   = event->value;
	sample_t        f_phase_correction = (sample_t) phase_correction;
	sample_t        tmp_1;

	delay->write_index += phase_correction;
	while (delay->write_index < 0.0) {
		delay->write_index += delay->bufsize;
	}
	while (delay->write_index >= delay->bufsize) {
		delay->write_index -= delay->bufsize;
	}

	chorus->lfo_index_a += f_phase_correction * chorus->lfo_adjust;
	while (chorus->lfo_index_a < 0.0) {
		chorus->lfo_index_a += F_WAVEFORM_SIZE;
	}
	while (chorus->lfo_index_a >= F_WAVEFORM_SIZE) {
		chorus->lfo_index_a -= F_WAVEFORM_SIZE;
	}

	chorus->lfo_index_b = chorus->lfo_index_a + (F_WAVEFORM_SIZE * 0.25);
	while (chorus->lfo_index_b < 0.0) {
		chorus->lfo_index_b += F_WAVEFORM_SIZE;
	}
	while (chorus->lfo_index_b >= F_WAVEFORM_SIZE) {
		chorus->lfo_index_b -= F_WAVEFORM_SIZE;
	}

	chorus->lfo_index_c = chorus->lfo_index_a + (F_WAVEFORM_SIZE * 0.5);
	while (chorus->lfo_index_c < 0.0) {
		chorus->lfo_index_c += F_WAVEFORM_SIZE;
	}
	while (chorus->lfo_index_c >= F_WAVEFORM_SIZE) {
		chorus->lfo_index_c -= F_WAVEFORM_SIZE;
	}

	chorus->lfo_index_d = chorus->lfo_index_a + (F_WAVEFORM_SIZE * 0.75);
	while (chorus->lfo_index_d < 0.0) {
		chorus->lfo_index_d += F_WAVEFORM_SIZE;
	}
	while (chorus->lfo_index_d >= F_WAVEFORM_SIZE) {
		chorus->lfo_index_d -= F_WAVEFORM_SIZE;
	}

	for (voice_num = 0; voice_num < setting_polyphony; voice_num++) {
		voice = get_voice(part_num, voice_num);
		for (osc = 0; osc < NUM_OSCS; osc++) {
			if (state->osc_freq_base[osc] >= FREQ_BASE_TEMPO) {
				switch (state->freq_mod_type[osc]) {
				case MOD_TYPE_LFO:
					tmp_1 = part->lfo_out[state->freq_lfo[osc]];
					break;
				case MOD_TYPE_OSC:
					tmp_1 = (voice->osc_out1[part->osc_freq_mod[osc]] +
					         voice->osc_out2[part->osc_freq_mod[osc]]) * 0.5;
					break;
				case MOD_TYPE_VELOCITY:
					tmp_1 = voice->velocity_coef_linear;
					break;
				default:
					tmp_1 = 0.0;
					break;
				}

				voice->index[osc] +=
					f_phase_correction *
					halfsteps_to_freq_mult((tmp_1 *
					                        state->freq_lfo_amount[osc]) +
					                       part->osc_pitch_bend[osc] +
					                       state->osc_transpose[osc] +
					                       state->voice_osc_tune[voice->id] ) *
					voice->osc_freq[osc] * wave_period;

				while (voice->index[osc] < 0.0) {
					voice->index[osc] += F_WAVEFORM_SIZE;
				}
				while (voice->index[osc] >= F_WAVEFORM_SIZE) {
					voice->index[osc] -= F_WAVEFORM_SIZE;
				}
			}
		}
	}
	for (lfo = 0; lfo < NUM_LFOS; lfo++) {
		if (state->lfo_freq_base[lfo] >= FREQ_BASE_TEMPO) {
			part->lfo_index[lfo] +=
				f_phase_correction *
				part->lfo_freq[lfo] *
				halfsteps_to_freq_mult(state->lfo_transpose[lfo] + part->lfo_pitch_bend[lfo]) *
				wave_period;

			while (part->lfo_index[lfo] < 0.0) {
				part->lfo_index[lfo] += F_WAVEFORM_SIZE;
			}
			while (part->lfo_index[lfo] >= F_WAVEFORM_SIZE) {
				part->lfo_index[lfo] -= F_WAVEFORM_SIZE;
			}
		}
	}
}
Beispiel #24
0
/*****************************************************************************
 * process_bpm_change()
 *
 * Process a BPM change pseudo MIDI message.  Currently used when syncing
 * JACK Transport, this adjust BPM, independent of controller assignment.
 *
 * TODO:  Rework _all_ phasex BPM code, since this is almost identical to
 * update_bpm() in bpm.c.
 *****************************************************************************/
void
process_bpm_change(MIDI_EVENT *event, unsigned int part_num)
{
	PART        *part   = get_part(part_num);
	PATCH_STATE *state  = get_active_state(part_num);
	PARAM       *param  = get_param(part_num, PARAM_BPM);
	DELAY       *delay  = get_delay(part_num);
	CHORUS      *chorus = get_chorus(part_num);
	VOICE       *voice;
	int         int_val = (int)(event->float_value);
	int         cc_val  = int_val - 64;
	int         voice_num;
	int         lfo;
	int         osc;

	PHASEX_DEBUG(DEBUG_CLASS_MIDI_TIMING, "+++ Processing BPM change.  New BPM = %lf +++\n",
	             event->float_value);

	param->value.cc_val  = cc_val;
	param->value.int_val = int_val;

	/* For now, this is handled much like the normal param
	   callback for BPM, execpt that here we use floating point
	   values instead of integer. */

	global.bpm = event->float_value;
	global.bps = event->float_value / 60.0;

	if (param->value.cc_val != cc_val) {
		param->value.cc_prev = param->value.cc_val;
		param->value.cc_val  = cc_val;
		param->value.int_val = int_val;
		param->updated        = 1;
	}

	/* initialize all variables based on bpm */
	state->bpm     = event->float_value;
	state->bpm_cc  = (short)(param->value.cc_val & 0x7F);

	/* re-initialize delay size */
	delay->size   = state->delay_time * f_sample_rate / global.bps;
	delay->length = (int)(delay->size);

	/* re-initialize chorus lfos */
	chorus->lfo_freq     = global.bps * state->chorus_lfo_rate;
	chorus->lfo_adjust   = chorus->lfo_freq * wave_period;
	chorus->phase_freq   = global.bps * state->chorus_phase_rate;
	chorus->phase_adjust = chorus->phase_freq * wave_period;

	/* per-lfo setup */
	for (lfo = 0; lfo < NUM_LFOS; lfo++) {
		/* re-calculate frequency and corresponding index adjustment */
		if (state->lfo_freq_base[lfo] >= FREQ_BASE_TEMPO) {
			part->lfo_freq[lfo]    = global.bps * state->lfo_rate[lfo];
			part->lfo_adjust[lfo]  = part->lfo_freq[lfo] * wave_period;
		}
	}

	/* per-oscillator setup */
	for (osc = 0; osc < NUM_OSCS; osc++) {
		/* re-calculate tempo based osc freq */
		if (state->osc_freq_base[osc] >= FREQ_BASE_TEMPO) {
			for (voice_num = 0; voice_num < setting_polyphony; voice_num++) {
				voice = get_voice(part_num, voice_num);
				voice->osc_freq[osc] = global.bps * state->osc_rate[osc];
			}
		}
	}
}
Beispiel #25
0
/*****************************************************************************
 * process_note_off()
 *
 * Process a single note-off event (either a note-off message, or a note-on
 * message with velocity set to zero).  Select a voices to be turned on/off,
 * remove key from list, and call process_keytrigger() for any portamento,
 * envelope, osc and lfo init-phase, and filter-follow triggering actions for
 * note-off events that cause new notes to be triggered (mono modes).
 *****************************************************************************/
void
process_note_off(MIDI_EVENT *event, unsigned int part_num)
{
	VOICE           *voice;
	VOICE           *old_voice      = NULL;
	VOICE           *loop_voice;
	PART            *part           = get_part(part_num);
	PATCH_STATE     *state          = get_active_state(part_num);
	int             keytrigger      = 0;
	int             free_voice      = -1;
	int             voice_num;
	int             unlink;
	int 			voice_count = 0;

	switch (state->keymode) {
	case KEYMODE_POLY:
		/* find voice mapped to note being shut off */
		vnum[part_num] = -1;
		for (voice_num = 0; voice_num < setting_polyphony; voice_num++) {
			loop_voice = get_voice(part_num, voice_num);
			if (loop_voice->midi_key == event->note) {
				loop_voice->keypressed = -1;
				vnum[part_num] = voice_num;
			}
		}
		if (vnum[part_num] == -1) {
			vnum[part_num] = 0;
			keytrigger = 0;
		}
		break;

	case KEYMODE_MONO_SMOOTH:
		/* find voice mapped to note being shut off, if any */
		keytrigger = 0;
		for (voice_num = 0; voice_num < setting_polyphony; voice_num++) {
			loop_voice = get_voice(part_num, voice_num);
			if (loop_voice->keypressed == event->note) {
				loop_voice->keypressed = -1;
				if (event->note == part->midi_key) {
					old_voice = loop_voice;
				}
			}
		}
		break;

	case KEYMODE_MONO_RETRIGGER:
		/* find voice mapped to note being shut off, if any */
		keytrigger = 0;
		for (voice_num = 0; voice_num < setting_polyphony; voice_num++) {
			loop_voice = get_voice(part_num,
			                       ((voice_num + vnum[part_num] + 1) % setting_polyphony));
			if (loop_voice->allocated == 0) {
				free_voice = loop_voice->id;
			}
			else if (loop_voice->midi_key == event->note) {
				loop_voice->keypressed = -1;
				vnum[part_num] = (voice_num + 1) % setting_polyphony;
				if (event->note == part->midi_key) {
					old_voice = loop_voice;
				}
			}
		}
		if ((old_voice != NULL) && (free_voice > -1)) {
			vnum[part_num] = free_voice;
		}
		break;

	case KEYMODE_MONO_UNISON_4:
		voice_count = 4;
		vnum[part_num] = 0;
		if (part->midi_key == event->note) {
			keytrigger = 1;
			old_voice = get_voice(part_num, vnum[part_num]);
		}
		break;
	case KEYMODE_MONO_UNISON_6:
		voice_count = 6;
		vnum[part_num] = 0;
		if (part->midi_key == event->note) {
			keytrigger = 1;
			old_voice = get_voice(part_num, vnum[part_num]);
		}
		break;
	case KEYMODE_MONO_UNISON_8:
		voice_count = 8;
		vnum[part_num] = 0;
		if (part->midi_key == event->note) {
			keytrigger = 1;
			old_voice = get_voice(part_num, vnum[part_num]);
		}
		break;
	case KEYMODE_MONO_MULTIKEY:
		/* mono multikey needs keytrigger activities on note off for
		   resetting oscillator frequencies. */
		vnum[part_num] = 0;
		if (part->midi_key == event->note) {
			keytrigger = 1;
			old_voice = get_voice(part_num, vnum[part_num]);
		}
		break;
	}

	part->prev_key = part->midi_key;
	part->midi_key = event->note;

	PHASEX_DEBUG(DEBUG_CLASS_MIDI_NOTE, "voice %2d:  Event Note Off:  part=%d  "
	             "voice=%2d  note=%3d  velocity=%3d  keylist=:",
	             (vnum[part_num] + 1),
	             (part_num + 1),
	             (vnum[part_num] + 1),
	             event->note,
	             event->velocity);

	/* remove this key from the list and then find the last key */
	part->prev = NULL;
	part->cur = part->head;
	unlink = 0;
	while (part->cur != NULL) {

		/* if note is found, unlink it from the list */
		if (part->cur->midi_key == event->note) {
			PHASEX_DEBUG(DEBUG_CLASS_MIDI_NOTE, "-%d-:", part->cur->midi_key);
			unlink = 1;
			if (part->prev != NULL) {
				part->prev->next = part->cur->next;
				part->cur->next  = NULL;
				part->cur        = part->prev->next;
			}
			else {
				part->head       = part->cur->next;
				part->cur->next  = NULL;
				part->cur        = part->head;
			}
		}
		/* otherwise, on to the next key in the list */
		else {
			PHASEX_DEBUG(DEBUG_CLASS_MIDI_NOTE, "%d:", part->cur->midi_key);
			part->prev = part->cur;
			part->cur  = part->cur->next;
		}
	}

	PHASEX_DEBUG(DEBUG_CLASS_MIDI_NOTE, "\n");
	PHASEX_DEBUG(DEBUG_CLASS_MIDI_TIMING,
	             DEBUG_COLOR_BLUE "------- %d ------- " DEBUG_COLOR_DEFAULT,
	             event->note);

	if (!unlink) {
		/* Received note-off w/o corresponding note-on. */
		PHASEX_DEBUG(DEBUG_CLASS_MIDI_TIMING,
		             DEBUG_COLOR_RED "----------- " DEBUG_COLOR_DEFAULT);
	}

	/* keep pointer to current voice around */
	voice = get_voice(part_num, vnum[part_num]);

	/* ignore the note in the note off message if found in list */
	if ((part->prev != NULL) && (part->prev->midi_key == event->note)) {
		part->cur = part->head;
		while (part->cur != NULL) {
			if (part->cur->midi_key != event->note) {
				part->prev = part->cur;
			}
			part->cur  = part->cur->next;
		}
	}
	/* check for keys left on the list */
	if (part->prev != NULL) {
		/* set last and current keys in play respective of notes
		   still held */
		part->last_key = part->prev->midi_key;
		part->midi_key = part->prev->midi_key;
		part->prev->next = NULL;

		/* Retrigger and smooth modes need voice allocation with keys
		   still on list multikey always need osc remapping until all
		   keys are done. */
		switch (state->keymode) {
		case KEYMODE_MONO_RETRIGGER:
			if (old_voice == NULL) {
				keytrigger--;
				break;
			}
			old_voice->cur_amp_interval = ENV_INTERVAL_RELEASE;
			old_voice->cur_amp_sample = -1;
			/* intentional fall-through */
		case KEYMODE_MONO_SMOOTH:
			voice->midi_key   = part->midi_key;
			voice->keypressed = part->midi_key;

			/* use previous velocity for this generated note event */
			voice->velocity               = part->velocity;
			voice->velocity_target_linear = voice->velocity_coef_linear =
				part->velocity_target   = part->velocity_coef =
				((sample_t) part->velocity) * 0.01;
			voice->velocity_target_log    = voice->velocity_coef_log =
				velocity_gain_table[state->amp_velocity_cc][part->velocity];

			/* intentional fall-through */
		case KEYMODE_MONO_UNISON_4:
		case KEYMODE_MONO_UNISON_6:
		case KEYMODE_MONO_UNISON_8:
		case KEYMODE_MONO_MULTIKEY:
			keytrigger++;
			break;
		}
	}
	/* re-init list if no keys */
	else {
		voice->midi_key   = -1;
		voice->keypressed = -1;
		for (voice_num = 0; voice_num < voice_count; voice_num++) {
			if ( vnum[part_num] == voice_num ) continue;
			loop_voice = get_voice(part_num, voice_num);
			loop_voice->midi_key = -1;
			loop_voice->keypressed = -1;
		}
		part->head           = NULL;
		if (!part->hold_pedal) {
			part->midi_key       = -1;
		}
	}

	if (keytrigger > 0) {
		process_keytrigger(event, old_voice, voice, part_num);
		for (voice_num = 0; voice_num < voice_count; voice_num++) {
			if ( vnum[part_num] == voice_num ) continue;
			loop_voice = get_voice(part_num, voice_num);
			process_keytrigger(event, old_voice, loop_voice, part_num);
		}
	}
}
Beispiel #26
0
int main(int argc, char **argv) {
	unsigned int start;
	int bytes_count = 0;
	char filename[256];
	memset(filename, 0, sizeof(filename));
	// Parsing command line
	char c;
	action_t action = NONE;
	bool start_addr_specified = false,
		pgm_specified = false,
		part_specified = false,
        bytes_count_specified = false;
	memtype_t memtype = FLASH;
	int i;
	programmer_t *pgm = NULL;
	const stm8_device_t *part = NULL;
	while((c = getopt (argc, argv, "r:w:v:nc:p:s:b:luV")) != (char)-1) {
		switch(c) {
			case 'c':
				pgm_specified = true;
				for(i = 0; pgms[i].name; i++) {
					if(!strcmp(optarg, pgms[i].name))
						pgm = &pgms[i];
				}
				break;
			case 'p':
				part_specified = true;
				part = get_part(optarg);
				break;
			case 'l':
				for(i = 0; stm8_devices[i].name; i++)
					printf("%s ", stm8_devices[i].name);
				printf("\n");
				exit(0);
			case 'r':
				action = READ;
				strcpy(filename, optarg);
				break;
			case 'w':
				action = WRITE;
				strcpy(filename, optarg);
				break;
			case 'v':
				action = VERIFY;
				strcpy(filename, optarg);
				break;
                        case 'u':
				action = UNLOCK;
				start  = 0x4800;
				memtype = OPT;
				strcpy(filename, "Workaround");
				break;
			case 's':
                // Start addr is depending on MCU type
				if(strcasecmp(optarg, "flash") == 0) {
					memtype = FLASH;
                } else if(strcasecmp(optarg, "eeprom") == 0) {
					memtype = EEPROM;
                } else if(strcasecmp(optarg, "ram") == 0) {
					memtype = RAM;
                } else if(strcasecmp(optarg, "opt") == 0) {
					memtype = OPT;
				} else {
					// Start addr is specified explicitely
					memtype = UNKNOWN;
					int success = sscanf(optarg, "%x", &start);
					assert(success);
                    start_addr_specified = true;
				}
				break;
			case 'b':
				bytes_count = atoi(optarg);
                bytes_count_specified = true;
				break;
			case 'V':
                                print_version_and_exit( (bool)0);
				break;
			case '?':
                                print_help_and_exit(argv[0], false);
			default:
				print_help_and_exit(argv[0], true);
		}
	}
	if(argc <= 1)
		print_help_and_exit(argv[0], true);
	if(pgm_specified && !pgm) {
		fprintf(stderr, "No valid programmer specified. Possible values are:\n");
		dump_pgms( (programmer_t *) &pgms);
		exit(-1);
	}
	if(!pgm)
		spawn_error("No programmer has been specified");
	if(part_specified && !part) {
		fprintf(stderr, "No valid part specified. Use -l to see the list of supported devices.\n");
		exit(-1);
	}
	if(!part)
		spawn_error("No part has been specified");

    // Try define memory type by address
	if(memtype == UNKNOWN) {
        if((start >= 0x4800) && (start < 0x4880)) {
            memtype = OPT;
        }
        if((start >= part->ram_start) && (start < part->ram_start + part->ram_size)) {
            memtype = RAM;
        }
        else if((start >= part->flash_start) && (start < part->flash_start + part->flash_size)) {
            memtype = FLASH;
        }
        else if((start >= part->eeprom_start) && (start < part->eeprom_start + part->eeprom_size)) {
            memtype = EEPROM;
        }
    }

	if(memtype != UNKNOWN) {
		// Selecting start addr depending on
		// specified part and memtype
		switch(memtype) {
			case RAM:
                if(!start_addr_specified) {
                    start = part->ram_start;
                }
                if(!bytes_count_specified || bytes_count > part->ram_size) {
                    bytes_count = part->ram_size;
                }
                fprintf(stderr, "Determine RAM area\r\n");
				break;
			case EEPROM:
                if(!start_addr_specified) {
                    start = part->eeprom_start;
                }
                if(!bytes_count_specified || bytes_count > part->eeprom_size) {
                    bytes_count = part->eeprom_size;
                }
                fprintf(stderr, "Determine EEPROM area\r\n");
				break;
			case FLASH:
                if(!start_addr_specified) {
                    start = part->flash_start;
                }
                if(!bytes_count_specified || bytes_count > part->flash_size) {
                    bytes_count = part->flash_size;
                }
                fprintf(stderr, "Determine FLASH area\r\n");
				break;
			case OPT:
                if(!start_addr_specified) {
                    start = 0x4800;
                }
                size_t opt_size = (part->flash_size <= 8*1024 ? 0x40 : 0x80);
                if(!bytes_count_specified || bytes_count > opt_size) {
                    bytes_count = opt_size;
                }
                fprintf(stderr, "Determine OPT area\r\n");
                break;
		}
		start_addr_specified = true;
	}
	if(!action)
		spawn_error("No action has been specified");
	if(!start_addr_specified)
		spawn_error("No memtype or start_addr has been specified");
	if (!strlen(filename))
		spawn_error("No filename has been specified");
	if(!action || !start_addr_specified || !strlen(filename))
		print_help_and_exit(argv[0], true);
	if(!usb_init(pgm, pgm->usb_vid, pgm->usb_pid))
		spawn_error("Couldn't initialize stlink");
	if(!pgm->open(pgm))
		spawn_error("Error communicating with MCU. Please check your SWIM connection.");


	FILE *f;
	if(action == READ) {
		fprintf(stderr, "Reading %d bytes at 0x%x... ", bytes_count, start);
		fflush(stderr);
        int bytes_count_align = ((bytes_count-1)/256+1)*256; // Reading should be done in blocks of 256 bytes
		unsigned char *buf = malloc(bytes_count_align);
		if(!buf) spawn_error("malloc failed");
		int recv = pgm->read_range(pgm, part, buf, start, bytes_count_align);
        if(recv < bytes_count_align) {
            fprintf(stderr, "\r\nRequested %d bytes but received only %d.\r\n", bytes_count_align, recv);
			spawn_error("Failed to read MCU");
        }
		if(!(f = fopen(filename, "w")))
			spawn_error("Failed to open file");
		if(is_ext(filename, ".ihx") || is_ext(filename, ".hex"))
		{
			fprintf(stderr, "Reading from Intel hex file ");
			ihex_write(f, buf, start, start+bytes_count);
		}
		else if(is_ext(filename, ".s19") || is_ext(filename, ".s8") || is_ext(filename, ".srec"))
		{
			printf("Reading from Motorola S-record files are not implemented (yet)\n");
      printf("Exiting...\n");
			exit(-1);

			//TODO Remove the above message and exit, and implement reading from S-record.
			fprintf(stderr, "Reading from Motorola S-record file ");
			srec_write(f, buf, start, start+bytes_count);
		}
		else
		{
			fwrite(buf, 1, bytes_count, f);
		}
		fclose(f);
		fprintf(stderr, "OK\n");
		fprintf(stderr, "Bytes received: %d\n", bytes_count);
    } else if (action == VERIFY) {
		fprintf(stderr, "Verifing %d bytes at 0x%x... ", bytes_count, start);
		fflush(stderr);

        int bytes_count_align = ((bytes_count-1)/256+1)*256; // Reading should be done in blocks of 256 bytes
		unsigned char *buf = malloc(bytes_count_align);
		if(!buf) spawn_error("malloc failed");
		int recv = pgm->read_range(pgm, part, buf, start, bytes_count_align);
        if(recv < bytes_count_align) {
            fprintf(stderr, "\r\nRequested %d bytes but received only %d.\r\n", bytes_count_align, recv);
			spawn_error("Failed to read MCU");
        }

		if(!(f = fopen(filename, "r")))
			spawn_error("Failed to open file");
		unsigned char *buf2 = malloc(bytes_count);
		if(!buf2) spawn_error("malloc failed");
		int bytes_to_verify;
		/* reading bytes to RAM */
		if(is_ext(filename, ".ihx") || is_ext(filename, ".hex")) {
			bytes_to_verify = ihex_read(f, buf, start, start + bytes_count);
		} else {
			fseek(f, 0L, SEEK_END);
			bytes_to_verify = ftell(f);
            if(bytes_count_specified) {
                bytes_to_verify = bytes_count;
            } else if(bytes_count < bytes_to_verify) {
                bytes_to_verify = bytes_count;
            }
			fseek(f, 0, SEEK_SET);
			fread(buf2, 1, bytes_to_verify, f);
		}
		fclose(f);

        if(memcmp(buf, buf2, bytes_to_verify) == 0) {
            fprintf(stderr, "OK\n");
            fprintf(stderr, "Bytes verified: %d\n", bytes_to_verify);
        } else {
            fprintf(stderr, "FAILED\n");
            exit(-1);
        }


	} else if (action == WRITE) {
		if(!(f = fopen(filename, "r")))
			spawn_error("Failed to open file");
        int bytes_count_align = ((bytes_count-1)/part->flash_block_size+1)*part->flash_block_size;
		unsigned char *buf = malloc(bytes_count_align);
		if(!buf) spawn_error("malloc failed");
        memset(buf, 0, bytes_count_align); // Clean aligned buffer
		int bytes_to_write;

		/* reading bytes to RAM */
		if(is_ext(filename, ".ihx") || is_ext(filename, ".hex")) {
			fprintf(stderr, "Writing Intel hex file ");
			bytes_to_write = ihex_read(f, buf, start, start + bytes_count);
		} else if (is_ext(filename, ".s19") || is_ext(filename, ".s8") || is_ext(filename, ".srec")) {
			fprintf(stderr, "Writing Motorola S-record file ");
			bytes_to_write = srec_read(f, buf, start, start + bytes_count);
		} else {
			fprintf(stderr, "Writing binary file ");
			fseek(f, 0L, SEEK_END);
			bytes_to_write = ftell(f);
            if(bytes_count_specified) {
                bytes_to_write = bytes_count;
            } else if(bytes_count < bytes_to_write) {
                bytes_to_write = bytes_count;
            }
			fseek(f, 0, SEEK_SET);
			fread(buf, 1, bytes_to_write, f);
		}
		fprintf(stderr, "%d bytes at 0x%x... ", bytes_to_write, start);

		/* flashing MCU */
		int sent = pgm->write_range(pgm, part, buf, start, bytes_to_write, memtype);
		if(pgm->reset) {
			// Restarting core (if applicable)
			pgm->reset(pgm);
		}
		fprintf(stderr, "OK\n");
		fprintf(stderr, "Bytes written: %d\n", sent);
		fclose(f);
	} else if (action == UNLOCK) {
		int bytes_to_write=part->option_bytes_size;

		if (part->read_out_protection_mode==ROP_UNKNOWN) spawn_error("No unlocking mode defined for this device. You may need to edit the file stm8.c");

		unsigned char *buf=malloc(bytes_to_write);
		if(!buf) spawn_error("malloc failed");

		if (part->read_out_protection_mode==ROP_STM8S_STD) {
			for (int i=0; i<bytes_to_write;i++) {
				buf[i]=0;
				if ((i>0)&&((i&1)==0)) buf[i]=0xff;
			}
		}

		/* flashing MCU */
		int sent = pgm->write_range(pgm, part, buf, start, bytes_to_write, memtype);
		if(pgm->reset) {
			// Restarting core (if applicable)
			pgm->reset(pgm);
		}
		fprintf(stderr, "Unlocked device. Option bytes reset to default state.\n");
		fprintf(stderr, "Bytes written: %d\n", sent);
	}
	return(0);
}
Beispiel #27
0
/*****************************************************************************
 * process_keytrigger()
 *
 * Process voice/patch/param updates for keytrigger events.  This function
 * contains most of the logic for activating voices, and should be broken up
 * into its logical components.
 *****************************************************************************/
void
process_keytrigger(MIDI_EVENT   *UNUSED(event),
                   VOICE        *old_voice,
                   VOICE        *voice,
                   unsigned int part_num)
{
	VOICE           *loop_voice;
	PART            *part           = get_part(part_num);
	PATCH_STATE     *state          = get_active_state(part_num);
	int             osc;
	int             lfo;
	int             voice_num;
	int             staccato        = 1;
	int             env_trigger     = 0;
	sample_t        tmp;


	PHASEX_DEBUG(DEBUG_CLASS_MIDI_NOTE,
	             "voice %2d:  process_keytrigger():  old_voice=%2d  voice=%2d\n",
	             (voice->id + 1),
	             (old_voice == NULL ? 0 : (old_voice->id + 1)),
	             (voice->id + 1));

	/* check for notes currently in play */
	switch (state->keymode) {
	case KEYMODE_MONO_RETRIGGER:
		env_trigger = 1;
		/* intentional fall-through */
	case KEYMODE_MONO_UNISON_4:
	case KEYMODE_MONO_UNISON_6:
	case KEYMODE_MONO_UNISON_8:
	case KEYMODE_MONO_MULTIKEY:
	case KEYMODE_MONO_SMOOTH:
		if (voice->cur_amp_interval >= ENV_INTERVAL_RELEASE) {
			staccato = 1;
			env_trigger = 1;
		}
		else {
			staccato = 0;
		}
		break;
	case KEYMODE_POLY:
		staccato = 1;
		for (voice_num = 0; voice_num < setting_polyphony; voice_num++) {
			loop_voice = get_voice(part_num, voice_num);
			if (loop_voice->cur_amp_interval < ENV_INTERVAL_RELEASE) {
				staccato = 0;
				break;
			}
		}
		env_trigger = 1;
		break;
	}

	/* staccato, mono retrig, and poly get new envelopes and initphases */
	if (env_trigger) {

		/* start new amp and filter envelopes */
		voice->cur_amp_interval    = ENV_INTERVAL_ATTACK;
		voice->cur_filter_interval = ENV_INTERVAL_ATTACK;

		voice->cur_amp_sample    = voice->amp_env_dur[ENV_INTERVAL_ATTACK] =
			env_interval_dur[ENV_INTERVAL_ATTACK][state->amp_attack];
		voice->cur_filter_sample = voice->filter_env_dur[ENV_INTERVAL_ATTACK] =
			env_interval_dur[ENV_INTERVAL_ATTACK][state->filter_attack];

		/* TODO: test with hold pedal.                                */
		/* without hold pedal:                                        */
		/* voice->amp_env_delta[ENV_INTERVAL_ATTACK]    =             */
		/*      (1.0 - voice->amp_env_raw) /                          */
		/*      (sample_t)voice->amp_env_dur[ENV_INTERVAL_ATTACK];    */
		/* voice->filter_env_delta[ENV_INTERVAL_ATTACK] =             */
		/*      (1.0 - voice->filter_env_raw) /                       */
		/*      (sample_t)voice->filter_env_dur[ENV_INTERVAL_ATTACK]; */
		/* with hold pedal:  everything until next comment.           */
		voice->amp_env_raw = 0.0;
		voice->filter_env_raw = 0.0;

		if (state->amp_attack || state->amp_decay) {
			voice->amp_env_delta[ENV_INTERVAL_ATTACK]    =
				(1.0 - voice->amp_env_raw) /
				(sample_t) voice->amp_env_dur[ENV_INTERVAL_ATTACK];
		}
		else {
			voice->amp_env_delta[ENV_INTERVAL_ATTACK]    =
				(state->amp_sustain - voice->amp_env_raw) /
				(sample_t) voice->amp_env_dur[ENV_INTERVAL_ATTACK];
		}
		if (state->filter_attack || state->filter_decay) {
			voice->filter_env_delta[ENV_INTERVAL_ATTACK] =
				(1.0 - voice->filter_env_raw) /
				(sample_t) voice->filter_env_dur[ENV_INTERVAL_ATTACK];
		}
		else {
			voice->filter_env_delta[ENV_INTERVAL_ATTACK] =
				(state->filter_sustain - voice->filter_env_raw) /
				(sample_t) voice->filter_env_dur[ENV_INTERVAL_ATTACK];
		}
		/* end of hold pedal code changes */

		/* everything except mono multikey gets new init phases. */
		if (state->keymode != KEYMODE_MONO_MULTIKEY) {
			/* init phase for keytrig oscs */
			for (osc = 0; osc < NUM_OSCS; osc++) {
				/* init phase (unshifted by lfo) at note start */
				if ((state->osc_freq_base[osc] == FREQ_BASE_TEMPO_KEYTRIG) ||
				    (state->osc_freq_base[osc] == FREQ_BASE_MIDI_KEY)) {
					voice->index[osc] = part->osc_init_index[osc];
				}
			}
		}

		/* init phase for keytrig lfos if needed */
		/* TODO:  determine if including env retrigger is appropriate here */
		//if ((staccato) || (env_trigger)) {
		if (staccato) {
			for (lfo = 0; lfo < NUM_LFOS; lfo++) {
				switch (state->lfo_freq_base[lfo]) {
				case FREQ_BASE_MIDI_KEY:
				case FREQ_BASE_TEMPO_KEYTRIG:
					part->lfo_index[lfo] = part->lfo_init_index[lfo];
					/* intentional fallthrough */
				case FREQ_BASE_TEMPO:
					part->lfo_adjust[lfo] = part->lfo_freq[lfo] * wave_period;
					break;
				}
			}
		}
	}

	/* Both high key and low key are set to the last key and adjusted later
	   if necessary */
	part->high_key = part->low_key = part->last_key;

	/* set highest and lowest keys in play for things that need
	   keyfollow */
	part->cur = part->head;
	while (part->cur != NULL) {
		if (part->cur->midi_key < part->low_key) {
			part->low_key = part->cur->midi_key;
		}
		if (part->cur->midi_key > part->high_key) {
			part->high_key = part->cur->midi_key;
		}
		part->cur = part->cur->next;
	}

	/* volume keyfollow is set by last key for poly */
	if (state->keymode == KEYMODE_POLY) {
		voice->vol_key = part->last_key;
	}
	/* volume keyfollow is set by high key for mono */
	else {
		voice->vol_key = part->high_key;
	}

	/* set filter keyfollow key based on keyfollow mode */
	switch (state->filter_keyfollow) {
	case KEYFOLLOW_LAST:
		tmp = (sample_t)(part->last_key + state->transpose - 64);
		for (voice_num = 0; voice_num < setting_polyphony; voice_num++) {
			loop_voice = get_voice(part_num, voice_num);
			loop_voice->filter_key_adj = tmp;
		}
		break;
	case KEYFOLLOW_HIGH:
		tmp = (sample_t)(part->high_key + state->transpose - 64);
		for (voice_num = 0; voice_num < setting_polyphony; voice_num++) {
			loop_voice = get_voice(part_num, voice_num);
			loop_voice->filter_key_adj = tmp;
		}
		break;
	case KEYFOLLOW_LOW:
		tmp = (sample_t)(part->low_key + state->transpose - 64);
		for (voice_num = 0; voice_num < setting_polyphony; voice_num++) {
			loop_voice = get_voice(part_num, voice_num);
			loop_voice->filter_key_adj = tmp;
		}
		break;
	case KEYFOLLOW_MIDI:
		voice->filter_key_adj = (sample_t)(part->last_key + state->transpose - 64);
		break;
	case KEYFOLLOW_NONE:
		voice->filter_key_adj = 0.0;
		break;
	}

	/* start at beginning of list of keys in play */
	part->cur = part->head;

	/* Keytrigger volume only applicable to midi key based oscs portamento
	   applicable to midi key based oscs _and_ lfos. */

	/* handle per-osc portamento for the different keymodes */
	for (osc = 0; osc < NUM_OSCS; osc++) {

		/* portamento for midi key based main osc */
		if (state->osc_freq_base[osc] == FREQ_BASE_MIDI_KEY) {

			/* decide which key in play to assign to this oscillator */
			switch (state->keymode) {
			case KEYMODE_MONO_MULTIKEY:
				/* use notes in order in oscillators */
				if (part->cur != NULL) {
					voice->osc_key[osc] = part->cur->midi_key;
					if (part->cur->next != NULL) {
						part->cur = part->cur->next;
					}
					else {
						part->cur = part->head;
					}
				}
				else {
					voice->osc_key[osc] = part->last_key;
				}
				break;
			case KEYMODE_MONO_UNISON_4:
			case KEYMODE_MONO_UNISON_6:
			case KEYMODE_MONO_UNISON_8:
			case KEYMODE_MONO_SMOOTH:
			case KEYMODE_MONO_RETRIGGER:
				/* default mono -- use key just pressed */
				voice->osc_key[osc] = part->last_key;
				break;
			case KEYMODE_POLY:
				/* use midi key assigned to voice */
				voice->osc_key[osc] = voice->midi_key;
				break;
			}

			/* Set oscillator frequencies based on midi note, global transpose
			   value, and optional portamento.  state->osc_transpose[osc] is
			   taken into account every sample in the engine. */
			if ((state->portamento > 0)) {
				/* Portamento always starts from previous key hit, no matter
				   which voice.  Mono multikey always uses same voice. */
				if (state->keymode != KEYMODE_MONO_MULTIKEY) {
					if (part->prev_key == -1) {
						voice->osc_freq[osc] =
							freq_table[state->patch_tune_cc]
							[256 + part->last_key + state->transpose +
							 state->osc_transpose_cc[osc] - 64];
					}
					else {
						voice->osc_freq[osc] =
							freq_table[state->patch_tune_cc]
							[256 + part->prev_key + state->transpose +
							 state->osc_transpose_cc[osc] - 64];
					}
				}
				/* Portamento slide calculation works the same for all
				   keymodes.  Start portamento now that frequency adjustment
				   is known. */
				if ((old_voice == NULL) || (old_voice == voice)) {
					voice->osc_portamento[osc] = 4.0 *
						(freq_table[state->patch_tune_cc]
						 [256 + voice->osc_key[osc] + state->transpose +
						  state->osc_transpose_cc[osc] - 64]
						 - voice->osc_freq[osc]) /
						(sample_t)(voice->portamento_samples - 1);
					part->portamento_sample  = part->portamento_samples;
					voice->portamento_sample = voice->portamento_samples;
				}
				else {
					voice->osc_portamento[osc] = 4.0 *
						(freq_table[state->patch_tune_cc]
						 [256 + voice->osc_key[osc] + state->transpose +
						  state->osc_transpose_cc[osc] - 64]
						 - old_voice->osc_freq[osc]) /
						(sample_t)(voice->portamento_samples - 1);
					part->portamento_sample  = part->portamento_samples;
					voice->portamento_sample = voice->portamento_samples;
					/* Mono modes set portamento on voice just finishing to
					   match new voice. */
					if ((state->keymode == KEYMODE_MONO_SMOOTH) ||
					    (state->keymode == KEYMODE_MONO_RETRIGGER) ||
					    (state->keymode == KEYMODE_MONO_UNISON_4) ||
					    (state->keymode == KEYMODE_MONO_UNISON_6) ||
					    (state->keymode == KEYMODE_MONO_UNISON_8)) {
						old_voice->osc_portamento[osc] =
							voice->osc_portamento[osc];
						old_voice->portamento_sample   =
							voice->portamento_sample;
						old_voice->portamento_samples  =
							voice->portamento_samples;
					}
				}
			}

			/* If portamento is not needed, set the oscillator frequency
			   directly. */
			else {
				voice->osc_freq[osc] = freq_table[state->patch_tune_cc]
					[256 + voice->osc_key[osc] +
					 state->transpose + state->osc_transpose_cc[osc] - 64];
				voice->osc_portamento[osc] = 0.0;
				voice->portamento_sample   = 0;
				voice->portamento_samples  = 0;
			}
		}
	}

	/* portamento for midi key based lfo */
	for (lfo = 0; lfo < NUM_LFOS; lfo++) {

		if (state->lfo_freq_base[lfo] == FREQ_BASE_MIDI_KEY) {

			/* decide which key in play to assign to this lfo */
			switch (state->keymode) {
			case KEYMODE_MONO_MULTIKEY:
				/* use notes in order in lfos */
				if (part->cur != NULL) {
					part->lfo_key[lfo] = part->cur->midi_key;
					if (part->cur->next != NULL) {
						part->cur = part->cur->next;
					}
					else {
						part->cur = part->head;
					}
				}
				else {
					part->lfo_key[lfo] = part->last_key;
				}
				break;
			case KEYMODE_MONO_SMOOTH:
			case KEYMODE_MONO_RETRIGGER:
			case KEYMODE_MONO_UNISON_4:
			case KEYMODE_MONO_UNISON_6:
			case KEYMODE_MONO_UNISON_8:
				/* default mono -- use key just pressed */
				part->lfo_key[lfo] = part->last_key;
				break;
			case KEYMODE_POLY:
				/* use midi key assigned to allocated voice */
				part->lfo_key[lfo] = voice->midi_key;
				break;
			}

			/* Set lfo portamento frequencies based on
			   midi note and transpose value. */
			if ((state->portamento > 0) && (part->portamento_samples > 0)) {
				part->lfo_portamento[lfo] =
					(freq_table[state->patch_tune_cc]
					 [256 + part->lfo_key[lfo]] - part->lfo_freq[lfo]) /
					(sample_t) part->portamento_samples;
			}

			/* If portamento is not needed, set the lfo frequency directly. */
			else {
				part->lfo_portamento[lfo] = 0.0;
				part->lfo_freq[lfo] = freq_table[state->patch_tune_cc][256 + part->lfo_key[lfo]];
			}

		}
	}
	/* allocate voice (engine actually activates allocated voices) */
	voice->allocated = 1;
}
Beispiel #28
0
/*****************************************************************************
 * process_note_on()
 *
 * Process a note on event for a single part.  Add the note to the current
 * part's keylist and select a voice, stealing one if necessary.  All note on
 * events are processed with process_keytrigger() unless the velocity is set
 * to zero, and process_note_off() is used instead.
 *****************************************************************************/
void
process_note_on(MIDI_EVENT *event, unsigned int part_num)
{
	VOICE           *voice;
	VOICE           *old_voice     = NULL;
	VOICE           *loop_voice;
	PART            *part          = get_part(part_num);
	PATCH_STATE     *state         = get_active_state(part_num);
	int             voice_num;
	int             oldest_age;
	int             free_voice;
	int             steal_voice;
	int             same_key;
	int				osc;
	int				voice_count = 0;

	/* if this is velocity 0 style note off, fall through */
	if (event->velocity > 0) {

		/* keep track of previous to last key pressed! */
		part->prev_key = part->midi_key;
		part->midi_key = event->note;
		part->last_key = event->note;

		/* allocate voice for the different keymodes */
		switch (state->keymode) {
		case KEYMODE_MONO_SMOOTH:
			old_voice = get_voice(part_num, vnum[part_num]);
			old_voice->keypressed = -1;
			/* allocate new voice for staccato in mid-release only. */
			if (old_voice->allocated &&
			    ((old_voice->cur_amp_interval == ENV_INTERVAL_RELEASE) ||
			     (old_voice->cur_amp_interval == ENV_INTERVAL_FADE))) {
				old_voice->keypressed = -1;
				old_voice->cur_amp_interval = ENV_INTERVAL_RELEASE;
				old_voice->cur_amp_sample = -1;
				PHASEX_DEBUG(DEBUG_CLASS_MIDI_NOTE,
				             "voice %2d:  ^^^^^^^  Mono-Smooth:  "
				             "Fading out voice.  (Note On)  ^^^^^^^\n",
				             (old_voice->id + 1));
				vnum[part_num] = (vnum[part_num] + 1) % setting_polyphony;
			}
			break;
		case KEYMODE_MONO_UNISON_4:
			voice_count = 4;
			vnum[part_num] = 0;
			break;
		case KEYMODE_MONO_UNISON_6:
			voice_count = 6;
			vnum[part_num] = 0;
			break;
		case KEYMODE_MONO_UNISON_8:
			voice_count = 8;
			vnum[part_num] = 0;
			break;
		case KEYMODE_MONO_MULTIKEY:
			vnum[part_num] = 0;
			break;
		case KEYMODE_MONO_RETRIGGER:
			for (voice_num = 0; voice_num < setting_polyphony; voice_num++) {
				loop_voice = get_voice(part_num, voice_num);
				if (loop_voice->allocated) {
					loop_voice->keypressed = -1;
					loop_voice->cur_amp_interval = ENV_INTERVAL_RELEASE;
					loop_voice->cur_amp_sample = -1;
					old_voice = loop_voice;
					PHASEX_DEBUG(DEBUG_CLASS_MIDI_NOTE,
					             "voice %2d:  ^^^^^^^  Mono-Retrigger:  "
					             "Fading out voice.  (Note On)  ^^^^^^^\n",
					             (loop_voice->id + 1));
				}
			}
			vnum[part_num] = (vnum[part_num] + setting_polyphony - 1) % setting_polyphony;
			break;
		case KEYMODE_POLY:
			vnum[part_num] = 0;

			/* voice allocation with note stealing */
			oldest_age          = 0;
			free_voice          = -1;
			steal_voice         = setting_polyphony - 1;
			same_key            = -1;

			/* look through all the voices */
			for (voice_num = 0; voice_num < setting_polyphony; voice_num++) {
				loop_voice = get_voice(part_num, voice_num);

				/* priority 1: a free voice */
				if (loop_voice->allocated == 0) {
					free_voice = voice_num;
					vnum[part_num] = free_voice;
					voice_num = setting_polyphony;
					break;
				}
				else {
					if (loop_voice->midi_key == part->midi_key) {
						PHASEX_DEBUG(DEBUG_CLASS_MIDI_TIMING,
						             DEBUG_COLOR_RED "+++++++++++ "
						             DEBUG_COLOR_DEFAULT);
					}

					/* priority 2: find the absolute oldest in play */
					if ((same_key == -1) && (loop_voice->age > oldest_age)) {
						oldest_age = loop_voice->age;
						steal_voice = voice_num;
					}
				}
			}

			/* priorities 1 and 2 */
			if (free_voice >= 0) {
				vnum[part_num] = free_voice;
			}
			else {
				vnum[part_num] = steal_voice;
				PHASEX_DEBUG(DEBUG_CLASS_MIDI_NOTE,
				             "*** Part %d:  stealing voice %d!\n",
				             (part_num + 1), vnum[part_num]);
				PHASEX_DEBUG(DEBUG_CLASS_MIDI_TIMING,
				             DEBUG_COLOR_YELLOW "+++++++++++ "
				             DEBUG_COLOR_DEFAULT);
			}

			break;
		}

		/* keep pointer to current voice around */
		voice = get_voice(part_num, vnum[part_num]);
		/* assign midi note */
		voice->midi_key   = part->midi_key;
		voice->keypressed = part->midi_key;
		/* keep velocity for this note event */
		voice->velocity               = event->velocity;
		voice->velocity_target_linear = voice->velocity_coef_linear =
			part->velocity_target = part->velocity_coef = ((sample_t) event->velocity) * 0.01;
		voice->velocity_target_log    = voice->velocity_coef_log =
			velocity_gain_table[state->amp_velocity_cc][event->velocity];

		for (voice_num = 1; voice_num < voice_count; voice_num++) {
			if ( vnum[part_num] == voice_num ) continue;
			loop_voice = get_voice(part_num, voice_num);
			/* assign midi note */
			loop_voice->midi_key   = part->midi_key;
			loop_voice->keypressed = part->midi_key;
			/* keep velocity for this note event */
			loop_voice->velocity               = event->velocity;
			loop_voice->velocity_target_linear = loop_voice->velocity_coef_linear =
				part->velocity_target = part->velocity_coef = ((sample_t) event->velocity) * 0.01;
			loop_voice->velocity_target_log    = loop_voice->velocity_coef_log =
				velocity_gain_table[state->amp_velocity_cc][event->velocity];
		}

		if (event->velocity > 0) {
			part->velocity = event->velocity;
			PHASEX_DEBUG(DEBUG_CLASS_MIDI_NOTE,
			             "voice %2d:  Event Note On:   part=%d  "
			             "voice=%2d  note=%3d  velocity=%3d  keylist=:",
			             (vnum[part_num] + 1),
			             (part_num + 1),
			             (vnum[part_num] + 1),
			             event->note,
			             event->velocity);
			PHASEX_DEBUG(DEBUG_CLASS_MIDI_TIMING,
			             DEBUG_COLOR_RED "!!!!!!! %d !!!!!!! "
			             DEBUG_COLOR_DEFAULT,
			             event->note);
		}

		/* staccato, or no previous notes in play */
		if ((part->prev_key == -1) || (part->head == NULL)) {
			old_voice = NULL;

			/* put this key at the start of the list */
			part->head = & (part->keylist[part->midi_key]);
			part->head->next = NULL;
		}

		/* legato, or previous notes still in play */
		else {
			/* Link this key to the end of the list,
			   unlinking from the middle if necessary. */
			part->cur = part->head;
			part->prev = NULL;
			while (part->cur != NULL) {
				PHASEX_DEBUG(DEBUG_CLASS_MIDI_NOTE, "%d:", part->cur->midi_key);
				if (part->cur == &part->keylist[part->midi_key]) {
					if (part->prev != NULL) {
						part->prev->next = part->cur->next;
					}
				}
				part->prev = part->cur;
				part->cur = part->cur->next;
			}
			//PHASEX_DEBUG (DEBUG_CLASS_MIDI_NOTE, "\n");
			part->cur = & (part->keylist[part->midi_key]);

			/* if there is no end of the list, link it to the head */
			if (part->prev == NULL) {
				part->head = part->cur;
				PHASEX_WARN("*** process_note_on(): [part%d] found "
				            "previous key in play with no keylist!\n",
				            (part_num + 1));
			}
			else {
				part->prev->next = part->cur;
			}
			part->cur->next = NULL;
		}

		if (event->velocity > 0) {
			PHASEX_DEBUG(DEBUG_CLASS_MIDI_NOTE, "\n");
		}

		/* process parameters dependent on keytrigger events */
		process_keytrigger(event, old_voice, voice, part_num);
		for (voice_num = 0; voice_num < voice_count; voice_num++) {
			if ( vnum[part_num] == voice_num ) continue;
			loop_voice = get_voice(part_num, voice_num);
			process_keytrigger(event, old_voice, loop_voice, part_num);
		}
	}

	/* velocity 0 style note off */
	else {
		process_note_off(event, part_num);
	}
}