1 #include <stdio.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <math.h>
5 #include <sys/soundcard.h>
6 #include <sys/ioctl.h>
7 #include <unistd.h>
8 #include <fcntl.h>
9 #include <string.h>
10
11 #include "sapLib.h"
12
13 #define sapcmp(a, b, c) if (strncmp(a, b, strlen(a))==0) {printf("%s: %s", c, b+strlen(a)+1); st=1;}
14
15 #define sapfind(d, a, c) {unsigned char testBuf[1000]; int st=0; FILE *f=fopen(d, "rb"); do { fgets((char *)testBuf, 1000, f); if(testBuf[0]!=0xff) sapcmp(a, (char *)testBuf, c); } while(testBuf[0]!=0xff); if(st==0) printf("%s: <?>\n", c); fclose(f); }
16
17 signed short buffer[88200];
18 int fd, format;
19
main(int argc,char ** argv)20 int main(int argc, char **argv)
21 {
22 printf("Penguin Sap v0.01 by Jaymz Julian (jaymz@dspaudio.com)\n");
23 printf("Sap Library v1.52 by Adam Bienias\n");
24
25 char *file2play;
26 int verbose=0;
27 int bits=16;
28 int mono=0;
29 int songNum=0;
30 // parse the options
31 if(argc==1)
32 {
33 printf("Usage: %s [-v] filename.sap\n", argv[0]);
34 printf(" -oX : Song number\n");
35 printf(" -v : Print verbose info\n");
36 printf(" -m : Mono audio output (Default is stereo)\n");
37 printf(" -8 : 8 bit output (Default is 16 bit)\n");
38 exit(1);
39 }
40
41 for(int x=1;x<argc;x++)
42 {
43 if(argv[x][0]=='-')
44 {
45 // it's an option
46 switch(argv[x][1])
47 {
48 case 'v':
49 verbose=1;
50 break;
51 case 'm':
52 mono=1;
53 break;
54 case '8':
55 bits=8;
56 break;
57 case 'o':
58 songNum=atoi(argv[x]+2);
59 break;
60 default:
61 printf("Invalid paramater - run without any parameters for help!\n");
62 exit(1);
63 break;
64 }
65 }
66 else
67 {
68 // it's a file
69 file2play=argv[x];
70 }
71 }
72
73
74 printf("Filenames : %s\n",file2play);
75 sapMUSICstrc *fish=sapLoadMusicFile(file2play);
76
77 if(fish->defSong== -1) fish->defSong=1;
78 if(fish->numOfSongs== -1) fish->numOfSongs=1;
79
80 if(songNum!=0)
81 sapPlaySong(songNum);
82 else
83 songNum=fish->defSong;
84
85
86 // FIXME: detect file type here (binary, chaos music,digi, etc)
87 printf("File format : Atari XL/XE SAP (Type)\n");
88
89 // print sidplay like info
90 // FIXME: support chaos music/softsynth types
91 // FIXME: get load address
92
93 sapfind(file2play, "NAME" , "Name ");
94 sapfind(file2play, "AUTHOR" , "Author ");
95 sapfind(file2play, "DATE" , "Copyright ");
96 if(verbose==1)
97 {
98 printf("Load Address : <?>\n");
99 sapfind(file2play, "INIT" , "Init address ");
100 sapfind(file2play, "PLAYER" , "Play address ");
101 }
102 sapfind(file2play, "TIME" , "Play time ");
103
104 printf("Setting Song : %d out of %d (default = %d)\n", songNum, fish->numOfSongs, fish->defSong);
105
106 // FIXME: support fastplay
107 printf("Song speed : 50 Hz VBI (PAL)\n");
108
109 printf("Playing, press ^C to stop ...\n");
110 fflush(stdout);
111
112 // loading succesful - init the soundcard
113 // why does this code work in FLAW, but not in penguin sap?
114 fd=open("/dev/mixer", O_WRONLY, 0);
115 fd=open("/dev/dsp", O_WRONLY, 0);
116 if(bits==16)
117 format=AFMT_S16_LE;
118 else
119 format=AFMT_U8;
120
121 ioctl(fd, SNDCTL_DSP_SETFMT, &format);
122 format=44100;
123 ioctl(fd, SNDCTL_DSP_SPEED, &format);
124
125 if(mono==1)
126 format=1;
127 else
128 format=2;
129
130 ioctl(fd, SNDCTL_DSP_CHANNELS, &format);
131
132 do
133 {
134 int dataSize=22050*4;
135 sapRenderBuffer(buffer, 22050);
136 if(mono==1)
137 {
138 // transform to mono
139 for(int c=0;c<22050;c++)
140 buffer[c]=((buffer[c*2]+buffer[c*2+1])/2);
141 dataSize/=2;
142 }
143
144 if(bits==8)
145 {
146 short ws;
147 dataSize/=2;
148 for(int c=0;c<dataSize;c++)
149 {
150 ws=(buffer[c]>>8)+128;
151 ((char *)buffer)[c]=(char)ws;
152 }
153 }
154 write(fd, buffer, dataSize);
155 } while(0==0);
156 }
157