home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / Apps / SoundApps / Patchmix / Source / Instrum.m < prev    next >
Encoding:
Text File  |  1995-06-12  |  7.0 KB  |  308 lines

  1.  
  2. /* Generated by Interface Builder */
  3.  
  4. #import "Instrum.h"
  5. #import <objc/List.h>
  6. #import <appkit/Form.h>
  7. #import <appkit/Panel.h>
  8. #import <objc/Storage.h>
  9. #import "UnitGen.h"
  10. #import "Oscil.h"
  11. #import "Out.h"
  12. #import "Statement.h"
  13.  
  14. @implementation Instrum
  15.  
  16. - init
  17. {
  18.     ugenList = [[List alloc] initCount:5];
  19.     varList = [[List alloc] initCount:10];
  20.     assignList = [[List alloc] initCount:10];
  21.     loopList = [[List alloc] initCount:10];
  22.     endList = [[List alloc] initCount:5];
  23.     
  24.     setline = inputSound = NO;
  25.     
  26.     return self;
  27. }
  28.  
  29. - printUgenLocs        // displays unit generator locations, for debugging
  30. {
  31.     id ugen;
  32.     int i;
  33.     unsigned int c;
  34.     
  35.     c = [ugenList count];
  36.     for(i = 0; i < [ugenList count]; i++) {
  37.         ugen = [ugenList objectAt:i];
  38.         [ugen show];
  39.     }
  40.     return self;
  41. }
  42.  
  43. - findUgenAtPoint:(NXPoint *)point        // find the unit generator at PatchView location
  44. {
  45.     id         ugen;
  46.     int     i;
  47.     NXRect  *rect;
  48.     
  49.     // get the ugen 
  50.     for(i = 0; i < [ugenList count]; i++) {
  51.         ugen = [ugenList objectAt:i];
  52.         rect = [ugen getRect];
  53.         if(NXMouseInRect(point,rect,NO)) {
  54.             return ugen;
  55.         }
  56.     }
  57.     return nil;
  58. }
  59.  
  60. - putUgenInList:ugen        // store a new unit generator
  61. {
  62.     unsigned int n;
  63.  
  64.     n = [ugenList count];
  65.     [ugen setIndex:n];
  66.     [ugenList addObject:ugen];
  67.     return self;
  68. }
  69.  
  70. - removeUgenFromList:ugen        // delete a unit generator
  71. {
  72.     unsigned int n;
  73.     unsigned int c;
  74.     int i;
  75.  
  76.     n = [ugen getIndex];
  77.     c = [ugenList count];
  78.     [ugenList removeObject:ugen];
  79.     for(i = n; i < c; i++)
  80.         [[ugenList objectAt:n] setIndex:n];
  81.     
  82.     return self;
  83. }
  84.  
  85. - putVarInList:(char *)var        // store a variable used by a unit generator 
  86. {
  87.     id statement;
  88.     
  89.     statement = [Statement alloc];
  90.     [statement storeString:var];
  91.     [varList addObject:statement];
  92.     return self;
  93. }
  94.  
  95. - putAssignInList:(char *)assign    // store an assignment statement used by a unit generator
  96. {
  97.     id statement;
  98.     
  99.     statement = [Statement alloc];
  100.     [statement storeString:assign];
  101.     [assignList addObject:statement];
  102.     return self;
  103. }
  104.  
  105. - putLoopInList:(char *)loop        //  store a statement occurring within sample loop
  106.                             //  used by a unit generator
  107. {
  108.     id statement;
  109.     
  110.     statement = [Statement alloc];
  111.     [statement storeString:loop];
  112.     [loopList addObject:statement];
  113.     return self;
  114. }
  115.  
  116. - putEndInList:(char *)end        //  store a statement occurring within sample loop
  117.                             //  used by a unit generator
  118. {
  119.     id statement;
  120.     
  121.     statement = [Statement alloc];
  122.     [statement storeString:end];
  123.     [endList addObject:statement];
  124.     return self;
  125. }
  126.  
  127. - writeCodeWithName:(char *)instName andDir:(char *)instDir andCmd:(char *)cmdDir andCmix:(char *)cmixDir
  128.                             // write out the instrument code
  129. {
  130.     id outUgen;
  131.     int i;
  132.     
  133.     strcpy(name,instName);
  134.     strcpy(directory,instDir);
  135.     sprintf(file,"%s/%s.c",directory,name);
  136.  
  137.     outUgen = [ugenList objectAt:0];
  138.     
  139.     for(i = 0; i < [ugenList count]; i++) 
  140.         [[ugenList objectAt:i] newWrite];    // set all ugens as not written
  141.     
  142.     [self freeCodeLists];         // removed old code
  143.                                 // recursively writes all the code for each ugen
  144.     [outUgen writeUgen];        // from out, travels up tree and then down, 
  145.                             // writing code for each ugen as finished
  146.  
  147.     if (![self head:cmixDir])
  148.         return self;
  149.     [self body];
  150.     [self tail];
  151.     [self profile:cmixDir];
  152.     [self makeWithCmd:cmdDir andCmix:cmixDir];
  153.     return self;
  154. }
  155.  
  156. - head:(char *)cmixDir            // writes out include statements, etc. of cmix instrument
  157. {
  158.     fp = fopen(file,"w");
  159.     if(!fp) {
  160.         NXRunAlertPanel("patchmix","This file can't be opened. Check out the directory. %s","OK",NULL,NULL,file);
  161.         return 0;
  162.     }
  163.                             // variables & includes for all instr:    
  164.     fprintf(fp, "#include \"%s/H/ugens.h\"\n",cmixDir);
  165.      fprintf(fp, "#include \"%s/H/sfheader.h\"\n",cmixDir);
  166.      fprintf(fp, "#include \"%s/macros/macros.h\"\n",cmixDir);
  167.      fprintf(fp, "#include <stdio.h>\n#include <sys/file.h>\n");
  168.     fprintf(fp, "#include <sys/types.h>\n\n");
  169.            fprintf(fp, "extern SFHEADER      sfdesc[NFILES];\n\n");
  170.     fprintf(fp, "%s(p,n_args)\n\n", name);
  171.     fprintf(fp, "float *p; /* array of p-fields */\n");
  172.     fprintf(fp, "int n_args; /* number of p-fields */\n\n{\n");
  173.  
  174.     fprintf(fp, "\tint chans;\n");
  175.     fprintf(fp, "\tlong nsamps,i;\n");
  176.     fclose(fp);
  177.     return self;
  178. }
  179.  
  180. - body            // writes body of cmix instrument, from the 3 lists of 
  181.                 // variable declarations, assignment statements and 
  182.                 // statements occurring within the sample loop
  183. {
  184.     int i;
  185.     char *str;    
  186.  
  187.     fp = fopen(file,"a");
  188.     if(!fp) {
  189.         NXRunAlertPanel("patchmix","This file can't be opened. Check out the directory. %s","OK",NULL,NULL,file);
  190.         return 0;
  191.     }
  192.     fprintf(fp, "\tfloat amp;\n");
  193.     fprintf(fp, "\tfloat out[2];\n");
  194.  
  195.     for(i = 0; i < [varList count]; i++) {
  196.         str = [[varList objectAt:i] getString];
  197.         fprintf(fp,"%s",str);
  198.     }
  199.     fprintf(fp, "\tnsamps = setnote(p[0],p[1],0);\n"); 
  200.     fprintf(fp, "\tchans = sfchans(&sfdesc[0]);\n");
  201.  
  202. // initial assignment statements
  203.     for(i = 0; i < [assignList count]; i++) {
  204.         str = [[assignList objectAt:i] getString];
  205.         fprintf(fp,"%s",str);
  206.     }
  207.  
  208. //  sample loop statements (signal processing)
  209.     fprintf(fp, "\tfor(i = 0; i < nsamps; i++) {\n");
  210.     for(i = 0; i < [loopList count]; i++) {
  211.         str = [[loopList objectAt:i] getString];
  212.         fprintf(fp,"%s",str);
  213.     }
  214.     
  215.     fclose(fp);
  216.     return self;
  217. }
  218.  
  219. - tail            // end of instrument code 
  220. {
  221.     int i;
  222.     char *str;    
  223.     
  224.     fp = fopen(file,"a");
  225.     if(!fp) {
  226.         NXRunAlertPanel("patchmix","This file can't be opened. Check out the directory. %s","OK",NULL,NULL,file);
  227.         return 0;
  228.     }
  229.     fprintf(fp, "\t\tADDOUT(out,0);\n\t}\n");
  230.  
  231.     fprintf(fp, "\tendnote(0);\n");
  232.  
  233.     for(i = 0; i < [endList count]; i++) {
  234.         str = [[endList objectAt:i] getString];
  235.         fprintf(fp,"%s",str);
  236.     }
  237.  
  238.     fprintf(fp, "}\n");
  239.  
  240.     fclose(fp);
  241.     return self;
  242. }
  243.  
  244. - profile:(char *)cmixDir        // writes cmix "profile.c", which introduces your instrument
  245.                         // into the list of cmix functions when compiled with cmix objects
  246. {
  247.     char profile[80];
  248.  
  249.     sprintf(profile,"%s/profile.c",directory);
  250.     fp = fopen(profile,"w");
  251.     if(!fp) {
  252.         NXRunAlertPanel("patchmix","This file can't be opened. Check out the directory. %s","OK",NULL,NULL,profile);
  253.         return 0;
  254.     }
  255.  
  256.     fprintf(fp,"#include \"%s/H/ugens.h\"\n",cmixDir);
  257.     fprintf(fp,"int FSPACE = 1;\n");
  258.     fprintf(fp,"int NBYTES = 32768;\n\n");
  259.     fprintf(fp,"profile()\n{\n");
  260.     fprintf(fp,"\tUG_INTRO(\"%s\",%s);\n}\n",name,name);
  261.     fclose(fp);
  262.     return self;
  263. }
  264.  
  265. - makeWithCmd:(char *)cmdDir andCmix:(char *)cmixDir     // writes out makefile 
  266. {
  267.     char makefile[80];
  268.     
  269.     sprintf(makefile,"%s/Makefile",directory);
  270.     fp = fopen(makefile,"w");
  271.     if(!fp) {
  272.         NXRunAlertPanel("patchmix","This file can't be opened. Check out the directory. %s","OK",NULL,NULL,makefile);
  273.         return 0;
  274.     }
  275.  
  276.     fprintf(fp,"CFLAGS =  -O\n");
  277.     fprintf(fp,"POBJECTS = %s.o profile.o\n",name);
  278.     fprintf(fp,"LDFLAGS =  %s/cmix.o %s/lib/genlib.a -lm\n\n",cmdDir,cmixDir);
  279.     fprintf(fp,"%s:  %s/H/ugens.h $(POBJECTS) %s/cmix.o\n", name,cmixDir, cmdDir);
  280.     fprintf(fp,"\tcc -o %s $(POBJECTS) $(LDFLAGS)\n",name);
  281.     fclose(fp);    
  282.     return self;
  283. }
  284.  
  285.  
  286. - freeUgens
  287. {
  288.     [ugenList freeObjects];
  289.     [ugenList empty];
  290.     [self freeCodeLists];
  291.     return self;
  292. }
  293.  
  294. - freeCodeLists
  295. {
  296.     [varList freeObjects];
  297.     [varList empty];
  298.     [assignList freeObjects];
  299.     [assignList empty];
  300.     [loopList freeObjects];
  301.     [loopList empty];
  302.     [endList freeObjects];
  303.     [endList empty];
  304.     return self;
  305. }
  306.  
  307. @end
  308.