This is PatchParam.m in view mode; [Download] [Up]
/**************************************************
* SynthBuilder
* Copyright 1993 Nick Porcaro All Rights Reserved
**************************************************/
#define DEBUG_PRINT printf
/*
* PatchParam.m
* Nick Porcaro Summer 1993
*/
#import <stdlib.h>
#import <sys/param.h>
#import <dsp/dsp.h>
#import <strings.h>
#import <appkit/Application.h>
#import <appkit/View.h>
#import <appkit/Panel.h>
#import <appkit/PopUpList.h>
#import <appkit/Control.h>
#import <appkit/Slider.h>
#import <appkit/Matrix.h>
#import <appkit/TextField.h>
#import <musickit/Midi.h>
#import <musickit/Conductor.h>
#import <musickit/Envelope.h>
#import "PatchParam.h"
#import "FakeSynthPatch.h"
#import "FakeUG.h"
#import "EnvDelegate.h"
#import "EnvController.h"
#import "ParamInterface.h"
/* #import "EnvelopeGraphView.h" */
#import "Utilities.h"
extern char *getAppName();
@implementation PatchParam
static char ErrorMsg[1024];
+ initialize
/* Set the version. This can be used in a later version to distinguish older
* formats when unarchiving documents.
*/
{
[PatchParam setVersion:5];
return self;
}
- awakeFromNib
{
ugSelectorPop = [ugSelector target];
[inputInterface setMode:CONTROLS];
[ugSelectorPop setTarget:self];
[ugSelectorPop setAutoupdate:YES];
[ugSelectorPop changeButtonTitle:YES];
[ugSelectorPop setAction:@selector(selectFakeUG:)];
argSelectorPop = [argSelector target];
[argSelectorPop setTarget:self];
[argSelectorPop setAction:@selector(selectArg:)];
[argSelectorPop setAutoupdate:YES];
[argSelectorPop changeButtonTitle:YES];
clickCount = 0;
currNoteCount = 0;
return self;
}
- init
/* This reads in the nib file for dealing with a PatchParam
* Make sure you call setPatch after this or the mapper will not work
* So here's an example of how you create one of these objects
* (in this example self is a FakeUG):
*
* patchParam = [[PatchParam alloc] init];
* [patchParam setPatch:[self thePatch]];
* [patchParam setPatchParamName:name];
*/
{
[super init];
[self addNoteReceiver:[[NoteReceiver alloc] init]];
/* Create a new patch param inspector
* for the patchParam in this FakeUG.
* We load the nib section each time so
* we can get multiple patchParamInspector panels
*/
[NXApp loadNibSection:"PatchParam.nib" owner:self withNames:YES];
/* The correct values are set in the nib file fields to
* reflect the following:
*/
midiController = 0;
strcpy(midiControllerName,"Off");
midiCtrlScaleVal = 1.0;
minMidiCtrlScaleVal = 0.0;
maxMidiCtrlScaleVal = 2.0;
midiCtrlOffsetVal = 0.0;
minMidiCtrlOffsetVal = 0.0;
maxMidiCtrlOffsetVal = 127.0;
noteTypeToControl = MK_noteOn;
[offsetSlider setDoubleValue:midiCtrlOffsetVal];
[offsetSlider setMinValue:minMidiCtrlOffsetVal];
[offsetSlider setMaxValue:maxMidiCtrlOffsetVal];
[scaleSlider setDoubleValue:midiCtrlScaleVal];
[scaleSlider setMinValue:minMidiCtrlScaleVal];
[scaleSlider setMaxValue:maxMidiCtrlScaleVal];
mapEnvelope = nil;
envDelegate = nil;
theFakeUG = nil;
clickCount = 0;
[self syncMapEnvelope];
paramEnabled = YES;
useInspectorRect = NO;
inspectorRectJustLoaded = NO;
currNoteCount = 0;
thinEnabled = NO;
thinFactor = 1; // No thinning
return self;
}
- takeParamEnabled:sender
{
paramEnabled = ([sender intValue] ? YES : NO);
return self;
}
- takeThinFactor:sender
{
thinFactor = [sender intValue];
return self;
}
- takeThinEnable:sender
{
thinEnabled = ([sender intValue] ? YES : NO);
return self;
}
- free
/* Usually called by the FakeUG associated with this PatchParam */
{
if (envDelegate)
{
[envDelegate free];
envDelegate = nil;
}
if (mapEnvelope)
{
[mapEnvelope free];
mapEnvelope = nil;
}
return self;
}
- setPatchParamName: (char *) aName
{
if (! [[thePatch utilities] checkName:aName])
{
if (thePPName)
{
[thePPName setStringValue:theName];
}
return nil;
}
strcpy(theName, aName);
return self;
}
- (char *) getName;
{
return theName;
}
- setPatch:aPatch
{
thePatch = aPatch;
fakeUGs = [thePatch getFakeUGs];
return self;
}
- setViewFakeUG:aFakeUG
{
theViewFakeUG = aFakeUG;
return self;
}
- thePatch
{
return thePatch;
}
- setInspectorTitles
{
if (inspector)
{
[inspector setTitle:""];
[inspector setTitle:theName];
[thePPName setStringValue:theName];
}
return self;
}
- takeNameFrom:sender
{
if (![sender stringValue])
{
NXRunAlertPanel(getAppName(), "Invalid name", NULL, NULL, NULL);
return self;
}
[self setPatchParamName: (char *) [sender stringValue]];
[self setInspectorTitles];
return self;
}
- takeMidiCtrlFrom:sender
{
char *sys_str, *user_str;
int num;
if ([sender isKindOfClassNamed: "TextField"])
{
/* This came from the user. so be paranoid */
user_str = (char *) [sender stringValue];
sys_str = [paramInterface validControlName: user_str Number: &num];
if (sys_str)
{
midiController = num;
[sender setStringValue:sys_str]; /* Make the case correct */
strcpy(midiControllerName, sys_str);
}
else
{
NXRunAlertPanel(getAppName(), "Invalid controller", NULL, NULL, NULL);
}
}
else
{
/* a "trusted" source */
midiController = [sender intValue];
strcpy(midiControllerName, (char *)[midiCtrlField stringValue]);
}
midiControllerAsMKParm = [paramInterface MidiParamAsMK:midiController];
return self;
}
- takeScaleFrom:sender
{
midiCtrlScaleVal = [sender doubleValue];
[sender setDoubleValue:midiCtrlScaleVal];
[scaleSlider setDoubleValue:midiCtrlScaleVal];
[midiCtrlScale setDoubleValue:midiCtrlScaleVal];
if (midiCtrlScaleVal > maxMidiCtrlScaleVal)
{
maxMidiCtrlScaleVal = midiCtrlScaleVal;
[maxMidiCtrlScale setDoubleValue:maxMidiCtrlScaleVal];
[scaleSlider setMaxValue:maxMidiCtrlScaleVal];
}
else if (midiCtrlScaleVal < minMidiCtrlScaleVal)
{
minMidiCtrlScaleVal = midiCtrlScaleVal;
[minMidiCtrlScale setDoubleValue:minMidiCtrlScaleVal];
[scaleSlider setMinValue:minMidiCtrlScaleVal];
}
return self;
}
- takeMinScaleFrom:sender
{
minMidiCtrlScaleVal = [sender doubleValue];
if (midiCtrlScaleVal < minMidiCtrlScaleVal)
{
midiCtrlScaleVal = minMidiCtrlScaleVal;
[midiCtrlScale setDoubleValue:midiCtrlScaleVal];
[scaleSlider setDoubleValue:midiCtrlScaleVal];
}
[scaleSlider setMinValue:minMidiCtrlScaleVal];
[sender setDoubleValue:minMidiCtrlScaleVal];
return self;
}
- takeMaxScaleFrom:sender
{
maxMidiCtrlScaleVal = [sender doubleValue];
if (midiCtrlScaleVal > maxMidiCtrlScaleVal)
{
midiCtrlScaleVal = maxMidiCtrlScaleVal;
[midiCtrlScale setDoubleValue:midiCtrlScaleVal];
[scaleSlider setDoubleValue:midiCtrlScaleVal];
}
[scaleSlider setMaxValue:maxMidiCtrlScaleVal];
[sender setDoubleValue:maxMidiCtrlScaleVal];
return self;
}
- takeOffsetFrom:sender
{
midiCtrlOffsetVal = [sender doubleValue];
[sender setDoubleValue:midiCtrlOffsetVal];
[offsetSlider setDoubleValue:midiCtrlOffsetVal];
[midiCtrlOffset setDoubleValue:midiCtrlOffsetVal];
if (midiCtrlOffsetVal > maxMidiCtrlOffsetVal)
{
maxMidiCtrlOffsetVal = midiCtrlOffsetVal;
[maxMidiCtrlOffset setDoubleValue:maxMidiCtrlOffsetVal];
[offsetSlider setMaxValue:maxMidiCtrlOffsetVal];
}
else if (midiCtrlOffsetVal < minMidiCtrlOffsetVal)
{
minMidiCtrlOffsetVal = midiCtrlOffsetVal;
[minMidiCtrlOffset setDoubleValue:minMidiCtrlOffsetVal];
[offsetSlider setMinValue:minMidiCtrlOffsetVal];
}
return self;
}
- takeMinOffsetFrom:sender
{
minMidiCtrlOffsetVal = [sender doubleValue];
if (midiCtrlOffsetVal < minMidiCtrlOffsetVal)
{
midiCtrlOffsetVal = minMidiCtrlOffsetVal;
[midiCtrlOffset setDoubleValue:midiCtrlOffsetVal];
[offsetSlider setDoubleValue:midiCtrlOffsetVal];
}
[offsetSlider setMinValue:minMidiCtrlOffsetVal];
[sender setDoubleValue:minMidiCtrlOffsetVal];
return self;
}
- takeMaxOffsetFrom:sender
{
maxMidiCtrlOffsetVal = [sender doubleValue];
if (midiCtrlOffsetVal > maxMidiCtrlOffsetVal)
{
midiCtrlOffsetVal = maxMidiCtrlOffsetVal;
[midiCtrlOffset setDoubleValue:midiCtrlOffsetVal];
[offsetSlider setDoubleValue:midiCtrlOffsetVal];
}
[offsetSlider setMaxValue:maxMidiCtrlOffsetVal];
[sender setDoubleValue:maxMidiCtrlOffsetVal];
return self;
}
- takeMapEnableFrom:sender
{
if ([sender intValue])
{
mapEnabled = YES;
}
else
{
mapEnabled = NO;
}
return self;
}
- displayInspector
{
NXRect virginRect;
if ([thePatch hasControllableSoundMakers])
{
if (! inspector)
{
[NXApp loadNibSection:"PatchParam.nib" owner:self withNames:YES];
[inspector getFrame:&virginRect];
}
if (inspectorRectJustLoaded)
{
if (useInspectorRect)
{
[inspector placeWindowAndDisplay:&inspectorRect];
useInspectorRect = NO;
}
inspectorRectJustLoaded = NO;
}
else
{
inspectorRect = virginRect;
}
[self updateUgSelector];
[self updateArgSelector];
if (midiController)
{
[midiCtrlField setStringValue:midiControllerName];
}
[midiCtrlField setStringValue:midiControllerName];
[midiCtrlScale setDoubleValue:midiCtrlScaleVal];
[minMidiCtrlScale setDoubleValue:minMidiCtrlScaleVal];
[maxMidiCtrlScale setDoubleValue:maxMidiCtrlScaleVal];
[midiCtrlOffset setDoubleValue:midiCtrlOffsetVal];
[minMidiCtrlOffset setDoubleValue:minMidiCtrlOffsetVal];
[maxMidiCtrlOffset setDoubleValue:maxMidiCtrlOffsetVal];
[offsetSlider setDoubleValue:midiCtrlOffsetVal];
[offsetSlider setMaxValue:maxMidiCtrlOffsetVal];
[offsetSlider setMinValue:minMidiCtrlOffsetVal];
[scaleSlider setDoubleValue:midiCtrlScaleVal];
[scaleSlider setMaxValue:maxMidiCtrlScaleVal];
[scaleSlider setMinValue:minMidiCtrlScaleVal];
if (mapEnabled)
{
[enableSwitch setIntValue:1];
}
else
{
[enableSwitch setIntValue:0];
}
if (paramEnabled)
{
[paramEnabledSwitch setIntValue:1];
}
else
{
[paramEnabledSwitch setIntValue:0];
}
[thinField setIntValue:thinFactor];
if (thinEnabled)
{
[thinSwitch setIntValue:1];
}
else
{
[thinSwitch setIntValue:0];
}
[self setInspectorTitles];
/* This line adds the PatchParam panel to the WindowsMenu
* This happens automatically for FakePatchPoints and FakeUGs
* (maybe because they are separate Views?).
* When the user closes the PatchParam inspector, this
* item is automatically removed from the WindowsMenu
* (presumably by NXApp)
*/
[NXApp addWindowsItem: inspector title:[self getName] filename:NO];
/* doHighlight toggle prevents the instance
* from being highlighted twice
*/
doHighlight = NO;
[theViewFakeUG setDoHighlight:NO];
[inspector makeKeyAndOrderFront:self];
inspectorDisplayed = YES;
doHighlight = YES;
[theViewFakeUG setDoHighlight:YES];
}
else
{
NXRunAlertPanel(getAppName(), "This patch has no controllable unit generators",
NULL, NULL, NULL);
}
return self;
}
- selectFakeUG:sender
/* This sets the theFakeUG
* based on the selection from the ugSelectorPop
*/
{
char *name;
name = (char *) [ugSelectorPop selectedItem];
[self setFakeUG:name];
[self perform:@selector(updateUgSelector) with:nil afterDelay:0 cancelPrevious:NO];
[self perform:@selector(updateArgSelector) with:nil afterDelay:0 cancelPrevious:NO];
return self;
}
- selectArg:sender
/* This sets the theArg
* based on the selection from the argSelectorPop
*/
{
char *name;
name = (char *) [argSelectorPop selectedItem];
[self setArg:name];
return self;
}
- takeNoteType:sender
{
switch ([[sender selectedCell] tag])
{
case (0):
{
noteTypeToControl = MK_noteOn;
break;
}
case (1):
{
noteTypeToControl = MK_noteOff;
break;
}
case (2):
{
noteTypeToControl = MK_noteUpdate;
break;
}
default:
{
noteTypeToControl = MK_noteOn;
break;
}
}
return self;
}
- setFakeUG:(char *) name
/* This sets theFakeUG
*/
{
theFakeUG = [self getFakeUG:name];
return self;
}
- getFakeUG:(char *) name
/* This returns the id named FakeUG
* in the List fakeUGs
*/
{
int count, i;
char *old_name;
/* Yeah, I could do this with a Hash, but there
* are typically less than 20 FakeUGs in a patch
* so a cheezy linear search doesn't hurt us.
*/
count = [fakeUGs count];
for (i=0; i<count; i++)
{
old_name = [ [fakeUGs objectAt:i] getName];
if (old_name)
{
if (strcmp(old_name, name) == 0)
{
#ifdef DEBUG_PARAM
DEBUG_PRINT("found %s in list of existing fakeUGs\n", old_name);
#endif DEBUG_PARAM
return [fakeUGs objectAt:i];
break;
}
}
}
return nil;
}
- updateUgSelector
/*
* Update the list of available FakeUGs that
* can be controlled by the this parameter
*/
{
int count, i, availUG = -1;
char *name;
id aFakeUG;
count = [ugSelectorPop count];
for (i = count-1; i >= 0; i--)
{
[[ugSelectorPop removeItemAt:i] free];
}
fakeUGs = [thePatch getFakeUGs];
count = [fakeUGs count];
for (i=0; i<count; i++)
{
aFakeUG = [fakeUGs objectAt:i];
if ([aFakeUG isSoundMaker] && [aFakeUG getArgCount])
{
name = [[fakeUGs objectAt:i] getName];
availUG = i;
[ugSelectorPop addItem:name];
}
}
if (! theFakeUG && (availUG >= 0))
{
/* If we got this far, we are assured object 0 exists and
* is legit
*/
theFakeUG = [fakeUGs objectAt:availUG];
}
if (theFakeUG)
{
[ugSelector setTitle:[theFakeUG getName]];
}
else
{
/* Should never ever happen */
theFakeUG = nil;
[ugSelector setTitle:""];
}
return self;
}
- inspectorClosed
/* Called by the inspector's delegate */
{
inspectorDisplayed = NO;
return self;
}
- closeInspector
{
[inspector performClose:self];
if (envDelegate)
{
[envDelegate closeInspector];
}
return self;
}
- highlightSelf
{
if ( (![thePatch windowMiniaturized]) && doHighlight)
{
[theViewFakeUG highlightSelf];
}
return self;
}
- setArg:(char *) name
/* This sets theArg
*/
{
/* The theArg cannot be set unless the
* theFakeUG is set
*/
if (! theFakeUG)
{
NXRunAlertPanel(getAppName(), "Select UG to control first", NULL, NULL, NULL);
return self;
}
theArg = [self getIndexForArg:name FromFakeUG:theFakeUG];
if (theArg < 0)
{ /* snafu */
sprintf(ErrorMsg, "Unexpected theArg file: %s line: %d\n", __FILE__, __LINE__);
NXRunAlertPanel(getAppName(), ErrorMsg, NULL, NULL, NULL);
return self;
}
return self;
}
- (int) getIndexForArg:(char *) name FromFakeUG:aFakeUG
/* This returns the index of the arg named "name"
* in aFakeUG
*/
{
int i;
char *aName;
for (i=0; i<[aFakeUG getArgCount]; i++)
{
aName = [aFakeUG getArgName:i];
if (strcmp(aName, name) == 0)
{
#ifdef DEBUG_PARAM
DEBUG_PRINT("Found arg: %s (index %d)\n",
aName, i);
#endif DEBUG_PARAM
return i;
break;
}
}
return -1;
}
- updateArgSelector
/* Update the list of args for theFakeUG
*/
{
int count, i;
count = [argSelectorPop count];
for (i = count-1; i >= 0; i--)
{
[[argSelectorPop removeItemAt:i] free];
}
if (! theFakeUG)
{
return self;
}
for (i=0; i<[theFakeUG getArgCount]; i++)
{
[argSelectorPop addItem:[theFakeUG getArgName:i]];
}
[argSelector setTitle:[theFakeUG getArgName:theArg]];
return self;
}
- createDefaultMapEnvelope
{
static double x[150], y[150], s[150];
int i, npoints;
npoints = 0;
for (i=0; i<127; i++)
{
if ((i % 5) == 0)
{
x[npoints] = (double) i;
y[npoints] = (double) i;
s[npoints] = 1.0;
npoints++;
}
}
x[0] = 0;
y[0] = 0;
s[0] = 1.0;
x[npoints-1] = 127;
y[npoints-1] = 127;
s[npoints-1] = 1.0;
mapEnvelope = [[[Envelope alloc] init]
setPointCount: npoints
xArray: x
orSamplingPeriod: 1.0
yArray: y
smoothingArray: s
orDefaultSmoothing: 1.0
];
return self;
}
- syncMapEnvelope
{
if (! envDelegate)
{
envDelegate = [[EnvDelegate alloc] init];
}
[envDelegate setPatchParameter:self];
[envDelegate setFakeUG:nil ArgNum:-1];
return self;
}
- clearMapEnvelope
{
mapEnvelope = nil;
return self;
}
- setMapEnvelope:anEnv
{
mapEnvelope = anEnv;
return self;
}
- displayMapEnvelope:sender
{
id envController;
int val;
[self syncMapEnvelope];
if (mapEnvelope)
{
envController = [envDelegate envController];
[envController setNewEnvelope:mapEnvelope];
[envController reScaleLimits:self];
[envController makeGraphType:0];
}
else
{
val = NXRunAlertPanel(getAppName(),
"No lookup table defined. Create default lookup table?",
"YES", /* default */
"NO", /* alt */
"Cancel"); /* other */
switch (val)
{
case(NX_ALERTDEFAULT):
{
[self createDefaultMapEnvelope];
envController = [envDelegate envController];
[envController setNewEnvelope:mapEnvelope];
[envController reScaleLimits:self];
[envController makeGraphType:0];
[envController reScaleLimits:self];
break;
}
case(NX_ALERTALTERNATE):
{
break;
}
default:
{
return self;
}
}
}
sprintf(ErrorMsg, "%s - lookup table", theName);
[envDelegate displayWindow:ErrorMsg];
return self;
}
- setParamValue:(double) ctrl_val
/* Send the float value to our controlled arg(s) */
{
static char value[512];
/* May have caused delays [Conductor lockPerformance]; */
sprintf(value, "%f", ctrl_val);
#ifdef DEBUG_PARAM
DEBUG_PRINT("setParamValue %s sending %s to fakeUG: %s arg %s (index=%d)\n",
theName, value, [theFakeUG getName],
[theFakeUG getArgName:theArg], theArg);
#endif DEBUG_PARAM
[theFakeUG setArgWithIndex: theArg To:value];
if ([thePatch allowPPInspectorUpdate] || [thePatch alwaysUpdate])
{
[theFakeUG displayArg: theArg];
[thePatch setAllowPPInspectorUpdate:NO];
}
/* May have caused delays [Conductor unlockPerformance]; */
return self;
}
- (double) applyMap:(double) val
{
double newVal;
if ( (mapEnvelope) && (mapEnabled) )
{
newVal = [mapEnvelope lookupYForX:val];
}
else if ( ! (mapEnvelope) && (mapEnabled) )
{
newVal = 0.0;
}
else
{
newVal = val;
}
return newVal;
}
// #define DEBUG_PARAM 0
- realizeNote:aNote fromNoteReceiver:aNR
{
double controlVal;
double fval;
double pbSensitivity;
double bend;
double pitchBend;
double frequency;
static double lastFreq = 0.0;
static double pitchbendSensitivity = 2.0;
/* Do we even send it ?*/
if ( !(([aNote noteType] == noteTypeToControl) &&
paramEnabled &&
[theFakeUG isArgEnabled:theArg]))
{
return self;
}
#ifdef DEBUG_PARAM
DEBUG_PRINT("- **** PatchParam/realizeNote Looking for midiController: %s (%d)\n",
[paramInterface getControlName:midiController], midiController);
#endif DEBUG_PARAM
/* Make sure the Note isn't being "thinned=out" */
if (thinEnabled)
{
currNoteCount++;
if ((currNoteCount % thinFactor) != 0)
{
return self;
}
else
{
currNoteCount = 0;
}
}
// printf ("**** Processing note: %d\n", [aNote noteType]);
/* Deal with some common MusicKit parameters */
if (midiControllerAsMKParm == MK_freq)
{
/* Convert the keyNum to freq */
if (MKIsNoteParPresent(aNote, MK_keyNum))
{
frequency = MKKeyNumToFreq([aNote keyNum]);
[aNote setPar:MK_freq toDouble:frequency];
}
}
if (isControlPresent(aNote, midiController))
{
if (MKIsNoteParPresent(aNote, MK_pitchBend) &&
(midiControllerAsMKParm == MK_pitchBend))
{
if (lastFreq > 0)
{
#ifdef DEBUG_PARAM
DEBUG_PRINT("- !bend! **** PatchParam/realizeNote Have midiController: %s (%d)\n",
[paramInterface getControlName:midiController], midiController);
#endif DEBUG_PARAM
if (MKIsNoteParPresent(aNote, MK_pitchBendSensitivity))
{
pitchbendSensitivity = MKGetNoteParAsDouble(aNote,
MK_pitchBendSensitivity);
}
else
{
pitchbendSensitivity = 2.0; // Pick something "reasonable"
}
pbSensitivity = (pitchbendSensitivity / 12.0) / 8192.0;
bend = MKGetNoteParAsDouble(aNote, MK_pitchBend);
pitchBend = pow(2.0, (bend - 8192.0) * pbSensitivity);
#ifdef DEBUG_PARAM
DEBUG_PRINT("pitchbendSensitivity: %f pbSensitivity: %f bend: %f pitchBend: %f\n",
pitchbendSensitivity, pbSensitivity, bend, pitchBend);
#endif DEBUG_PARAM
fval = lastFreq * pitchBend;
#ifdef DEBUG_PARAM
DEBUG_PRINT("PatchParam realizeNote: Have pitchBend %f\n", fval);
#endif DEBUG_PARAM
fval = [self applyMap:fval];
fval = (fval * midiCtrlScaleVal) + midiCtrlOffsetVal;
[self setParamValue:fval];
}
}
else
{
#ifdef DEBUG_PARAM
DEBUG_PRINT("- **** PatchParam/realizeNote Have midiController: %s (%d)\n",
[paramInterface getControlName:midiController], midiController);
#endif DEBUG_PARAM
controlVal = getControlValAsDouble(aNote, midiController);
controlVal = [self applyMap:controlVal];
controlVal = (controlVal * midiCtrlScaleVal) + midiCtrlOffsetVal;
#ifdef DEBUG_PARAM
DEBUG_PRINT("PatchParam realizeNote: Have controller %d val: %f\n",
midiController, controlVal);
#endif DEBUG_PARAM
[self setParamValue:controlVal];
}
}
/* Hack for pitch bend */
if (MKIsNoteParPresent(aNote, MK_freq) || MKIsNoteParPresent(aNote, MK_keyNum))
{
lastFreq = [self applyMap:[aNote freq]];
}
return self;
}
/* Stuff that came from Mike's mapper **********************
>
> - free
> {
> [[envelopeView window] close];
> [[envelopeView window] free];
> return [super free];
> }
>
> - editEnvelope:sender
> {
> if (! mapEnvelope)
> {
> double x[2], y[2];
> mapEnvelope = [[Envelope allocFromZone:[self zone]] init];
> x[0] = y[0] = 0.0;
> x[1] = y[1] = 127.0;
> [mapEnvelope setPointCount:2 xArray:x yArray:y];
> }
>
> [envelopeView setEnvelope:mapEnvelope];
> [[envelopeView window] setTitle:[self getName]];
> [[envelopeView window] orderFront:sender];
> return self;
> }
>
> - windowDidBecomeKey:sender
> {
> if ([[envelopeView window] isVisible])
> [[envelopeView window] orderWindow:NX_BELOW
> relativeTo:[inspector windowNum]];
> return self;
> }
>
>
**************************************************/
- write:(NXTypedStream *) stream
{
char *aName;
[super write:stream];
aName = midiControllerName;
NXWriteTypes(stream, "*", &aName);
aName = theName;
NXWriteTypes(stream, "*", &aName);
NXWriteTypes(stream, "d", &midiCtrlScaleVal);
NXWriteTypes(stream, "d", &minMidiCtrlScaleVal);
NXWriteTypes(stream, "d", &maxMidiCtrlScaleVal);
NXWriteTypes(stream, "d", &midiCtrlOffsetVal);
NXWriteTypes(stream, "d", &minMidiCtrlOffsetVal);
NXWriteTypes(stream, "d", &maxMidiCtrlOffsetVal);
NXWriteTypes(stream, "i", ¬eTypeToControl);
NXWriteTypes(stream, "@", &theFakeUG);
NXWriteTypes(stream, "i", &theArg);
NXWriteTypes(stream, "i", &midiController);
NXWriteTypes(stream, "i", &midiControllerAsMKParm);
[self syncMapEnvelope];
NXWriteTypes(stream, "@", &mapEnvelope);
NXWriteTypes(stream, "c", &mapEnabled);
NXWriteTypes(stream, "c", ¶mEnabled);
NXWriteTypes(stream, "c", &thinEnabled);
NXWriteTypes(stream, "i", &thinFactor);
if (inspector)
{
useInspectorRect = YES;
[inspector getFrame:&inspectorRect];
}
else
{
useInspectorRect = NO;
inspectorRect.origin.x = -1;
inspectorRect.origin.y = -1;
inspectorRect.size.width = -1;
inspectorRect.size.height = -1;
}
NXWriteTypes(stream, "d", &inspectorRect.origin.x);
NXWriteTypes(stream, "d", &inspectorRect.origin.y);
NXWriteTypes(stream, "d", &inspectorRect.size.width);
NXWriteTypes(stream, "d", &inspectorRect.size.height);
NXWriteTypes(stream, "c", &useInspectorRect);
NXWriteTypes(stream, "c", &inspectorDisplayed);
return self;
}
- read:(NXTypedStream *) stream
{
int version;
char *aName;
[super read:stream];
thinEnabled = NO;
thinFactor = 1;
paramEnabled = YES;
mapEnabled = NO;
version = NXTypedStreamClassVersion(stream, "PatchParam");
switch (version)
{
case(5):
{
NXReadTypes(stream, "*", &aName);
strcpy(midiControllerName, aName);
NXReadTypes(stream, "*", &aName);
strcpy(theName, aName);
NXReadTypes(stream, "d", &midiCtrlScaleVal);
NXReadTypes(stream, "d", &minMidiCtrlScaleVal);
NXReadTypes(stream, "d", &maxMidiCtrlScaleVal);
NXReadTypes(stream, "d", &midiCtrlOffsetVal);
NXReadTypes(stream, "d", &minMidiCtrlOffsetVal);
NXReadTypes(stream, "d", &maxMidiCtrlOffsetVal);
NXReadTypes(stream, "i", ¬eTypeToControl);
NXReadTypes(stream, "@", &theFakeUG);
NXReadTypes(stream, "i", &theArg);
NXReadTypes(stream, "i", &midiController);
NXReadTypes(stream, "i", &midiControllerAsMKParm);
NXReadTypes(stream, "@", &mapEnvelope);
NXReadTypes(stream, "c", &mapEnabled);
NXReadTypes(stream, "c", ¶mEnabled);
NXReadTypes(stream, "c", &thinEnabled);
NXReadTypes(stream, "i", &thinFactor);
NXReadTypes(stream, "d", &inspectorRect.origin.x);
NXReadTypes(stream, "d", &inspectorRect.origin.y);
NXReadTypes(stream, "d", &inspectorRect.size.width);
NXReadTypes(stream, "d", &inspectorRect.size.height);
NXReadTypes(stream, "c", &useInspectorRect);
NXReadTypes(stream, "c", &inspectorDisplayed);
inspectorRectJustLoaded = YES;
break;
}
case(4):
{
NXReadTypes(stream, "*", &aName);
strcpy(midiControllerName, aName);
NXReadTypes(stream, "*", &aName);
strcpy(theName, aName);
NXReadTypes(stream, "d", &midiCtrlScaleVal);
NXReadTypes(stream, "d", &minMidiCtrlScaleVal);
NXReadTypes(stream, "d", &maxMidiCtrlScaleVal);
NXReadTypes(stream, "d", &midiCtrlOffsetVal);
NXReadTypes(stream, "d", &minMidiCtrlOffsetVal);
NXReadTypes(stream, "d", &maxMidiCtrlOffsetVal);
NXReadTypes(stream, "i", ¬eTypeToControl);
NXReadTypes(stream, "@", &theFakeUG);
NXReadTypes(stream, "i", &theArg);
NXReadTypes(stream, "i", &midiController);
NXReadTypes(stream, "i", &midiControllerAsMKParm);
NXReadTypes(stream, "@", &mapEnvelope);
NXReadTypes(stream, "c", &mapEnabled);
NXReadTypes(stream, "c", ¶mEnabled);
NXReadTypes(stream, "d", &inspectorRect.origin.x);
NXReadTypes(stream, "d", &inspectorRect.origin.y);
NXReadTypes(stream, "d", &inspectorRect.size.width);
NXReadTypes(stream, "d", &inspectorRect.size.height);
NXReadTypes(stream, "c", &useInspectorRect);
NXReadTypes(stream, "c", &inspectorDisplayed);
inspectorRectJustLoaded = YES;
break;
}
case(3):
{
NXReadTypes(stream, "*", &aName);
strcpy(midiControllerName, aName);
NXReadTypes(stream, "*", &aName);
strcpy(theName, aName);
NXReadTypes(stream, "d", &midiCtrlScaleVal);
NXReadTypes(stream, "d", &minMidiCtrlScaleVal);
NXReadTypes(stream, "d", &maxMidiCtrlScaleVal);
NXReadTypes(stream, "d", &midiCtrlOffsetVal);
NXReadTypes(stream, "d", &minMidiCtrlOffsetVal);
NXReadTypes(stream, "d", &maxMidiCtrlOffsetVal);
NXReadTypes(stream, "i", ¬eTypeToControl);
NXReadTypes(stream, "@", &theFakeUG);
NXReadTypes(stream, "i", &theArg);
NXReadTypes(stream, "i", &midiController);
NXReadTypes(stream, "i", &midiControllerAsMKParm);
NXReadTypes(stream, "@", &mapEnvelope);
NXReadTypes(stream, "c", &mapEnabled);
NXReadTypes(stream, "c", ¶mEnabled);
break;
}
case(2):
{
NXReadTypes(stream, "*", &aName);
strcpy(midiControllerName, aName);
NXReadTypes(stream, "*", &aName);
strcpy(theName, aName);
NXReadTypes(stream, "d", &midiCtrlScaleVal);
NXReadTypes(stream, "d", &minMidiCtrlScaleVal);
NXReadTypes(stream, "d", &maxMidiCtrlScaleVal);
NXReadTypes(stream, "d", &midiCtrlOffsetVal);
NXReadTypes(stream, "d", &minMidiCtrlOffsetVal);
NXReadTypes(stream, "d", &maxMidiCtrlOffsetVal);
NXReadTypes(stream, "i", ¬eTypeToControl);
NXReadTypes(stream, "@", &theFakeUG);
NXReadTypes(stream, "i", &theArg);
NXReadTypes(stream, "i", &midiController);
NXReadTypes(stream, "i", &midiControllerAsMKParm);
NXReadTypes(stream, "@", &mapEnvelope);
NXReadTypes(stream, "c", &mapEnabled);
paramEnabled = YES;
break;
}
default:
{
sprintf(ErrorMsg,
"Unexpected document version: %d reading a PatchParam: File: %s Line: %d\n",
version, __FILE__, __LINE__);
NXRunAlertPanel(getAppName(), ErrorMsg, NULL, NULL, NULL);
}
}
/* Make sure the map envelope is synced */
if (envDelegate)
{
[envDelegate free];
envDelegate = nil;
}
[self syncMapEnvelope];
return self;
}
- displayIfDoubleClick
{
clickCount++;
if (clickCount >= 2)
{
clickCount = 0;
[self displayInspector];
}
return self;
}
- displayInspectorIfWasActive
{
if (inspectorDisplayed)
{
[self displayInspector];
}
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.