This is Looching.m in view mode; [Download] [Up]
/* Generated by Interface Builder */ #include <libc.h> #include <strings.h> #import "Looching.h" #import <appkit/Form.h> #import <appkit/Slider.h> #import <musickit/musickit.h> #import <musickit/synthpatches/synthpatches.h> #import "LoochPerformer.h" #import "Bark.h" #import "RandomIzer.h" #import "LoochWaves.h" #define NWAVES 7 #define FADELO 10 #define FADEHI 20 #define AMPLO 0.05 #define AMPHI 0.1 #define DURSHORT 5.0 #define DURLONG 20.0 #define SLEEPLO 2 #define SLEEPHI 10 extern int Pid; @implementation Looching /* these are the global vars */ static int IsLooching = 0; static int ToneRow = 0; static int TimbreSet = 0; static int fds[2]; static int isPiped = 0; double VibWide; double VibRate; double FreqSpread; - setInVibRate:anObject { inVibRate = anObject; [inVibRate setDoubleValue:0.5]; VibRate = 0.5; /* initialize the variable */ return self; } - setInVibWidth:anObject { inVibWidth = anObject; [inVibWidth setDoubleValue:1.0]; VibWide = 1.0; /* initialize the variable */ return self; } - setOutVibRate:anObject { outVibRate = anObject; [outVibRate setDoubleValue:0.5 at:0]; return self; } - setOutVibWidth:anObject { outVibWidth = anObject; [outVibWidth setDoubleValue:1.0 at:0]; return self; } - setInSpread:anObject { inSpread = anObject; [inSpread setDoubleValue:1.0]; FreqSpread = 1.0; /* initialize the variable */ return self; } - setOutSpread:anObject { outSpread = anObject; [outSpread setDoubleValue:1.0 at:0]; return self; } - displaySpread:sender { double val; val = [inSpread doubleValue]; [outSpread setDoubleValue:val at:0]; return self; } - setParams:sender { FreqSpread = [inSpread doubleValue]; VibWide = [inVibWidth doubleValue]; VibRate = [inVibRate doubleValue]; if (isPiped == 1) { write(fds[1], (char *) &FreqSpread, sizeof(double)); write(fds[1], (char *) &VibWide, sizeof(double)); write(fds[1], (char *) &VibRate, sizeof(double)); write(fds[1], (char *) &ToneRow, sizeof(int)); } return self; } - StartAndStop:sender { FreqSpread = [inSpread doubleValue]; VibWide = [inVibWidth doubleValue]; VibRate = [inVibRate doubleValue]; if (IsLooching == 0) { IsLooching = 1; if (!isPiped) { pipe(fds); /* set up communications with the child process */ isPiped = 1; } Pid = fork(); if (Pid == 0) { /* child does the playing */ int i,j,n; int sleeptime; int nfound = 0; double fade,coin; int isPlaying[4] = {0, 0, 0, 0}; double durations[4] = {0.0, 0.0, 0.0, 0.0}; double val,sval,fval; id aLoochPerformer[4],theOrch; SynthInstrument *anIns[4]; id RanNum; id aPartials[NWAVES]; double *LWfreqptr,*LWampptr; fd_set rfds,wfds; struct timeval ttt; RanNum = [RandomIzer new]; [RanNum setit]; /* Create the Partials objects. */ for (i = 0; i < NWAVES; i++) { aPartials[i] = [Partials new]; LWfreqptr = freqs[TimbreSet][i]; LWampptr = amps[TimbreSet][i]; /* Fill the object with data. */ [aPartials[i] setPartialCount:7 freqRatios:LWfreqptr ampRatios:LWampptr phases:NULL orDefaultPhase:0.0]; } /* Create the Orchestra which manages all DSP activity. */ theOrch = [Orchestra new]; if (![theOrch open]) { fprintf(stderr, "Can't open the DSP!\n"); Pid = 0; exit(-1); } [theOrch setSamplingRate:22050.0]; for(i = 0; i < 4; i++) { /* make performers */ aLoochPerformer[i] = [LoochPerformer new]; /* create instruments */ anIns[i] = [SynthInstrument new]; /* Assign the class of SynthPatch. */ [anIns[i] setSynthPatchClass:[Bark class]]; /* set up the performer--instrument connection and get ready to roll */ [[aLoochPerformer[i] noteSender] connect:[anIns[i] noteReceiver]]; [aLoochPerformer[i] activate]; [aLoochPerformer[i] pause]; /* Start paused */ } [theOrch run]; /* Start the DSP. */ sleeptime = 0.0; while(1) { for(j = 0; j < 4; j++) { if (isPlaying[j]) { durations[j] -= sleeptime; if (durations[j] <= 0) { /* choose the fadeout dur */ fade = [RanNum GetNumberRangeHi:FADEHI Lo:FADELO]; [aLoochPerformer[j] setdecay:fade]; [aLoochPerformer[j] stopNote]; [theOrch flushTimedMessages]; durations[j] += fade; isPlaying[j] = 0; } } else { durations[j] -= sleeptime; if (durations[j] > 0) { ; } else { /* play a new note? */ coin = [RanNum GetNumber]; if (coin < 0.5) { /* set the waveform */ n = [RanNum GetIndex:(NWAVES-1)]; [aLoochPerformer[j] setwave:aPartials[n]]; /* set the frequency */ n = [RanNum GetIndex:toneindex[ToneRow]]; fval = pitches[ToneRow][n]; sval = ( ([RanNum GetNumber:FreqSpread]) / 100.0 ) * fval; [aLoochPerformer[j] setfreq:fval spread:sval]; /* set the amplitude */ val = [RanNum GetNumberRangeHi:AMPHI Lo:AMPLO]; [aLoochPerformer[j] setamp:val]; /* set vibrato0 */ val = [RanNum GetNumber:VibRate]; [aLoochPerformer[j] setvibfreq0:val]; /* set amp0 */ val = ( ([RanNum GetNumber:VibWide]) / 100.0 ) * fval; [aLoochPerformer[j] setvibamp0:val]; /* set vibrato1 */ val = [RanNum GetNumber:VibRate]; [aLoochPerformer[j] setvibfreq1:val]; /* set amp1 */ val = ( ([RanNum GetNumber:VibWide]) / 100.0 ) *fval; [aLoochPerformer[j] setvibamp1:val]; /* set attack time */ fade = [RanNum GetNumberRangeHi:FADEHI Lo:FADELO]; [aLoochPerformer[j] setattack:fade]; /* set note duration */ durations[j] = [RanNum GetNumberRangeHi:DURLONG Lo:DURSHORT]; [theOrch flushTimedMessages]; [aLoochPerformer[j] startNote]; [theOrch flushTimedMessages]; isPlaying[j] = 1; } } } } sleeptime = [RanNum GetIndexRangeHi:SLEEPHI Lo:SLEEPLO]; ttt.tv_sec = sleeptime; ttt.tv_usec = 0; FD_ZERO(&rfds); FD_SET(fds[0],&rfds); nfound = select(5, &rfds, 0, 0, &ttt); if ( (nfound > 0) && (FD_ISSET(fds[0], &rfds)) ) { read(fds[0], (char *) &FreqSpread, sizeof(double)); read(fds[0], (char *) &VibWide, sizeof(double)); read(fds[0], (char *) &VibRate, sizeof(double)); read(fds[0], (char *) &ToneRow, sizeof(int)); } } } } else { char s[10] = "kill "; char num[10]; sprintf(num,"%d",Pid); strcat(s,num); system(s); IsLooching = 0; Pid = 0; } return self; } - trArnie:sender { ToneRow = 3; TimbreSet = 2; return self; } - trBach:sender { ToneRow = 4; TimbreSet = 0; return self; } - displayVibWidth:sender { double val; val = [inVibWidth doubleValue]; [outVibWidth setDoubleValue:val at:0]; return self; } - displayVibRate:sender { double val; val = [inVibRate doubleValue]; [outVibRate setDoubleValue:val at:0]; return self; } - trDrone:sender { ToneRow = 2; TimbreSet = 1; return self; } - trMorning:sender { ToneRow = 1; TimbreSet = 1; return self; } - trOriginal:sender { ToneRow = 0; TimbreSet = 0; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.