[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Musical Playback In Aztec C
- Subject: Musical Playback In Aztec C
- From: Bill Buckels <bbuckels@escape.ca>
- Date: Tue, 15 Apr 2008 06:27:00 -0700 (PDT)
- Complaints-to: groups-abuse@google.com
- Injection-info: q1g2000prf.googlegroups.com; posting-host=142.161.248.51; posting-account=lfN1DgkAAAAuU7dh9hSE-dqv44ZCj35R
- Newsgroups: comp.sys.apple2
- Organization: http://groups.google.com
- User-agent: G2/1.0
- Xref: g2news1.google.com comp.sys.apple2:34131
Musical Playback functions for Aztec C that runs on the apple ][
The ProDOS 8 version will also run nicely on a GS. Code for a ProDOS
demo is
also below as is a SND file converter that runs in MS-DOS.
On the apple, it's all based on clicking the speaker at varying
intervals.
That's why the SID chip on the C64 was so cool!
x--- snip ---x
/*
/* create a proper musical scale for the apple */
/* this is the algorithm that will be used */
/* june 1991 */
/* tired of flat notes... select a piano scale */
/* Apple Pitch Values */
int __pitch[5][12]={
/* C C# D D# E F F# G G# A A# B */
/* 0 1 2 3 4 5 6 7 8 9 10 11 */
285, 270, 257, 243, 229, 215, 200, 188, 179, 171, 167, 160,
150, 142, 132, 126, 117, 111, 106, 99, 93, 88, 83, 79,
74, 70, 65, 61, 58, 55, 51, 48, 45, 43, 40, 38,
36, 34, 32, 30, 28, 26, 24, 23, 21, 20, 19, 18,
17, 34, 32, 30, 28, 26, 24, 23, 21, 20, 19, 18};
sound(octave,note,duration)
char octave,note,duration;
{
int j,pit,temp;
switch(octave)
{
case 0:
case 1: pit= __pitch[0][note];break;
case 2: pit= __pitch[1][note];break;
case 3: pit= __pitch[2][note];break;
case 4: pit= __pitch[3][note];break;
case 5:
case 6: pit= __pitch[4][note];break;
/* silence... try to match the sound loop */
case 7: pit= 128;
temp=(1024*duration)/pit;
NOPER:; /* loop the required note length */
j=pit;
COUNTING:;
if(j--)goto COUNTING;
if(temp--)goto NOPER;
return 0;
}
temp=(1024*duration)/pit;
TOPPER:; /* loop the required note length */
#asm
BIT $C030
#endasm
j=pit;
COUNTER:;
if(j--)goto COUNTER;
if(temp--)goto TOPPER;
/* wait for the duration specified by pitch */
/* then click it again */
}
x--- snip ---x
play(song)
char *song;
{
char octave, note, duration;
int ctr=0;
while( (octave=song[ctr++])!=255)
{
note=song[ctr++];
duration=song[ctr++];
sound(octave,note,duration);
}
}
x--- snip ---x
#include <stdio.h>
int getch();
/* musical array created from file WEASEL.SND */
/* array structure is octave, note, duration */
char WEASEL[]={
2, 7, 2, 7, 0, 2, 2, 7, 2, 2, 9, 2, 7, 0, 2, 2, 9, 2,
2, 11, 2, 3, 2, 2, 2, 11, 2, 2, 7, 2, 7, 0, 2, 2, 2, 2,
2, 7, 2, 7, 0, 2, 2, 7, 2, 2, 9, 2, 7, 0, 2, 2, 9, 2,
2, 11, 6, 2, 7, 2, 7, 0, 2, 2, 2, 2, 2, 7, 2, 7, 0, 2,
2, 7, 2, 2, 9, 2, 7, 0, 2, 2, 9, 2, 2, 11, 2, 3, 2, 2,
2, 11, 2, 2, 7, 2, 7, 0, 4, 3, 4, 2, 7, 0, 4, 2, 9, 2,
7, 0, 2, 3, 0, 2, 2, 11, 6, 2, 7, 2, 7, 0, 4, 3, 7, 2,
7, 0, 2, 3, 7, 2, 3, 4, 2, 7, 0, 2, 3, 7, 2, 3, 6, 2,
3, 9, 2, 3, 6, 2, 3, 2, 2, 7, 0, 4, 3, 7, 2, 7, 0, 2,
3, 7, 2, 3, 4, 2, 7, 0, 2, 3, 7, 2, 3, 6, 6, 3, 2, 2,
7, 0, 2, 2, 11, 2, 3, 0, 2, 7, 0, 2, 2, 11, 2, 3, 0, 2,
7, 0, 2, 3, 2, 2, 3, 4, 2, 7, 0, 2, 3, 6, 2, 3, 7, 2,
7, 0, 4, 3, 4, 2, 7, 0, 4, 2, 9, 2, 7, 0, 2, 3, 0, 2,
2, 11, 6, 2, 7, 2,
'\xff','\xff','\xff'};
/* musical array created from file FROG.SND */
/* array structure is octave, note, duration */
char FROG[]={
3, 0, 6, 3, 5, 3, 3, 5, 3, 3, 5, 3, 3, 5, 3, 3, 5, 3,
3, 5, 3, 3, 9, 6, 3, 7, 6, 3, 2, 6, 3, 0, 6, 3, 5, 12,
7, 0, 6, 3, 0, 6, 3, 5, 12, 7, 0, 12, 3, 9, 3, 4, 0, 3,
4, 0, 3, 4, 0, 3, 4, 0, 3, 4, 0, 3, 4, 2, 6, 4, 0, 6,
3, 9, 6, 3, 5, 6, 3, 7, 6, 3, 5, 6, 3, 5, 6, 3, 5, 3,
3, 7, 3, 3, 9, 6, 3, 5, 6, 3, 2, 6, 3, 0, 6, 3, 5, 12,
7, 0, 6, 3, 0, 6, 3, 5, 12,
'\xff','\xff','\xff'};
/* musical array created from file bug.snd */
/* array structure is octave, note, duration */
char bug[]={
2, 2, 1, 7, 0, 1, 2, 2, 1, 7, 0, 1, 2, 2, 1, 7, 0, 1,
2, 7, 1, 7, 0, 5, 2, 11, 1, 7, 0, 3, 2, 2, 1, 7, 0, 1,
2, 2, 1, 7, 0, 1, 2, 2, 1, 7, 0, 1, 2, 7, 1, 7, 0, 5,
2, 11, 1, 7, 0, 5, 1, 2, 1, 7, 0, 1, 1, 2, 1, 7, 0, 1,
1, 7, 1, 7, 0, 3, 2, 7, 1, 7, 0, 1, 2, 7, 1, 7, 0, 1,
2, 6, 1, 7, 0, 1, 2, 6, 1, 7, 0, 1, 2, 4, 1, 7, 0, 1,
2, 4, 1, 7, 0, 1, 2, 2, 8, 7, 0, 2, 2, 2, 1, 7, 0, 1,
2, 2, 1, 7, 0, 1, 2, 2, 1, 7, 0, 1, 2, 6, 1, 7, 0, 5,
2, 9, 1, 7, 0, 3, 2, 2, 1, 7, 0, 1, 2, 2, 1, 7, 0, 1,
2, 2, 1, 7, 0, 1, 2, 6, 1, 7, 0, 5, 2, 9, 1, 7, 0, 5,
1, 9, 1, 7, 0, 1, 1, 9, 1, 7, 0, 1, 1, 2, 1, 7, 0, 3,
3, 2, 2, 3, 4, 2, 3, 2, 2, 3, 0, 2, 2, 11, 2, 2, 9, 2,
2, 7, 8,
'\xff','\xff','\xff'};
main()
{
int c=0;
scr_clear();
scr_curs(1,0);
printf("SONGSTER by Bill Buckels 2007\n");
printf("1 - Pop Goes The Weasel\n");
printf("2 - Froggy Went a Courting\n");
printf("3 - La Cucaracha\n");
printf("ESC Exit to PRODOS\n");
for(;;) {
c = getch();
if (c == 27)break;
switch(c)
{
case 49: play(WEASEL); break;
case 50: play(FROG); break;
case 51: play(bug); break;
default: sound(0,0,3);
}
}
scr_clear();
_exit();
}
x--- snip ---x
And here's how I made those... this is in 16 bit IBM C
/* converts binary musical files of type .SND */
/* to character arrays for embedding in C code */
/* a binary file of the array is also created. */
/* the output files are music macros for the apple II */
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
char far *soundbuffer;
#define S_IWRITE 0000200 /* write permission, owner */
int makefile(char *filename,int length)
{
int fh;
if((fh = open(filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IWRITE)) ==
-1)
return 0;
write(fh,(char *)&soundbuffer[0],length);
if(close(fh) == -1)
return 0;
}
int xplay(int xfrequency)
{
if(xfrequency < 64 || xfrequency > 4096 )
{
/* if we are out of range don't play anything */
return -1;
}
/* octave 0 */
if(xfrequency<127)
{
if(xfrequency<67 ) return 0 ;
if(xfrequency<71 ) return 1 ;
if(xfrequency<76 ) return 2 ;
if(xfrequency<80 ) return 3 ;
if(xfrequency<85 ) return 4 ;
if(xfrequency<90 ) return 5 ;
if(xfrequency<96 ) return 6 ;
if(xfrequency<101) return 7 ;
if(xfrequency<107) return 8 ;
if(xfrequency<114) return 9 ;
if(xfrequency<120) return 10;
return 11;
}
/* first octave */
if(xfrequency<255)
{
if(xfrequency<136) return 12;
if(xfrequency<143) return 13;
if(xfrequency<152) return 14;
if(xfrequency<160) return 15;
if(xfrequency<170) return 16;
if(xfrequency<180) return 17;
if(xfrequency<190) return 18;
if(xfrequency<202) return 19;
if(xfrequency<215) return 20;
if(xfrequency<227) return 21;
if(xfrequency<240) return 22;
return 23;
}
/* second octave */
if(xfrequency<512)
{
if(xfrequency<270)return 24;
if(xfrequency<286)return 25;
if(xfrequency<304)return 26;
if(xfrequency<322)return 27;
if(xfrequency<340)return 28;
if(xfrequency<360)return 29;
if(xfrequency<382)return 30;
if(xfrequency<406)return 31;
if(xfrequency<428)return 32;
if(xfrequency<454)return 33;
if(xfrequency<480)return 34;
return 35;
}
/* third octave */
if(xfrequency<1024)
{
if(xfrequency<540)return 36 ;
if(xfrequency<572)return 37 ;
if(xfrequency<605)return 38 ;
if(xfrequency<643)return 39 ;
if(xfrequency<680)return 40 ;
if(xfrequency<720)return 41 ;
if(xfrequency<765)return 42 ;
if(xfrequency<810)return 43 ;
if(xfrequency<855)return 44 ;
if(xfrequency<910)return 45 ;
if(xfrequency<965)return 46 ;
return 47 ;
}
/* fourth octave */
if(xfrequency<2048)
{
if(xfrequency<1080) return 48;
if(xfrequency<1144) return 49;
if(xfrequency<1210) return 50;
if(xfrequency<1286) return 51;
if(xfrequency<1340) return 52;
if(xfrequency<1440) return 53;
if(xfrequency<1530) return 54;
if(xfrequency<1620) return 55;
if(xfrequency<1710) return 56;
if(xfrequency<1820) return 57;
if(xfrequency<1930) return 58;
return 59;
}
/* fifth octave */
/* sixth octave ignored */
if(xfrequency<2160)return 60;
if(xfrequency<2288)return 61;
if(xfrequency<2420)return 62;
if(xfrequency<2572)return 63;
if(xfrequency<2680)return 64;
if(xfrequency<2880)return 65;
if(xfrequency<3060)return 66;
if(xfrequency<3240)return 67;
if(xfrequency<3420)return 68;
if(xfrequency<3640)return 69;
if(xfrequency<3860)return 70;
return 71;
}
main(int argc, char *argv[])
{
FILE *fp,*fp2;
char *wordptr;
char *ptr;
long target;
int bincounter=0;
int *intptr;
int octave, note;
int frequency,duration,counter=0;
char scratchbuffer[128],writebuffer[128],binbuffer[128];
if(argc!=2)
{
printf("SND filename required...");
exit(0);
}
if((fp=fopen(argv[1],"rb"))==NULL)
{
perror(argv[1]);
exit(0);
}
strcpy(scratchbuffer,argv[1]);
wordptr=strtok(scratchbuffer,".");
sprintf(writebuffer,"%s.TXT",scratchbuffer);
sprintf(binbuffer,"%s.BIN",scratchbuffer);
fp2=fopen(writebuffer,"w");
target=filelength(fileno(fp))+8;
soundbuffer = _fmalloc(target);
memset(soundbuffer,0,target);
ptr= (char *)&soundbuffer[2];
fprintf(fp2,
"/* musical array created from file %s */\n",argv[1]);
fprintf(fp2,
"/* array structure is octave, note, duration */\n");
fprintf(fp2,
"char %s[]={\n",scratchbuffer);
while((frequency=getw(fp))!=-1){
duration=fgetc(fp);
if((frequency=xplay(frequency))<0)
{
octave=7;
note =0;
}
else
{
octave = frequency/12;
note = frequency%12;
}
fprintf(fp2,"%2d, %2d, %2d,",octave,note,duration);
*ptr++=(char)octave;
*ptr++=(char)note;
*ptr++=(char)duration;
bincounter+=3;
counter++;
if(counter==6){
fprintf(fp2,"\n");
counter=0;
}
}
/* use 255 as the terminator... */
fprintf(fp2,"\n\'\\xff\',\'\\xff\',\'\\xff\'};\n",scratchbuffer);
*ptr++='\xff';
*ptr++='\xff';
*ptr++='\xff';
bincounter+=3;
fclose(fp);
fclose(fp2);
intptr=(int *)&soundbuffer[0];
*intptr=bincounter;
makefile(binbuffer,bincounter+2);
_ffree(soundbuffer);
exit(0);
}