2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
4 * All source code herein is the property of Volition, Inc. You may not sell
5 * or otherwise commercially exploit the source or things you created based on the
14 #include "osregistry.h"
17 static int OAL_capture_recording = 0;
19 struct capture_buffer {
20 uint samples_per_second;
29 static capture_buffer Capture;
31 static ALCdevice *al_capture_device = NULL;
32 static std::string CaptureDevice;
35 void oal_capture_release_buffer()
37 if (al_capture_device != NULL) {
38 alcCaptureCloseDevice(al_capture_device);
39 al_capture_device = NULL;
43 // create a capture buffer with the specified format
44 // exit: 0 -> buffer created successfully
45 // !0 -> error creating the buffer
46 int oal_capture_create_buffer(int freq, int bits_per_sample, int nchannels, int nseconds)
48 ALenum al_format = AL_FORMAT_MONO8;
49 ALsizei buf_size = freq * nseconds;
51 SDL_assert( (nchannels == 1) || (nchannels == 2) );
52 SDL_assert( (bits_per_sample == 8) || (bits_per_sample == 16) );
54 if ( !oal_is_initted() ) {
59 if (bits_per_sample == 8) {
60 al_format = AL_FORMAT_MONO8;
61 } else if (bits_per_sample == 16) {
62 al_format = AL_FORMAT_MONO16;
64 } else if (nchannels == 2) {
65 if (bits_per_sample == 8) {
66 al_format = AL_FORMAT_STEREO8;
67 } else if (bits_per_sample == 16) {
68 al_format = AL_FORMAT_STEREO16;
72 al_capture_device = alcCaptureOpenDevice(CaptureDevice.c_str(), freq, al_format, buf_size);
74 if (al_capture_device == NULL) {
78 // this gets around hang-on-close bug on Windows
79 alcCaptureStart(al_capture_device);
80 alcCaptureStop(al_capture_device);
82 if ( alcGetError(al_capture_device) != ALC_NO_ERROR ) {
83 alcCaptureCloseDevice(al_capture_device);
88 Capture.format = al_format;
89 Capture.bits_per_sample = bits_per_sample;
90 Capture.n_channels = nchannels;
91 Capture.samples_per_second = freq;
92 Capture.block_align = (nchannels * bits_per_sample) / 8;
97 void oal_capture_init()
99 const char *ptr = NULL;
100 ALCdevice *tdevice = NULL;
102 ptr = os_config_read_string("Audio", "CaptureDevice", "default");
104 if ( ptr && !SDL_strcasecmp(ptr, "default") ) {
108 tdevice = alcCaptureOpenDevice(ptr, 11025, AL_FORMAT_MONO8, 11025 * 2);
110 if (tdevice == NULL) {
111 tdevice = alcCaptureOpenDevice(NULL, 11025, AL_FORMAT_MONO8, 11025 * 2);
113 if (tdevice == NULL) {
114 mprintf((" Capture device : * Unavailable *\n"));
120 if ( alcGetError(tdevice) != ALC_NO_ERROR ) {
121 mprintf((" Capture device : * Unavailable *\n"));
122 alcCaptureCloseDevice(tdevice);
127 ptr = alcGetString(tdevice, ALC_CAPTURE_DEVICE_SPECIFIER);
130 mprintf((" Capture device : %s\n", ptr));
134 // this gets around hang-on-close bug on Windows
135 alcCaptureStart(tdevice);
136 alcCaptureStop(tdevice);
138 alcCaptureCloseDevice(tdevice);
141 int oal_capture_supported()
143 return oal_is_initted();
146 // start recording into the buffer
147 int oal_capture_start_record()
149 if ( !oal_is_initted() ) {
153 if (OAL_capture_recording) {
157 alcCaptureStart(al_capture_device);
159 OAL_capture_recording = 1;
161 // nprintf(("Alan","RTVOICE => start record\n"));
166 // stop recording into the buffer
167 int oal_capture_stop_record()
169 if ( !oal_is_initted() ) {
173 if ( !OAL_capture_recording ) {
177 alcCaptureStop(al_capture_device);
179 OAL_capture_recording = 0;
181 // nprintf(("Alan","RTVOICE => stop record\n"));
186 void oal_capture_close()
188 oal_capture_stop_record();
190 if (al_capture_device != NULL) {
191 alcCaptureCloseDevice(al_capture_device);
192 al_capture_device = NULL;
196 // return the max buffer size
197 int oal_capture_max_buffersize()
199 if ( !oal_is_initted() ) {
203 ALCsizei num_samples = 0;
205 alcGetIntegerv(al_capture_device, ALC_CAPTURE_SAMPLES, sizeof(ALCsizei), &num_samples);
207 if (alcGetError(al_capture_device) != ALC_NO_ERROR) {
211 return (num_samples * Capture.block_align);
214 // retrieve the recorded voice data
215 int oal_capture_get_raw_data(ubyte *outbuf, uint max_size)
217 if ( !oal_is_initted() ) {
221 if (outbuf == NULL) {
225 ALCsizei num_samples = 0;
227 alcGetIntegerv(al_capture_device, ALC_CAPTURE_SAMPLES, sizeof(ALCsizei), &num_samples);
229 if (num_samples <= 0) {
233 ALCsizei max_buf_size = SDL_min(num_samples, ALsizei(max_size / Capture.block_align));
235 alcCaptureSamples(al_capture_device, outbuf, max_buf_size);
237 if (alcGetError(al_capture_device) != ALC_NO_ERROR) {
241 return (int)max_buf_size * Capture.block_align;