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.