Mercurial > sdl-ios-xcode
comparison src/audio/sun/SDL_sunaudio.c @ 1895:c121d94672cb
SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 10 Jul 2006 21:04:37 +0000 |
parents | af30090c0330 |
children | 152dcc2f089f |
comparison
equal
deleted
inserted
replaced
1894:c69cee13dd76 | 1895:c121d94672cb |
---|---|
46 | 46 |
47 /* Open the audio device for playback, and don't block if busy */ | 47 /* Open the audio device for playback, and don't block if busy */ |
48 #define OPEN_FLAGS (O_WRONLY|O_NONBLOCK) | 48 #define OPEN_FLAGS (O_WRONLY|O_NONBLOCK) |
49 | 49 |
50 /* Audio driver functions */ | 50 /* Audio driver functions */ |
51 static int DSP_OpenAudio(_THIS, SDL_AudioSpec *spec); | 51 static int DSP_OpenAudio(_THIS, SDL_AudioSpec * spec); |
52 static void DSP_WaitAudio(_THIS); | 52 static void DSP_WaitAudio(_THIS); |
53 static void DSP_PlayAudio(_THIS); | 53 static void DSP_PlayAudio(_THIS); |
54 static Uint8 *DSP_GetAudioBuf(_THIS); | 54 static Uint8 *DSP_GetAudioBuf(_THIS); |
55 static void DSP_CloseAudio(_THIS); | 55 static void DSP_CloseAudio(_THIS); |
56 | 56 |
57 static Uint8 snd2au(int sample); | 57 static Uint8 snd2au(int sample); |
58 | 58 |
59 /* Audio driver bootstrap functions */ | 59 /* Audio driver bootstrap functions */ |
60 | 60 |
61 static int Audio_Available(void) | 61 static int |
62 { | 62 Audio_Available(void) |
63 int fd; | 63 { |
64 int available; | 64 int fd; |
65 | 65 int available; |
66 available = 0; | 66 |
67 fd = SDL_OpenAudioPath(NULL, 0, OPEN_FLAGS, 1); | 67 available = 0; |
68 if ( fd >= 0 ) { | 68 fd = SDL_OpenAudioPath(NULL, 0, OPEN_FLAGS, 1); |
69 available = 1; | 69 if (fd >= 0) { |
70 close(fd); | 70 available = 1; |
71 } | 71 close(fd); |
72 return(available); | 72 } |
73 } | 73 return (available); |
74 | 74 } |
75 static void Audio_DeleteDevice(SDL_AudioDevice *device) | 75 |
76 { | 76 static void |
77 SDL_free(device->hidden); | 77 Audio_DeleteDevice(SDL_AudioDevice * device) |
78 SDL_free(device); | 78 { |
79 } | 79 SDL_free(device->hidden); |
80 | 80 SDL_free(device); |
81 static SDL_AudioDevice *Audio_CreateDevice(int devindex) | 81 } |
82 { | 82 |
83 SDL_AudioDevice *this; | 83 static SDL_AudioDevice * |
84 | 84 Audio_CreateDevice(int devindex) |
85 /* Initialize all variables that we clean on shutdown */ | 85 { |
86 this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | 86 SDL_AudioDevice *this; |
87 if ( this ) { | 87 |
88 SDL_memset(this, 0, (sizeof *this)); | 88 /* Initialize all variables that we clean on shutdown */ |
89 this->hidden = (struct SDL_PrivateAudioData *) | 89 this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice)); |
90 SDL_malloc((sizeof *this->hidden)); | 90 if (this) { |
91 } | 91 SDL_memset(this, 0, (sizeof *this)); |
92 if ( (this == NULL) || (this->hidden == NULL) ) { | 92 this->hidden = (struct SDL_PrivateAudioData *) |
93 SDL_OutOfMemory(); | 93 SDL_malloc((sizeof *this->hidden)); |
94 if ( this ) { | 94 } |
95 SDL_free(this); | 95 if ((this == NULL) || (this->hidden == NULL)) { |
96 } | 96 SDL_OutOfMemory(); |
97 return(0); | 97 if (this) { |
98 } | 98 SDL_free(this); |
99 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | 99 } |
100 audio_fd = -1; | 100 return (0); |
101 | 101 } |
102 /* Set the function pointers */ | 102 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); |
103 this->OpenAudio = DSP_OpenAudio; | 103 audio_fd = -1; |
104 this->WaitAudio = DSP_WaitAudio; | 104 |
105 this->PlayAudio = DSP_PlayAudio; | 105 /* Set the function pointers */ |
106 this->GetAudioBuf = DSP_GetAudioBuf; | 106 this->OpenAudio = DSP_OpenAudio; |
107 this->CloseAudio = DSP_CloseAudio; | 107 this->WaitAudio = DSP_WaitAudio; |
108 | 108 this->PlayAudio = DSP_PlayAudio; |
109 this->free = Audio_DeleteDevice; | 109 this->GetAudioBuf = DSP_GetAudioBuf; |
110 | 110 this->CloseAudio = DSP_CloseAudio; |
111 return this; | 111 |
112 this->free = Audio_DeleteDevice; | |
113 | |
114 return this; | |
112 } | 115 } |
113 | 116 |
114 AudioBootStrap SUNAUDIO_bootstrap = { | 117 AudioBootStrap SUNAUDIO_bootstrap = { |
115 "audio", "UNIX /dev/audio interface", | 118 "audio", "UNIX /dev/audio interface", |
116 Audio_Available, Audio_CreateDevice | 119 Audio_Available, Audio_CreateDevice |
117 }; | 120 }; |
118 | 121 |
119 #ifdef DEBUG_AUDIO | 122 #ifdef DEBUG_AUDIO |
120 void CheckUnderflow(_THIS) | 123 void |
124 CheckUnderflow(_THIS) | |
121 { | 125 { |
122 #ifdef AUDIO_GETINFO | 126 #ifdef AUDIO_GETINFO |
123 audio_info_t info; | 127 audio_info_t info; |
124 int left; | 128 int left; |
125 | 129 |
126 ioctl(audio_fd, AUDIO_GETINFO, &info); | 130 ioctl(audio_fd, AUDIO_GETINFO, &info); |
127 left = (written - info.play.samples); | 131 left = (written - info.play.samples); |
128 if ( written && (left == 0) ) { | 132 if (written && (left == 0)) { |
129 fprintf(stderr, "audio underflow!\n"); | 133 fprintf(stderr, "audio underflow!\n"); |
130 } | 134 } |
131 #endif | 135 #endif |
132 } | 136 } |
133 #endif | 137 #endif |
134 | 138 |
135 void DSP_WaitAudio(_THIS) | 139 void |
140 DSP_WaitAudio(_THIS) | |
136 { | 141 { |
137 #ifdef AUDIO_GETINFO | 142 #ifdef AUDIO_GETINFO |
138 #define SLEEP_FUDGE 10 /* 10 ms scheduling fudge factor */ | 143 #define SLEEP_FUDGE 10 /* 10 ms scheduling fudge factor */ |
139 audio_info_t info; | 144 audio_info_t info; |
140 Sint32 left; | 145 Sint32 left; |
141 | 146 |
142 ioctl(audio_fd, AUDIO_GETINFO, &info); | 147 ioctl(audio_fd, AUDIO_GETINFO, &info); |
143 left = (written - info.play.samples); | 148 left = (written - info.play.samples); |
144 if ( left > fragsize ) { | 149 if (left > fragsize) { |
145 Sint32 sleepy; | 150 Sint32 sleepy; |
146 | 151 |
147 sleepy = ((left - fragsize)/frequency); | 152 sleepy = ((left - fragsize) / frequency); |
148 sleepy -= SLEEP_FUDGE; | 153 sleepy -= SLEEP_FUDGE; |
149 if ( sleepy > 0 ) { | 154 if (sleepy > 0) { |
150 SDL_Delay(sleepy); | 155 SDL_Delay(sleepy); |
151 } | 156 } |
152 } | 157 } |
153 #else | 158 #else |
154 fd_set fdset; | 159 fd_set fdset; |
155 | 160 |
156 FD_ZERO(&fdset); | 161 FD_ZERO(&fdset); |
157 FD_SET(audio_fd, &fdset); | 162 FD_SET(audio_fd, &fdset); |
158 select(audio_fd+1, NULL, &fdset, NULL, NULL); | 163 select(audio_fd + 1, NULL, &fdset, NULL, NULL); |
159 #endif | 164 #endif |
160 } | 165 } |
161 | 166 |
162 void DSP_PlayAudio(_THIS) | 167 void |
163 { | 168 DSP_PlayAudio(_THIS) |
164 /* Write the audio data */ | 169 { |
165 if ( ulaw_only ) { | 170 /* Write the audio data */ |
166 /* Assuming that this->spec.freq >= 8000 Hz */ | 171 if (ulaw_only) { |
167 int accum, incr, pos; | 172 /* Assuming that this->spec.freq >= 8000 Hz */ |
168 Uint8 *aubuf; | 173 int accum, incr, pos; |
169 | 174 Uint8 *aubuf; |
170 accum = 0; | 175 |
171 incr = this->spec.freq/8; | 176 accum = 0; |
172 aubuf = ulaw_buf; | 177 incr = this->spec.freq / 8; |
173 switch (audio_fmt & 0xFF) { | 178 aubuf = ulaw_buf; |
174 case 8: { | 179 switch (audio_fmt & 0xFF) { |
175 Uint8 *sndbuf; | 180 case 8: |
176 | 181 { |
177 sndbuf = mixbuf; | 182 Uint8 *sndbuf; |
178 for ( pos=0; pos < fragsize; ++pos ) { | 183 |
179 *aubuf = snd2au((0x80-*sndbuf)*64); | 184 sndbuf = mixbuf; |
180 accum += incr; | 185 for (pos = 0; pos < fragsize; ++pos) { |
181 while ( accum > 0 ) { | 186 *aubuf = snd2au((0x80 - *sndbuf) * 64); |
182 accum -= 1000; | 187 accum += incr; |
183 sndbuf += 1; | 188 while (accum > 0) { |
184 } | 189 accum -= 1000; |
185 aubuf += 1; | 190 sndbuf += 1; |
186 } | 191 } |
187 } | 192 aubuf += 1; |
188 break; | 193 } |
189 case 16: { | 194 } |
190 Sint16 *sndbuf; | 195 break; |
191 | 196 case 16: |
192 sndbuf = (Sint16 *)mixbuf; | 197 { |
193 for ( pos=0; pos < fragsize; ++pos ) { | 198 Sint16 *sndbuf; |
194 *aubuf = snd2au(*sndbuf/4); | 199 |
195 accum += incr; | 200 sndbuf = (Sint16 *) mixbuf; |
196 while ( accum > 0 ) { | 201 for (pos = 0; pos < fragsize; ++pos) { |
197 accum -= 1000; | 202 *aubuf = snd2au(*sndbuf / 4); |
198 sndbuf += 1; | 203 accum += incr; |
199 } | 204 while (accum > 0) { |
200 aubuf += 1; | 205 accum -= 1000; |
201 } | 206 sndbuf += 1; |
202 } | 207 } |
203 break; | 208 aubuf += 1; |
204 } | 209 } |
210 } | |
211 break; | |
212 } | |
205 #ifdef DEBUG_AUDIO | 213 #ifdef DEBUG_AUDIO |
206 CheckUnderflow(this); | 214 CheckUnderflow(this); |
207 #endif | 215 #endif |
208 if ( write(audio_fd, ulaw_buf, fragsize) < 0 ) { | 216 if (write(audio_fd, ulaw_buf, fragsize) < 0) { |
209 /* Assume fatal error, for now */ | 217 /* Assume fatal error, for now */ |
210 this->enabled = 0; | 218 this->enabled = 0; |
211 } | 219 } |
212 written += fragsize; | 220 written += fragsize; |
213 } else { | 221 } else { |
214 #ifdef DEBUG_AUDIO | 222 #ifdef DEBUG_AUDIO |
215 CheckUnderflow(this); | 223 CheckUnderflow(this); |
216 #endif | 224 #endif |
217 if ( write(audio_fd, mixbuf, this->spec.size) < 0 ) { | 225 if (write(audio_fd, mixbuf, this->spec.size) < 0) { |
218 /* Assume fatal error, for now */ | 226 /* Assume fatal error, for now */ |
219 this->enabled = 0; | 227 this->enabled = 0; |
220 } | 228 } |
221 written += fragsize; | 229 written += fragsize; |
222 } | 230 } |
223 } | 231 } |
224 | 232 |
225 Uint8 *DSP_GetAudioBuf(_THIS) | 233 Uint8 * |
226 { | 234 DSP_GetAudioBuf(_THIS) |
227 return(mixbuf); | 235 { |
228 } | 236 return (mixbuf); |
229 | 237 } |
230 void DSP_CloseAudio(_THIS) | 238 |
231 { | 239 void |
232 if ( mixbuf != NULL ) { | 240 DSP_CloseAudio(_THIS) |
233 SDL_FreeAudioMem(mixbuf); | 241 { |
234 mixbuf = NULL; | 242 if (mixbuf != NULL) { |
235 } | 243 SDL_FreeAudioMem(mixbuf); |
236 if ( ulaw_buf != NULL ) { | 244 mixbuf = NULL; |
237 SDL_free(ulaw_buf); | 245 } |
238 ulaw_buf = NULL; | 246 if (ulaw_buf != NULL) { |
239 } | 247 SDL_free(ulaw_buf); |
240 close(audio_fd); | 248 ulaw_buf = NULL; |
241 } | 249 } |
242 | 250 close(audio_fd); |
243 int DSP_OpenAudio(_THIS, SDL_AudioSpec *spec) | 251 } |
244 { | 252 |
245 char audiodev[1024]; | 253 int |
254 DSP_OpenAudio(_THIS, SDL_AudioSpec * spec) | |
255 { | |
256 char audiodev[1024]; | |
246 #ifdef AUDIO_SETINFO | 257 #ifdef AUDIO_SETINFO |
247 int enc; | 258 int enc; |
248 #endif | 259 #endif |
249 int desired_freq = spec->freq; | 260 int desired_freq = spec->freq; |
250 | 261 |
251 /* Initialize our freeable variables, in case we fail*/ | 262 /* Initialize our freeable variables, in case we fail */ |
252 audio_fd = -1; | 263 audio_fd = -1; |
253 mixbuf = NULL; | 264 mixbuf = NULL; |
254 ulaw_buf = NULL; | 265 ulaw_buf = NULL; |
255 | 266 |
256 /* Determine the audio parameters from the AudioSpec */ | 267 /* Determine the audio parameters from the AudioSpec */ |
257 switch ( spec->format & 0xFF ) { | 268 switch (spec->format & 0xFF) { |
258 | 269 |
259 case 8: { /* Unsigned 8 bit audio data */ | 270 case 8: |
260 spec->format = AUDIO_U8; | 271 { /* Unsigned 8 bit audio data */ |
272 spec->format = AUDIO_U8; | |
261 #ifdef AUDIO_SETINFO | 273 #ifdef AUDIO_SETINFO |
262 enc = AUDIO_ENCODING_LINEAR8; | 274 enc = AUDIO_ENCODING_LINEAR8; |
263 #endif | 275 #endif |
264 } | 276 } |
265 break; | 277 break; |
266 | 278 |
267 case 16: { /* Signed 16 bit audio data */ | 279 case 16: |
268 spec->format = AUDIO_S16SYS; | 280 { /* Signed 16 bit audio data */ |
281 spec->format = AUDIO_S16SYS; | |
269 #ifdef AUDIO_SETINFO | 282 #ifdef AUDIO_SETINFO |
270 enc = AUDIO_ENCODING_LINEAR; | 283 enc = AUDIO_ENCODING_LINEAR; |
271 #endif | 284 #endif |
272 } | 285 } |
273 break; | 286 break; |
274 | 287 |
275 default: { | 288 default: |
276 SDL_SetError("Unsupported audio format"); | 289 { |
277 return(-1); | 290 SDL_SetError("Unsupported audio format"); |
278 } | 291 return (-1); |
279 } | 292 } |
280 audio_fmt = spec->format; | 293 } |
281 | 294 audio_fmt = spec->format; |
282 /* Open the audio device */ | 295 |
283 audio_fd = SDL_OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 1); | 296 /* Open the audio device */ |
284 if ( audio_fd < 0 ) { | 297 audio_fd = SDL_OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 1); |
285 SDL_SetError("Couldn't open %s: %s", audiodev, | 298 if (audio_fd < 0) { |
286 strerror(errno)); | 299 SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno)); |
287 return(-1); | 300 return (-1); |
288 } | 301 } |
289 | 302 |
290 ulaw_only = 0; /* modern Suns do support linear audio */ | 303 ulaw_only = 0; /* modern Suns do support linear audio */ |
291 #ifdef AUDIO_SETINFO | 304 #ifdef AUDIO_SETINFO |
292 for(;;) { | 305 for (;;) { |
293 audio_info_t info; | 306 audio_info_t info; |
294 AUDIO_INITINFO(&info); /* init all fields to "no change" */ | 307 AUDIO_INITINFO(&info); /* init all fields to "no change" */ |
295 | 308 |
296 /* Try to set the requested settings */ | 309 /* Try to set the requested settings */ |
297 info.play.sample_rate = spec->freq; | 310 info.play.sample_rate = spec->freq; |
298 info.play.channels = spec->channels; | 311 info.play.channels = spec->channels; |
299 info.play.precision = (enc == AUDIO_ENCODING_ULAW) | 312 info.play.precision = (enc == AUDIO_ENCODING_ULAW) |
300 ? 8 : spec->format & 0xff; | 313 ? 8 : spec->format & 0xff; |
301 info.play.encoding = enc; | 314 info.play.encoding = enc; |
302 if( ioctl(audio_fd, AUDIO_SETINFO, &info) == 0 ) { | 315 if (ioctl(audio_fd, AUDIO_SETINFO, &info) == 0) { |
303 | 316 |
304 /* Check to be sure we got what we wanted */ | 317 /* Check to be sure we got what we wanted */ |
305 if(ioctl(audio_fd, AUDIO_GETINFO, &info) < 0) { | 318 if (ioctl(audio_fd, AUDIO_GETINFO, &info) < 0) { |
306 SDL_SetError("Error getting audio parameters: %s", | 319 SDL_SetError("Error getting audio parameters: %s", |
307 strerror(errno)); | 320 strerror(errno)); |
308 return -1; | 321 return -1; |
309 } | 322 } |
310 if(info.play.encoding == enc | 323 if (info.play.encoding == enc |
311 && info.play.precision == (spec->format & 0xff) | 324 && info.play.precision == (spec->format & 0xff) |
312 && info.play.channels == spec->channels) { | 325 && info.play.channels == spec->channels) { |
313 /* Yow! All seems to be well! */ | 326 /* Yow! All seems to be well! */ |
314 spec->freq = info.play.sample_rate; | 327 spec->freq = info.play.sample_rate; |
315 break; | 328 break; |
316 } | 329 } |
317 } | 330 } |
318 | 331 |
319 switch(enc) { | 332 switch (enc) { |
320 case AUDIO_ENCODING_LINEAR8: | 333 case AUDIO_ENCODING_LINEAR8: |
321 /* unsigned 8bit apparently not supported here */ | 334 /* unsigned 8bit apparently not supported here */ |
322 enc = AUDIO_ENCODING_LINEAR; | 335 enc = AUDIO_ENCODING_LINEAR; |
323 spec->format = AUDIO_S16SYS; | 336 spec->format = AUDIO_S16SYS; |
324 break; /* try again */ | 337 break; /* try again */ |
325 | 338 |
326 case AUDIO_ENCODING_LINEAR: | 339 case AUDIO_ENCODING_LINEAR: |
327 /* linear 16bit didn't work either, resort to µ-law */ | 340 /* linear 16bit didn't work either, resort to µ-law */ |
328 enc = AUDIO_ENCODING_ULAW; | 341 enc = AUDIO_ENCODING_ULAW; |
329 spec->channels = 1; | 342 spec->channels = 1; |
330 spec->freq = 8000; | 343 spec->freq = 8000; |
331 spec->format = AUDIO_U8; | 344 spec->format = AUDIO_U8; |
332 ulaw_only = 1; | 345 ulaw_only = 1; |
333 break; | 346 break; |
334 | 347 |
335 default: | 348 default: |
336 /* oh well... */ | 349 /* oh well... */ |
337 SDL_SetError("Error setting audio parameters: %s", | 350 SDL_SetError("Error setting audio parameters: %s", |
338 strerror(errno)); | 351 strerror(errno)); |
339 return -1; | 352 return -1; |
340 } | 353 } |
341 } | 354 } |
342 #endif /* AUDIO_SETINFO */ | 355 #endif /* AUDIO_SETINFO */ |
343 written = 0; | 356 written = 0; |
344 | 357 |
345 /* We can actually convert on-the-fly to U-Law */ | 358 /* We can actually convert on-the-fly to U-Law */ |
346 if ( ulaw_only ) { | 359 if (ulaw_only) { |
347 spec->freq = desired_freq; | 360 spec->freq = desired_freq; |
348 fragsize = (spec->samples*1000)/(spec->freq/8); | 361 fragsize = (spec->samples * 1000) / (spec->freq / 8); |
349 frequency = 8; | 362 frequency = 8; |
350 ulaw_buf = (Uint8 *)SDL_malloc(fragsize); | 363 ulaw_buf = (Uint8 *) SDL_malloc(fragsize); |
351 if ( ulaw_buf == NULL ) { | 364 if (ulaw_buf == NULL) { |
352 SDL_OutOfMemory(); | 365 SDL_OutOfMemory(); |
353 return(-1); | 366 return (-1); |
354 } | 367 } |
355 spec->channels = 1; | 368 spec->channels = 1; |
356 } else { | 369 } else { |
357 fragsize = spec->samples; | 370 fragsize = spec->samples; |
358 frequency = spec->freq/1000; | 371 frequency = spec->freq / 1000; |
359 } | 372 } |
360 #ifdef DEBUG_AUDIO | 373 #ifdef DEBUG_AUDIO |
361 fprintf(stderr, "Audio device %s U-Law only\n", | 374 fprintf(stderr, "Audio device %s U-Law only\n", |
362 ulaw_only ? "is" : "is not"); | 375 ulaw_only ? "is" : "is not"); |
363 fprintf(stderr, "format=0x%x chan=%d freq=%d\n", | 376 fprintf(stderr, "format=0x%x chan=%d freq=%d\n", |
364 spec->format, spec->channels, spec->freq); | 377 spec->format, spec->channels, spec->freq); |
365 #endif | 378 #endif |
366 | 379 |
367 /* Update the fragment size as size in bytes */ | 380 /* Update the fragment size as size in bytes */ |
368 SDL_CalculateAudioSpec(spec); | 381 SDL_CalculateAudioSpec(spec); |
369 | 382 |
370 /* Allocate mixing buffer */ | 383 /* Allocate mixing buffer */ |
371 mixbuf = (Uint8 *)SDL_AllocAudioMem(spec->size); | 384 mixbuf = (Uint8 *) SDL_AllocAudioMem(spec->size); |
372 if ( mixbuf == NULL ) { | 385 if (mixbuf == NULL) { |
373 SDL_OutOfMemory(); | 386 SDL_OutOfMemory(); |
374 return(-1); | 387 return (-1); |
375 } | 388 } |
376 SDL_memset(mixbuf, spec->silence, spec->size); | 389 SDL_memset(mixbuf, spec->silence, spec->size); |
377 | 390 |
378 /* We're ready to rock and roll. :-) */ | 391 /* We're ready to rock and roll. :-) */ |
379 return(0); | 392 return (0); |
380 } | 393 } |
381 | 394 |
382 /************************************************************************/ | 395 /************************************************************************/ |
383 /* This function (snd2au()) copyrighted: */ | 396 /* This function (snd2au()) copyrighted: */ |
384 /************************************************************************/ | 397 /************************************************************************/ |
395 /* Rich Gopstein and Harris Corporation make no representations */ | 408 /* Rich Gopstein and Harris Corporation make no representations */ |
396 /* about the suitability of this software for any purpose. It */ | 409 /* about the suitability of this software for any purpose. It */ |
397 /* provided "as is" without express or implied warranty. */ | 410 /* provided "as is" without express or implied warranty. */ |
398 /************************************************************************/ | 411 /************************************************************************/ |
399 | 412 |
400 static Uint8 snd2au(int sample) | 413 static Uint8 |
401 { | 414 snd2au(int sample) |
402 | 415 { |
403 int mask; | 416 |
404 | 417 int mask; |
405 if (sample < 0) { | 418 |
406 sample = -sample; | 419 if (sample < 0) { |
407 mask = 0x7f; | 420 sample = -sample; |
408 } else { | 421 mask = 0x7f; |
409 mask = 0xff; | 422 } else { |
410 } | 423 mask = 0xff; |
411 | 424 } |
412 if (sample < 32) { | 425 |
413 sample = 0xF0 | (15 - sample / 2); | 426 if (sample < 32) { |
414 } else if (sample < 96) { | 427 sample = 0xF0 | (15 - sample / 2); |
415 sample = 0xE0 | (15 - (sample - 32) / 4); | 428 } else if (sample < 96) { |
416 } else if (sample < 224) { | 429 sample = 0xE0 | (15 - (sample - 32) / 4); |
417 sample = 0xD0 | (15 - (sample - 96) / 8); | 430 } else if (sample < 224) { |
418 } else if (sample < 480) { | 431 sample = 0xD0 | (15 - (sample - 96) / 8); |
419 sample = 0xC0 | (15 - (sample - 224) / 16); | 432 } else if (sample < 480) { |
420 } else if (sample < 992) { | 433 sample = 0xC0 | (15 - (sample - 224) / 16); |
421 sample = 0xB0 | (15 - (sample - 480) / 32); | 434 } else if (sample < 992) { |
422 } else if (sample < 2016) { | 435 sample = 0xB0 | (15 - (sample - 480) / 32); |
423 sample = 0xA0 | (15 - (sample - 992) / 64); | 436 } else if (sample < 2016) { |
424 } else if (sample < 4064) { | 437 sample = 0xA0 | (15 - (sample - 992) / 64); |
425 sample = 0x90 | (15 - (sample - 2016) / 128); | 438 } else if (sample < 4064) { |
426 } else if (sample < 8160) { | 439 sample = 0x90 | (15 - (sample - 2016) / 128); |
427 sample = 0x80 | (15 - (sample - 4064) / 256); | 440 } else if (sample < 8160) { |
428 } else { | 441 sample = 0x80 | (15 - (sample - 4064) / 256); |
429 sample = 0x80; | 442 } else { |
430 } | 443 sample = 0x80; |
431 return (mask & sample); | 444 } |
432 } | 445 return (mask & sample); |
446 } | |
447 | |
448 /* vi: set ts=4 sw=4 expandtab: */ |