dropping SDL for the cross-platform version almost done
[dosdemo] / libs / mikmod / drivers / drv_sgi.c
1 /*      MikMod sound library
2         (c) 1998, 1999, 2000 Miodrag Vallat and others - see file AUTHORS for
3         complete list.
4
5         This library is free software; you can redistribute it and/or modify
6         it under the terms of the GNU Library General Public License as
7         published by the Free Software Foundation; either version 2 of
8         the License, or (at your option) any later version.
9
10         This program is distributed in the hope that it will be useful,
11         but WITHOUT ANY WARRANTY; without even the implied warranty of
12         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13         GNU Library General Public License for more details.
14
15         You should have received a copy of the GNU Library General Public
16         License along with this library; if not, write to the Free Software
17         Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18         02111-1307, USA.
19 */
20
21 /*==============================================================================
22
23   $Id$
24
25   Driver for output on SGI audio system (needs libaudio from the dmedia
26   package).
27
28 ==============================================================================*/
29
30 /*
31
32         Written by Stephan Kanthak <kanthak@i6.informatik.rwth-aachen.de>
33
34         Fragment configuration:
35         =======================
36
37         You can use the driver options fragsize and bufsize to override the
38         default size of the audio buffer. If you experience crackles & pops,
39         try experimenting with these values.
40
41         Please read the SGI section of libmikmod's README file first before
42         contacting the author because there are some things to know about the
43         specials of the SGI audio driver.
44
45 */
46
47 #ifdef HAVE_CONFIG_H
48 #include "config.h"
49 #endif
50
51 #include "mikmod_internals.h"
52
53 #ifdef DRV_SGI
54
55 #ifdef HAVE_UNISTD_H
56 #include <unistd.h>
57 #endif
58 #include <stdio.h>
59 #include <stdlib.h>
60 #include <dmedia/audio.h>
61
62 #define DEFAULT_SGI_BUFSIZE   40000
63 #define DEFAULT_SGI_FRAGSIZE  (DEFAULT_SGI_BUFSIZE / 2)
64
65 static  ALconfig sgi_config;
66 static  ALport sgi_port;
67 static  int sample_factor;
68 static  int sgi_fragsize=DEFAULT_SGI_FRAGSIZE;
69 static  int sgi_bufsize=DEFAULT_SGI_BUFSIZE;
70 static  SBYTE *audiobuffer=NULL;
71
72 static void SGI_CommandLine(const CHAR *cmdline)
73 {
74         CHAR *ptr;
75
76         if ((ptr=MD_GetAtom("fragsize",cmdline,0)) != NULL) {
77                 sgi_fragsize=atol(ptr);
78                 MikMod_free(ptr);
79         } else sgi_fragsize=DEFAULT_SGI_FRAGSIZE;
80
81         if ((ptr=MD_GetAtom("bufsize",cmdline,0)) != NULL) {
82                 sgi_bufsize=atol(ptr);
83                 MikMod_free(ptr);
84         } else sgi_bufsize=DEFAULT_SGI_BUFSIZE;
85 }
86
87 static BOOL SGI_IsThere(void)
88 {
89         ALseterrorhandler(0);
90         return(ALqueryparams(AL_DEFAULT_DEVICE,0,0))?1:0;
91 }
92
93 static int SGI_Init(void)
94 {
95         long chpars[] = { AL_OUTPUT_RATE, AL_RATE_22050 };
96
97         switch(md_mixfreq) {
98                 case 8000:
99                         chpars[1] = AL_RATE_8000;
100                         break;
101                 case 11025:
102                         chpars[1] = AL_RATE_11025;
103                         break;
104                 case 16000:
105                         chpars[1] = AL_RATE_16000;
106                         break;
107                 case 22050:
108                         chpars[1] = AL_RATE_22050;
109                         break;
110                 case 32000:
111                         chpars[1] = AL_RATE_32000;
112                         break;
113                 case 44100:
114                         chpars[1] = AL_RATE_44100;
115                         break;
116                 case 48000:
117                         chpars[1] = AL_RATE_48000;
118                         break;
119                 default:
120                         _mm_errno=MMERR_SGI_SPEED;
121                         return 1;
122         }
123         ALseterrorhandler(0);
124         ALsetparams(AL_DEFAULT_DEVICE, chpars, 2);
125
126         if (!(sgi_config=ALnewconfig())) {
127                 _mm_errno=MMERR_OPENING_AUDIO;
128                 return 1;
129         }
130
131         if (md_mode&DMODE_16BITS) {
132                 if (ALsetwidth(sgi_config,AL_SAMPLE_16)<0) {
133                         _mm_errno=MMERR_SGI_16BIT;
134                         return 1;
135                 }
136                 sample_factor = 1;
137         } else {
138                 if (ALsetwidth(sgi_config,AL_SAMPLE_8)<0) {
139                         _mm_errno=MMERR_SGI_8BIT;
140                         return 1;
141                 }
142                 sample_factor = 0;
143         }
144
145         if (md_mode&DMODE_STEREO) {
146                 if (ALsetchannels(sgi_config,AL_STEREO)<0) {
147                         _mm_errno=MMERR_SGI_STEREO;
148                         return 1;
149                 }
150         } else {
151                 if (ALsetchannels(sgi_config,AL_MONO)<0) {
152                         _mm_errno=MMERR_SGI_MONO;
153                         return 1;
154                 }
155         }
156
157         if ((getenv("MM_SGI_FRAGSIZE"))&&(sgi_fragsize!=DEFAULT_SGI_FRAGSIZE))
158                 sgi_fragsize=atol(getenv("MM_SGI_FRAGSIZE"));
159         if (!sgi_fragsize) sgi_fragsize=DEFAULT_SGI_FRAGSIZE;
160         if ((getenv("MM_SGI_BUFSIZE"))&&(sgi_bufsize!=DEFAULT_SGI_BUFSIZE))
161                 sgi_bufsize=atol(getenv("MM_SGI_BUFSIZE"));
162         if (!sgi_bufsize) sgi_fragsize=DEFAULT_SGI_BUFSIZE;
163
164         ALsetqueuesize(sgi_config, sgi_bufsize);
165         if (!(sgi_port=ALopenport("libmikmod","w",sgi_config))) {
166                 _mm_errno=MMERR_OPENING_AUDIO;
167                 return 1;
168         }
169
170         if(!(audiobuffer=(SBYTE*)MikMod_malloc(sgi_fragsize))) return 1;
171
172         return VC_Init();
173 }
174
175 static void SGI_Exit(void)
176 {
177         VC_Exit();
178         MikMod_free(audiobuffer);
179         audiobuffer=NULL;
180 }
181
182 static void SGI_Update(void)
183 {
184         ALwritesamps(sgi_port,audiobuffer,
185                      VC_WriteBytes(audiobuffer,sgi_fragsize)>>sample_factor);
186 }
187
188 MIKMODAPI MDRIVER drv_sgi={
189         NULL,
190         "SGI Audio System",
191         "SGI Audio System driver v0.5",
192         0,255,
193         "sgi",
194         "fragsize:r:0,99999,20000:Sound buffer fragment size\n"
195         "bufsize:r:0,199999,40000:Sound buffer total size\n",
196         SGI_CommandLine,
197         SGI_IsThere,
198         VC_SampleLoad,
199         VC_SampleUnload,
200         VC_SampleSpace,
201         VC_SampleLength,
202         SGI_Init,
203         SGI_Exit,
204         NULL,
205         VC_SetNumVoices,
206         VC_PlayStart,
207         VC_PlayStop,
208         SGI_Update,
209         NULL,
210         VC_VoiceSetVolume,
211         VC_VoiceGetVolume,
212         VC_VoiceSetFrequency,
213         VC_VoiceGetFrequency,
214         VC_VoiceSetPanning,
215         VC_VoiceGetPanning,
216         VC_VoicePlay,
217         VC_VoiceStop,
218         VC_VoiceStopped,
219         VC_VoiceGetPosition,
220         VC_VoiceRealVolume
221 };
222
223 #else
224
225 MISSING(drv_sgi);
226
227 #endif
228
229 /* ex:set ts=4: */