FS2_Open
Open source remastering of the Freespace 2 engine
dscap.cpp
Go to the documentation of this file.
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 "globalincs/pstypes.h"
11 #include "sound/ds.h"
12 #include "sound/dscap.h"
13 #include "sound/openal.h"
14 
15 #include <string>
16 
17 
18 int dscap_inited = 0; // flag to indicate that DirectSoundCapture inited ok
19 int dscap_recording = 0; // flag to indicate that sound is being recorded
20 
21 typedef struct ALcapture_t {
26 
28  ALsizei buffer_size;
29 } ALcapture_t;
30 
31 static ALcapture_t ALCaptureInfo;
32 
33 static ALCdevice *ds_capture_device = NULL;
34 static SCP_string capture_dev_name;
35 
36 
37 // init the capture system
38 // exit: 0 -> success
39 // !0 -> failure
41 {
42  if (dscap_inited) {
43  return 0;
44  }
45 
46  bool rval = openal_init_device(NULL, &capture_dev_name);
47 
48  if ( !rval || capture_dev_name.empty() ) {
49  dscap_inited = 0;
50 
51  return -1;
52  }
53 
54  dscap_inited = 1;
55 
56  return 0;
57 }
58 
60 {
61  if (ds_capture_device != NULL) {
62  OpenAL_C_ErrorPrint( alcCaptureCloseDevice(ds_capture_device) );
63  ds_capture_device = NULL;
64  }
65 }
66 
67 // create a capture buffer with the specified format
68 // exit: 0 -> buffer created successfully
69 // !0 -> error creating the buffer
70 int dscap_create_buffer(int freq, int bits_per_sample, int nchannels, int nseconds)
71 {
72  ALenum al_format = AL_FORMAT_MONO8;
73  ALsizei buf_size = freq * nseconds;
74 
75  if ( !dscap_inited ) {
76  dscap_init();
77  }
78 
79  //Just in case we couldn't init for whatever reason
80  if ( !dscap_inited ) { //-V581
81  return -1;
82  }
83 
84  Assert( (nchannels == 1) || (nchannels == 2) );
85  Assert( (bits_per_sample == 8) || (bits_per_sample == 16) );
86 
87  if (nchannels == 1) {
88  if (bits_per_sample == 8) {
89  al_format = AL_FORMAT_MONO8;
90  } else if (bits_per_sample == 16) {
91  al_format = AL_FORMAT_MONO16;
92  }
93  } else if (nchannels == 2) {
94  if (bits_per_sample == 8) {
95  al_format = AL_FORMAT_STEREO8;
96  } else if (bits_per_sample == 16) {
97  al_format = AL_FORMAT_STEREO16;
98  }
99  }
100 
101  const ALCchar *dev_name = (const ALCchar*) capture_dev_name.c_str();
102  ds_capture_device = alcCaptureOpenDevice(dev_name, freq, al_format, buf_size);
103 
104  if (ds_capture_device == NULL) {
105  return -1;
106  }
107 
108  if ( alcGetError(ds_capture_device) != ALC_NO_ERROR ) {
109  return -1;
110  }
111 
112  ALCaptureInfo.format = al_format;
113  ALCaptureInfo.bits_per_sample = bits_per_sample;
114  ALCaptureInfo.n_channels = nchannels;
115  ALCaptureInfo.samples_per_second = freq;
116  ALCaptureInfo.block_align = (nchannels * bits_per_sample) / 8;
117 
118  return 0;
119 }
120 
121 // check if DirectSoundCapture is supported
123 {
124  if ( !dscap_inited ) {
125  dscap_init();
126  }
127 
128  return dscap_inited;
129 }
130 
131 // start recording into the buffer
133 {
134  if ( !dscap_inited ) {
135  return -1;
136  }
137 
138  if (dscap_recording) {
139  return -1;
140  }
141 
142  OpenAL_C_ErrorCheck( alcCaptureStart(ds_capture_device), return -1 );
143 
144  dscap_recording = 1;
145 
146 // nprintf(("Alan","RTVOICE => start record\n"));
147 
148  return 0;
149 }
150 
151 // stop recording into the buffer
153 {
154  if ( !dscap_inited ) {
155  return -1;
156  }
157 
158  if ( !dscap_recording ) {
159  return -1;
160  }
161 
162  OpenAL_C_ErrorCheck( alcCaptureStop(ds_capture_device), return -1 );
163 
164  dscap_recording = 0;
165 
166 // nprintf(("Alan","RTVOICE => stop record\n"));
167 
168  return 0;
169 }
170 
171 // close the DirectSoundCapture system
173 {
175 
176  if (ds_capture_device != NULL) {
177  OpenAL_C_ErrorPrint( alcCaptureCloseDevice(ds_capture_device) );
178  ds_capture_device = NULL;
179  }
180 }
181 
182 // return the max buffer size
184 {
185  if ( !dscap_inited ) {
186  dscap_init();
187  }
188 
189  //Just in case we're still not initialized
190  if ( !dscap_inited ) { //-V581
191  return -1;
192  }
193 
194  ALCsizei num_samples = 0;
195 
196  OpenAL_C_ErrorCheck( alcGetIntegerv(ds_capture_device, ALC_CAPTURE_SAMPLES, sizeof(ALCsizei), &num_samples), return -1 );
197 
198  return (num_samples * ALCaptureInfo.block_align);
199 }
200 
201 // retreive the recorded voice data
202 int dscap_get_raw_data(unsigned char *outbuf, unsigned int max_size)
203 {
204  if ( !dscap_inited ) {
205  dscap_init();
206  }
207 
208  //Just in case we're still not initialized
209  if ( !dscap_inited ) { //-V581
210  return 0;
211  }
212 
213  if (outbuf == NULL) {
214  return 0;
215  }
216 
217  ALCsizei num_samples = 0;
218 
219  OpenAL_C_ErrorPrint( alcGetIntegerv(ds_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 / ALCaptureInfo.block_align));
226 
227  OpenAL_C_ErrorCheck( alcCaptureSamples(ds_capture_device, outbuf, max_buf_size), return 0 );
228 
229  return (int)max_buf_size * ALCaptureInfo.block_align;
230 }
231 
#define MIN(a, b)
Definition: pstypes.h:296
int dscap_max_buffersize()
Definition: dscap.cpp:183
uint bits_per_sample
Definition: dscap.cpp:23
struct ALcapture_t ALcapture_t
int dscap_start_record()
Definition: dscap.cpp:132
Assert(pm!=NULL)
uint block_align
Definition: dscap.cpp:25
ALuint *typedef ALuint *typedef ALenum
Definition: ds.cpp:133
std::basic_string< char, std::char_traits< char >, std::allocator< char > > SCP_string
Definition: vmallocator.h:21
int dscap_recording
Definition: dscap.cpp:19
void dscap_release_buffer()
Definition: dscap.cpp:59
ALsizei buffer_size
Definition: dscap.cpp:28
unsigned int uint
Definition: pstypes.h:64
uint n_channels
Definition: dscap.cpp:24
int dscap_inited
Definition: dscap.cpp:18
int dscap_get_raw_data(unsigned char *outbuf, unsigned int max_size)
Definition: dscap.cpp:202
int dscap_stop_record()
Definition: dscap.cpp:152
int dscap_create_buffer(int freq, int bits_per_sample, int nchannels, int nseconds)
Definition: dscap.cpp:70
int dscap_supported()
Definition: dscap.cpp:122
uint samples_per_second
Definition: dscap.cpp:22
#define OpenAL_C_ErrorCheck(x, y)
Definition: openal.h:43
ALenum format
Definition: dscap.cpp:27
int dscap_init()
Definition: dscap.cpp:40
bool openal_init_device(SCP_string *playback, SCP_string *capture)
Definition: openal.cpp:323
void dscap_close()
Definition: dscap.cpp:172
#define OpenAL_C_ErrorPrint(x)
Definition: openal.h:53