mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-11 12:41:47 -10:00
git-svn-id: svn://svn.icculus.org/fs2open/trunk/fs2_open@4000 387891d4-d844-0410-90c0-e4c51a9137d3
469 lines
15 KiB
C
469 lines
15 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.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* $Logfile: /Freespace2/code/Sound/ds.h $
|
|
* $Revision: 2.21 $
|
|
* $Date: 2007-02-11 18:20:19 $
|
|
* $Author: taylor $
|
|
*
|
|
* Header file for interface to DirectSound
|
|
*
|
|
* $Log: not supported by cvs2svn $
|
|
* Revision 2.20 2006/07/06 22:02:11 taylor
|
|
* some better handling of OpenAL errors during init
|
|
*
|
|
* Revision 2.19 2006/06/27 04:58:58 taylor
|
|
* sync up current OpenAL changes
|
|
* - "SoundDeviceOAL" reg option for user specified sound device (used instead of "Soundcard" for OpenAL)
|
|
* - reset current context when we are leaving, may be leaving drivers in a bad state, and it hasn't hung up in quite a while
|
|
* - if sound card (which DS or OAL) is set to "no sound" then be sure to disable both sound and music
|
|
* fix various things that Valgrind complained about
|
|
* make sure we can report both AL and ALC errors
|
|
* fix for ds_get_free_channel(), it shouldn't return -1 on an AL error
|
|
*
|
|
* Revision 2.18 2006/05/14 05:22:43 taylor
|
|
* forgot to remove STRICT define before commit, gets rid of a Windows compiler warning
|
|
*
|
|
* Revision 2.17 2006/05/13 07:10:37 taylor
|
|
* some Windows specific OpenAL changes
|
|
* add MVE files to MSVC6 project
|
|
*
|
|
* Revision 2.16 2006/01/02 07:26:43 taylor
|
|
* remove ALUT headers, we don't it anyway and it's not included with OpenAL anymore
|
|
*
|
|
* Revision 2.15 2005/07/13 03:35:29 Goober5000
|
|
* remove PreProcDefine #includes in FS2
|
|
* --Goober5000
|
|
*
|
|
* Revision 2.14 2005/04/05 11:48:23 taylor
|
|
* remove acm-unix.cpp, replaced by acm-openal.cpp since it's properly cross-platform now
|
|
* better error handling for OpenAL functions
|
|
* Windows can now build properly with OpenAL
|
|
* extra check to make sure we don't try and use too many hardware bases sources
|
|
* fix memory error from OpenAL extension list in certain instances
|
|
*
|
|
* Revision 2.13 2005/04/05 05:53:25 taylor
|
|
* s/vector/vec3d/g, better support for different compilers (Jens Granseuer)
|
|
*
|
|
* Revision 2.12 2005/04/01 07:33:08 taylor
|
|
* fix hanging on exit with OpenAL
|
|
* some better error handling on OpenAL init and make it more Windows friendly too
|
|
* basic 3d sound stuff for OpenAL, not working right yet
|
|
*
|
|
* Revision 2.11 2005/03/28 00:40:09 taylor
|
|
* fix to snd_time_remaining() to make sure we are getting the correct index into Sounds[]
|
|
*
|
|
* Revision 2.10 2005/02/02 10:36:23 taylor
|
|
* merge with Linux/OSX tree - p0202
|
|
*
|
|
* Revision 2.9 2005/01/31 23:27:55 taylor
|
|
* merge with Linux/OSX tree - p0131-2
|
|
*
|
|
* Revision 2.8 2004/12/25 00:23:46 wmcoolmon
|
|
* Ogg support for WIN32
|
|
*
|
|
* Revision 2.7 2004/08/11 05:06:34 Kazan
|
|
* added preprocdefines.h to prevent what happened with fred -- make sure to make all fred2 headers include this file as the _first_ include -- i have already modified fs2 files to do this
|
|
*
|
|
* Revision 2.6 2004/06/28 02:13:08 bobboau
|
|
* high level index buffer suport and d3d implementation,
|
|
* OGL people need to get this working on your end as it's broke now
|
|
*
|
|
* Revision 2.5 2004/06/27 01:45:23 wmcoolmon
|
|
* Commented out ogg header
|
|
*
|
|
* Revision 2.4 2004/06/22 23:14:10 wmcoolmon
|
|
* Nonworking OGG support for sound (not music) added, disabled load-only-used-weapons code, modification to sound system registry code.
|
|
* OGG code has been commented out, so you don't need the SDK yet.
|
|
*
|
|
* Revision 2.3 2004/06/18 04:59:55 wmcoolmon
|
|
* Only used weapons paged in instead of all, fixed music box in FRED, sound quality settable with SoundSampleRate and SoundSampleBits registry values
|
|
*
|
|
* Revision 2.2 2003/03/02 06:37:24 penguin
|
|
* Use multimedia headers in local dir, not system's (headers are not present in MinGW distribution)
|
|
* - penguin
|
|
*
|
|
* Revision 2.1 2002/08/01 01:41:10 penguin
|
|
* The big include file move
|
|
*
|
|
* Revision 2.0 2002/06/03 04:02:29 penguin
|
|
* Warpcore CVS sync
|
|
*
|
|
* Revision 1.1 2002/05/02 18:03:13 mharris
|
|
* Initial checkin - converted filenames and includes to lower case
|
|
*
|
|
*
|
|
* 5 8/27/99 6:38p Alanl
|
|
* crush the blasted repeating messages bug
|
|
*
|
|
* 4 8/01/99 2:06p Alanl
|
|
* increase the rolloff for A3D
|
|
*
|
|
* 3 5/23/99 8:11p Alanl
|
|
* Added support for EAX
|
|
*
|
|
* 2 10/07/98 10:54a Dave
|
|
* Initial checkin.
|
|
*
|
|
* 1 10/07/98 10:51a Dave
|
|
*
|
|
* 21 5/05/98 4:49p Lawrance
|
|
* Put in code to authenticate A3D, improve A3D support
|
|
*
|
|
* 20 4/20/98 12:03a Lawrance
|
|
* Allow prioritizing of CTRL3D buffers
|
|
*
|
|
* 19 4/18/98 9:12p Lawrance
|
|
* Added Aureal support.
|
|
*
|
|
* 18 4/13/98 5:04p Lawrance
|
|
* Write functions to determine how many milliseconds are left in a sound
|
|
*
|
|
* 17 3/23/98 10:32a Lawrance
|
|
* Add functions for extracting raw sound data
|
|
*
|
|
* 16 2/15/98 11:10p Lawrance
|
|
* more work on real-time voice system
|
|
*
|
|
* 15 2/15/98 4:43p Lawrance
|
|
* work on real-time voice
|
|
*
|
|
* 14 2/06/98 7:30p John
|
|
* Added code to monitor the number of channels of sound actually playing.
|
|
*
|
|
* 13 2/06/98 8:56a Allender
|
|
* fixed calling convention problem with DLL handles
|
|
*
|
|
* 12 2/04/98 6:08p Lawrance
|
|
* Read function pointers from dsound.dll, further work on
|
|
* DirectSoundCapture.
|
|
*
|
|
* 11 1/31/98 5:48p Lawrance
|
|
* Start on real-time voice recording
|
|
*
|
|
* 10 12/05/97 5:19p Lawrance
|
|
* re-do sound priorities to make more general and extensible
|
|
*
|
|
* 9 11/20/97 5:36p Dave
|
|
* Hooked in a bunch of main hall changes (including sound). Made it
|
|
* possible to reposition (rewind/ffwd)
|
|
* sound buffer pointers. Fixed animation direction change framerate
|
|
* problem.
|
|
*
|
|
* 8 10/13/97 7:41p Lawrance
|
|
* store duration of sound
|
|
*
|
|
* 7 7/28/97 11:39a Lawrance
|
|
* allow individual volume scaling on 3D buffers
|
|
*
|
|
* 6 7/17/97 9:32a John
|
|
* made all directX header files name start with a v
|
|
*
|
|
* 5 7/15/97 11:15a Lawrance
|
|
* limit the max instances of simultaneous sound effects, implement
|
|
* priorities to force critical sounds
|
|
*
|
|
* 4 6/09/97 11:50p Lawrance
|
|
* integrating DirectSound3D
|
|
*
|
|
* 3 6/02/97 1:45p Lawrance
|
|
* implementing hardware mixing
|
|
*
|
|
* 2 5/29/97 12:04p Lawrance
|
|
* creation of file to hold DirectSound specific portions
|
|
*
|
|
* $NoKeywords: $
|
|
*/
|
|
|
|
#ifndef __DS_H__
|
|
#define __DS_H__
|
|
|
|
#ifdef _WIN32
|
|
#define VC_EXTRALEAN
|
|
|
|
#include <windows.h>
|
|
#include <mmsystem.h>
|
|
#endif
|
|
|
|
#ifndef USE_OPENAL
|
|
#include "directx/vdsound.h"
|
|
#else
|
|
#if !(defined(__APPLE__) || defined(_WIN32))
|
|
#include <AL/al.h>
|
|
#include <AL/alc.h>
|
|
#else
|
|
#include "al.h"
|
|
#include "alc.h"
|
|
#endif // !__APPLE__ && !_WIN32
|
|
#endif // USE_OPENAL
|
|
|
|
#include "sound/ogg/ogg.h"
|
|
#include "globalincs/pstypes.h"
|
|
#include "cfile/cfile.h"
|
|
|
|
#define DS_HARDWARE (1<<0)
|
|
#define DS_3D (1<<1)
|
|
#define DS_USE_DS3D (1<<2)
|
|
|
|
// Constants that DirectSound should assign, but doesn't
|
|
#define MAX_PAN 1500.0f
|
|
#define MIN_PITCH 100
|
|
#define MAX_PITCH 100000
|
|
|
|
|
|
// limits placed on how many concurrent sounds of the same type can play simultaneously
|
|
#define DS_MUST_PLAY 0
|
|
#define DS_LIMIT_ONE 1
|
|
#define DS_LIMIT_TWO 2
|
|
#define DS_LIMIT_THREE 3
|
|
|
|
#define DS_DUP_FAILED -99
|
|
|
|
typedef struct sound_info {
|
|
int format; // WAVE_FORMAT_* defines from mmreg.h
|
|
OggVorbis_File ogg_info;
|
|
uint size;
|
|
int sample_rate;
|
|
int avg_bytes_per_sec;
|
|
int n_block_align;
|
|
int bits;
|
|
int n_channels;
|
|
int duration; // time in ms for duration of sound
|
|
ubyte *data;
|
|
} sound_info;
|
|
|
|
|
|
#ifdef USE_OPENAL
|
|
typedef struct channel
|
|
{
|
|
int sig; // uniquely identifies the sound playing on the channel
|
|
int snd_id; // identifies which kind of sound is playing
|
|
ALuint source_id; // OpenAL source id
|
|
int buf_id; // currently bound buffer index (-1 if none)
|
|
int looping; // flag to indicate that the sound is looping
|
|
int vol;
|
|
int priority; // implementation dependant priority
|
|
bool is_voice_msg;
|
|
uint last_position;
|
|
} channel;
|
|
|
|
extern channel *Channels;
|
|
|
|
extern const char* openal_error_string(int get_alc = 0);
|
|
|
|
// if an error occurs after executing 'x' then do 'y'
|
|
#define OpenAL_ErrorCheck( x, y ) do { \
|
|
x; \
|
|
const char *error_text = openal_error_string(0); \
|
|
if ( error_text != NULL ) { \
|
|
nprintf(("Warning", "SOUND: %s:%d - OpenAL error = '%s'\n", __FILE__, __LINE__, error_text)); \
|
|
y; \
|
|
} \
|
|
} while (0);
|
|
|
|
// like OpenAL_ErrorCheck() except that it gives the error message from x but does nothing about it
|
|
#define OpenAL_ErrorPrint( x ) do { \
|
|
x; \
|
|
const char *error_text = openal_error_string(0); \
|
|
if ( error_text != NULL ) { \
|
|
nprintf(("Sound", "OpenAL ERROR: \"%s\" in %s, line %i\n", error_text, __FILE__, __LINE__)); \
|
|
} \
|
|
} while (0);
|
|
|
|
// same as the above two, but looks for ALC errors instead of standard AL errors
|
|
#define OpenAL_C_ErrorCheck( x, y ) do { \
|
|
x; \
|
|
const char *error_text = openal_error_string(1); \
|
|
if ( error_text != NULL ) { \
|
|
nprintf(("Warning", "SOUND: %s:%d - OpenAL error = '%s'\n", __FILE__, __LINE__, error_text)); \
|
|
y; \
|
|
} \
|
|
} while (0);
|
|
|
|
// like OpenAL_ErrorCheck() except that it gives the error message from x but does nothing about it
|
|
#define OpenAL_C_ErrorPrint( x ) do { \
|
|
x; \
|
|
const char *error_text = openal_error_string(1); \
|
|
if ( error_text != NULL ) { \
|
|
nprintf(("Sound", "OpenAL ERROR: \"%s\" in %s, line %i\n", error_text, __FILE__, __LINE__)); \
|
|
} \
|
|
} while (0);
|
|
#else
|
|
|
|
extern LPDIRECTSOUNDBUFFER pPrimaryBuffer;
|
|
extern LPDIRECTSOUND pDirectSound;
|
|
|
|
extern HRESULT (__stdcall *pfn_DirectSoundCaptureCreate)(LPGUID lpGUID, LPDIRECTSOUNDCAPTURE *lplpDSC, LPUNKNOWN pUnkOuter);
|
|
|
|
|
|
// EAX buffer reverb property set {4a4e6fc0-c341-11d1-b73a-444553540000}
|
|
DEFINE_GUID(DSPROPSETID_EAXBUFFER_ReverbProperties,
|
|
0x4a4e6fc0,
|
|
0xc341,
|
|
0x11d1,
|
|
0xb7, 0x3a, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00);
|
|
|
|
// EAX (listener) reverb property set {4a4e6fc1-c341-11d1-b73a-444553540000}
|
|
DEFINE_GUID(DSPROPSETID_EAX_ReverbProperties,
|
|
0x4a4e6fc1,
|
|
0xc341,
|
|
0x11d1,
|
|
0xb7, 0x3a, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00);
|
|
|
|
#endif // USE_OPENAL
|
|
|
|
|
|
extern int ds_initialized;
|
|
|
|
int ds_init(int use_a3d, int use_eax, unsigned int sample_rate, unsigned short sample_bits);
|
|
void ds_close();
|
|
void ds_get_primary_format(WAVEFORMATEX *wfx, DWORD sample_rate, WORD sample_bits);
|
|
int ds_parse_sound(CFILE *fp, ubyte **dest, uint *dest_size, WAVEFORMATEX **header, bool ogg = false, OggVorbis_File *ovf = NULL);
|
|
int ds_parse_sound_info(char *real_filename, sound_info *s_info);
|
|
int ds_load_buffer(int *sid, int *hid, int *final_size, void *header, sound_info *si, int flags);
|
|
void ds_unload_buffer(int sid, int hid);
|
|
int ds_play(int sid, int hid, int snd_id, int priority, int volume, int pan, int looping, bool is_voice_msg = false);
|
|
int ds_convert_volume(float volume); // Convert a volume from 0.0f->1.0f to -10000 -> 0
|
|
float ds_get_percentage_vol(int ds_vol); // Convert a volume from -10000 -> 0 to 0.0f->1.0f
|
|
int ds_get_channel(int sig);
|
|
int ds_is_channel_playing(int channel);
|
|
void ds_stop_channel(int channel);
|
|
void ds_stop_channel_all();
|
|
void ds_set_volume( int channel, int vol );
|
|
void ds_set_pan( int channel, int pan );
|
|
int ds_get_pitch(int channel);
|
|
void ds_set_pitch(int channel, int pitch);
|
|
void ds_chg_loop_status(int channel, int loop);
|
|
void ds_set_position(int channel, DWORD offset);
|
|
DWORD ds_get_play_position(int channel);
|
|
DWORD ds_get_write_position(int channel);
|
|
int ds_get_data(int sid, char *data);
|
|
int ds_get_size(int sid, int *size);
|
|
|
|
int ds_create_buffer(int frequency, int bits_per_sample, int nchannels, int nseconds);
|
|
int ds_lock_data(int sid, unsigned char *data, int size);
|
|
int ds_play_easy(int sid, int volume);
|
|
void ds_stop_easy(int sid);
|
|
int ds_get_channel_size(int channel);
|
|
int ds_is_3d_buffer(int sid);
|
|
int ds_using_ds3d();
|
|
bool ds_using_a3d();
|
|
|
|
int ds_get_sound_id(int channel);
|
|
|
|
unsigned int ds_get_primary_buffer_interface();
|
|
unsigned int ds_get_dsound_interface();
|
|
unsigned int ds_get_property_set_interface();
|
|
|
|
// Returns the number of channels that are actually playing
|
|
int ds_get_number_channels();
|
|
|
|
int ds3d_play( int sid, int hid, int snd_id, vec3d *pos, vec3d *vel, int min, int max, int looping, int max_volume, int estimated_vol, int priority=DS_MUST_PLAY );
|
|
|
|
// Get a character string for the error code
|
|
char *get_DSERR_text(int DSResult);
|
|
|
|
void ds_do_frame();
|
|
|
|
// --------------------
|
|
//
|
|
// Creative eax.h
|
|
//
|
|
// --------------------
|
|
|
|
typedef enum
|
|
{
|
|
DSPROPERTY_EAX_ALL, // all reverb properties
|
|
DSPROPERTY_EAX_ENVIRONMENT, // standard environment no.
|
|
DSPROPERTY_EAX_VOLUME, // loudness of the reverb
|
|
DSPROPERTY_EAX_DECAYTIME, // how long the reverb lasts
|
|
DSPROPERTY_EAX_DAMPING // the high frequencies decay faster
|
|
} DSPROPERTY_EAX_REVERBPROPERTY;
|
|
|
|
#define EAX_NUM_STANDARD_PROPERTIES (DSPROPERTY_EAX_DAMPING + 1)
|
|
|
|
// use this structure for get/set all properties...
|
|
typedef struct
|
|
{
|
|
unsigned long environment; // 0 to EAX_ENVIRONMENT_COUNT-1
|
|
float fVolume; // 0 to 1
|
|
float fDecayTime_sec; // seconds, 0.1 to 100
|
|
float fDamping; // 0 to 1
|
|
} EAX_REVERBPROPERTIES;
|
|
|
|
|
|
enum
|
|
{
|
|
EAX_ENVIRONMENT_GENERIC,
|
|
EAX_ENVIRONMENT_PADDEDCELL,
|
|
EAX_ENVIRONMENT_ROOM,
|
|
EAX_ENVIRONMENT_BATHROOM,
|
|
EAX_ENVIRONMENT_LIVINGROOM,
|
|
EAX_ENVIRONMENT_STONEROOM,
|
|
EAX_ENVIRONMENT_AUDITORIUM,
|
|
EAX_ENVIRONMENT_CONCERTHALL,
|
|
EAX_ENVIRONMENT_CAVE,
|
|
EAX_ENVIRONMENT_ARENA,
|
|
EAX_ENVIRONMENT_HANGAR,
|
|
EAX_ENVIRONMENT_CARPETEDHALLWAY,
|
|
EAX_ENVIRONMENT_HALLWAY,
|
|
EAX_ENVIRONMENT_STONECORRIDOR,
|
|
EAX_ENVIRONMENT_ALLEY,
|
|
EAX_ENVIRONMENT_FOREST,
|
|
EAX_ENVIRONMENT_CITY,
|
|
EAX_ENVIRONMENT_MOUNTAINS,
|
|
EAX_ENVIRONMENT_QUARRY,
|
|
EAX_ENVIRONMENT_PLAIN,
|
|
EAX_ENVIRONMENT_PARKINGLOT,
|
|
EAX_ENVIRONMENT_SEWERPIPE,
|
|
EAX_ENVIRONMENT_UNDERWATER,
|
|
EAX_ENVIRONMENT_DRUGGED,
|
|
EAX_ENVIRONMENT_DIZZY,
|
|
EAX_ENVIRONMENT_PSYCHOTIC,
|
|
|
|
EAX_ENVIRONMENT_COUNT // total number of environments
|
|
};
|
|
|
|
#define EAX_MAX_ENVIRONMENT (EAX_ENVIRONMENT_COUNT - 1)
|
|
|
|
typedef enum
|
|
{
|
|
DSPROPERTY_EAXBUFFER_ALL, // all reverb buffer properties
|
|
DSPROPERTY_EAXBUFFER_REVERBMIX // the wet source amount
|
|
} DSPROPERTY_EAXBUFFER_REVERBPROPERTY;
|
|
|
|
// use this structure for get/set all properties...
|
|
typedef struct
|
|
{
|
|
float fMix; // linear factor, 0.0F to 1.0F
|
|
} EAXBUFFER_REVERBPROPERTIES;
|
|
|
|
#define EAX_REVERBMIX_USEDISTANCE -1.0F // out of normal range
|
|
// signifies the reverb engine should
|
|
// calculate it's own reverb mix value
|
|
// based on distance
|
|
|
|
// prototypes
|
|
|
|
int ds_eax_init();
|
|
void ds_eax_close();
|
|
|
|
int ds_eax_set_preset(unsigned long envid);
|
|
|
|
int ds_eax_set_volume(float volume);
|
|
int ds_eax_set_decay_time(float seconds);
|
|
int ds_eax_set_damping(float damp);
|
|
int ds_eax_set_environment(unsigned long envid);
|
|
int ds_eax_set_all(unsigned long id, float volume, float damping, float decay);
|
|
int ds_eax_get_all(EAX_REVERBPROPERTIES *er);
|
|
int ds_eax_is_inited();
|
|
|
|
#endif /* __DS_H__ */
|