Mercurial > ~darius > hgwebdir.cgi > mikmod
comparison playercode/unix_drv/drv_AF.c @ 8:b30908f9d9f9
Initial entry of mikmod into the CVS tree.
author | darius |
---|---|
date | Fri, 23 Jan 1998 16:05:10 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
7:de95ce2eacfd | 8:b30908f9d9f9 |
---|---|
1 /* | |
2 | |
3 Name: | |
4 DRV_AF.C | |
5 | |
6 Description: | |
7 Mikmod driver for output on AF audio server. | |
8 | |
9 Written by Roine Gustafsson <e93_rog@e.kth.se> Oct 25, 1995 | |
10 | |
11 Portability: | |
12 Unixes running Digital AudioFile library, available from | |
13 ftp://crl.dec.com/pub/DEC/AF | |
14 | |
15 Usage: | |
16 Run the audio server (Aaxp&, Amsb&, whatever) | |
17 Set environment variable AUDIOFILE to something like 'mymachine:0'. | |
18 Remember, stereo is default! See commandline switches. | |
19 | |
20 I have a version which uses 2 computers for stereo. | |
21 Contact me if you want it. | |
22 | |
23 THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | |
24 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, | |
25 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR | |
26 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | |
27 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, | |
28 NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |
29 CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
30 | |
31 History: | |
32 ver 1.21 Bugfix: AFFragmentSize could end up uneven. | |
33 Thanks to Marcus Sundberg <e94_msu@e.kth.se> | |
34 ver 1.22 Compatibility: change "AFBuffer" to "audiobuffer" | |
35 Steve McIntyre <stevem@chiark.greenend.org.uk> | |
36 ver 1.30 Compatibility: Use new driver API | |
37 Steve McIntyre <stevem@chiark.greenend.org.uk> | |
38 */ | |
39 | |
40 #include <malloc.h> | |
41 #include <stdlib.h> | |
42 #include <AF/AFlib.h> | |
43 | |
44 #include "mikmod.h" | |
45 | |
46 /* Global variables */ | |
47 | |
48 SBYTE *audiobuffer; | |
49 static int AFFragmentSize; | |
50 AFAudioConn *AFaud; | |
51 ATime AFtime; | |
52 AC AFac; | |
53 AFDeviceDescriptor *AFdesc; | |
54 | |
55 BOOL AF_IsThere(void) | |
56 { | |
57 | |
58 /* I'll think of a detection routine ... somtime */ | |
59 | |
60 return 1; | |
61 | |
62 } | |
63 | |
64 BOOL AF_Init(void) | |
65 { | |
66 unsigned long mask; | |
67 AFSetACAttributes attributes; | |
68 int srate; | |
69 ADevice device; | |
70 unsigned int channels; | |
71 AEncodeType type; | |
72 char *server; | |
73 int n; | |
74 | |
75 AFaud = AFOpenAudioConn( "" ); | |
76 if ( AFaud == NULL ) { | |
77 myerr="Cannot open sounddevice."; | |
78 return 0; | |
79 } | |
80 | |
81 /* Search for a suitable device */ | |
82 device = -1; | |
83 for ( n = 0; n < AFaud->ndevices; n++ ) { | |
84 AFdesc = AAudioDeviceDescriptor( AFaud, n ); | |
85 if ( AFdesc->playNchannels == 2 && md_mode&DMODE_STEREO ) { | |
86 device = n; | |
87 break; | |
88 } | |
89 if ( AFdesc->playNchannels == 1 && !(md_mode&DMODE_STEREO) ) { | |
90 device = n; | |
91 break; | |
92 } | |
93 } | |
94 if ( device == -1 ) { | |
95 myerr="Cannot find suitable audio port!"; | |
96 AFCloseAudioConn( AFaud ); | |
97 return 0; | |
98 } | |
99 | |
100 attributes.preempt = Mix; | |
101 attributes.start_timeout = 0; | |
102 attributes.end_silence = 0; | |
103 attributes.type = LIN16; /* In case of an 8bit device, the AF converts the 16 bit data to 8 bit */ | |
104 attributes.channels = (md_mode&DMODE_STEREO)? Stereo: Mono; | |
105 | |
106 mask = ACPreemption | ACEncodingType | ACStartTimeout | ACEndSilence | ACChannels; | |
107 AFac = AFCreateAC( AFaud, device, mask, &attributes ); | |
108 srate=AFac->device->playSampleFreq; | |
109 | |
110 md_mode|=DMODE_16BITS; /* This driver only handles 16bits */ | |
111 AFFragmentSize = (srate/40)*8; /* Update 5 times/sec */ | |
112 md_mixfreq=srate; /* set mixing freq */ | |
113 | |
114 if ( md_mode & DMODE_STEREO ) { | |
115 if ( ( audiobuffer = (SBYTE *)malloc( 2*2*AFFragmentSize ) ) == NULL ) { | |
116 myerr="Out of memory!"; | |
117 AFCloseAudioConn( AFaud ); | |
118 return 0; | |
119 } | |
120 | |
121 } else { | |
122 if ( ( audiobuffer = (SBYTE *)malloc( 2*AFFragmentSize ) ) == NULL ) { | |
123 myerr="Out of memory!"; | |
124 AFCloseAudioConn( AFaud ); | |
125 return 0; | |
126 } | |
127 } | |
128 | |
129 if ( !VC_Init() ) { | |
130 AFCloseAudioConn( AFaud ); | |
131 free( audiobuffer ); | |
132 return 0; | |
133 } | |
134 | |
135 return 1; | |
136 } | |
137 | |
138 void AF_PlayStart( void ) | |
139 { | |
140 | |
141 AFtime = AFGetTime( AFac ); | |
142 VC_PlayStart(); | |
143 | |
144 } | |
145 | |
146 | |
147 void AF_Exit(void) | |
148 { | |
149 | |
150 VC_Exit(); | |
151 AFCloseAudioConn(AFaud); | |
152 free( AFBuffer ); | |
153 | |
154 } | |
155 | |
156 void AF_Update(void) | |
157 { | |
158 | |
159 UWORD *p,*l,*r; | |
160 int i; | |
161 | |
162 | |
163 VC_WriteBytes( AFBuffer, AFFragmentSize ); | |
164 if ( md_mode & DMODE_STEREO ) { | |
165 AFPlaySamples( AFac, AFtime, AFFragmentSize, (unsigned char *)AFBuffer ); | |
166 AFtime+=AFFragmentSize/4; | |
167 // while ( AFGetTime( AFac ) < AFtime-1000 ); | |
168 } else { | |
169 AFPlaySamples( AFac, AFtime, AFFragmentSize, (unsigned char *)AFBuffer ); | |
170 AFtime+=AFFragmentSize/2; | |
171 // while ( AFGetTime( AFac ) < AFtime-1000 ); | |
172 } | |
173 | |
174 } | |
175 | |
176 | |
177 DRIVER drv_AF={ | |
178 NULL, | |
179 "AF driver", | |
180 "MikMod AudioFile Driver v1.22", | |
181 AF_IsThere, | |
182 VC_SampleLoad, | |
183 VC_SampleUnload, | |
184 VC_SampleSpace, | |
185 VC_SampleLength, | |
186 AF_Init, | |
187 AF_Exit, | |
188 VC_SetNumChannels, | |
189 AF_PlayStart, | |
190 VC_PlayStop, | |
191 AF_Update, | |
192 VC_VoiceSetVolume, | |
193 VC_VoiceSetFrequency, | |
194 VC_VoiceSetPanning, | |
195 VC_VoicePlay, | |
196 VC_VoiceStop, | |
197 VC_VoiceStopped, | |
198 VC_VoiceReleaseSustain, | |
199 VC_VoiceGetPosition, | |
200 VC_RealVolume | |
201 }; |