mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 08:15:59 -10:00
232 lines
4.7 KiB
C++
232 lines
4.7 KiB
C++
/*
|
|
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
|
*
|
|
* All source code herein is the property of Volition, Inc. You may not sell
|
|
* or otherwise commercially exploit the source or things you created based on the
|
|
* source.
|
|
*
|
|
*/
|
|
|
|
#include "globalincs/pstypes.h"
|
|
#include "sound/ds.h"
|
|
#include "sound/dscap.h"
|
|
#include "sound/openal.h"
|
|
|
|
#include <string>
|
|
|
|
|
|
int dscap_inited = 0; // flag to indicate that DirectSoundCapture inited ok
|
|
int dscap_recording = 0; // flag to indicate that sound is being recorded
|
|
|
|
typedef struct ALcapture_t {
|
|
uint samples_per_second;
|
|
uint bits_per_sample;
|
|
uint n_channels;
|
|
uint block_align;
|
|
|
|
ALenum format;
|
|
ALsizei buffer_size;
|
|
} ALcapture_t;
|
|
|
|
static ALcapture_t ALCaptureInfo;
|
|
|
|
static ALCdevice *ds_capture_device = NULL;
|
|
static SCP_string capture_dev_name;
|
|
|
|
|
|
// init the capture system
|
|
// exit: 0 -> success
|
|
// !0 -> failure
|
|
int dscap_init()
|
|
{
|
|
if (dscap_inited) {
|
|
return 0;
|
|
}
|
|
|
|
bool rval = openal_init_device(NULL, &capture_dev_name);
|
|
|
|
if ( !rval || capture_dev_name.empty() ) {
|
|
dscap_inited = 0;
|
|
|
|
return -1;
|
|
}
|
|
|
|
dscap_inited = 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void dscap_release_buffer()
|
|
{
|
|
if (ds_capture_device != NULL) {
|
|
OpenAL_C_ErrorPrint( alcCaptureCloseDevice(ds_capture_device) );
|
|
ds_capture_device = NULL;
|
|
}
|
|
}
|
|
|
|
// create a capture buffer with the specified format
|
|
// exit: 0 -> buffer created successfully
|
|
// !0 -> error creating the buffer
|
|
int dscap_create_buffer(int freq, int bits_per_sample, int nchannels, int nseconds)
|
|
{
|
|
ALenum al_format = AL_FORMAT_MONO8;
|
|
ALsizei buf_size = freq * nseconds;
|
|
|
|
if ( !dscap_inited ) {
|
|
dscap_init();
|
|
}
|
|
|
|
//Just in case we couldn't init for whatever reason
|
|
if ( !dscap_inited ) { //-V581
|
|
return -1;
|
|
}
|
|
|
|
Assert( (nchannels == 1) || (nchannels == 2) );
|
|
Assert( (bits_per_sample == 8) || (bits_per_sample == 16) );
|
|
|
|
if (nchannels == 1) {
|
|
if (bits_per_sample == 8) {
|
|
al_format = AL_FORMAT_MONO8;
|
|
} else if (bits_per_sample == 16) {
|
|
al_format = AL_FORMAT_MONO16;
|
|
}
|
|
} else if (nchannels == 2) {
|
|
if (bits_per_sample == 8) {
|
|
al_format = AL_FORMAT_STEREO8;
|
|
} else if (bits_per_sample == 16) {
|
|
al_format = AL_FORMAT_STEREO16;
|
|
}
|
|
}
|
|
|
|
const ALCchar *dev_name = (const ALCchar*) capture_dev_name.c_str();
|
|
ds_capture_device = alcCaptureOpenDevice(dev_name, freq, al_format, buf_size);
|
|
|
|
if (ds_capture_device == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
if ( alcGetError(ds_capture_device) != ALC_NO_ERROR ) {
|
|
return -1;
|
|
}
|
|
|
|
ALCaptureInfo.format = al_format;
|
|
ALCaptureInfo.bits_per_sample = bits_per_sample;
|
|
ALCaptureInfo.n_channels = nchannels;
|
|
ALCaptureInfo.samples_per_second = freq;
|
|
ALCaptureInfo.block_align = (nchannels * bits_per_sample) / 8;
|
|
|
|
return 0;
|
|
}
|
|
|
|
// check if DirectSoundCapture is supported
|
|
int dscap_supported()
|
|
{
|
|
if ( !dscap_inited ) {
|
|
dscap_init();
|
|
}
|
|
|
|
return dscap_inited;
|
|
}
|
|
|
|
// start recording into the buffer
|
|
int dscap_start_record()
|
|
{
|
|
if ( !dscap_inited ) {
|
|
return -1;
|
|
}
|
|
|
|
if (dscap_recording) {
|
|
return -1;
|
|
}
|
|
|
|
OpenAL_C_ErrorCheck( alcCaptureStart(ds_capture_device), return -1 );
|
|
|
|
dscap_recording = 1;
|
|
|
|
// nprintf(("Alan","RTVOICE => start record\n"));
|
|
|
|
return 0;
|
|
}
|
|
|
|
// stop recording into the buffer
|
|
int dscap_stop_record()
|
|
{
|
|
if ( !dscap_inited ) {
|
|
return -1;
|
|
}
|
|
|
|
if ( !dscap_recording ) {
|
|
return -1;
|
|
}
|
|
|
|
OpenAL_C_ErrorCheck( alcCaptureStop(ds_capture_device), return -1 );
|
|
|
|
dscap_recording = 0;
|
|
|
|
// nprintf(("Alan","RTVOICE => stop record\n"));
|
|
|
|
return 0;
|
|
}
|
|
|
|
// close the DirectSoundCapture system
|
|
void dscap_close()
|
|
{
|
|
dscap_stop_record();
|
|
|
|
if (ds_capture_device != NULL) {
|
|
OpenAL_C_ErrorPrint( alcCaptureCloseDevice(ds_capture_device) );
|
|
ds_capture_device = NULL;
|
|
}
|
|
}
|
|
|
|
// return the max buffer size
|
|
int dscap_max_buffersize()
|
|
{
|
|
if ( !dscap_inited ) {
|
|
dscap_init();
|
|
}
|
|
|
|
//Just in case we're still not initialized
|
|
if ( !dscap_inited ) { //-V581
|
|
return -1;
|
|
}
|
|
|
|
ALCsizei num_samples = 0;
|
|
|
|
OpenAL_C_ErrorCheck( alcGetIntegerv(ds_capture_device, ALC_CAPTURE_SAMPLES, sizeof(ALCsizei), &num_samples), return -1 );
|
|
|
|
return (num_samples * ALCaptureInfo.block_align);
|
|
}
|
|
|
|
// retreive the recorded voice data
|
|
int dscap_get_raw_data(unsigned char *outbuf, unsigned int max_size)
|
|
{
|
|
if ( !dscap_inited ) {
|
|
dscap_init();
|
|
}
|
|
|
|
//Just in case we're still not initialized
|
|
if ( !dscap_inited ) { //-V581
|
|
return 0;
|
|
}
|
|
|
|
if (outbuf == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
ALCsizei num_samples = 0;
|
|
|
|
OpenAL_C_ErrorPrint( alcGetIntegerv(ds_capture_device, ALC_CAPTURE_SAMPLES, sizeof(ALCsizei), &num_samples) );
|
|
|
|
if (num_samples <= 0) {
|
|
return 0;
|
|
}
|
|
|
|
ALCsizei max_buf_size = MIN(num_samples, ALsizei(max_size / ALCaptureInfo.block_align));
|
|
|
|
OpenAL_C_ErrorCheck( alcCaptureSamples(ds_capture_device, outbuf, max_buf_size), return 0 );
|
|
|
|
return (int)max_buf_size * ALCaptureInfo.block_align;
|
|
}
|
|
|