home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GEMini Atari
/
GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso
/
files
/
music
/
stsynth
/
soundkey.c
next >
Wrap
C/C++ Source or Header
|
1987-05-18
|
29KB
|
699 lines
/* SoundKey.c
David T. Jarvis
Atari ST -- Lattice C -- Version 052686
*/
#define SPACE_K 32 /* space key */
#define ESC_K 27 /* ESC key */
#define RETURN_K 13 /* return key */
#define DURA 1000 /* note duration */
#define TUNE_INC 6 /* adjust tuning by this much */
#define MAX_OCT 6 /* maximum octave */
#define MAX_VOL 15 /* maximum volume */
#define MAX_WAV 15 /* maximum waveform */
#define N_P_OCT 15 /* notes per octave */
#define MOUS_OFF 256 /* disable mouse */
#define MOUS_ON 257 /* enable mouse */
#define T_OUTLINE 0x10 /* text style--outline */
#define T_NORMAL 0x0 /* text style--normal */
#define T_SKEWED 0x0004 /* text style--skewed */
#define T_THICK 0X0001 /* text style--thick */
#define CH_ENA_R 7 /* voice channel enable(read) */
#define CH_ALO_W 128 /* channel,voice a lo,write */
#define CH_AHI_W 129 /* channel,voice a hi,write */
#define CH_BLO_W 130 /* " , " b lo, " */
#define CH_BHI_W 131 /* " , " b hi, " */
#define CH_CLO_W 132 /* " , " c lo, " */
#define CH_CHI_W 133 /* " , " c hi, " */
#define CH_ENA_W 135 /* voice channel enable(write) */
#define CH_AVL_W 136 /* channel a volume, write */
#define CH_BVL_W 137 /* " b " , " */
#define CH_CVL_W 138 /* " c " , " */
#define RG_ENV_W 140 /* envelope register, write */
#define RG_WAV_W 141 /* waveform register, write */
#define CONTERM 0X484 /* attributes of console */
#include <stdio.h> /* standard io library */
#include <osbind.h> /* GEMDOS,BIOS,XBIOS macros */
#include <ctype.h> /* character type macros */
#define Supexec(a) xbios(38,a) /* Exec routine,supervisor mode */
/* play contains the numbers to plug into the ST sound chip */
short int play[ MAX_OCT ][ N_P_OCT ] =
{
{ 3906,3689,3472,3189,3048,2906,2728,2551,2411,2272,2160,2049,1923,1817,1712 },
{ 1923,1817,1712,1633,1524,1436,1350,1275,1205,1136,1076,1016,954,902,850 },
{ 954,902,850,807,757,714,675,637,602,568,537,506,477,451,425 },
{ 477,451,425,401,378,358,338,318,301,284,268,253,239,225,212 },
{ 239,225,212,200,189,179,169,159,150,142,134,126,119,112,106 },
{ 119,112,106,100, 94, 89, 84, 79, 75, 71, 67, 63, 59, 54, 51 }
};
short int contrl[12],
intin[256], intout[256],
ptsin[256], ptsout[256],
workin[20], workout[100],
handle, i, j,
dvar, port_state,
key_rate,fast_key = 1,
x_note, y_note, z_note,
old_note = 0;
char c, x_low, x_high, y_low, y_high, z_low, z_high;
char *std_msg = "Press ESC to Exit ";
short int hold_n = 0, /* flag-- hold notes */
period = 10, /* period for sound waves */
wave = 0, /* waveform */
vol_a = MAX_VOL, /* voice a volume */
vol_b = MAX_VOL, /* voice b volume */
vol_c = MAX_VOL, /* voice c volume */
oct_a = 2, /* voice a octave */
oct_b = 2, /* voice b octave */
oct_c = 2, /* voice c octave */
tune = 6, /* tuning (added to pitch) */
tn_a=2,tn_b=2,tn_c=2, /* tuning for individual voices */
diss = 3; /* dissonance level */
int nonoise(); /* routine to disable noise */
main()
{
/* Check for correct resolution */
if (Getrez() != 1)
{
printf("Sorry, this program must be run in medium resolution.\n");
exit(0);
}
/* Initialize application */
appl_init();
handle=graf_handle( &dvar, &dvar, &dvar, &dvar );
for ( i = 0; i < 10; workin[ i++ ]=1 ); workin[ 10 ] = 2;
v_opnvwk( workin, &handle, workout );
/* Hide mouse, disable keyclick,bell, speed up keyboard repeat rate */
graf_mouse( MOUS_OFF, 0 );
Supexec(nonoise);
key_rate = Kbrate( 0x01,0x01 );
/* Initialize sound chip, enable channels a and b */
sound_off();
port_state = Giaccess( i, CH_ENA_R );
Giaccess( (port_state & 0xc0) | 56, CH_ENA_W );
/* Make music */
play_keys();
/* turn off the sound chip, restore initial state */
Giaccess( port_state, CH_ENA_W );
/* restore keyboard repeat rate, close application and exit */
Kbrate( (key_rate >> 8) & 0x00ff, key_rate & 0x00ff );
v_clsvwk( handle );
appl_exit();
}
play_keys()
{
register char c=' ', c2=' ';
keys_screen();
while (c != ESC_K)
{
if (Bconstat(2))
{
vol_c = 0;
c = Bconin(2); c = tolower(c);
switch(c)
{
case '1':
locate(22,1);
put_msg( "H=>Higher, L=>Lower, RETURN=>Done ");
x_note = play[ oct_a ][ 0 ] + tn_a;
y_note = play[ oct_b ][ 0 ] + tn_b;
sound_on();
do
{
c2 = Bconin(2); c2 = tolower(c2);
switch(c2)
{
case 'h':
if (tune)
{
tune -= TUNE_INC;
tn_a = tune/(oct_a+1);
tn_b = tune/(oct_b+1);
tn_c = tune/(oct_c+1);
x_note = play[ oct_a ][ 0 ] + tn_a;
y_note = play[ oct_b ][ 0 ] + tn_b;
sound_on();
dsp_vals();
}
break;
case 'l':
if (tune < TUNE_INC*5)
{
tune += TUNE_INC;
tn_a = tune/(oct_a+1);
tn_b = tune/(oct_b+1);
tn_c = tune/(oct_c+1);
y_note = play[ oct_b ][ 0 ] + tn_b;
x_note = play[ oct_a ][ 0 ] + tn_a;
sound_on();
dsp_vals();
}
break;
default:
break;
}
} while (c2 != RETURN_K );
sound_off();
put_msg( std_msg );
x_note = old_note;
break;
case '2':
locate(22,1);
put_msg(
"M => More, L=>Less, RETURN=>Done ");
x_note = play[ oct_a ][ 0 ] + tn_a;
y_note = play[ oct_b ][ 0 ] + tn_b + diss;
sound_on();
do
{
c2 = Bconin(2); c2 = tolower(c2);
switch(c2)
{
case 'l':
if (diss)
{
diss--;
x_note = play[ oct_a ][ 0 ]
+ tn_a;
y_note = play[ oct_b ][ 0 ]
+ tn_b + diss;
sound_on();
dsp_vals();
}
break;
case 'm':
if (diss < 7)
{
diss++;
x_note = play[ oct_a ][ 0 ]
+ tn_a;
y_note = play[ oct_b ][ 0 ]
+ tn_b + diss;
sound_on();
dsp_vals();
}
break;
default:
break;
}
} while (c2 != RETURN_K );
sound_off();
put_msg( std_msg );
x_note = old_note;
break;
case '3':
wave++;
if (wave == 1) wave = 4;
if (wave == 5) wave = 8;
if (wave > MAX_WAV)
wave = 0;
Giaccess( wave, RG_WAV_W );
dsp_vals();
x_note = old_note;
break;
case '4':
Kbrate((key_rate>>8)&0x00ff,key_rate&0x00ff);
fast_key = 0;
dsp_vals();
x_note = old_note;
break;
case '5':
fast_key = 1;
Kbrate( 0x01,0x01 );
dsp_vals();
x_note = old_note;
break;
case 'a':
x_note = play[ oct_a ][ 0 ] + tn_a;
y_note = play[ oct_b ][ 0 ] + tn_b + diss;
break;
case 'w':
x_note = play[ oct_a ][ 1 ] + tn_a;
y_note = play[ oct_b ][ 1 ] + tn_b + diss;
break;
case 's':
x_note = play[ oct_a ][ 2 ] + tn_a;
y_note = play[ oct_b ][ 2 ] + tn_b + diss;
break;
case 'e':
x_note = play[ oct_a ][ 3 ] + tn_a;
y_note = play[ oct_b ][ 3 ] + tn_b + diss;
break;
case 'd':
x_note = play[ oct_a ][ 4 ] + tn_a;
y_note = play[ oct_b ][ 4 ] + tn_b + diss;
break;
case 'f':
x_note = play[ oct_a ][ 5 ] + tn_a;
y_note = play[ oct_b ][ 5 ] + tn_b + diss;
break;
case 't':
x_note = play[ oct_a ][ 6 ] + tn_a;
y_note = play[ oct_b ][ 6 ] + tn_b + diss;
break;
case 'g':
x_note = play[ oct_a ][ 7 ] + tn_a;
y_note = play[ oct_b ][ 7 ] + tn_b + diss;
break;
case 'u':
x_note = play[ oct_a ][ 8 ] + tn_a;
y_note = play[ oct_b ][ 8 ] + tn_b + diss;
break;
case 'j':
x_note = play[ oct_a ][ 9 ] + tn_a;
y_note = play[ oct_b ][ 9 ] + tn_b + diss;
break;
case 'i':
x_note = play[ oct_a ][ 10 ] + tn_a;
y_note = play[ oct_b ][ 10 ] + tn_b + diss;
break;
case 'k':
x_note = play[ oct_a ][ 11 ] + tn_a;
y_note = play[ oct_b ][ 11 ] + tn_b + diss;
break;
case 'o':
x_note = play[ oct_a ][ 12 ] + tn_a;
y_note = play[ oct_b ][ 12 ] + tn_b + diss;
break;
case 'l':
x_note = play[ oct_a ][ 13 ] + tn_a;
y_note = play[ oct_b ][ 13 ] + tn_b + diss;
break;
case 'p':
x_note = play[ oct_a ][ 14 ] + tn_a;
y_note = play[ oct_b ][ 14 ] + tn_b + diss;
break;
case 'z':
x_note = play[ oct_a ][ 0 ] + tn_a;
y_note = play[ oct_b ][ 4 ] + tn_b;
z_note = play[ oct_c ][ 7 ] + tn_c;
vol_c = vol_a;
break;
case 'x':
x_note = play[ oct_a ][ 2 ] + tn_a;
y_note = play[ oct_b ][ 5 ] + tn_b;
z_note = play[ oct_c ][ 9 ] + tn_c;
vol_c = vol_a;
break;
case 'c':
x_note = play[ oct_a ][ 4 ] + tn_a;
y_note = play[ oct_b ][ 7 ] + tn_b;
z_note = play[ oct_c ][ 11 ] + tn_c;
vol_c = vol_a;
break;
case 'v':
x_note = play[ oct_a ][ 5 ] + tn_a;
y_note = play[ oct_b ][ 9 ] + tn_b;
z_note = play[ oct_c ][ 12 ] + tn_c;
vol_c = vol_a;
break;
case 'b':
x_note = play[ oct_a ][ 2 ] + tn_a;
y_note = play[ oct_b ][ 7 ] + tn_b;
z_note = play[ oct_c ][ 11 ] + tn_c;
vol_c = vol_a;
break;
case 'n':
x_note = play[ oct_a ][ 4 ] + tn_a;
y_note = play[ oct_b ][ 9 ] + tn_b;
z_note = play[ oct_c ][ 12 ] + tn_c;
vol_c = vol_a;
break;
case 'm':
x_note = play[ oct_a ][ 2 ] + tn_a;
y_note = play[ oct_b ][ 5 ] + tn_b;
z_note = play[ oct_c ][ 11 ] + tn_c;
vol_c = vol_a;
break;
case ',':
case '<':
x_note = play[ oct_a ][ 4 ] + tn_a;
y_note = play[ oct_b ][ 7 ] + tn_b;
z_note = play[ oct_c ][ 12 ] + tn_c;
vol_c = vol_a;
break;
case ']':
oct_a++; oct_b++; oct_c++;
if (oct_a > MAX_OCT) oct_a = 0;
if (oct_b > MAX_OCT) oct_b = 0;
if (oct_c > MAX_OCT) oct_c = 0;
x_note = old_note;
tn_a = tune/(oct_a+1);
tn_b = tune/(oct_b+1);
tn_c = tune/(oct_c+1);
dsp_vals();
break;
case '[':
oct_a--; oct_b--; oct_c--;
if (oct_a < 0) oct_a = MAX_OCT;
if (oct_b < 0) oct_b = MAX_OCT;
if (oct_c < 0) oct_c = MAX_OCT;
x_note = old_note;
tn_a = tune/(oct_a+1);
tn_b = tune/(oct_b+1);
tn_c = tune/(oct_c+1);
dsp_vals();
break;
case '}':
oct_a++;
if (oct_a > MAX_OCT) oct_a = 0;
x_note = old_note;
tn_a = tune/(oct_a+1);
dsp_vals();
break;
case '{':
oct_a--;
if (oct_a < 0) oct_a = MAX_OCT;
x_note = old_note;
tn_a = tune/(oct_a+1);
dsp_vals();
break;
case SPACE_K:
x_note = old_note;
hold_n = !hold_n;
dsp_vals();
if (!hold_n)
sound_off();
break;
default:
x_note = old_note;
break;
}
if (x_note != old_note)
{
x_low = (char)(x_note);
y_low = (char)(y_note);
z_low = (char)(z_note);
x_high = (char)(x_note >> 8);
y_high = (char)(y_note >> 8);
z_high = (char)(z_note >> 8);
Giaccess( x_low, CH_ALO_W );
Giaccess( x_high, CH_AHI_W );
Giaccess( y_low, CH_BLO_W );
Giaccess( y_high, CH_BHI_W );
Giaccess( z_low, CH_CLO_W );
Giaccess( z_high, CH_CHI_W );
Giaccess( vol_a, CH_AVL_W );
Giaccess( vol_b, CH_BVL_W );
Giaccess( vol_c, CH_CVL_W );
j = 1;
}
}
else
{
j++;
if ((j == DURA) && (!hold_n))
{
Giaccess( 0, CH_AVL_W );
Giaccess( 0, CH_BVL_W );
Giaccess( 0, CH_CVL_W );
}
}
}
sound_off();
}
keys_screen()
{
keys_menu(); /* Display control keys menu */
dsp_prms(); /* Display parameter names */
dsp_vals(); /* Display parameter values */
draw_kbd(); /* Draw a keyboard map */
author();
}
keys_menu()
{
v_clrwk( handle );
empt_box(4,6,636,198,1);
empt_box(8,18,312,102,3);
vst_effects( handle, T_SKEWED );
vst_color( handle,2 );
v_gtext( handle, 264, 6, "ST SYNTHESIZER" );
vst_effects( handle, T_OUTLINE );
vst_color( handle,3 );
v_gtext( handle, 80, 16, "PARAMETER CONTROL" );
vst_effects( handle, T_NORMAL );
vst_color( handle,1 );
v_gtext( handle,16,30, "1 -- Tune Keyboard (on C)" );
v_gtext( handle,16,38, "2 -- Dissonance" );
v_gtext( handle,16,46, "3 -- Next Waveform" );
v_gtext( handle,16,54, "4,5 -- Slow/Fast Key Speed" );
v_gtext( handle,16,62, "[ -- Lower Octave, Both Voices");
v_gtext( handle,16,70, "] -- Higher Octave, Both Voices");
v_gtext( handle,16,78, "{ -- Lower Octave, Voice A");
v_gtext( handle,16,86, "} -- Higher Octave, Voice A");
v_gtext( handle,16,94, "SPACE -- Toggle Sustain Mode");
empt_box( 8,182,324,194,3 );
vst_color( handle,2 );
vst_effects( handle, T_THICK );
}
dsp_prms()
{
empt_box( 320,18,632,102,3 );
vst_effects( handle, T_OUTLINE );
vst_color( handle,3 );
v_gtext( handle,400,16,"PARAMETER VALUES" );
vst_effects( handle, T_NORMAL );
vst_color( handle,1 );
v_gtext( handle,328,30, "Tuning : ");
v_gtext( handle,328,38, "Dissonance : ");
v_gtext( handle,328,46, "Waveform : ");
v_gtext( handle,328,54, "Key Speed : ");
v_gtext( handle,328,62, "Octave A : ");
v_gtext( handle,328,70, "Octave B : ");
v_gtext( handle,328,78, "Octave C : ");
v_gtext( handle,328,86, "Octave Mix : ");
v_gtext( handle,328,94, "Sustain : ");
}
dsp_vals()
{
char buffer[ 36 ];
vst_color( handle,1 );
vst_effects( handle,T_NORMAL );
sprintf(buffer,"%d%s",tune," "); v_gtext( handle,448,30,buffer );
sprintf(buffer,"%d%s",diss," "); v_gtext( handle,448,38,buffer );
sprintf(buffer,"%d%s",wave," "); v_gtext( handle,448,46,buffer );
if (fast_key)
sprintf(buffer,"%s","Fast ");
else
sprintf(buffer,"%s","Normal ");
v_gtext( handle,448,54,buffer );
sprintf(buffer,"%d%s",oct_a," "); v_gtext( handle,448,62,buffer );
sprintf(buffer,"%d%s",oct_b," "); v_gtext( handle,448,70,buffer );
sprintf(buffer,"%d%s",oct_c," "); v_gtext( handle,448,78,buffer );
if (oct_a == oct_b)
sprintf(buffer,"%s","Same ");
else
sprintf(buffer,"%s","Split ");
v_gtext( handle,448,86,buffer );
if (hold_n)
sprintf(buffer,"%s","On ");
else
sprintf(buffer,"%s","Off ");
v_gtext( handle,448,94,buffer );
}
draw_kbd()
{
int row, key, kl, kt, kr, kb, offset=0, rowsize = 15;
int ledge = 120;
int tedge = 114;
int keynum = 0;
short int ret_key[ 14 ];
empt_box( ledge-8,tedge-4,ledge+4+306,tedge+8+45,2 );
vst_color( handle,1 );
vst_effects( handle,T_SKEWED );
v_gtext( handle,500,tedge+6,"Control");
vst_color( handle,2 );
v_gtext( handle,500,tedge+18,"Notes");
vst_color( handle,3 );
v_gtext( handle,500,tedge+30,"Chords");
v_gtext( handle,500,tedge+42,"Not Used");
empt_box( 460,tedge,475,tedge+7,1 );
empt_box( 460,tedge+12,475,tedge+19,2 );
full_box( 460,tedge+24,475,tedge+31,3,6 );
empt_box( 460,tedge+36,475,tedge+43,3 );
for (row = 0, kl = 10; row < 4; row++)
{
kl = ledge;
kt = tedge + (row*10);
kr = kl + 15 + offset;
kb = kt + 7;
empt_box( kl,kt,kr,kb,3 );
kl += offset;
keynum++;
for (key = 1; key < rowsize; key++)
{
kl += 20;
kr += 20;
if ((row == 0)&&(key == 14))
kr += 7;
switch(keynum)
{
case 1: case 2: case 3: case 4: case 5:
case 26: case 27:
empt_box( kl,kt,kr,kb,1 );
break;
case 17: case 18: case 20: case 22:
case 23: case 24: case 25: case 30:
case 31: case 32: case 33: case 34:
case 36: case 37: case 38:
empt_box( kl,kt,kr,kb,2 );
break;
case 28:
ret_key[ 0 ] = ret_key[ 10 ] = ret_key[ 12 ] = kl;
ret_key[ 1 ] = ret_key[ 3 ] = ret_key[ 13 ] = kt;
ret_key[ 2 ] = ret_key[ 4 ] = kr;
ret_key[ 5 ] = ret_key[ 7 ] = kt + 17;
ret_key[ 6 ] = ret_key[ 8 ] = kl - 11;
ret_key[ 9 ] = ret_key[ 11 ] = kt + 10;
vsl_color( handle,3 );
v_pline( handle,7,ret_key );
empt_box( kl+20,kt,kr+17,kb,3 );
empt_box( kl+20,kt+10,kr+17,kb+10,3 );
break;
case 41:
break;
case 43: case 44: case 45: case 46:
case 47: case 48: case 49: case 50:
full_box( kl,kt,kr,kb,3,6 );
break;
case 53:
empt_box( kl,kt,kr + 5,kb,3 );
break;
default:
empt_box( kl,kt,kr,kb,3 );
break;
}
keynum++;
}
rowsize--;
offset += 10;
}
tedge += (row*10);
empt_box( ledge+20,tedge,ledge+40,tedge+7,3 );
vsl_color( handle,1 );
empt_box( ledge+45,tedge,ledge+240,tedge+7,1 );
vsl_color( handle,3 );
empt_box( ledge+245,tedge,ledge+265,tedge+7,3 );
}
author()
{
long time = 150000L;
vst_color( handle,2 );
vst_effects( handle,T_SKEWED );
v_gtext( handle,14,192," by David T. Jarvis ");
while (time--)
;
put_msg( std_msg );
}
put_msg( s )
char *s;
{
vst_color( handle,2 );
vst_effects( handle,T_THICK );
v_gtext( handle,14,192,s );
}
locate( row, col )
short int row, col;
{
Cconout( ESC_K );
Cconout('Y');
Cconout( row + 32 );
Cconout( col + 32 );
}
sound_off()
{
Giaccess( 0, CH_AVL_W );
Giaccess( 0, CH_BVL_W );
Giaccess( 0, CH_CVL_W );
}
sound_on()
{
x_low = (char)(x_note);
y_low = (char)(y_note);
z_low = (char)(z_note);
x_high = (char)(x_note >> 8);
y_high = (char)(y_note >> 8);
z_high = (char)(z_note >> 8);
Giaccess( period, RG_ENV_W );
Giaccess( wave, RG_WAV_W );
Giaccess( x_low, CH_ALO_W );
Giaccess( x_high, CH_AHI_W );
Giaccess( y_low, CH_BLO_W );
Giaccess( y_high, CH_BHI_W );
Giaccess( z_low, CH_CLO_W );
Giaccess( z_high, CH_CHI_W );
Giaccess( vol_a, CH_AVL_W );
Giaccess( vol_b, CH_BVL_W );
Giaccess( vol_c, CH_CVL_W );
}
empt_box( left, top, right, bottom, color )
short int left, top, right, bottom, color;
{
short int pxy[ 10 ];
pxy[ 0 ] = left; pxy[ 1 ] = top;
pxy[ 2 ] = right; pxy[ 3 ] = top;
pxy[ 4 ] = right; pxy[ 5 ] = bottom;
pxy[ 6 ] = left; pxy[ 7 ] = bottom;
pxy[ 8 ] = left; pxy[ 9 ] = top;
vsl_color( handle,color );
v_pline( handle, 5, pxy );
}
full_box( left,top,right,bottom,color,style )
short int left,top,right,bottom,color,style;
{
short int pxy[ 4 ];
vsl_color( handle,color );
vsf_interior( handle,2 );
vsf_color( handle,color );
vswr_mode( handle,1 );
vsf_style( handle,style );
vsf_perimeter( handle,1 );
empt_box( left,top,right,bottom,color );
pxy[ 0 ] = left; pxy[ 1 ] = top;
pxy[ 2 ] = right; pxy[ 3 ] = bottom;
vr_recfl( handle,pxy );
}
nonoise()
{
char *con_ptr;
con_ptr = CONTERM;
*con_ptr = *con_ptr & (char)0xfa;
}