ReverbEdit.c++ 11.1 KB

/*******************************************************************************
 *  File:  ReverbEdit.c
 *
 *  Impliments the gui for the reverb editor portion of midiDmon.
 *
 ******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <Xm/Xm.h>
#include <Xm/Label.h>
#include <Xm/ToggleB.h>
#include <Xm/RowColumn.h>
#include <Xm/Separator.h>
#include <Xm/Form.h>
#include <Xm/Scale.h>
#include <Xm/MainW.h>

#include "Editor.h"
#include "EditMgr.h"
#include "Mgrs.h"


static char  noFXStr[] = "Sorry, no effects were specified in the config file";

static char* paramNames[] = { "input", 
                          "output", 
                          "fbcoef", 
                          "ffcoef", 
                          "gain", 
                          "chorus rate", 
                          "chorus depth",
                          "lpfilt" };

#define INPUT_PARAM      0
#define OUPUT_PARAM      1
#define FBCOEF_PARAM     2
#define FFCOEF_PARAM     3
#define GAIN_PARAM       4
#define C_RATE_PARAM     5
#define C_DEPTH_PARAM    6
#define LPFILT_PARAM     7

/* Callbacks */
static void param_section_cb(Widget w, XtPointer client_data, XmAnyCallbackStruct *call_data);
static void param_value_cb(Widget w, XtPointer client_data, XmScaleCallbackStruct *call_data);
static void destroy_editor_cb(Widget w, XtPointer client_data, XmAnyCallbackStruct *call_data);
static void destroy_item_cb(Widget w, XtPointer client_data, XmAnyCallbackStruct *call_data);

/******************************************************************************
 *
 *    Init the Reverb Editor's gui. 
 *      1) create the shell widget
 *      2) create the row column widget for selecting the primatives
 *      3) add the toggle buttons for the primatives
 *      4) create the separator widget
 *      5) create the row column widget for the scale widgets
 *      6) create the scale widgets with their labels
 *
 ******************************************************************************/

ReverbEditor::ReverbEditor(void *theEdMgr, Display *display)
{
    Widget     theForm, sep1Widg;
    Widget     butRowCol, tog;
    Widget     scaleRowCol;
    Widget     label[NUM_FX_PARAMS];
    int        i,n;
    int        paramID;
    Arg        args[8];
    XmString   xms;
    AEItemRef  *itemRef;
    char       numStr[6];
    s32        paramVal,delaySize;

    reverbAsset = theAssetMgr->GetReverb();
 
    shellWidget = XtVaAppCreateShell("ReverbEditor", "XReverbEditor",
                                           topLevelShellWidgetClass, display, NULL); 

    XtAddCallback(shellWidget, XmNdestroyCallback, destroy_editor_cb, (XtPointer)theEdMgr);

    if(reverbAsset &&  reverbAsset->GetParam(0, &numFxSets))
    {
	curParamSet = 0;
	
	theForm = XtVaCreateManagedWidget("ReverbForm", xmFormWidgetClass, shellWidget, NULL);

	butRowCol = XtVaCreateManagedWidget("OneOfMany", xmRowColumnWidgetClass, theForm,
                                     XmNorientation,    XmVERTICAL,
                                     XmNradioBehavior, TRUE,
                                     XmNradioAlwaysOne, TRUE,
                                     XmNleftAttachment, XmATTACH_FORM,
                                     XmNtopAttachment, XmATTACH_FORM,
                                     XmNbottomAttachment, XmATTACH_FORM,
                                     NULL); 

	/* Add the ToggleButton widgets */
	for(i = 0; i < numFxSets; i++)
	{
	    sprintf(numStr,"%d",i);
	    xms = XmStringCreateLtoR(numStr, XmSTRING_DEFAULT_CHARSET);
	    if(i == 0)
		tog = XtVaCreateManagedWidget("TButton", xmToggleButtonWidgetClass, butRowCol,
                                         XmNset, TRUE,
                                         XmNlabelString,   xms,
                                         NULL);
	    else
		tog = XtVaCreateManagedWidget("TButton", xmToggleButtonWidgetClass, butRowCol,
                                         XmNlabelString,   xms,
                                         NULL);
	    itemRef = (AEItemRef*)malloc(sizeof(AEItemRef));
	    itemRef->item = i;
	    itemRef->editor = this;
	    XtAddCallback(tog, XmNvalueChangedCallback, param_section_cb, (XtPointer)itemRef);
	    XtAddCallback(tog, XmNdestroyCallback, destroy_item_cb, (XtPointer)itemRef);
	    XmStringFree(xms);
	}
    
	sep1Widg = XtVaCreateManagedWidget("Separator", xmSeparatorWidgetClass, theForm,
                                      XmNorientation, XmVERTICAL,
                                      XmNleftAttachment, XmATTACH_WIDGET,
                                      XmNleftWidget, butRowCol,
                                      XmNtopAttachment, XmATTACH_FORM,
                                      XmNbottomAttachment, XmATTACH_FORM,
                                      NULL);

	scaleRowCol = XtVaCreateManagedWidget("ScaleRowCol", xmRowColumnWidgetClass, theForm,
                                     XmNorientation,    XmVERTICAL,
                                     XmNleftAttachment, XmATTACH_WIDGET,
                                     XmNleftWidget, sep1Widg,                        
                                     XmNtopAttachment, XmATTACH_FORM,
                                     XmNbottomAttachment, XmATTACH_FORM,
                                     XmNrightAttachment, XmATTACH_FORM,
                                     NULL); 

	/* Add the scale widgets */
	if(!reverbAsset->GetParam(1, &delaySize))
	    delaySize = 44100; /* pick a default of one second at 44100 */
	paramID = (curParamSet * NUM_FX_PARAMS) + FX_PARAM_OFFSET;
	for(i = 0; i < NUM_FX_PARAMS; i++, paramID++)
	{
	    if(!reverbAsset->GetParam(paramID,&paramVal))
	       paramVal = 0;

	    xms = XmStringCreateLtoR(paramNames[i], XmSTRING_DEFAULT_CHARSET);
	    label[i] = XtVaCreateManagedWidget("Label", xmLabelWidgetClass, scaleRowCol,
					 XmNlabelString,   xms,
                                         NULL);
	    XmStringFree(xms);

	    n = 0;
	    XtSetArg(args[n], XmNwidth, 500);                  n++;
	    XtSetArg(args[n], XmNorientation, XmHORIZONTAL);   n++;
	    XtSetArg(args[n], XmNborderWidth, 1);              n++;
	    XtSetArg(args[n], XmNshowValue, TRUE);             n++;
	    XtSetArg(args[n], XmNvalue, paramVal);             n++;

	    switch(i)
	    {
		case INPUT_PARAM:
		    XtSetArg(args[n], XmNminimum, 0);          n++;
		    XtSetArg(args[n], XmNmaximum, delaySize);  n++;
		    XtSetArg(args[n], XmNdecimalPoints, 0);    n++;
		    break;
		case OUPUT_PARAM:
		    XtSetArg(args[n], XmNminimum, 0);          n++;
		    XtSetArg(args[n], XmNmaximum, delaySize);  n++;
		    XtSetArg(args[n], XmNdecimalPoints, 0);    n++;
		    break;
		case FBCOEF_PARAM:
		    XtSetArg(args[n], XmNminimum, -32768);     n++;
		    XtSetArg(args[n], XmNmaximum, 32767);      n++;
		    XtSetArg(args[n], XmNdecimalPoints, 0);    n++;
		    break;
		case FFCOEF_PARAM:
		    XtSetArg(args[n], XmNminimum, -32768);     n++;
		    XtSetArg(args[n], XmNmaximum, 32767);      n++;
		    XtSetArg(args[n], XmNdecimalPoints, 0);    n++;
		    break;
		case GAIN_PARAM:
		    XtSetArg(args[n], XmNminimum, 0);          n++;
		    XtSetArg(args[n], XmNmaximum, 0x7fff);     n++;
		    XtSetArg(args[n], XmNdecimalPoints, 0);    n++;
		    break;
		case LPFILT_PARAM:
		    XtSetArg(args[n], XmNminimum, -32768);     n++;
		    XtSetArg(args[n], XmNmaximum, 32767);      n++;
		    XtSetArg(args[n], XmNdecimalPoints, 0);    n++;
		    break;
		case C_RATE_PARAM:
		    XtSetArg(args[n], XmNminimum, 0);          n++;
		    XtSetArg(args[n], XmNmaximum, 32767);      n++;
		    XtSetArg(args[n], XmNdecimalPoints, 0);    n++;
		    break;
		case C_DEPTH_PARAM:
		    XtSetArg(args[n], XmNminimum, 0);          n++;
		    XtSetArg(args[n], XmNmaximum, 32767);      n++;
		    XtSetArg(args[n], XmNdecimalPoints, 0);    n++;
		    break;
	    }
	    scale[i] = XtCreateManagedWidget("RScale", xmScaleWidgetClass, scaleRowCol,
					     args, n);
	    itemRef = (AEItemRef*)malloc(sizeof(AEItemRef));
	    itemRef->item = i;
	    itemRef->editor = this;
	    XtAddCallback(scale[i], XmNvalueChangedCallback, param_value_cb, (XtPointer)itemRef);
	    XtAddCallback(scale[i], XmNdragCallback, param_value_cb, (XtPointer)itemRef);
	    XtAddCallback(scale[i], XmNdestroyCallback, destroy_item_cb, (XtPointer)itemRef);
	}
    }  /* end if(reverbAsset &&  reverbAsset->GetParam(0, &numFxSets)) */
    else
    {
	xms = XmStringCreateLtoR(noFXStr, XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("Label", xmLabelWidgetClass, shellWidget,
					 XmNlabelString,   xms,
                                         NULL);
	XmStringFree(xms);
    }

    XtRealizeWidget(shellWidget);
}


/******************************************************************************
 *
 * param_set_cb. Called everytime a new section is selected.
 *
 *****************************************************************************/
static void param_section_cb(Widget w, XtPointer client_data, XmAnyCallbackStruct *call_data)
{
    AEItemRef     *ref = (AEItemRef*)client_data;
    ReverbEditor  *editor = (ReverbEditor*)ref->editor;
    AEReverb      *revAsset = editor->reverbAsset;
    int           selected = ref->item;
    int           i;
    int           paramID;
    s32           paramVal;

    if(editor->curParamSet != selected) /* if it is a new primative */
    {
        editor->curParamSet = selected;
        paramID = (selected * NUM_FX_PARAMS) + FX_PARAM_OFFSET;
        for(i = 0; i < NUM_FX_PARAMS; i++,paramID++)
	{
	    if(!revAsset->GetParam(paramID,&paramVal))
		paramVal = 0;
            XmScaleSetValue(editor->scale[i], paramVal);  /* change the scale widgets to */
                                                             /* reflect the new values */
	}
    }
}

#define INPUT_PARAM         0
#define OUTPUT_PARAM        1

static void param_value_cb(Widget w, XtPointer client_data, XmScaleCallbackStruct *call_data)
{
    AEItemRef     *ref = (AEItemRef*)client_data;
    ReverbEditor  *editor = (ReverbEditor*)ref->editor;
    AEReverb      *revAsset = editor->reverbAsset;
    int           paramID = ref->item;
    s32           otherPtr,otherParamID;

    paramID += (editor->curParamSet * NUM_FX_PARAMS) + FX_PARAM_OFFSET;
    if(ref->item == INPUT_PARAM)
    {
	otherParamID = (editor->curParamSet * NUM_FX_PARAMS) + FX_PARAM_OFFSET + OUTPUT_PARAM;
	revAsset->GetParam(otherParamID, &otherPtr);
	if(call_data->value == otherPtr)
	{
	    printf("Trying to set input to the output value\n");
	    return;
	}
    }
    else if(ref->item == OUTPUT_PARAM)
    {
	otherParamID = (editor->curParamSet * NUM_FX_PARAMS) + FX_PARAM_OFFSET + INPUT_PARAM;
	revAsset->GetParam(otherParamID, &otherPtr);
	if(call_data->value == otherPtr)
	{
	    printf("Trying to set output to the input value\n");
	    return;
	}
    }

    revAsset->SetParam(paramID, call_data->value);
    theU64Dev->UpdateFXParam(paramID, call_data->value);
}

static void destroy_editor_cb(Widget w, XtPointer client_data, XmAnyCallbackStruct *call_data)
{
    EditMgr *theEdMgr = (EditMgr*)client_data;

    theEdMgr->removeReverb();
}

static void destroy_item_cb(Widget w, XtPointer client_data, XmAnyCallbackStruct *call_data)
{
    free (client_data);
}