This is Utilities.m in view mode; [Download] [Up]
/************************************************** * SynthBuilder * Copyright 1993 Nick Porcaro All Rights Reserved **************************************************/ #import <stdlib.h> #import <math.h> #import <stddef.h> #import <ctype.h> #import <string.h> #import <objc/NXBundle.h> #import <appkit/Application.h> #import <appkit/Panel.h> #import <appkit/Control.h> #import <musickit/Envelope.h> #import "Utilities.h" #define EOS '\0' char *getAppName() { /* this is the only place where the name of the program should be mentioned */ return "SynthBuilder"; } @implementation Utilities static char TempString[1024]; - init { [super init]; [NXApp loadNibSection:"Utilities.nib" owner:self withNames:YES]; return self; } - sortList:(List *) aList sortFunction:(ptrToIntFcn) fcn { int count; /* Is it worth sorting? */ if (! fcn) { return self; } count = [aList count]; if (count <= 1) { return self; } /* Sort the array. Hopefully the * List object will act properly after this!! */ qsort((void *)aList->dataPtr, count, sizeof(id), fcn); return self; } - (BOOL) checkName: (char *) aName /* The names of FakeUGs and FakePatchPoints must be a legal * C identifier */ { int len, i; if (! aName) { NXRunAlertPanel(getAppName(), "Invalid name", NULL, NULL, NULL); return NO; } len = strlen(aName); if (len > 0) { if (! isalpha(aName[0])) { NXRunAlertPanel(getAppName(), "Name must start with alpha character", NULL, NULL, NULL); return NO; } for (i=1; i<len; i++) { if ( ! ( isalnum(aName[i]) || aName[i] == '_')) { sprintf(TempString, "Illegal character in %s: %c", aName, aName[i]); NXRunAlertPanel(getAppName(), TempString, NULL, NULL, NULL); return NO; } } } return YES; } - (char *) getAppDir { char *dir; int len; static char temp[1024]; dir = (char *) [[NXBundle mainBundle] directory]; if (! dir) { NXRunAlertPanel(getAppName(), "Error getting bundle directory", NULL, NULL, NULL); return NULL; } /* Nightmare: If the directory does not end in .app * it probably means we are under GDB. Add * the .app dir name to the end of the dir if this is the case */ if (getenv("NICKGDB")) { len = strlen(dir); if ( ! ((dir[len-1] == 'p') && (dir[len-2] == 'p') && (dir[len-3] == 'a') && (dir[len-4] == '.')) ) { sprintf(temp, "%s/%s.app", dir, getAppName()); dir = temp; } } return dir; } - displayInspector:sender { [theInspector makeKeyAndOrderFront:self]; return self; } - getPhaseIncrement:sender { double freq; double phase_inc; double mag; double srate; double table_len; freq = [sender floatValue]; table_len = [theTableLength doubleValue]; srate = [theSrate doubleValue]; if (srate <= 0) { /* bogus */ srate = 44100; } /******************* From /Net/cmn14/projects/musicKit/mk/unitgenerators/OscgafUGs.m The formula is: phase_inc = (freq * _mag) / MK_OSCFREQSCALE where _mag = (double)tableLength / [orchestra samplingRate]; and MK_OSCFREQSCALE = 256.0, *********************/ mag = table_len / srate; phase_inc = (freq * mag)/256.0; [toPhaseInc setFloatValue:phase_inc]; return self; } - getFrequency:sender { double freq; double phase_inc; double table_len; double mag; double srate; phase_inc = [sender floatValue]; table_len = [theTableLength doubleValue]; srate = [theSrate doubleValue]; if (srate <= 0) { /* bogus */ srate = 44100; } /******************* From /Net/cmn14/projects/musicKit/mk/unitgenerators/OscgafUGs.m The formula is: phase_inc = (freq * _mag) / MK_OSCFREQSCALE freq = (phase_inc/_mag) * MK_OSCFREQSCALE where _mag = (double)tableLength / [orchestra samplingRate]; and MK_OSCFREQSCALE = 256.0, substituting: *********************/ mag = table_len / srate; freq = (phase_inc/mag) * 256.0; [toFreq setFloatValue:freq]; return self; } - (char *) envelopeToText:anEnvelope { int i, count; double *x, *y; unsigned int env_size; int stick; BOOL do_stick = NO; char *envString; /* Do something to the envelope so the File's Owner * object can do something cool with it */ if (! anEnvelope) { return NULL; } count = [anEnvelope pointCount]; if (count <= 0) { return NULL; } x = [anEnvelope xArray]; y = [anEnvelope yArray]; stick = [anEnvelope stickPoint]; if (stick != MAXINT) { do_stick = YES; } if (! (x && y) ) { return NULL; } /* The max a coordinate of an envelope can be is %03.5 = 9 characters * add a comma and paren for each coordinate (make it 4 to be safe) * Then we have 9+5 = 14 characters for each coordinate * or 28 characters for each point */ env_size = count * 28 + 256; /* add 256 for extra fudge */ envString = (char *) NXZoneCalloc([self zone], env_size, sizeof(char)); if (! envString) { NXRunAlertPanel(getAppName(), "Grave danger -- malloc error", NULL, NULL, NULL); return NULL; } strcpy(envString, ""); for (i=0; i<count; i++) { sprintf(envString, "%s(%4.4f, %f)", envString, x[i], y[i]); if (do_stick && (stick == i)) { strcat(envString, "|"); } } return envString; } - textToEnvelope: (char *) aString { int i, j; int pointCount = 0; int stickPoint = -1; double *xArray, *yArray, *smoothingArray; id newEnv; if (! aString) { return nil; } for (i=0; aString[i] != '\0'; i++) { if (aString[i]=='|') { stickPoint = pointCount-1; } if (aString[i]=='(') pointCount++; } if (pointCount <= 0) { return nil; } xArray = (double *) NXZoneCalloc([self zone], pointCount, sizeof(double)); yArray = (double *) NXZoneCalloc([self zone], pointCount, sizeof(double)); smoothingArray = (double *) NXZoneCalloc([self zone], pointCount, sizeof(double)); j=0; for (i=0; i<pointCount; i++) { xArray[i] = yArray[i] = 0.0; smoothingArray[i] = 1.0; while (aString[j]!='(') { j++; } sscanf(aString+j, "(%lf,%lf,%lf)", &xArray[i], &yArray[i], &smoothingArray[i]); j++; } newEnv = [[[Envelope alloc] init] setPointCount: pointCount xArray: xArray orSamplingPeriod: 1.0 yArray: yArray smoothingArray: smoothingArray orDefaultSmoothing: 1.0 ]; if (stickPoint != -1) { [newEnv setStickPoint:stickPoint]; } return newEnv; } #define MAX_PATHLEN 1024 #define RETURN_LEAF(Path) \ strcpy(buffer, Path); \ len = strlen(buffer); \ if (len <= 0 || len >= MAX_PATHLEN) \ return NULL; \ i = len; \ while (buffer[i] != '/' && i >= 0) i--; \ return &buffer[i+1]; - (char *) getPathLeaf: (char *) path { static char buffer[1024]; /* Character buffer */ static char leaf[256]; /* Buffer to hold leaf directory */ int len; /* Length of path */ int i, j; /* Counter */ int position; /* Position in string */ int leading_slash = 0; /* Position of a leading slash */ int slash_count = 0; /* Number of slashes in a path */ strcpy(leaf,path); len = strlen(leaf); if (len <= 0 || len >= MAX_PATHLEN) { /* Crap */ return NULL; } if (len > 1) { if (strcmp(leaf,"..") == 0) { RETURN_LEAF((char *)"..") } if (strcmp(leaf,"//") == 0) { return leaf; } position = len - 1; for (i = len - 1 ; i >= 0; i--) { if (leaf[i] == '/') { position = i; slash_count++; } else { break; } leaf[position] = EOS; position--; } /* Special case: all characters are slashes */ if (slash_count == len) { strcpy(buffer,"//"); return buffer; } /* Begining of string */ if (leaf[0] == '/' ) { i = 0; while (leaf[leading_slash] != '/' && leading_slash <= len) { if (leaf[i] == '/') leading_slash++; else break; } if (i > 2) { /* Extra slashes at begining of string */ j = 0; for (i = leading_slash; i <= len; i++) { buffer[j++] = leaf[i]; } buffer[j] = EOS; strcpy(leaf,"//"); strcat(leaf,buffer); } } /* Position to the first non-extraneous slash */ while (leaf[position] != '/' && position >= 0) position--; /* Deal with case where slash is first character or no slashes in path */ if (position == 0) { if (leaf[position] == '/') { /* Case where something line '/foo' was entered */ return &leaf[position+1]; } else { /* Case where a leaf like 'my_file' was entered (no slashes (/'s)) */ return leaf; } } else { /* Regular leafy path */ return &leaf[position+1]; } } else { /* Single character paths. All special cases */ if ( (strcmp(leaf,"/") == 0) || (strcmp(leaf,".") == 0) || (strcmp(leaf,"~") == 0) ) { RETURN_LEAF((char *)leaf) } { /* A single non-special character */ return leaf; } } } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.