]> icculus.org git repositories - taylor/freespace2.git/blob - src/sound/oal_capture.cpp
cleaner cfg setup, launcher, initial user prep
[taylor/freespace2.git] / src / sound / oal_capture.cpp
1 /*
2  * Copyright (C) Volition, Inc. 1999.  All rights reserved.
3  *
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
6  * source.
7  *
8 */
9
10 #include <string>
11
12 #include "pstypes.h"
13 #include "oal.h"
14 #include "osregistry.h"
15
16
17 static int OAL_capture_recording = 0;
18
19 struct capture_buffer {
20         uint samples_per_second;
21         uint bits_per_sample;
22         uint n_channels;
23         uint block_align;
24
25         ALenum format;
26         ALsizei buffer_size;
27 };
28
29 static capture_buffer Capture;
30
31 static ALCdevice *al_capture_device = NULL;
32 static std::string CaptureDevice;
33
34
35 void oal_capture_release_buffer()
36 {
37         if (al_capture_device != NULL) {
38                 alcCaptureCloseDevice(al_capture_device);
39                 al_capture_device = NULL;
40         }
41 }
42
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)
47 {
48         ALenum al_format = AL_FORMAT_MONO8;
49         ALsizei buf_size = freq * nseconds;
50
51         SDL_assert( (nchannels == 1) || (nchannels == 2) );
52         SDL_assert( (bits_per_sample == 8) || (bits_per_sample == 16) );
53
54         if ( !oal_is_initted() ) {
55                 return -1;
56         }
57
58         if (nchannels == 1) {
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;
63                 }
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;
69                 }
70         }
71
72         al_capture_device = alcCaptureOpenDevice(CaptureDevice.c_str(), freq, al_format, buf_size);
73
74         if (al_capture_device == NULL) {
75                 return -1;
76         }
77
78         if ( alcGetError(al_capture_device) != ALC_NO_ERROR ) {
79                 alcCaptureCloseDevice(al_capture_device);
80
81                 return -1;
82         }
83
84         Capture.format = al_format;
85         Capture.bits_per_sample = bits_per_sample;
86         Capture.n_channels = nchannels;
87         Capture.samples_per_second = freq;
88         Capture.block_align = (nchannels * bits_per_sample) / 8;
89
90         return 0;
91 }
92
93 void oal_capture_init()
94 {
95         const char *ptr = NULL;
96         ALCdevice *tdevice = NULL;
97
98         ptr = os_config_read_string("Audio", "CaptureDevice", "default");
99
100         if ( ptr && !SDL_strcasecmp(ptr, "default") ) {
101                 ptr = NULL;
102         }
103
104         tdevice = alcCaptureOpenDevice(ptr, 11025, AL_FORMAT_MONO8, 11025 * 2);
105
106         if (tdevice == NULL) {
107                 tdevice = alcCaptureOpenDevice(NULL, 11025, AL_FORMAT_MONO8, 11025 * 2);
108
109                 if (tdevice == NULL) {
110                         mprintf(("  Capture device  : * Unavailable *\n"));
111
112                         return;
113                 }
114         }
115
116         if ( alcGetError(tdevice) != ALC_NO_ERROR ) {
117                 mprintf(("  Capture device  : * Unavailable *\n"));
118                 alcCaptureCloseDevice(tdevice);
119
120                 return;
121         }
122
123         ptr = alcGetString(tdevice, ALC_CAPTURE_DEVICE_SPECIFIER);
124         SDL_assert( ptr );
125
126         mprintf(("  Capture device  : %s\n", ptr));
127
128         CaptureDevice = ptr;
129
130         alcCaptureCloseDevice(tdevice);
131 }
132
133 int oal_capture_supported()
134 {
135         return oal_is_initted();
136 }
137
138 // start recording into the buffer
139 int oal_capture_start_record()
140 {
141         if ( !oal_is_initted() ) {
142                 return -1;
143         }
144
145         if (OAL_capture_recording) {
146                 return -1;
147         }
148
149         alcCaptureStart(al_capture_device);
150
151         OAL_capture_recording = 1;
152
153 //      nprintf(("Alan","RTVOICE => start record\n"));
154
155         return 0;
156 }
157
158 // stop recording into the buffer
159 int oal_capture_stop_record()
160 {
161         if ( !oal_is_initted() ) {
162                 return -1;
163         }
164
165         if ( !OAL_capture_recording ) {
166                 return -1;
167         }
168
169         alcCaptureStop(al_capture_device);
170
171         OAL_capture_recording = 0;
172
173 //      nprintf(("Alan","RTVOICE => stop record\n"));
174
175         return 0;
176 }
177
178 void oal_capture_close()
179 {
180         oal_capture_stop_record();
181
182         if (al_capture_device != NULL) {
183                 alcCaptureCloseDevice(al_capture_device);
184                 al_capture_device = NULL;
185         }
186 }
187
188 // return the max buffer size
189 int oal_capture_max_buffersize()
190 {
191         if ( !oal_is_initted() ) {
192                 return 0;
193         }
194
195         ALCsizei num_samples = 0;
196
197         alcGetIntegerv(al_capture_device, ALC_CAPTURE_SAMPLES, sizeof(ALCsizei), &num_samples);
198
199         if (alcGetError(al_capture_device) != ALC_NO_ERROR) {
200                 return 0;
201         }
202
203         return (num_samples * Capture.block_align);
204 }
205
206 // retrieve the recorded voice data
207 int oal_capture_get_raw_data(ubyte *outbuf, uint max_size)
208 {
209         if ( !oal_is_initted() ) {
210                 return 0;
211         }
212
213         if (outbuf == NULL) {
214                 return 0;
215         }
216
217         ALCsizei num_samples = 0;
218
219         alcGetIntegerv(al_capture_device, ALC_CAPTURE_SAMPLES, sizeof(ALCsizei), &num_samples);
220
221         if (num_samples <= 0) {
222                 return 0;
223         }
224
225         ALCsizei max_buf_size = min(num_samples, ALsizei(max_size / Capture.block_align));
226
227         alcCaptureSamples(al_capture_device, outbuf, max_buf_size);
228
229         if (alcGetError(al_capture_device) != ALC_NO_ERROR) {
230                 return 0;
231         }
232
233         return (int)max_buf_size * Capture.block_align;
234 }