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.