This is MKCodeGen.m in view mode; [Download] [Up]
/**************************************************
* SynthBuilder
* Copyright 1993 Nick Porcaro All Rights Reserved
**************************************************/
/*
* MKCodeGen.m
* Music Kit Code generator object (split off from FakeSynthPatch)
*/
#import <stdio.h>
#import <stdlib.h>
#import <string.h>
#import <ctype.h>
#import <appkit/Application.h>
#import <dpsclient/event.h>
#import <appkit/Matrix.h>
#import <appkit/OpenPanel.h>
#import <appkit/SavePanel.h>
#import "NodeView.h"
#import "FakeSynthPatch.h"
#import "FakePatchPoint.h"
#import "FakeUG.h"
#import "UGDef.h"
#import "MKCodeGen.h"
#import "Controller.h"
#import "Utilities.h"
#define EOS '\0'
static char TempString[1024];
extern id savePanel;
extern id openPanel;
extern char *getSavePath(char *banner);
extern char *getOpenPath(char *banner);
extern char *getAppName();
double atod(STR s)
{
double x;
sscanf(s, "%lf", &x);
return x;
}
@implementation MKCodeGen
- init
{
[super init];
[NXApp loadNibSection:"MKCodeGen.nib" owner:self withNames:YES];
return self;
}
- displayInspector:sender
{
theSP = [theMainController theSP];
fakeUGs = [theSP getFakeUGs];
fakePatchPoints = [theSP getFakePatchPoints];
if (theSP && [fakeUGs count] && [fakePatchPoints count])
{
[theInspector makeKeyAndOrderFront:self];
}
else
{
NXRunAlertPanel(getAppName(),
"Nothing to generate code for", NULL, NULL, NULL);
}
return self;
}
- emitCode:sender
{
char *file_name;
char *path_leaf;
int comments;
int dest;
int len;
[theInspector performClose:self];
comments = [generateComments intValue];
dest = [[patchDest selectedCell] tag];
/* Get the file name from the user and make sure it is
* a cool name for the code generator
*/
sprintf(TempString, "%s Generate Code", getAppName());
if (! (file_name = getSavePath(TempString)))
{
return self;
}
path_leaf = [utilities getPathLeaf:file_name];
len = strlen(path_leaf);
if (len > 2 && path_leaf[len-2] == '.')
{
path_leaf[len-2] = EOS;
}
if (! [utilities checkName:path_leaf])
{
return self;
}
[self emitCodeTo:file_name genComments:comments ToDest:dest];
return self;
}
- emitCodeTo:(char *) file genComments:(int) comments ToDest: (int) aDest
{
int len;
static char header_file[512], code_file[512];
char *newFileName;
/* Turn off the sound in case the user generates code
* to an app that
* needs the dsp
*/
theSP = [theMainController theSP];
fakeUGs = [theSP getFakeUGs];
fakePatchPoints = [theSP getFakePatchPoints];
strcpy(code_file, file);
[theSP deallocatePatch:self];
newFileName = [self makeObjCCode:code_file:comments];
if (! newFileName)
{
NXRunAlertPanel(getAppName(),
"Could not process file: %s", NULL, NULL, NULL, code_file);
return self;
}
strcpy(code_file, newFileName);
/* Get the header file name from the
* code file name -- assume code file ends in .m and
* header file ends in .h
*/
strcpy(header_file, code_file);
len = strlen(header_file);
header_file[len-2] = '\0';
strcat(header_file, ".h");
newFileName = [self makeHeaderFile:header_file];
if (! newFileName)
{
NXRunAlertPanel(getAppName(),
"Could not process file: %s", NULL, NULL, NULL, header_file);
}
strcpy(header_file, newFileName);
/* Now do the right thing with the file */
switch (aDest)
{
case(0):
{
sprintf(TempString, "open %s %s", code_file, header_file);
system(TempString);
break;
}
case(1): /* Standard test script */
{
sprintf(TempString, "%s/mk-tester -mfile %s -sb_dir %s&",
[utilities getAppDir], code_file, [utilities getAppDir]);
printf("Shell command: %s\n", TempString);
system(TempString);
break;
}
case(2): /* Custom test script */
{
sprintf(TempString, "%s -mfile %s -sb_dir %s &",
[testerScript stringValue], code_file, [utilities getAppDir]);
printf("Shell command: %s\n", TempString);
system(TempString);
break;
}
case(3): /* Future -- make it go to the paste board */
{
break;
}
case(4): /* Just create the file silently */
{
break;
}
}
return self;
}
- (char *) makeHeaderFile:(char *)fileName
{
char *theFileName;
FILE *f;
theFileName = [self setClassNameFromFileName: 'h' : (char *)fileName];
if (!theFileName)
{
NXRunAlertPanel(getAppName(),
"%s could not be processed as a file name.",
NULL, NULL, NULL,
fileName);
return NULL;
}
f = fopen(theFileName, "w");
if (!f)
{
NXRunAlertPanel(getAppName(),
"Could not open: %s",
NULL, NULL, NULL,
theFileName);
return NULL;
}
fprintf(f, "#import <musickit/SynthPatch.h>\n");
fprintf(f, "#import <musickit/WaveTable.h>\n");
fprintf(f, "#import <musickit/Envelope.h>\n\n");
fprintf(f, "@interface %s:SynthPatch\n{\n",[theSP getName]);
fprintf(f, " /*** ADD INSTANCE VARIABLES HERE ***/\n");
fprintf(f, "}\n\n");
fprintf(f, "+patchTemplateFor:currentNote;\n");
fprintf(f, "-init;\n");
fprintf(f, "-testNote;\n");
fprintf(f, "-noteOnSelf:aNote;\n");
fprintf(f, "-preemptFor:aNote;\n");
fprintf(f, "-noteUpdateSelf:aNote;\n");
fprintf(f, "-(double)noteOffSelf:aNote;\n");
fprintf(f, "-noteEndSelf;\n\n");
// fprintf(f, "-_setDefaults;\n");
// fprintf(f, "-_updateParameters:aNote;\n\n");
fprintf(f, "@end\n");
fclose(f);
return theFileName;
}
- (char *) makeObjCCode:(char *)fileName:(int)doComments
{
int i, j, k, l;
BOOL first;
id patchPoint, theUG, aFakeUG, fromFakeUG;
BOOL isDataElement, isSineRom, isConstantpp, isEnvelope, declareThem, hasEnvelope;
char *ug_name, *ug_type, *inst_name, *arg_val, *arg_name, *type_str, *cast_str;
char *thing;
int arg_type;
int arg_count = 0;
int pointCount=0, stickPoint = -1;
int envelopes_processed = 0;
double *xArray, *yArray, *smoothingArray;
char first_part[256], curr_env[256], x_array[20], y_array[20], smooth_array[20];
FILE *f;
extern char *getenv();
char *theFileName;
theFileName = [self setClassNameFromFileName: 'm' : fileName];
if (!theFileName)
{
NXRunAlertPanel(getAppName(),
"%s could not be processed as a file name.",
NULL, NULL, NULL,
fileName);
return NULL;
}
f = fopen(theFileName, "w");
if (!f)
{
NXRunAlertPanel(getAppName(),
"Could not open: %s",
NULL, NULL, NULL,
theFileName);
return NULL;
}
fprintf(f, "#import <appkit/appkit.h>\n"); /*** Added by Nick ***/
fprintf(f, "#import <musickit/unitgenerators/unitgenerators.h>\n");
fprintf(f, "#import <musickit/PatchTemplate.h>\n");
fprintf(f, "#import \"%s.h\"\n\n", [theSP getName]);
fprintf(f, "#define SE NX_ADDRESS(synthElements)\n\n");
fprintf(f, "@implementation %s:SynthPatch\n\n",[theSP getName]);
fprintf(f, "static int ");
first=YES;
for (i=0; i<[fakeUGs count]; i++)
{
aFakeUG = [fakeUGs objectAt:i];
if ([aFakeUG isSoundMaker])
{
if (![aFakeUG isData])
{
if (first)
{
fprintf(f, "%s", [aFakeUG getName]);
first=NO;
}
else
{
fprintf(f, ", %s", [aFakeUG getName]);
}
}
}
}
for (i=0; i<[fakePatchPoints count]; i++)
{
fromFakeUG = [[[fakePatchPoints objectAt:i] getFromNode] superview];
if ([fromFakeUG isSoundMaker])
{
if (![fromFakeUG isSineROM])
{
if (first)
{
fprintf(f, "%s",[[fakePatchPoints objectAt:i] getName]);
first=NO;
}
else
{
fprintf(f, ", %s",[[fakePatchPoints objectAt:i] getName]);
}
}
}
}
fprintf(f, ";\n\n");
fprintf(f, "+patchTemplateFor:currentNote\n");
fprintf(f, "{\n static PatchTemplate *template = nil;\n");
fprintf(f, " if (template)\n return template;\n");
fprintf(f, " [UnitGenerator enableErrorChecking:YES]; /*** Comment this out once your patch is working. ***/\n");
fprintf(f, " template = [[PatchTemplate alloc] init];\n");
for (i=0; i<[fakeUGs count]; i++)
{
aFakeUG = [fakeUGs objectAt:i];
if ([aFakeUG isSoundMaker])
{
if (![aFakeUG isData])
{
ug_name = [self checkForUnconnectedPins: i ];
fprintf(f, " %s = [template addUnitGenerator:[%s class]];\n",
[aFakeUG getName], ug_name);
}
}
}
#define KARPLUS_STRONG_WORKS1 1 /* This causes Karplus Strong to go higher pitched */
#ifdef KARPLUS_STRONG_WORKS1
for (i=0; i<[fakePatchPoints count]; i++)
{
fromFakeUG = [[[fakePatchPoints objectAt:i] getFromNode] superview];
if ([fromFakeUG isSoundMaker])
{
if ([fromFakeUG isData])
{
if ([[fakePatchPoints objectAt:i] getXMemory])
{
theUG = [[[fakePatchPoints objectAt:i] getFromNode] superview];
if ( [ theUG hasConstant] && ! [theUG isStorage])
{
fprintf(f, " %s = [template addPatchpoint:MK_xData];\n",
[[fakePatchPoints objectAt:i] getName]);
}
else
{
fprintf(f, " %s = [template addSynthData:MK_xData length:%i];\n",
[[fakePatchPoints objectAt:i] getName],
[[[[fakePatchPoints objectAt:i]
getFromNode] superview] getLength]);
}
}
else
{
if (![[[[fakePatchPoints objectAt:i] getFromNode] superview]
isSineROM])
{
fprintf(f, " %s = [template addSynthData:MK_yData length:%i];\n",
[[fakePatchPoints objectAt:i] getName],
[[[[fakePatchPoints objectAt:i]
getFromNode] superview] getLength]);
}
}
}
else
{
if ([[fakePatchPoints objectAt:i] getXMemory])
{
fprintf(f, " %s = [template addPatchpoint:MK_xPatch];\n",
[[fakePatchPoints objectAt:i] getName]);
}
else
{
fprintf(f, " %s = [template addPatchpoint:MK_yPatch];\n",
[[fakePatchPoints objectAt:i] getName]);
}
}
}
}
fprintf(f, " return template;\n}");
fprintf(f, "\n\n-_setDefaults\n{\n");
fprintf(f, " /*** ADD ANY INITIALIZATION CODE HERE. ***/\n");
fprintf(f, " return self;\n}\n\n");
#else
for (i=0; i<[fakePatchPoints count]; i++)
{
fromFakeUG = [[[fakePatchPoints objectAt:i] getFromNode] superview];
if ([fromFakeUG isSoundMaker])
{
if ([fromFakeUG isData])
if ([[fakePatchPoints objectAt:i] getXMemory])
fprintf(f, " %s = [template addSynthData:MK_xData length:%i];\n",
[[fakePatchPoints objectAt:i] getName],
[[[[fakePatchPoints objectAt:i]
getFromNode] superview] getLength]);
else {
if (![fromFakeUG isSineROM])
fprintf(f, " %s = [template addSynthData:MK_yData length:%i];\n",
[[fakePatchPoints objectAt:i] getName],
[[[[fakePatchPoints objectAt:i]
getFromNode] superview] getLength]);
}
else
if ([[fakePatchPoints objectAt:i] getXMemory])
fprintf(f, " %s = [template addPatchpoint:MK_xPatch];\n",
[[fakePatchPoints objectAt:i] getName]);
else
fprintf(f, " %s = [template addPatchpoint:MK_yPatch];\n",
[[fakePatchPoints objectAt:i] getName]);
}
}
fprintf(f, " return template;\n}");
fprintf(f, "\n\n-_setDefaults\n{\n");
fprintf(f, " /*** ADD ANY INITIALIZATION CODE HERE. ***/\n");
fprintf(f, " return self;\n}\n\n");
#endif KARPLUS_STRONG_WORKS1
// Declare static id variables for the envelopes (Nick)
envelopes_processed = 0;
for (i=0; i<[fakeUGs count]; i++)
{
aFakeUG = [fakeUGs objectAt:i];
if ([aFakeUG isSoundMaker])
{
if ([[fakeUGs objectAt:i] isEnvelopeHandler])
{
ug_name = [[fakeUGs objectAt:i] getName];
envelopes_processed++;
fprintf(f, "static id envelope%d = nil;\n", envelopes_processed);
}
}
}
fprintf(f, "\n\n");
// Put the envelope code in _updateParameters (Nick)
fprintf(f, "-_updateParameters:aNote\n{\n\n");
fprintf(f, "\n");
fprintf(f, " if ([self phraseStatus] <= MK_phraseRearticulate) {\n");
envelopes_processed = 0;
for (i=0; i<[fakeUGs count]; i++)
{
aFakeUG = [fakeUGs objectAt:i];
if ([aFakeUG isSoundMaker])
{
if ([[fakeUGs objectAt:i] isEnvelopeHandler])
{
ug_name = [[fakeUGs objectAt:i] getName];
envelopes_processed++;
sprintf(curr_env, "envelope%d", envelopes_processed);
fprintf(f, " MKUpdateAsymp(SE[%s], %s, 0.0, 1.0,\n", ug_name, curr_env);
fprintf(f, " MK_NODVAL, MK_NODVAL, MK_NODVAL,\n");
fprintf(f, " [self phraseStatus]);\n");
}
}
}
fprintf(f, " }\n");
fprintf(f, " return self;\n}\n\n");
fprintf(f, "-init\n{\n");
// Figure out if we need to declare freqs, amps, partials
declareThem = NO;
for (i=0; i<[fakePatchPoints count]; i++)
{
int k;
fromFakeUG = [[fakePatchPoints objectAt:i] getFromFakeUG];
if ([fromFakeUG isSoundMaker])
{
if ([fromFakeUG isData])
{
if (![fromFakeUG hasConstant])
{
for (k=0; k<MAXNOTEPARAMETERS; k++)
{
if ([fromFakeUG getArgType:k] == PARTIALS)
{
declareThem = YES;
break;
}
}
}
}
}
}
if (declareThem)
{
fprintf(f, " double *freqs, *amps;\n id partials;\n");
}
for (i=0; i<[fakePatchPoints count]; i++)
{
int k;
patchPoint = [fakePatchPoints objectAt:i];
fromFakeUG = [patchPoint getFromFakeUG];
if (! [fromFakeUG isSoundMaker])
{
goto end_of_loop0;
}
if (![fromFakeUG isData])
fprintf(f, " [SE[%s] %sSE[%s]];\n",
[fromFakeUG getName],
[fromFakeUG
getConnectionName:[patchPoint getFromConnectionNumber]],
[patchPoint getName]);
else
if ([fromFakeUG hasConstant])
{
fprintf(f, " [SE[%s]",[patchPoint getName]);
/** Fixed by Nick **/
fprintf(f, " setToConstant:DSPDoubleToFix24(%f)];\n",
atod([fromFakeUG getConstant]));
}
else
{
for (k=0; k<MAXNOTEPARAMETERS; k++)
{
if (([fromFakeUG getArgType:k])==PARTIALS)
{
int l;
for (l=0; l<[[patchPoint getToNodes] count]; l++)
{
double *freqs, *amps;
char *scoreString;
int p, q, pointCount=0;
scoreString = [fromFakeUG getArgName:k];
for (p=0; scoreString[p]!='\0'; p++)
if (scoreString[p]=='{')
pointCount++;
freqs = (double *) NXZoneCalloc([self zone],
pointCount, sizeof(double));
amps = (double *) NXZoneCalloc([self zone],
pointCount, sizeof(double));
q=0;
for (p=0; p<pointCount; p++)
{
freqs[p] = amps[p] = 0.0;
while (scoreString[q]!='{')
q++;
sscanf(scoreString+q, "{%lf,%lf}",
&freqs[p], &s[p]);
q++;
}
fprintf(f, " partials=[[Partials alloc]");
fprintf(f, " init];\n freqs=(double *)");
fprintf(f, " calloc(%i, sizeof(*freqs));\n",
pointCount);
fprintf(f, " amps=(double *) calloc(%i,",
pointCount);
fprintf(f, " sizeof(*amps));\n");
for (p=0; p<pointCount; p++)
fprintf(f, " freqs[%i]=%f;\n", p, freqs[p]);
for (p=0; p<pointCount; p++)
fprintf(f, " amps[%i]=%f;\n", p, amps[p]);
fprintf(f, " [partials setPartialCount:%i",
pointCount);
fprintf(f, " freqRatios:freqs ampRatios:amps");
fprintf(f, " phases:NULL orDefaultPhase:0.0];\n");
fprintf(f, " [SE[%s]", [patchPoint getName]);
fprintf(f, " setData:[partials dataDSPLength:%i]];\n",
[fromFakeUG getLength]);
}
}
}
}
/* A UG is an output if it has no output nodes. */
for (k=0; k<[[patchPoint getToNodes] count]; k++)
{
id toFakeUG = [[[patchPoint getToNodes] objectAt:k] superview];
if ([toFakeUG getConnectionName:0]!=NULL)
{
if (([fromFakeUG isData]
&& ([fromFakeUG isSineROM])
&& ([toFakeUG isOscg])))
{
fprintf(f, " [SE[%s]",
[toFakeUG getName]);
fprintf(f, " setTableToSineROM];\n");
}
else
fprintf(f, " [SE[%s] %sSE[%s]];\n",
[toFakeUG getName],
[toFakeUG
getConnectionName:[[[patchPoint getToNodes]
objectAt:k]
getTag]],
[patchPoint getName]);
}
}
end_of_loop0:
;
}
fprintf(f, " [self _setDefaults]; \n");
fprintf(f, " return self;\n}\n\n");
// ****************************************
// start testNote method (Nick)
// ****************************************
fprintf(f, "// ** Added by Nick **\n");
fprintf(f, "-testNote\n");
fprintf(f, "{\n\n");
envelopes_processed = 0;
for (i=0; i<[fakeUGs count]; i++)
{
aFakeUG = [fakeUGs objectAt:i];
if (! [aFakeUG isSoundMaker])
{
goto end_of_loop;
}
isDataElement = [aFakeUG isData];
isSineRom = [aFakeUG isSineROM];
isEnvelope = [aFakeUG isEnvelopeHandler];
ug_name = [aFakeUG getName];
ug_type = [aFakeUG getTypeString];
inst_name = [aFakeUG getName];
arg_count = [aFakeUG getArgCount];
/* I think this line is flawed */
isConstantpp = [[[[fakePatchPoints objectAt:i] getFromNode] superview] hasConstant];
if (doComments)
{
/* Generate the comments */
if (isConstantpp || isDataElement)
{
thing = "Synth Data";
}
else
{
thing = "Unit Generator";
}
fprintf(f, "\n//\n");
fprintf(f, "// *** %s (graph instance number %d) ***\n", thing, i);
fprintf(f, "// Instance name: %s\n", inst_name);
fprintf(f, "// Type: %s", ug_type);
if ( (isDataElement) && (! isSineRom) && (!isConstantpp))
{
fprintf(f, " (data element of length: %d)\n",
[aFakeUG getLength]);
}
else if (isEnvelope)
{
fprintf(f, "\n// Envelope!\n");
}
else
{
fprintf(f, "\n");
}
fprintf(f, "// Number of arguments: %d\n", arg_count);
for (j=0; j<arg_count; j++)
{
arg_val = [aFakeUG getArg:j];
if (! arg_val || (strcmp(arg_val, "") == 0) )
{
arg_val = "UNSET";
}
arg_type = [aFakeUG getArgType:j];
arg_name = [aFakeUG getArgName:j];
if ( (!arg_name) || (strcmp(arg_name, "") == 0) )
{
break;
}
type_str = [aFakeUG getArgTypeStr:arg_type];
if (!type_str)
{
cast_str = "";
}
if (arg_type == PARTIALS)
{
fprintf(f, "// *** WARNING cannot generate code for UG of type %s\n",
type_str);
}
fprintf(f, "// %s %s %s\n",
arg_name, type_str, arg_val);
}
fprintf(f, " \n");
}
// Generate the code
if ( (arg_count > 0) && (! isDataElement))
{
for (j=0; j<arg_count; j++)
{
/* Make sure we can even do it */
isEnvelope = NO;
arg_type = [aFakeUG getArgType:j];
type_str = [aFakeUG getArgTypeStr:arg_type];
pointCount = 0;
if (arg_type == ENV)
{
isEnvelope = YES;
envelopes_processed++;
sprintf(curr_env, "envelope%d", envelopes_processed);
sprintf(x_array, "xArray%d", envelopes_processed);
sprintf(y_array, "yArray%d", envelopes_processed);
sprintf(smooth_array, "smoothArray%d", envelopes_processed);
arg_val = [aFakeUG getArg:j];
for (k=0; arg_val[k] != '\0'; k++)
{
if (arg_val[k]=='|')
{
stickPoint = pointCount-1;
}
if (arg_val[k]=='(')
pointCount++;
}
xArray = (double *) NXZoneCalloc([self zone],
pointCount, sizeof(double));
yArray = (double *) NXZoneCalloc([self zone],
pointCount, sizeof(double));
smoothingArray = (double *) NXZoneCalloc([self zone],
pointCount, sizeof(double));
l=0;
for (k=0; k<pointCount; k++)
{
xArray[k] = yArray[k] = 0.0;
smoothingArray[k] = 1.0;
while (arg_val[l]!='(')
{
l++;
}
sscanf(arg_val+l, "(%lf,%lf,%lf)",
&xArray[k], &yArray[k], &smoothingArray[k]);
l++;
}
fprintf(f, " if (! %s) {\n", curr_env);
fprintf(f, " double %s[] = {", x_array);
for (k=0; k<pointCount; k++)
{
if (k == pointCount -1)
{
fprintf(f, "%f};\n", xArray[k]);
}
else
{
fprintf(f, "%f, ", xArray[k]);
}
}
fprintf(f, " double %s[] = {", y_array);
for (k=0; k<pointCount; k++)
{
if (k == pointCount - 1)
{
fprintf(f, "%f};\n", yArray[k]);
}
else
{
fprintf(f, "%f, ", yArray[k]);
}
}
fprintf(f, " double %s[] = {", smooth_array);
for (k=0; k<pointCount; k++)
{
if (k == pointCount - 1)
{
fprintf(f, "%f};\n", smoothingArray[k]);
}
else
{
fprintf(f, "%f, ", smoothingArray[k]);
}
}
fprintf(f, " %s = [[Envelope alloc] init];\n", curr_env);
// I added orSamplingPeriod:0 per DAJ mail of 12/20/92
fprintf(f, " [%s setPointCount: %d xArray:%s orSamplingPeriod:0 yArray:%s smoothingArray:%s orDefaultSmoothing:1.0];\n",
curr_env, pointCount, x_array, y_array, smooth_array);
if (stickPoint!=-1)
{
fprintf(f, " [%s setStickPoint: %d];\n", curr_env, stickPoint);
}
fprintf(f, " [SE[%s] setEnvelope:%s yScale:1.0 yOffset:0.0 xScale:1.0 releaseXScale:1.0 funcPtr:NULL];\n",ug_name, curr_env);
fprintf(f, " }\n");
NXZoneFree([self zone], xArray);
NXZoneFree([self zone], smoothingArray);
NXZoneFree([self zone], yArray);
xArray = NULL;
smoothingArray = NULL;
yArray = NULL;
}
else if (arg_type == PARTIALS)
{
fprintf(f, "// *** ERROR cannot generate code for UG of type %s\n",
type_str);
break;
}
else /* All other argument types */
{
/* Write out the first part */
sprintf(first_part, " [SE[%s] ", ug_name);
/* Write code for paramter method setting */
arg_val = [aFakeUG getArg:j];
arg_name = [aFakeUG getArgName:j];
cast_str = [aFakeUG getArgCast:arg_type];
if ( (!cast_str) || (strcmp(cast_str, "") == 0))
{
fprintf(stderr, "Warning: NULL cast on method %s for UG %s\n",
arg_name, type_str);
cast_str = "";
}
/* Only generate the code for non-NULL arg_val's
* This corresponds to David Jaffe's request not to
* generate code for "unset" values
*/
if (arg_val && (strcmp(arg_val, "") != 0) )
{
// fprintf(f, "%s %s %s %s];\n", first_part, arg_name, cast_str, arg_val);
// Took out cast per daj request of 3-5-93 (nick)
fprintf(f, "%s %s %s];\n", first_part, arg_name, arg_val);
}
}
}
}
end_of_loop:
;
}
// ****************************************
// end testNote method (Nick)
// ****************************************
fprintf(f, " return self;\n}\n");
fprintf(f, "-noteOnSelf:aNote\n");
fprintf(f, "{\n");
fprintf(f, "// This produces the sound designed in %s.\n", getAppName());
fprintf(f, "// For further control, remove the testNote method and add\n");
fprintf(f, "// parmeter-setting code to _updateParameters:\n");
fprintf(f, " [self testNote];\n"); /** (added by Nick) **/
fprintf(f, " [self _updateParameters:aNote];\n");
for (i=0; i<[fakePatchPoints count]; i++)
{
int k;
id patchPoint = [fakePatchPoints objectAt:i];
for (k=0; k<[[patchPoint getToNodes] count]; k++)
{
id toFakeUG = [[[patchPoint getToNodes] objectAt:k] superview];
if ([toFakeUG isSoundMaker])
{
if ([toFakeUG getConnectionName:0]==NULL)
fprintf(f, " [SE[%s] %sSE[%s]];\n",
[toFakeUG getName],
[toFakeUG
getConnectionName:[[[patchPoint getToNodes]
objectAt:k]
getTag]],
[patchPoint getName]);
}
}
}
fprintf(f, " [synthElements makeObjectsPerform:@selector(run)];\n");
fprintf(f, " return self;\n}\n\n");
fprintf(f, "-noteUpdateSelf:aNote\n");
fprintf(f, "{\n [self _updateParameters:aNote];\n");
fprintf(f, " return self;\n}\n\n");
fprintf(f, "-(double)noteOffSelf:aNote\n");
fprintf(f, "{\n double t=0;\n");
hasEnvelope = NO;
for (i=0; i<[fakeUGs count]; i++)
{
aFakeUG = [fakeUGs objectAt:i];
if ([aFakeUG isSoundMaker])
{
if ([[fakeUGs objectAt:i] isEnvelopeHandler])
{
hasEnvelope = YES;
break;
}
}
}
if (hasEnvelope)
{
fprintf(f, " double u;\n");
}
fprintf(f, " [self _updateParameters:aNote];\n");
for (i=0; i<[fakeUGs count]; i++)
{
aFakeUG = [fakeUGs objectAt:i];
if ([aFakeUG isSoundMaker])
{
if ([aFakeUG isEnvelopeHandler])
{
fprintf(f, " u = [SE[%s] finish];\n t=(u>t)?u:t;\n",
[aFakeUG getName]);
}
}
}
fprintf(f, " return t;\n}\n\n");
fprintf(f, "-noteEndSelf\n{\n");
for (i=0; i<[fakePatchPoints count]; i++)
{
id patchPoint = [fakePatchPoints objectAt:i];
int k;
id toFakeUG;
for (k=0; k<[[patchPoint getToNodes] count]; k++)
{
toFakeUG = [[[patchPoint getToNodes] objectAt:k] superview];
if ([toFakeUG isSoundMaker])
{
if ([toFakeUG getConnectionName:0] == NULL)
/*** The following change made by DAJ. July 26, 1992 ***/
fprintf(f,
" [SE[%s] idle];\n",
[[[[patchPoint getToNodes] objectAt:0] superview]
getName]);
}
}
}
for (i=0; i<[fakeUGs count]; i++)
if ([[fakeUGs objectAt:i] isEnvelopeHandler])
fprintf(f,
" [SE[%s] abortEnvelope];\n", [[fakeUGs objectAt:i] getName]);
fprintf(f, " return self;\n}\n\n");
fprintf(f, "-preemptFor:aNote\n{\n");
for (i=0; i<[fakeUGs count]; i++)
if ([[fakeUGs objectAt:i] isEnvelopeHandler])
fprintf(f,
" [SE[%s] preemptEnvelope];\n", [[fakeUGs objectAt:i] getName]);
fprintf(f, " return self;\n}\n\n@end\n");
fclose(f);
return theFileName;
}
- (char *)setClassNameFromFileName:(char) suff : (char *) fileName
/* Utilitity function for setting class name from a filename.
* The suffix suff is ignored in setting the class name.
* The fileName is returned with suff appended if it didn't already exist
* If something bizzare happens, NULL is returned.
*/
{
int l;
static char name_buf[1024];
char *path_leaf;
if (! fileName)
{
return(NULL);
}
/* Change the patch name to reflect the "root" name of the file
* (that is, the name with no suffix).
* We assume the name is legit from an earlier check
*/
strcpy(name_buf, fileName);
l = strlen(name_buf);
if ( l > 2 && (name_buf[l-1] == suff) && (name_buf[l-2] == '.'))
{
/* Get rid of the suffix */
name_buf[l-2] = EOS;
}
path_leaf = [utilities getPathLeaf:name_buf];
if (! path_leaf)
{
return NULL;
}
[theSP changeName:path_leaf];
/* Add in the suffix again and return it */
l = strlen(name_buf);
name_buf[l] = '.';
name_buf[l+1] = suff;
name_buf[l+2] = EOS;
return(name_buf);
}
- (char *)checkForUnconnectedPins: (int) index
/* Function to check connections. Eventually add code
* to check all the connections.
*/
{
static char ug_name_out[256];
char *ug_name;
ug_name = [[fakeUGs objectAt:index] getTypeString];
if (strcmp([[fakeUGs objectAt:index] getTypeString], "Add2UGxx") == 0)
{
NXRunAlertPanel(getAppName(),
"%s may have unconnected pins. Naming it Add2UGxxx",
NULL, NULL, NULL,
ug_name);
ug_name = "Add2UGxxx";
}
strcpy(ug_name_out, ug_name);
return (ug_name_out);
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.