Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/openal-0.0.8/src/backends/alc_backend_windows.c @ 17

Last change on this file since 17 was 17, checked in by landauf, 16 years ago

added openal

File size: 6.5 KB
Line 
1/* vi:set ts=8:
2 *
3 * windows_native.c
4 *
5 * functions related to the aquisition and management of the native
6 * audio on Windows.
7 *
8 */
9
10#include "al_siteconfig.h"
11
12#include <AL/al.h>
13#include <stdio.h>
14#include <stdlib.h>
15#include <windows.h>
16#include <mmsystem.h>
17
18#include "backends/alc_backend.h"
19
20#include "al_main.h"
21#include "al_debug.h"
22
23#include "alc/alc_context.h"
24
25#include "al_mutexlib.h"
26
27#define DEF_BITSPERSAMPLE 16
28#define DEF_SPEED         44100
29#define DEF_FORMAT        WAVE_FORMAT_PCM
30#define DEF_CHANNELS      2
31#define DEF_CBSIZE        0
32
33#define MAX_AUDIOBUFS     8
34#define MAX_PCMDATA       (DEF_SPEED * DEF_CHANNELS)
35#define EMAIL_ADDRESS     "tsaotsao@lokigames.com"
36
37static MutexID mutex;
38
39static struct {
40        WAVEHDR whdrs[MAX_AUDIOBUFS];
41        int index;
42} audiobufs;
43
44static struct {
45        HWAVEOUT hwo;
46        WAVEFORMATEX pwfx;
47} WinAudioHandle;
48
49static char pcmdata[MAX_PCMDATA];
50static int scalesize = 0;
51
52
53static void CALLBACK WinFillAudio(UNUSED(HWAVEOUT hwo),
54        UNUSED(UINT uMsg),
55        UNUSED(DWORD dwInstance),
56        UNUSED(DWORD dwParam1),
57        UNUSED(DWORD dwParam2)) {
58
59        /* Only service "buffer done playing" messages */
60        if( uMsg == WOM_DONE ) {
61                _alUnlockMutex(mutex);
62        }
63
64        return;
65}
66
67
68static const char *implement_me(const char *fn) {
69        static char retval[2048];
70
71        snprintf(retval, sizeof(retval),
72        "%s is not implemented under Windows.  Please contact %s for\n"
73        "information on how you can help get %s implemented on Windows.\n",
74        fn, EMAIL_ADDRESS, fn);
75
76        return retval;
77}
78
79static void *grab_read_native(void) {
80        return NULL;
81}
82
83static void *grab_write_native(void) {
84        MMRESULT err;
85        LPWAVEFORMATEX pwfx = &WinAudioHandle.pwfx;
86        int i;
87
88        audiobufs.index = 0;
89        mutex = _alCreateMutex();
90
91        for(i = 0; i < MAX_AUDIOBUFS; i++) {
92                audiobufs.whdrs[i].lpData  = NULL;
93                audiobufs.whdrs[i].dwBufferLength = 0;
94                audiobufs.whdrs[i].dwFlags = WHDR_DONE;
95        }
96
97        memset(pwfx, 0, sizeof *pwfx);
98
99        pwfx->wFormatTag      = DEF_FORMAT;
100        pwfx->nChannels       = DEF_CHANNELS;
101        pwfx->wBitsPerSample  = DEF_BITSPERSAMPLE;
102        pwfx->nBlockAlign     = DEF_CHANNELS * (pwfx->wBitsPerSample / 8);
103        pwfx->nSamplesPerSec  = DEF_SPEED;
104        pwfx->nAvgBytesPerSec = pwfx->nSamplesPerSec * pwfx->nBlockAlign;
105        pwfx->cbSize          = DEF_CBSIZE;
106
107        err = waveOutOpen(&WinAudioHandle.hwo, WAVE_MAPPER, pwfx,
108                (DWORD) WinFillAudio,
109                0,
110                CALLBACK_FUNCTION);
111
112        if(err == MMSYSERR_NOERROR) {
113                fprintf(stderr, "got Windows native audio\n");
114
115                return &WinAudioHandle.hwo;
116        }
117
118        fprintf(stderr, "Could not open Windows native audio: %d\n",
119                err);
120
121        return NULL;
122}
123
124void *
125alcBackendOpenNative_( ALC_OpenMode mode )
126{
127        return mode == ALC_OPEN_INPUT_ ? grab_read_native() : grab_write_native();
128}
129
130void native_blitbuffer(void *handle, void *dataptr, int bytes_to_write) {
131        WAVEHDR *whdr;
132        MMRESULT err;
133        HWAVEOUT hwo;
134        char *bufptr;
135        char errmsg[256];
136
137        if(handle == NULL) {
138                return;
139        }
140
141        hwo = WinAudioHandle.hwo;
142
143        _alLockMutex(mutex);
144
145        whdr   = &audiobufs.whdrs[audiobufs.index];
146
147        do {
148                /* busy wait, ouch */
149                _alMicroSleep(0);
150        } while((whdr->dwFlags & WHDR_DONE) == 0);
151
152        bufptr = pcmdata + audiobufs.index * scalesize;
153        memcpy(bufptr, dataptr, bytes_to_write);
154
155        audiobufs.index = (audiobufs.index + 1) % MAX_AUDIOBUFS;
156
157        err = waveOutWrite(hwo, whdr, sizeof *whdr);
158        if(err != MMSYSERR_NOERROR) {
159                waveOutGetErrorText(err, errmsg, 256);
160                fprintf(stderr, "native_blitbuffer: write error %s\n",
161                        errmsg);
162        }
163
164        return;
165}
166
167/*
168 * FIXME: unprepare whdrs
169 */
170void release_native(void *handle) {
171        WAVEHDR *whdr;
172        HWAVEOUT hwo;
173        int i;
174
175        _alDestroyMutex(mutex);
176        mutex = NULL;
177
178        if(handle == NULL) {
179                return;
180        }
181
182        hwo = WinAudioHandle.hwo;
183        whdr = &audiobufs.whdrs[audiobufs.index];
184
185        for(i = 0; i < MAX_AUDIOBUFS; i++) {
186                /* not first time */
187                waveOutUnprepareHeader(hwo, whdr, sizeof *whdr);
188        }
189
190        waveOutClose(hwo);
191
192        return;
193}
194
195int set_nativechannel(UNUSED(void *handle),
196                      UNUSED(ALuint channel),
197                      UNUSED(ALfloat volume)) {
198        fprintf(stderr,  implement_me("set_nativechannel"));
199
200        return 0;
201}
202
203void pause_nativedevice(UNUSED(void *handle)) {
204        fprintf(stderr,  implement_me("pause_nativedevice"));
205
206        return;
207}
208
209void resume_nativedevice(UNUSED(void *handle)) {
210        fprintf(stderr,  implement_me("resume_nativedevice"));
211
212        return;
213}
214
215ALfloat get_nativechannel(UNUSED(void *handle), UNUSED(ALuint channel)) {
216        fprintf(stderr,  implement_me("get_nativechannel"));
217
218        return 0.0;
219}
220
221ALsizei capture_nativedevice(UNUSED(void *handle),
222                          UNUSED(void *capture_buffer),
223                          UNUSED(int bufsiz)) {
224        return 0; /* unimplemented */
225}
226
227
228static ALboolean set_write_native(UNUSED(void *handle),
229                                  UNUSED(unsigned int *bufsiz),
230                                  UNUSED(ALenum *fmt),
231                                  UNUSED(unsigned int *speed)) {
232        WAVEHDR *whdr;
233        MMRESULT err;
234        LPWAVEFORMATEX pwfx = &WinAudioHandle.pwfx;
235        int i;
236        char *bufptr;
237        HWAVEOUT hwo;
238        ALuint channels = _alGetChannelsFromFormat(*fmt);
239
240        /* close previous instance */
241        waveOutClose(WinAudioHandle.hwo);
242
243        memset(pwfx, 0, sizeof *pwfx);
244
245        pwfx->wFormatTag      = DEF_FORMAT;
246        pwfx->nChannels       = channels;
247        pwfx->wBitsPerSample  = _alGetBitsFromFormat(*fmt);
248        pwfx->nBlockAlign     = pwfx->nChannels * (pwfx->wBitsPerSample / 8);
249        pwfx->nSamplesPerSec  = *speed;
250        pwfx->nAvgBytesPerSec = pwfx->nSamplesPerSec * pwfx->nBlockAlign;
251        pwfx->cbSize          = DEF_CBSIZE;
252
253        fprintf(stderr, "chans %d bps %d bal %d sps %d abs %d cbs %d\n",
254                pwfx->nChannels,
255                pwfx->wBitsPerSample,
256                pwfx->nBlockAlign,
257                (int) pwfx->nSamplesPerSec,
258                (int) pwfx->nAvgBytesPerSec,
259                (int) pwfx->cbSize);
260
261        err = waveOutOpen(&WinAudioHandle.hwo, WAVE_MAPPER, pwfx,
262                (DWORD) WinFillAudio,
263                0,
264                CALLBACK_FUNCTION);
265
266        if(err != MMSYSERR_NOERROR) {
267                fprintf(stderr, "Could not setfmt: %d\n", err);
268                return AL_FALSE;
269        }
270
271        fprintf(stderr, "setfmt okay\n");
272
273        hwo = WinAudioHandle.hwo;
274
275        scalesize = *bufsiz;
276
277        for(i = 0; i < MAX_AUDIOBUFS; i++) {
278                whdr   = &audiobufs.whdrs[i];
279                bufptr = pcmdata + i * scalesize;
280
281                whdr->lpData  = (LPSTR) bufptr;
282                whdr->dwBufferLength = *bufsiz;
283                whdr->dwFlags = WHDR_DONE;
284
285                err = waveOutPrepareHeader(hwo, whdr, sizeof *whdr);
286
287                if(err != MMSYSERR_NOERROR) {
288                        fprintf(stderr, "Could not prepare header: %d\n", err);
289
290                        return AL_FALSE;
291                }
292        }
293
294        return AL_TRUE;
295}
296
297static ALboolean set_read_native(UNUSED(void *handle),
298                                 UNUSED(unsigned int *bufsiz),
299                                 UNUSED(ALenum *fmt),
300                                 UNUSED(unsigned int *speed)) {
301        return AL_FALSE;
302}
303
304ALboolean
305alcBackendSetAttributesNative_(ALC_OpenMode mode, void *handle, ALuint *bufsiz, ALenum *fmt, ALuint *speed)
306{
307        return mode == ALC_OPEN_INPUT_ ?
308                set_read_native(handle, bufsiz, fmt, speed) :
309                set_write_native(handle, bufsiz, fmt, speed);
310}
Note: See TracBrowser for help on using the repository browser.