home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Education Sampler 1992 [NeXTSTEP]
/
Education_1992_Sampler.iso
/
SoundAndMusic
/
Hyperupic
/
Hyperupic.app
/
HyperupicGen.m
< prev
next >
Wrap
Text File
|
1992-08-20
|
29KB
|
1,581 lines
#import "HyperupicGen.h"
@implementation HyperupicGen
+ create {
id newInstance;
newInstance = [ self new ];
return newInstance;
}
- init {
[super init];
[self setDefaults];
status = IDLE;
openReq = [OpenPanel new];
openMapReq = [OpenPanel new];
openTableReq = [OpenPanel new];
saveReq = [SavePanel new];
return self;
}
- setDefaults {
interp = 256;
srate = 44100.;
pi = 4 * atan(1.);
twopi = 8 * atan(1.);
ampref = 1.;
synt = 0.;
freqcon = 100.;
freqdiff = 50.;
tablesize = Default_Osc_Size;
x = -1;
y = -1;
xstart = -1;
xend = -1;
ystart = -1;
yend = -1;
srrand(76914020);
gotImage = NO;
gotMapFile = NO;
gotTableFile = NO;
oscilTable = NO;
savedSoundFile = YES;
gotSoundFileName = NO;
oscInit = NO;
adjusted = NO;
strcpy( harmsText, ".7 0 .2 0 .1\0" );
mapper = @selector(mapRGB);
dimension = @selector(genNorm);
display = @selector(displayMinMax);
coordinate = @selector(setYcoor);
spread = @selector(genHarmSeries);
minmax = @selector(mmHarmSeries);
osctable = @selector(setOscCos);
return self;
}
- (float) howFar {
return howfar;
}
- (int) xval {
return x;
}
- (int) yval {
return y;
}
- (int) xstartVal {
return xstart;
}
- (int) ystartVal {
return ystart;
}
- (int) xendVal {
return xend;
}
- (int) yendVal {
return yend;
}
- setHarmsText: sender {
strcpy( harmsText, [sender stringValue] );
return self;
}
- setxVal: sender {
int grabber;
if ( (grabber = [sender intValue]) > 0 )
xend = x = grabber;
xstart = 0;
return self;
}
- setyVal: sender {
int grabber;
if ( (grabber = [sender intValue]) > 0 )
yend = y = grabber;
ystart = 0;
return self;
}
- setxstartVal: sender {
int grabber;
if ( (grabber = [sender intValue]) > 0 && grabber < x )
xstart = grabber;
return self;
}
- setystartVal: sender {
int grabber;
if ( (grabber = [sender intValue]) > 0 && grabber < y )
ystart = grabber;
return self;
}
- setxendVal: sender {
int grabber;
if ( (grabber = [sender intValue]) > 0 && grabber < x )
xend = grabber;
return self;
}
- setyendVal: sender {
int grabber;
if ( (grabber = [sender intValue]) > 0 && grabber < y )
yend = grabber;
return self;
}
- (int) getStatus {
return status;
}
- (float) getBigee {
return bigee;
}
- (float) getDuration {
return duration;
}
- (float) adjustFrequency {
if (adjusted == YES) {
adjusted = NO;
return (freqcon /= srate / (float) tablesize);
}
else {
adjusted = YES;
return (freqcon *= srate / (float) tablesize);
}
}
- pause {
status = PAUSED;
return self;
}
- snuff {
status = DYING;
[self resume];
return self;
}
- resume // Gets called from the other thread
{
kern_return_t ec;
msg_header_t msg = {0,
TRUE,
sizeof(msg_header_t),
MSG_TYPE_NORMAL,
0};
if (status == IDLE && appToObjPort != PORT_NULL)
return nil;
msg.msg_local_port = PORT_NULL;
msg.msg_remote_port = appToObjPort;
ec = msg_send(&msg, SEND_TIMEOUT, 0);
// huh? (look below)
if (ec == SEND_TIMED_OUT);
return self;
}
- _waitForMessage { // David Jaffe's pause thread gift
struct {
msg_header_t header;
char data[MSG_SIZE_MAX];
} msg;
status = PAUSED;
(void)port_allocate(task_self(), &appToObjPort);
msg.header.msg_size = MSG_SIZE_MAX;
msg.header.msg_local_port = appToObjPort;
(void)msg_receive(&msg.header, MSG_OPTION_NONE,0);
(void)port_deallocate(task_self(),appToObjPort);
appToObjPort = PORT_NULL;
if (status != DYING)
status = RUNNING;
return self;
}
- setXcoor {
N = xend - xstart;
return self;
}
- setYcoor {
N = yend - ystart;
return self;
}
- displayFreqs: sender {
if ( x < 0 || y < 0 ) {
NXRunAlertPanel("The Beach Boys","Heavens to Murgatroyd! Need coordinates!",
"okie",NULL,NULL,NULL);
return nil;
}
[self perform:display];
return self;
}
- displayAll {
int i,
length;
char bonk[1024];
static NXRect wRect = {{120.0, 100.0},{150.0,325.0}};
[self allocateDataspace];
[self perform:coordinate];
[self perform:spread];
freqDisplay = [[TextView alloc] initFrame:&wRect];
[[freqDisplay window] setDelegate:self];
[freqDisplay setTitle:"Frequencies"];
if ( (wRect.origin.x < 20.0) || (wRect.origin.y < 20.0) ) {
wRect.origin.x = 120.0;
wRect.origin.y = 100.0;
}
else
NXOffsetRect(&wRect, 20.0, -20.0);
for ( i=0; i < N; i++ ) {
sprintf(bonk," %3f\n", *(freqs+i));
length = [freqDisplay textLength];
[freqDisplay setSel:length :length];
[freqDisplay replaceSel:bonk];
}
return self;
}
- displayMinMax {
int length;
char bonk[1024];
static NXRect wRect = {{250.0, 300.0},{200.0,100.0}};
[self perform:coordinate];
[self perform:minmax];
freqDisplay = [[TextView alloc] initFrame:&wRect];
[[freqDisplay window] setDelegate:self];
[freqDisplay setTitle:"Frequency Extrema"];
if ( (wRect.origin.x < 20.0) || (wRect.origin.y < 20.0) ) {
wRect.origin.x = 120.0;
wRect.origin.y = 100.0;
}
else
NXOffsetRect(&wRect, 20.0, -20.0);
sprintf(bonk,"minimum:\n%6f\n", mm.min);
length = [freqDisplay textLength];
[freqDisplay setSel:length :length];
[freqDisplay replaceSel:bonk];
sprintf(bonk,"\nmaximum:\n%6f\n", mm.max);
length = [freqDisplay textLength];
[freqDisplay setSel:length :length];
[freqDisplay replaceSel:bonk];
return self;
}
- (char *) getImagePath {
return imageFile;
}
- (char *) getMapPath {
return mapFile;
}
- (char *) getTablePath {
return tableFile;
}
- (char *) getSoundPath {
return soundFile;
}
- (BOOL) getGotImage {
return gotImage;
}
- (BOOL) getGotMapFile {
return gotMapFile;
}
- (BOOL) getGotTableFile {
return gotTableFile;
}
- (BOOL) getOscilTable {
return oscilTable;
}
- (BOOL) getSavedSoundFile {
return savedSoundFile;
}
- setImagePath: sender {
strcpy( imageFile, [sender stringValue]);
[self openImage];
return self;
}
- setMapPath: sender {
strcpy( mapFile, [sender stringValue]);
[self openMapFile];
return self;
}
- setTablePath: sender {
strcpy( tableFile, [sender stringValue]);
[self openTableFile];
return self;
}
- ampref: sender {
ampref = [sender doubleValue];
return self;
}
- time: sender {
interp = [sender intValue];
return self;
}
- freqcon: sender {
freqcon = (float) [sender doubleValue];
return self;
}
- freqdiff: sender {
freqdiff = (float) [sender doubleValue];
return self;
}
- samplingRate: sender {
srate = (float) [sender doubleValue];
return self;
}
- setSeed: sender {
seed = [sender intValue];
return self;
}
- setSynt: sender {
synt = [sender doubleValue];
return self;
}
- openRequest:sender
{
static const char *const types[] = {NULL, NULL};
[openReq setTitle:"looking for an Image file"];
if ([openReq runModalForTypes:types]) {
strcpy(imageFile, [openReq filename]);
[self openImage];
}
return self;
}
- openMapRequest:sender
{
static const char *const types[] = {NULL, NULL};
[openMapReq setTitle:"looking for a Mapping file"];
if ([openReq runModalForTypes:types]) {
strcpy(mapFile, [openReq filename]);
if ( ![self openMapFile] )
return nil;
}
return self;
}
- openTableRequest: sender
{
static const char *const types[] = {NULL, NULL};
[openTableReq setTitle:"looking for an oscillator Table file"];
if ([openReq runModalForTypes:types]) {
strcpy(tableFile, [openReq filename]);
if ( ![self openTableFile] )
return nil;
}
return self;
}
- saveRequest:sender
{
if (savedSoundFile == YES)
return self;
if (gotSoundFileName == NO)
[self saveInRequest:sender];
else
[self writeSound];
return self;
}
- saveInRequest:sender
{
[saveReq setTitle:"looking to be Saved!"];
[saveReq setRequiredFileType:""];
if ( ![saveReq runModal] )
return nil;
strcpy(soundFile, [saveReq filename]);
gotSoundFileName = YES;
[self writeSound];
return self;
}
- openImage {
NXColorSpace cs;
if (pict != nil) {
[pict free];
gotImage = NO;
}
pict = [[NXBitmapImageRep alloc] initFromFile:imageFile];
if (pict == nil) {
NXRunAlertPanel("Oral Hygiene",
"Lame user error. Couldn't open your imagined file.",
"okie",NULL,NULL,NULL);
return nil;
}
if ( (cs = [pict colorSpace]) != NX_RGBColorSpace ) {
NXRunAlertPanel("Roman Polanski","Retreat! Your image is not RGB approved!",
"okie",NULL,NULL,NULL);
return nil;
}
if ( ( [pict bitsPerPixel]) != 24 ) {
NXRunAlertPanel("Doris Day","Heavens to Murgatroyd! Use a 24-bit image!",
"dokie",NULL,NULL,NULL);
return nil;
}
pictdata = [pict data];
xend = x = [pict pixelsWide];
yend = y = [pict pixelsHigh];
xstart = ystart = 0;
gotImage = YES;
return self;
}
- openMapFile {
int i;
FILE *fp;
if ( mapFunk.data != NULL ) {
free( mapFunk.data );
gotMapFile = NO;
}
mapFunk.elms = Max_Table_Size;
mapFunk.data = (float *) space( Max_Table_Size, sizeof(float) );
if ( (fp = fopen( mapFile, "r" )) == NULL ) {
NXRunAlertPanel("Hamburger Helper","Lame user error. Couldn't open map file.",
"okie",NULL,NULL,NULL);
return nil;
}
i = 0;
while ( (fread(mapFunk.data+i, sizeof(float), 1, fp)) != 0 &&
i < Max_Table_Size )
++i;
mapFunk.elms = (i-1);
gotMapFile = YES;
return self;
}
- openTableFile {
int i;
FILE *fp;
if ( oscTable.data != NULL ) {
free( oscTable.data );
gotTableFile = NO;
}
oscTable.elms = Max_Osc_Size;
oscTable.data = (float *) space( Max_Osc_Size, sizeof(float) );
if ( (fp = fopen( tableFile, "r" )) == NULL ) {
NXRunAlertPanel("The Free Market is Fucked",
"Egad! Couldn't open oscillator table!",
"dokie",NULL,NULL,NULL);
return nil;
}
i = 0;
while ( (fread(oscTable.data+i, sizeof(float), 1, fp)) != 0 &&
i < Max_Osc_Size )
++i;
oscTable.elms = (i-1);
oscTable.data = (float *) realloc( oscTable.data, i * sizeof(float) );
if (oscilTable == YES)
tablesize = i - 1;
gotTableFile = YES;
return self;
}
- allocSound {
int width = 2,
size;
size = interp * maxtime;
soundPoint = 0;
bigee = 0.;
duration = 0.;
if ( sfh != NULL )
SNDFree(sfh);
SNDAlloc( &sfh, (size*width), SND_FORMAT_LINEAR_16, (int) srate, 1, 0);
SNDGetDataPointer(sfh, (char **)&soundData, &size, &width );
return self;
}
- writeSound {
int err;
err = SNDWriteSoundfile( soundFile, sfh );
if (err != SND_ERR_NONE) {
NXRunAlertPanel("Oedipa Maas","Gadzooks! Couldn't write your sound file!",
"okie",NULL,NULL,NULL);
return nil;
}
if (status == IDLE)
savedSoundFile = YES;
return self;
}
- playSound: sender {
SNDStartPlaying(sfh, 1, 0, 1, NULL, NULL);
return self;
}
- stopPlaying: sender {
SNDStop(1);
return self;
}
- allocateDataspace {
if ( ozone != NULL )
NXDestroyZone(ozone);
ozone = NXCreateZone( 3 * (N + interp) *
sizeof(float), vm_page_size, 0 );
freqs = (float *) zspace( ozone, N+1, sizeof(float) );
channel = (float *) zspace( ozone, N<<1+1, sizeof(float) );
output = (float *) zspace( ozone, interp+1, sizeof(float) );
return self;
}
- reverseMapping: sender {
int i,
elms;
float safety;
if (gotMapFile == NO) {
NXRunAlertPanel("Encephalitis","Lordy Lordy! Load amplitude map file first!",
"dokie",NULL,NULL,NULL);
return nil;
}
elms = mapFunk.elms;
for ( i=0; i < (elms>>1); i++ ) {
safety = *(mapFunk.data+i);
*(mapFunk.data+i) = *(mapFunk.data+(elms-1)-i);
*(mapFunk.data+(elms-1)-i) = safety;
}
return self;
}
- runGen {
status = RUNNING;
oscInit = NO;
srrand(seed);
howfar = 0.;
// call selected generation method
if ( [self perform:dimension] ) {
SNDStop(1);
NXBeep();
}
status = IDLE;
return self;
}
- genNorm {
int cnt;
N = yend - ystart; // set number of frequency amplitude pairs
ampscale = ampref / (float) N;
maxtime = xend;
[self allocSound];
savedSoundFile = NO;
[self allocateDataspace];
[self perform:spread]; // create frequency axis values
// main loop (iterate for each value of axis)
for ( timedim = xstart; timedim < maxtime; timedim++ ) {
timeinc = timedim * Bytes_Per_Pixel;
// check for death or pause
if (status > 2) {
if (status == PAUSED)
[self _waitForMessage];
else {
if (status == DYING)
return nil;
}
}
// increment along time axis
cnt = (N-1);
for ( freqdim = ystart; freqdim < yend; freqdim++ ) {
datainc = cnt * x * Bytes_Per_Pixel;
*(channel+(freqdim<<1)+1) = *(freqs+freqdim);
[self perform:mapper];
cnt--;
}
if ( ![self oscbank] )
return nil;
[self writeoutput];
howfar = ((float) timedim - xstart) / ((float) maxtime - xstart);
}
return self;
}
- genRotNorm {
int cnt;
N = xend - xstart; // set number of frequency amplitude pairs
ampscale = ampref / (float) N;
maxtime = yend;
[self allocSound];
savedSoundFile = NO;
[self allocateDataspace];
[self perform:spread]; // create frequency axis values
// main loop (iterate for each value of axis)
for ( timedim = (ystart * x * Bytes_Per_Pixel);
timedim < (maxtime * x * Bytes_Per_Pixel);
timedim += (x * Bytes_Per_Pixel) ) {
timeinc = timedim;
// check for death or pause
if (status > 2) {
if (status == PAUSED)
[self _waitForMessage];
else {
if (status == DYING)
return nil;
}
}
// increment along time axis
cnt = 0;
for ( freqdim = xstart; freqdim < xend; freqdim++ ) {
datainc = freqdim * Bytes_Per_Pixel;
*(channel+(freqdim<<1)+1) = *(freqs+freqdim);
[self perform:mapper];
cnt++;
}
if ( ![self oscbank] )
return nil;
[self writeoutput];
howfar = ( (float) (timedim / (x * Bytes_Per_Pixel)) - ystart )
/ ((float) maxtime - ystart);
}
return self;
}
- genRetro {
int cnt;
N = yend - ystart; // set number of frequency amplitude pairs
ampscale = ampref / (float) N;
maxtime = xend;
[self allocSound];
savedSoundFile = NO;
[self allocateDataspace];
[self perform:spread]; // create frequency axis values
// main loop (iterate for each value of axis)
for ( timedim=(maxtime-1); timedim >= xstart; timedim-- ) {
timeinc = timedim * Bytes_Per_Pixel;
// check for death or pause
if (status > 2) {
if (status == PAUSED)
[self _waitForMessage];
else {
if (status == DYING)
return nil;
}
}
// increment along time axis
cnt = (N-1);
for ( freqdim = ystart; freqdim < yend; freqdim++ ) {
datainc = cnt * x * Bytes_Per_Pixel;
*(channel+(freqdim<<1)+1) = *(freqs+freqdim);
[self perform:mapper];
cnt--;
}
if ( ![self oscbank] )
return nil;
[self writeoutput];
howfar = ( (float) (maxtime-1) - timedim ) /
((float) (maxtime-1) - xstart);
}
return self;
}
- genRotRetro {
int cnt;
N = xend - xstart; // set number of frequency amplitude pairs
ampscale = ampref / (float) N;
maxtime = yend;
[self allocSound];
savedSoundFile = NO;
[self allocateDataspace];
[self perform:spread]; // create frequency axis values
// main loop (iterate for each value of axis)
for ( timedim = ( (maxtime-1) * x * Bytes_Per_Pixel);
timedim >= ystart * x * Bytes_Per_Pixel;
timedim -= (x * Bytes_Per_Pixel) ) {
timeinc = timedim;
// check for death or pause
if (status > 2) {
if (status == PAUSED)
[self _waitForMessage];
else {
if (status == DYING)
return nil;
}
}
// increment along time axis
cnt = 0;
for ( freqdim = xstart; freqdim < xend; freqdim++ ) {
datainc = freqdim * Bytes_Per_Pixel;
*(channel+(freqdim<<1)+1) = *(freqs+freqdim);
[self perform:mapper];
cnt++;
}
if ( ![self oscbank] )
return nil;
[self writeoutput];
howfar = ( (float) (maxtime-1) - (timedim / (x * Bytes_Per_Pixel)) )
/ ((float) (maxtime-1) - ystart);
}
return self;
}
- genNormInv {
int cnt;
N = yend - ystart; // set number of frequency amplitude pairs
ampscale = ampref / (float) N;
maxtime = xend;
[self allocSound];
savedSoundFile = NO;
[self allocateDataspace];
[self perform:spread]; // create frequency axis values
// main loop (iterate for each value of axis)
for ( timedim=xstart; timedim < maxtime; timedim++ ) {
timeinc = timedim * Bytes_Per_Pixel;
// check for death or pause
if (status > 2) {
if (status == PAUSED)
[self _waitForMessage];
else {
if (status == DYING)
return nil;
}
}
// increment along time axis
cnt = (N-1);
for ( freqdim = ystart; freqdim < yend; freqdim++ ) {
datainc = cnt * x * Bytes_Per_Pixel;
*(channel+(freqdim<<1)+1) = *(freqs+cnt);
[self perform:mapper];
cnt--;
}
if ( ![self oscbank] )
return nil;
[self writeoutput];
howfar = ( (float) timedim - xstart ) / ((float) maxtime - xstart);
}
return self;
}
- genRotNormInv {
int cnt;
N = xend - xstart; // set number of frequency amplitude pairs
ampscale = ampref / (float) N;
maxtime = yend;
[self allocSound];
savedSoundFile = NO;
[self allocateDataspace];
[self perform:spread]; // create frequency axis values
// main loop (iterate for each value of axis)
for ( timedim = (ystart * x * Bytes_Per_Pixel);
timedim < (maxtime * x * Bytes_Per_Pixel);
timedim += (x * Bytes_Per_Pixel) ) {
timeinc = timedim;
// check for death or pause
if (status > 2) {
if (status == PAUSED)
[self _waitForMessage];
else {
if (status == DYING)
return nil;
}
}
// increment along time axis
cnt = 0;
for ( freqdim = xstart; freqdim < xend; freqdim++ ) {
datainc = freqdim * Bytes_Per_Pixel;
*(channel+(freqdim<<1)+1) = *(freqs + ( (x-1) - freqdim ));
[self perform:mapper];
cnt++;
}
if ( ![self oscbank] )
return nil;
[self writeoutput];
howfar = ( ((float) timedim / (x * Bytes_Per_Pixel)) - ystart ) /
((float) maxtime - ystart);
}
return self;
}
- genRetroInv {
int cnt;
N = yend - ystart; // set number of frequency amplitude pairs
ampscale = ampref / (float) N;
maxtime = xend;
[self allocSound];
savedSoundFile = NO;
[self allocateDataspace];
[self perform:spread]; // create frequency axis values
// main loop (iterate for each value of axis)
for ( timedim=(maxtime-1); timedim >= xstart; timedim-- ) {
timeinc = timedim * Bytes_Per_Pixel;
// check for death or pause
if (status > 2) {
if (status == PAUSED)
[self _waitForMessage];
else {
if (status == DYING)
return nil;
}
}
// increment along time axis
cnt = (N-1);
for ( freqdim = ystart; freqdim < yend; freqdim++ ) {
datainc = cnt * x * Bytes_Per_Pixel;
*(channel+(freqdim<<1)+1) = *(freqs+cnt);
[self perform:mapper];
cnt--;
}
if ( ![self oscbank] )
return nil;
[self writeoutput];
howfar = ( (float) (maxtime-1) - timedim ) /
((float) (maxtime-1) - xstart);
}
return self;
}
- genRotRetroInv {
int cnt;
N = xend - xstart; // set number of frequency amplitude pairs
ampscale = ampref / (float) N;
maxtime = yend;
[self allocSound];
savedSoundFile = NO;
[self allocateDataspace];
[self perform:spread]; // create frequency axis values
// main loop (iterate for each value of axis)
for ( timedim = ( (maxtime-1) * x * Bytes_Per_Pixel);
timedim >= ystart * x * Bytes_Per_Pixel;
timedim -= (x * Bytes_Per_Pixel) ) {
timeinc = timedim;
// check for death or pause
if (status > 2) {
if (status == PAUSED)
[self _waitForMessage];
else {
if (status == DYING)
return nil;
}
}
// increment along time axis
cnt = 0;
for ( freqdim = xstart; freqdim < xend; freqdim++ ) {
datainc = freqdim * Bytes_Per_Pixel;
*(channel+(freqdim<<1)+1) = *(freqs + ( (x-1) - freqdim ));
[self perform:mapper];
cnt++;
}
if ( ![self oscbank] )
return nil;
[self writeoutput];
howfar = ( (float) (maxtime-1) - (timedim / (x * Bytes_Per_Pixel)) )
/ ((float) maxtime - ystart);
}
return self;
}
- genHarmSeries {
int i;
for ( i=0; i<N; i++ )
*(freqs+i) = freqcon + (freqdiff * i);
return self;
}
- genScale {
int i;
*freqs = freqcon;
for ( i=1; i<N; i++ )
*(freqs+i) = *(freqs+i-1) * freqdiff;
return self;
}
- mmHarmSeries {
mm.min = freqcon;
mm.max = (N-1) * freqdiff + freqcon;
return self;
}
- mmScale {
mm.min = freqcon;
mm.max = pow(freqdiff, (N-1)) * freqcon;
return self;
}
- mapRGB {
static float scaler = 766.0;
*(channel+(freqdim<<1)) = *(mapFunk.data + (int) ( ( (float) (
(int) ( *(pictdata+datainc+timeinc) ) +
(int) ( *(pictdata+datainc+timeinc+1) ) +
(int) ( *(pictdata+datainc+timeinc+2) )) / scaler ) *
(float) mapFunk.elms ));
return self;
}
- mapR {
static float scaler = 256.0;
*(channel+(freqdim<<1)) = *(mapFunk.data + (int) ( ( (float) (
(int) ( *(pictdata+datainc+timeinc) )) / scaler ) *
(float) mapFunk.elms ));
return self;
}
- mapG {
static float scaler = 256.0;
*(channel+(freqdim<<1)) = *(mapFunk.data + (int) ( ( (float) (
(int) ( *(pictdata+datainc+timeinc+1) )) / scaler ) *
(float) mapFunk.elms ));
return self;
}
- mapB {
static float scaler = 256.0;
*(channel+(freqdim<<1)) = *(mapFunk.data + (int) ( ( (float) (
(int) ( *(pictdata+datainc+timeinc+2) )) / scaler ) *
(float) mapFunk.elms ));
return self;
}
- mapRG {
static float scaler = 511.0;
*(channel+(freqdim<<1)) = *(mapFunk.data + (int) ( ( (float) (
(int) ( *(pictdata+datainc+timeinc) ) +
(int) ( *(pictdata+datainc+timeinc+1) )) / scaler ) *
(float) mapFunk.elms ));
return self;
}
- mapRB {
static float scaler = 511.0;
*(channel+(freqdim<<1)) = *(mapFunk.data + (int) ( ( (float) (
(int) ( *(pictdata+datainc+timeinc) ) +
(int) ( *(pictdata+datainc+timeinc+2) )) / scaler ) *
(float) mapFunk.elms ));
return self;
}
- mapGB {
static float scaler = 511.0;
*(channel+(freqdim<<1)) = *(mapFunk.data + (int) ( ( (float) (
(int) ( *(pictdata+datainc+timeinc+1) ) +
(int) ( *(pictdata+datainc+timeinc+2) )) / scaler ) *
(float) mapFunk.elms ));
return self;
}
- selectGenHarmSeries: sender {
spread = @selector(genHarmSeries);
minmax = @selector(mmHarmSeries);
return self;
}
- selectGenScale: sender {
spread = @selector(genScale);
minmax = @selector(mmScale);
return self;
}
- selectDisplayAll: sender {
display = @selector(displayAll);
return self;
}
- selectDisplayMinMax: sender {
display = @selector(displayMinMax);
return self;
}
- selectXcoor: sender {
coordinate = @selector(setXcoor);
return self;
}
- selectYcoor: sender {
coordinate = @selector(setYcoor);
return self;
}
- selectGenNorm: sender {
dimension = @selector(genNorm);
return self;
}
- selectGenRetro: sender {
dimension = @selector(genRetro);
return self;
}
- selectGenRotNorm: sender {
dimension = @selector(genRotNorm);
return self;
}
- selectGenRotRetro: sender {
dimension = @selector(genRotRetro);
return self;
}
- selectGenNormInv: sender {
dimension = @selector(genNormInv);
return self;
}
- selectGenRetroInv: sender {
dimension = @selector(genRetroInv);
return self;
}
- selectGenRotNormInv: sender {
dimension = @selector(genRotNormInv);
return self;
}
- selectGenRotRetroInv: sender {
dimension = @selector(genRotRetroInv);
return self;
}
- selectMapR: sender {
mapper = @selector(mapR);
return self;
}
- selectMapG: sender {
mapper = @selector(mapG);
return self;
}
- selectMapB: sender {
mapper = @selector(mapB);
return self;
}
- selectMapRG: sender {
mapper = @selector(mapRG);
return self;
}
- selectMapRB: sender {
mapper = @selector(mapRB);
return self;
}
- selectMapGB: sender {
mapper = @selector(mapGB);
return self;
}
- selectMapRGB: sender {
mapper = @selector(mapRGB);
return self;
}
- writeoutput
{
int i;
for ( i=0; i < interp; i++ ) {
if (fabs( (*(output+i) *= ampscale) ) > bigee)
bigee = fabs( *(output+i) );
*(soundData + soundPoint + i) = (short) (32767. * *(output+i));
}
soundPoint += interp;
duration = (float) soundPoint / srate;
return self;
}
- selectOscCos: sender {
if (status != IDLE)
return nil;
oscilTable = NO;
tablesize = Default_Osc_Size;
osctable = @selector(setOscCos);
return self;
}
- selectOscComplex: sender {
int i,
grabber;
float hoax;
char *doink;
if (status != IDLE)
return nil;
oscilTable = NO;
doink = (char *) space( 8192, sizeof(char) );
strcpy( doink, harmsText );
harms.data = (float *) space( Max_Harm, sizeof(float) );
tablesize = Default_Osc_Size;
i = 0;
while ( i < Max_Harm ) {
if ( (grabber = sscanf(doink, "%f", &hoax)) == 0 || grabber == EOF)
break;
*(harms.data+i) = hoax;
++i;
if ( (doink = index( doink, ' ' )) == NULL )
break;
while ( isspace(*doink) )
doink++;
}
harms.elms = i;
osctable = @selector(setOscComplex);
return self;
}
- selectOscTable: sender {
if (status != IDLE)
return nil;
tablesize = oscTable.elms - 1;
oscilTable = YES;
osctable = @selector(setOscTable);
return self;
}
- setOscCos {
int i;
float twopioL = twopi / tablesize;
for ( i = 0; i < tablesize+1; i++ )
*(table+i) = cos( twopioL*i );
return self;
}
- setOscComplex {
int i,j;
float twopioL = twopi / tablesize;
for ( i=0; i < tablesize+1; i++ )
*(table+i) = cos( twopioL*i );
for ( j=2; j <= harms.elms; j++ ) {
for ( i=0; i < tablesize+1; i++ )
*(table+i) += cos( j*twopioL*i );
}
return self;
}
- setOscTable {
int i;
if (gotTableFile == NO) {
return nil;
}
tablesize = oscTable.elms - 1;
for ( i=0; i < tablesize+1; i++ )
*(table+i) = *(oscTable.data + i);
return self;
}
- oscbank
{
static float Iinv,
*lastamp,
*lastfreq,
*index,
Pinc;
int i,j,
amp,
freq;
/* first pass: allocate memory to hold previous values
of amplitude and frequency for each channel, the table
index for each oscillator, and the table itself; also
compute constants */
if ( oscInit == NO ) {
if ( funzone != NULL )
NXDestroyZone(funzone);
if (oscilTable == YES)
tablesize = oscTable.elms - 1;
funzone = NXCreateZone( 3 * (N + interp) *
sizeof(float), vm_page_size, 0 );
lastamp = (float *) zspace( funzone, N+1, sizeof(float) );
lastfreq = (float *) zspace( funzone, N+1, sizeof(float) );
index = (float *) zspace( funzone, N+1, sizeof(float) );
table = (float *) zspace( funzone, tablesize+1, sizeof(float) );
for ( i = 0; i < N+1; i++ ) {
*(lastamp+i) = *(lastfreq+i) = 0.;
*(index+i) = prand() * (float) tablesize;
}
if ( ![self perform:osctable] )
return nil;
Iinv = 1. / interp;
Pinc = ( (float) tablesize ) / srate;
oscInit = YES;
}
for ( i = 0; i < interp; i++ )
*(output+i) = 0.;
/* for each channel, compute I samples using linear
interpolation on the amplitude and frequency
control values */
for ( i=0; i < N; i++ ) {
register float a,
ainc,
f,
finc,
address;
freq = ( amp = ( i << 1 ) ) + 1;
if ( *(channel+amp) < synt ) /* skip the little ones */
continue;
*(channel+freq) *= Pinc;
finc = ( *(channel+freq) - ( f = *(lastfreq+i) ) ) * Iinv;
ainc = ( *(channel+amp) - ( a = *(lastamp+i) ) ) * Iinv;
address = *(index+i);
/* accumulate the I samples from each oscillator into
output array O (initially assumed to be zero);
f is frequency in Hz scaled by oscillator increment
factor and pitch (Pinc); a is amplitude; */
for ( j=0; j < interp; j++ ) {
*(output+j) += a * *(table + ( (int) address ));
address += f;
while ( address >= (float) tablesize )
address -= (float) tablesize;
while ( address < 0. )
address += (float) tablesize;
a += ainc;
f += finc;
}
/* save current values for next iteration */
*(lastfreq+i) = *(channel+freq);
*(lastamp+i) = *(channel+amp);
*(index+i) = address;
}
return self;
}
@end