This is Instrum.m in view mode; [Download] [Up]
/* Generated by Interface Builder */
#import "Instrum.h"
#import <objc/List.h>
#import <appkit/Form.h>
#import <appkit/Panel.h>
#import <objc/Storage.h>
#import "UnitGen.h"
#import "Oscil.h"
#import "Out.h"
#import "Statement.h"
@implementation Instrum
- init
{
ugenList = [[List alloc] initCount:5];
varList = [[List alloc] initCount:10];
assignList = [[List alloc] initCount:10];
loopList = [[List alloc] initCount:10];
endList = [[List alloc] initCount:5];
setline = inputSound = NO;
return self;
}
- printUgenLocs // displays unit generator locations, for debugging
{
id ugen;
int i;
unsigned int c;
c = [ugenList count];
for(i = 0; i < [ugenList count]; i++) {
ugen = [ugenList objectAt:i];
[ugen show];
}
return self;
}
- findUgenAtPoint:(NXPoint *)point // find the unit generator at PatchView location
{
id ugen;
int i;
NXRect *rect;
// get the ugen
for(i = 0; i < [ugenList count]; i++) {
ugen = [ugenList objectAt:i];
rect = [ugen getRect];
if(NXMouseInRect(point,rect,NO)) {
return ugen;
}
}
return nil;
}
- putUgenInList:ugen // store a new unit generator
{
unsigned int n;
n = [ugenList count];
[ugen setIndex:n];
[ugenList addObject:ugen];
return self;
}
- removeUgenFromList:ugen // delete a unit generator
{
unsigned int n;
unsigned int c;
int i;
n = [ugen getIndex];
c = [ugenList count];
[ugenList removeObject:ugen];
for(i = n; i < c; i++)
[[ugenList objectAt:n] setIndex:n];
return self;
}
- putVarInList:(char *)var // store a variable used by a unit generator
{
id statement;
statement = [Statement alloc];
[statement storeString:var];
[varList addObject:statement];
return self;
}
- putAssignInList:(char *)assign // store an assignment statement used by a unit generator
{
id statement;
statement = [Statement alloc];
[statement storeString:assign];
[assignList addObject:statement];
return self;
}
- putLoopInList:(char *)loop // store a statement occurring within sample loop
// used by a unit generator
{
id statement;
statement = [Statement alloc];
[statement storeString:loop];
[loopList addObject:statement];
return self;
}
- putEndInList:(char *)end // store a statement occurring within sample loop
// used by a unit generator
{
id statement;
statement = [Statement alloc];
[statement storeString:end];
[endList addObject:statement];
return self;
}
- writeCodeWithName:(char *)instName andDir:(char *)instDir andCmd:(char *)cmdDir andCmix:(char *)cmixDir
// write out the instrument code
{
id outUgen;
int i;
strcpy(name,instName);
strcpy(directory,instDir);
sprintf(file,"%s/%s.c",directory,name);
outUgen = [ugenList objectAt:0];
for(i = 0; i < [ugenList count]; i++)
[[ugenList objectAt:i] newWrite]; // set all ugens as not written
[self freeCodeLists]; // removed old code
// recursively writes all the code for each ugen
[outUgen writeUgen]; // from out, travels up tree and then down,
// writing code for each ugen as finished
if (![self head:cmixDir])
return self;
[self body];
[self tail];
[self profile:cmixDir];
[self makeWithCmd:cmdDir andCmix:cmixDir];
return self;
}
- head:(char *)cmixDir // writes out include statements, etc. of cmix instrument
{
fp = fopen(file,"w");
if(!fp) {
NXRunAlertPanel("patchmix","This file can't be opened. Check out the directory. %s","OK",NULL,NULL,file);
return 0;
}
// variables & includes for all instr:
fprintf(fp, "#include \"%s/H/ugens.h\"\n",cmixDir);
fprintf(fp, "#include \"%s/H/sfheader.h\"\n",cmixDir);
fprintf(fp, "#include \"%s/macros/macros.h\"\n",cmixDir);
fprintf(fp, "#include <stdio.h>\n#include <sys/file.h>\n");
fprintf(fp, "#include <sys/types.h>\n\n");
fprintf(fp, "extern SFHEADER sfdesc[NFILES];\n\n");
fprintf(fp, "%s(p,n_args)\n\n", name);
fprintf(fp, "float *p; /* array of p-fields */\n");
fprintf(fp, "int n_args; /* number of p-fields */\n\n{\n");
fprintf(fp, "\tint chans;\n");
fprintf(fp, "\tlong nsamps,i;\n");
fclose(fp);
return self;
}
- body // writes body of cmix instrument, from the 3 lists of
// variable declarations, assignment statements and
// statements occurring within the sample loop
{
int i;
char *str;
fp = fopen(file,"a");
if(!fp) {
NXRunAlertPanel("patchmix","This file can't be opened. Check out the directory. %s","OK",NULL,NULL,file);
return 0;
}
fprintf(fp, "\tfloat amp;\n");
fprintf(fp, "\tfloat out[2];\n");
for(i = 0; i < [varList count]; i++) {
str = [[varList objectAt:i] getString];
fprintf(fp,"%s",str);
}
fprintf(fp, "\tnsamps = setnote(p[0],p[1],0);\n");
fprintf(fp, "\tchans = sfchans(&sfdesc[0]);\n");
// initial assignment statements
for(i = 0; i < [assignList count]; i++) {
str = [[assignList objectAt:i] getString];
fprintf(fp,"%s",str);
}
// sample loop statements (signal processing)
fprintf(fp, "\tfor(i = 0; i < nsamps; i++) {\n");
for(i = 0; i < [loopList count]; i++) {
str = [[loopList objectAt:i] getString];
fprintf(fp,"%s",str);
}
fclose(fp);
return self;
}
- tail // end of instrument code
{
int i;
char *str;
fp = fopen(file,"a");
if(!fp) {
NXRunAlertPanel("patchmix","This file can't be opened. Check out the directory. %s","OK",NULL,NULL,file);
return 0;
}
fprintf(fp, "\t\tADDOUT(out,0);\n\t}\n");
fprintf(fp, "\tendnote(0);\n");
for(i = 0; i < [endList count]; i++) {
str = [[endList objectAt:i] getString];
fprintf(fp,"%s",str);
}
fprintf(fp, "}\n");
fclose(fp);
return self;
}
- profile:(char *)cmixDir // writes cmix "profile.c", which introduces your instrument
// into the list of cmix functions when compiled with cmix objects
{
char profile[80];
sprintf(profile,"%s/profile.c",directory);
fp = fopen(profile,"w");
if(!fp) {
NXRunAlertPanel("patchmix","This file can't be opened. Check out the directory. %s","OK",NULL,NULL,profile);
return 0;
}
fprintf(fp,"#include \"%s/H/ugens.h\"\n",cmixDir);
fprintf(fp,"int FSPACE = 1;\n");
fprintf(fp,"int NBYTES = 32768;\n\n");
fprintf(fp,"profile()\n{\n");
fprintf(fp,"\tUG_INTRO(\"%s\",%s);\n}\n",name,name);
fclose(fp);
return self;
}
- makeWithCmd:(char *)cmdDir andCmix:(char *)cmixDir // writes out makefile
{
char makefile[80];
sprintf(makefile,"%s/Makefile",directory);
fp = fopen(makefile,"w");
if(!fp) {
NXRunAlertPanel("patchmix","This file can't be opened. Check out the directory. %s","OK",NULL,NULL,makefile);
return 0;
}
fprintf(fp,"CFLAGS = -O\n");
fprintf(fp,"POBJECTS = %s.o profile.o\n",name);
fprintf(fp,"LDFLAGS = %s/cmix.o %s/lib/genlib.a -lm\n\n",cmdDir,cmixDir);
fprintf(fp,"%s: %s/H/ugens.h $(POBJECTS) %s/cmix.o\n", name,cmixDir, cmdDir);
fprintf(fp,"\tcc -o %s $(POBJECTS) $(LDFLAGS)\n",name);
fclose(fp);
return self;
}
- freeUgens
{
[ugenList freeObjects];
[ugenList empty];
[self freeCodeLists];
return self;
}
- freeCodeLists
{
[varList freeObjects];
[varList empty];
[assignList freeObjects];
[assignList empty];
[loopList freeObjects];
[loopList empty];
[endList freeObjects];
[endList empty];
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.