/*--------------------------------*/ /* Sounder.c */ /*--------------------------------*/ #include /* normal includes */ #include #include #include #include "sound.h" /* rsrc */ #define extern #include "soundef.h" /* globals and defines */ #undef extern #define PUT 0x80 #define NUMNOTES 12 #define NUMOCTS 5 char notes[NUMNOTES][3] = { "B ","A#","A ", "G#","G ","F#", "F ","E ","D#", "D ", "C#","C " }; int notelow[NUMOCTS][NUMNOTES] = { 63, 67, 71, 75, 79, 84, 89, 95, 100, 106, 112, 119, 127, 134, 142, 150, 159, 169, 179, 190, 201, 213, 225, 239, 253, 12, 28, 45, 63, 82, 102, 123, 146, 170, 195, 222, 250, 24, 56, 90, 126, 164, 204, 246, 36, 83, 134, 188, 244, 49, 112, 180, 9, 71, 152, 237, 71, 167, 12, 119 } ; int notehi[NUMOCTS][NUMNOTES] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 7 } ; int save7; /* lineaport *Aport; */ /* main - executes initialization code and the starts the application. */ main() { /* Initialize */ init_app(); /* Handle events for application. */ multi(); /* bye... Note: This will never be executed. */ shut_app(0); /* was shutdown(0);? */ } /*--------------------------------*/ /* init_app */ /*--------------------------------*/ init_app() { int dummy; /* Initiailize the ROMs. */ appl_init(); /* Load resources. */ init_resources(); /* Get the Physical work station handle. */ phys_handle = graf_handle(&dummy, &dummy, &dummy, &dummy); /* init_paths(); init filepaths? */ /* Initialize the mouse. */ POINT } /* end init_app */ /*--------------------------------*/ /*--------------------------------*/ /* init_resources */ /*--------------------------------*/ init_resources() { OBJECT *tree; if (!rsrc_load("sound.rsc")) { form_alert(1, "[0][Can't find resource|Terminating ...][Eh?]"); exit(2); } rsrc_gaddr( R_TREE, REGS, &tree); /* Init dialog strings */ sprintf( OBSPEC( tree, LOSSTR), "48"); sprintf( OBSPEC( tree, HISSTR), "3"); /* end init dialog strings */ /* Init menu */ /* rsrc_gaddr(0, MEN, &menu1); menu_bar(menu1, 1); */ /* Init dialog placement */ /* end init object placement */ } /* end init_resources */ /*--------------------------------*/ /*--------------------------------*/ /* shut_app - is the code that closes down the application. This routine is called when errors occurs and guarantees that all window's will be closed properly before exiting. */ /*--------------------------------*/ shut_app(code) int code; { /* Clean up memory. */ cleanup(); /* Shut down the application. */ appl_exit(); /* bye ... */ exit(code); } /* end shut_app */ /*--------------------------------*/ /*--------------------------------*/ /* cleanup - releases the memory used by the application. */ /*--------------------------------*/ cleanup() { /* Free memory used by resource. */ rsrc_free(); } /* end cleanup */ /*--------------------------------*/ /*--------------------------------*/ /* multi (one form node) */ /*--------------------------------*/ multi() { int done=0, type, flags, dad, obid, tedid, val, doitnow,dclick; OBJECT *tree; char *ted; GRECT ob; save7 = Giaccess( 0, 7); show_dial( REGS ); rsrc_gaddr( R_TREE, REGS, &tree ); objc_xywh( tree, 0, &ob); do{ obid = form_do( tree,0); doitnow = 1; dclick = val = 0; if( obid & 0x8000 ){ dclick = 1; obid &= ~0x8000; /* mask off any double clicks */ } flags = OBFLAGS( tree, obid ); type = EXTYPE( tree, obid ); dad = get_parent( tree, obid); if ( flags & TOUCHEXIT ){ switch( dad ){ case NABOX: case NBBOX: case NCBOX: do_note( tree, obid, dad, flags, type); break; case VOLA: /* Falls through, sets maximum slider value */ case VOLB: case VOLC: val = 16; case PIT: if( !val ) val = 31; case LOWSUS: if( !val ) doitnow = 0; /* wait till done sliding */ case HISUS: if( !val ){ val = 255; } ted = OBSPEC( tree, dad + 2); tedid = dad + 2; touchslide( tree, ted, tedid, 0, val, type); break; /* end fall-through */ case NOISE: OBSTAT( tree, obid) ^= CHECKED; objc_draw( tree, obid, 8, ob.g_x,ob.g_y,ob.g_w,ob.g_h); break; default: break; } /* end switch dad */ } /* end if touchexit */ else{ switch( obid ){ /* catch the rest, selectables? */ case SEND: /* re-does the chip */ break; case SNDCANC: do_gee( save7, 0); objc_dsel( tree, NA); objc_dsel( tree, NB); objc_dsel( tree, NC); /* turn off notes */ doitnow = 0; break; case EX: do_gee( save7, 0); doitnow = 0; done = 1; break; default: break; } if( dad != ENVBOX ) objc_dsel( tree, obid); } if( doitnow ) do_gee( save7, 1); /* how fast is it? Fast enough */ } while( !done ); hide_dial( REGS ); /* rest_soundregs(); */ return( type ); } /* end form_do of Multi */ do_gee( mask, on ) int mask, on; { int regvals[14]; int i; if ( on ){ mask &= 0xc0; set_regvals( regvals ); /* play tone */ for( i = 0; i<14; i++){ if( i == 7 ) Giaccess( (char)regvals[i]|mask, PUT|i); else Giaccess( (char)regvals[i], PUT|i); } } else{ for( i = 0; i < 3; i++) /* just sets volume to zero */ Giaccess( 0, PUT|( 8 + i ) ); } return( 0 ); } /* end do_gee */ set_regvals( vals ) /* sets values by reading the form */ int *vals; { OBJECT *tree; int id,note,octave,i; static int vols[3] = { VOLASTR, VOLBSTR, VOLCSTR }; static int tones[3] = { NA, NB, NC }; rsrc_gaddr( R_TREE, REGS, &tree); vals[7] = 0x3f; /* all voices off? */ for( i=0; i<3; i++) /* all volumes down */ vals[8 + i] = 0; for( i=0; i<3; i++){ if( selectp( tree, tones[i])){ get_note( tree, tones[i], ¬e, &octave); vals[0 + ( i*2 )] = notelow[octave][note]; vals[1 + ( i*2 )] = notehi[octave][note]; vals[8 + i] = atoi( OBSPEC( tree, vols[i]) ); setbit( &vals[7], i, 0); } if( statep( tree, NOISE1 + i, CHECKED) ) setbit( &vals[7], 3 + i, 0); else setbit( &vals[7], 3 + i, 1 ); } vals[6] = atoi( OBSPEC( tree, PITSTR)); vals[11] = atoi( OBSPEC( tree, LOSSTR)); vals[12] = atoi( OBSPEC( tree, HISSTR)); vals[13] = EXTYPE( tree, ENV1 + decode( tree, ENV1, 10, SELECTED)); return( 0 ); } /* end set_regs */ get_note( tree, ob, n, o) OBJECT *tree; int ob, *n, *o; { char note[3],*p; int dex; p = OBSPEC( tree, ob); note[0] = p[0]; note[1] = p[1]; note[2] = '\0'; for( dex = 0; dex < NUMNOTES; dex++ ) if( !strcmp( note, notes[dex]) ) break; *n = dex; *o = (int)(p[2]-'1'); return( 0 ); } /* end get_note */ setbit( i, bit, onff) int *i, bit, onff; { if( onff ) *i |= (1 << bit); else *i &= ( 0xFFFF - ( 1 << bit )); } /* end setbit */ do_note( tree, obid, dad, flags, type) OBJECT *tree; int obid, dad, flags, type; { if( flags & SELECTABLE ) /* it's the note itself, so just return */ return( 1 ); else{ /* else it's the slider */ note_slide( tree, dad+2, type); /* dad + 2 is notestring */ } return( selectp( tree, dad+2)); /* don't send sound if note's off */ } /* end do_note */ set_note( tree, ob, n, o) OBJECT *tree; int ob, n, o; { char *p; p = OBSPEC( tree, ob); sprintf( p, notes[n]); /* Copy C# to first two chars */ p[2] = (char)o + '1'; return( 0 ); } /* end set_note */ note_slide( tree, obid , up) OBJECT *tree; int obid, up; { GRECT ob; int note,octave; get_note( tree, obid, ¬e, &octave); note += (up)? -1:1; /* reverse direction to match keyboard? */ if( note<0 ){ note += NUMNOTES; if( octave > 0) octave -= 1; } else if( note == NUMNOTES ){ note = 0; if( octave < NUMOCTS - 1 ) octave += 1; } set_note( tree, obid, note, octave); objc_xywh( tree, obid, &ob); objc_draw( tree, obid, 8, ob ); return( note ); } /* end note_slide */ touchslide( tree, datated ,dataid, minval, maxval, upflag) register OBJECT *tree; char *datated; int dataid, minval, maxval, upflag; { GRECT ob; int val; val = atoi( datated ); if( upflag ){ if( val == maxval) return( val ); val += 1; } else{ if( val == minval) return( val ); val -= 1; } objc_xywh( tree, dataid, &ob); sprintf( datated,"%d",val); objc_draw( tree, dataid, 8, ob.g_x,ob.g_y,ob.g_w,ob.g_h); return ( val ); /* or use decode */ } /* end set sliders */