Descent3/sndlib/ds3dlib.h

454 lines
14 KiB
C++

/*
* Descent 3
* Copyright (C) 2024 Parallax Software
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
--- HISTORICAL COMMENTS FOLLOW ---
* $Logfile: /DescentIII/Main/lib/ds3dlib.h $
* $Revision: 49 $
* $Date: 8/23/99 5:29p $
* $Author: Samir $
*
* Low-level library for 3d sound
*
* $Log: /DescentIII/Main/lib/ds3dlib.h $
*
* 49 8/23/99 5:29p Samir
* incremental EAX 2.0 checkin
*
* 48 5/03/99 3:12a Samir
* fixed up aureal so it works (a little slow though...)
*
* 47 4/29/99 3:01p Samir
* added code for direct sound mixers only (and function for Aureal
* really) that will use direct sound looping for simple loops.
*
* 46 4/27/99 2:10p Samir
* added code to set the desired sound card given the descriptive name of
* a sound card.
*
* 45 4/23/99 7:51p Samir
* looping fixes for directsound.
*
* 44 4/22/99 10:33p Samir
* modifications so that DirectSound mixers use one thread for all looping
* and streaming sounds. It worked without crashing for about twenty
* minutes of playing from level 1 to level 2 of D3. We'll see.
*
* 43 4/13/99 4:09p Samir
* more priority stuff.
*
* 42 4/12/99 7:14p Samir
* prioritization code added.
*
* 41 4/10/99 5:08p Samir
* took out obsolete data from play_information structure that should save
* around 70 bytes per instance.
*
* 40 4/09/99 12:03p Samir
* took out windows.h again, this time made HWND a void pointer, and
* checked under both editor and main projects.
*
* 39 4/07/99 12:38a 3dsmax
* Misc changes to allow editor build, as per Samir's phone instructions.
* Will this break the game build? Who knows? (Matt, ChrisP)
*
* 38 4/06/99 8:29p Samir
* added error check system.
*
* 37 3/29/99 11:01a Samir
* added ability to change 3d environment.
*
* 36 3/17/99 4:20p Samir
* added functions to pause and resume individual sounds.
*
* 35 2/19/99 5:21p Kevin
* Fixed some connection DLLs and a Direct Sound bug with threads.
*
* 34 1/14/99 6:10p Samir
* added DirectSound buffer duplication code.
*
* 33 1/11/99 5:51p Samir
* reverb on the buffer level.
*
* 32 1/08/99 6:31p Samir
* added reverb
*
* 31 1/08/99 11:36a Samir
* implemented basic Aureal 2.0 support.
*
* 30 12/23/98 11:49a Samir
* reorganized code so it works with different APIs.
*
* 29 7/08/98 12:09p Samir
* use C RTL for thread creation.
*
* 28 7/06/98 1:48p Samir
* added A3d support.
*
* 27 6/29/98 4:15p Chris
* Streaming audio works
*
* 26 6/29/98 9:29a Chris
* Added some support for Direct Sound 3d
*
* 25 6/25/98 11:28a Chris
* Added some DS3d support
*
* 24 6/24/98 6:43p Chris
* Furthered the endless work on the sound system
*
* 23 6/24/98 4:39p Chris
* Improved the multiple mixer support
*
* 22 6/24/98 11:31a Chris
* Fixed an ordering bug
*
* 21 6/24/98 11:14a Chris
* Added more support and bug fixes
*
* 20 6/24/98 1:07a Chris
* Intermediate checkin
*
* 19 6/23/98 6:00p Chris
* DirectSound 16 mixer is active with 8 bit samples
*
* 18 6/22/98 12:00p Chris
* Working on sound system to make it in a nice shape.
*
* 17 6/19/98 3:09p Chris
* Improved IsSoundPlaying
*
* 16 6/19/98 3:03p Chris
* Made CheckAndForceSoundDataAlloc a SoundSystem function - useful for
* multiple mixers. Added IsSoundPlaying to the high level sound lib.
*
* 15 6/16/98 3:48p Chris
* Updated the sound system and added the start of sound streaming
*
* 14 2/26/98 5:11p Chris
* Removed a unused data element from the llsoundlib
*
* 13 2/26/98 3:08p Chris
* More NT stuff
*
* 12 2/25/98 3:19p Jeff
* more NT fixes
*
* 11 2/25/98 2:47p Jeff
* CHRIS: Added some NT support for sound code. It is pretty hokey right
* now.
*
* 10 2/25/98 12:13p Chris
* NT support? Not sure... I do not have the Editor in NT.
*
* 9 2/15/98 7:12p Chris
* More improvements to the sound lib
*
* 8 1/23/98 4:21p Chris
* Changed the low-level sound code from multimedia timers to a thread
* that sleeps();
*
* 7 1/02/98 5:32p Chris
* More radical changes to the sound system
*
* 6 12/31/97 2:58a Chris
* Another major revision to the SoundLib. This cleaned up the code after
* removing the direct sound secondary buffers.
*
* 5 12/22/97 6:19p Chris
* Working on new mixer functionality
*
* 4 12/19/97 4:08p Chris
* New dynamically loading sounds
*
* 3 12/10/97 4:47p Chris
* Revision 1.0 of new sound library (no hardware -- uses primary buffer
* streaming)
*
* 2 11/21/97 1:10p Chris
* Incremental Improvements
*
* 18 6/11/97 1:07p Samir
* The removal of gameos and replaced with oeApplication, oeDatabase
*
* 17 5/22/97 5:15p Chris
*
* 16 4/29/97 7:26a Chris
* Improved the sound code. It is healthy.
*
* 15 4/28/97 11:21a Chris
* Incremental improvements is the sound system
*
* 14 4/24/97 3:25a Chris
* // Added some more support for 3d sounds
*
* 13 4/03/97 8:37p Chris
* Added the Main_OS object pass in the sound library
* initialization code.
*
* 12 4/01/97 10:00a Chris
*
* 11 3/17/97 5:12p Chris
* Allowed new sound code to be demo'ed.
*
* 10 3/14/97 12:10p Chris
* Made a nice C++ abstract type for the low-level. It should make the
* MacMan very joyful. :)
*
* 9 2/07/97 5:48p Matt
* Renamed vector.h to vecmat.h to fix DevStudio problem
*
* $NoKeywords: $
*/
#ifndef __ds3dlib_h__
#define __ds3dlib_h__
#include <windows.h>
// #include <mmsystem.h> // Multi-media system support
// #include "dsound.h" // Direct sound header file
#include "ssl_lib.h" // Shared sound header (between high and low-levels)
#include "vecmat.h"
#ifndef DS3DLIB_INTERNAL_H
typedef void *LPDIRECTSOUND;
typedef void *LPDIRECTSOUNDBUFFER;
typedef void *LPDIRECTSOUND3DLISTENER;
typedef void *LPDIRECTSOUND3DBUFFER;
typedef void *LPDIRECTSOUNDCAPTURE;
typedef void *LPDIRECTSOUNDCAPTUREBUFFER;
typedef void *LPDIRECTSOUNDNOTIFY;
// typedef void *HWND;
class sound_buffer_info;
struct tPSBInfo;
#endif
// Sound cache list
class sound_buffer_cache {
public:
class sound_buffer_info *m_sound_cache; // List of all sounds current sounds
uint16_t m_max_sounds_played; // Maximum sounds played at any given moment
uint16_t m_cur_sounds_played; // Current number of sounds playing
unsigned m_loop_method; // what method do we do looping sounds (direct sound only)
public:
sound_buffer_info *FindSoundBuffer(int sound_index);
};
class emulated_listener {
public:
matrix orient;
vector position;
vector velocity;
};
// Sound library object
// Commonly passed arguments:
// sound_index -- index of a particular sample in the SoundArray
// sound_uid -- unique id of a particular sound being played
// sound_slot -- "channel" that a sample is being played on (derivable from sound_uid)
class win_llsSystem : public llsSystem {
private:
// Windows and Direct Sound information
LPDIRECTSOUND m_lp_ds; // pointer to direct sound object
void *m_hwnd_main; // Handle to main window -- needed for direct sound
// For DS3D
LPDIRECTSOUND3DLISTENER m_lp_listener;
// For 3d sounds and non-3D mixers
emulated_listener m_emulated_listener;
// For DS and DS3d mixers
void LoopStartStreaming(sound_buffer_info *sb, int buffer_type, float volume, float pan, pos_state *cur_pos);
void DSStartStreaming(sound_buffer_info *sb, float volume, float pan);
friend void __cdecl LoopStreamTimer(void *user_ptr);
// Creates a sound buffer
HRESULT CreateDSBuffer(int buffer_type, LPDIRECTSOUNDBUFFER *lp_lp_dsb, LPDIRECTSOUND3DBUFFER *lp_lp_dsb_3d,
DWORD sound_bytes, DWORD frequency, bool f_is_stereo, bool f_is_16_bit);
// Finds a free slot for a new sound, slot_uid is an SBID_xxx value.
#ifdef _DEBUG
int16_t FindFreeSoundSlot(int sound_index, float volume, int priority);
#else
int16_t FindFreeSoundSlot(float volume, int priority);
#endif
// updates a directsound buffer
void update_directsound_sb(sound_buffer_info *sb, bool update_looping = false);
// used to clean up direct sound buffer stuff
void cleanup_directsound_looping_sb(sound_buffer_info *sb);
// Makes a unique sound id from a sound slot number
inline int MakeUniqueId(int sound_slot);
// Validates and converts a unique sound id to a sound slot number
inline int ValidateUniqueId(int sound_uid);
friend void StreamMixer(char *ptr, int len);
friend void StreamFill(int start_byte, int num_bytes);
friend void __cdecl StreamTimer(void *user_ptr);
bool StartDSCleaner(void);
friend void __cdecl DSCleanerThread(void *user_ptr);
bool StartStreaming(void);
private:
// Total samples played since start of library
uint16_t m_total_sounds_played; // Used for unique ids and for stats
// Sound library status
uint8_t m_f_sound_lib_init; // Flag is set if sound library is initialized -- cmphack
uint8_t m_f_sound_lib_status; // Paused or running --
// cmphack
// May not need some of these
int m_primary_frequency; // Set to the primary buffers frequency -- cmphack
int m_primary_alignment;
int m_current_frequency; // -- cmphack
uint8_t m_primary_bit_depth; // 16 or 8 bits per sample -- cmphack
char m_sound_quality;
// muted looped sound system
int64_t m_timer_last_frametime;
float m_cache_stress_timer;
// clean interface
#ifdef DS3DLIB_INTERNAL_H // following data is available to internal functions
public:
#else
private:
#endif
bool CreateSoundBuffer(sound_buffer_info *sb, bool f_is_stereo, int size = -1, bool dynamic = false);
bool LoadSoundBuffer(sound_buffer_info *sb);
bool PlaySoundBuffer(sound_buffer_info *sb, tPSBInfo *psb);
bool DuplicateSoundBuffer(sound_buffer_info *sb);
bool m_in_sound_frame;
bool m_pending_actions; // are there sound events pending (outside of of start/end)
char m_mixer_type;
// Public functions
public:
// Initializes the object, but does not activate the sound library
win_llsSystem(void);
// Destructor -- calls the cleanup code.
~win_llsSystem(void);
// Starts the sound library
virtual int InitSoundLib(char mixer_type, oeApplication *sos, uint8_t max_sounds_played);
// Cleans up after the Sound Library
virtual void DestroySoundLib(void);
public: // only for win32 instances
int SetSoundPos(int sound_uid, int pos);
int GetSoundPos(int sound_uid);
public:
// reserve sound slots., returns an ID to this slot.
virtual void SetSoundCard(const char *name);
virtual void SetListener(pos_state *cur_pos);
virtual int PlaySound3d(play_information *play_info, int sound_index, pos_state *cur_pos, float master_volume,
bool f_looped, float reverb = 0.5f); //, uint16_t frequency)
virtual void AdjustSound(int sound_uid, float f_volume, float f_pan, uint16_t frequency);
virtual void AdjustSound(int sound_uid, pos_state *cur_pos, float adjusted_volume, float reverb = 0.5f);
// Sample cache and list of samples
class sound_buffer_cache m_sound_mixer; // Lists all stored samples (playing, cached, or unused)
// Plays a 2d sound
virtual int PlaySound2d(play_information *play_info, int sound_index, float volume, float pan, bool f_looped = false);
virtual int PlayStream(play_information *play_info);
virtual void StopAllSounds(void);
virtual bool SetSoundQuality(char quality);
virtual char GetSoundQuality(void);
virtual bool SetSoundMixer(char mixer_type);
virtual char GetSoundMixer(void);
// Checks if a sound is playing
virtual bool IsSoundInstancePlaying(int sound_uid);
virtual int IsSoundPlaying(int sound_index);
// Locks and unlocks sounds (used when changing play_info data)
virtual bool LockSound(int sound_uid);
virtual bool UnlockSound(int sound_uid);
// Stops 2d and 3d sounds
virtual void StopSound(int sound_uid, uint8_t f_immediately = SKT_STOP_IMMEDIATELY);
// Pause all sounds/resume all sounds
virtual void PauseSounds(void);
virtual void ResumeSounds(void);
virtual void PauseSound(int sound_uid);
virtual void ResumeSound(int sound_uid);
// Loads the actual sound data into memory
virtual bool CheckAndForceSoundDataAlloc(int sound_file_index);
// Begin sound frame
virtual void SoundStartFrame(void);
// End sound frame
virtual void SoundEndFrame(void);
// environmental sound interface
// volume modifier (0-1), damping(0-1), 1 = complete, 0 = none
// decay 0.1 to 100 seconds, how long it takes for a sound to die.
virtual bool SetGlobalReverbProperties(float volume, float damping, float decay);
// set special parameters for the 3d environment.
// of strcuture passed, you must set the appropriate 'flags' value for values you wish to modify
virtual void SetEnvironmentValues(const t3dEnvironmentValues *env);
// get special parameters for the 3d environment.
// of strcuture passed, you must set the appropriate 'flags' value for values you wish to modify
virtual void GetEnvironmentValues(t3dEnvironmentValues *env);
// enable special parameters for the 3d environment.
// of strcuture passed, you must set the appropriate 'flags' value for values you wish to modify
virtual void SetEnvironmentToggles(const t3dEnvironmentToggles *env);
// get states of special parameters for the 3d environment.
// of strcuture passed, you must set the appropriate 'flags' value for values you wish to modify
virtual void GetEnvironmentToggles(t3dEnvironmentToggles *env);
protected:
virtual void CheckForErrors(); // part of sound system error handler.
/////////////////////////////////////////////////////////////////////////////////
public:
// set auxillary 3d sound properties
virtual bool SoundPropertySupport() const;
// sound obstruction from 0 to 1.0 (1.0 = fully obstructed)
virtual void SetSoundProperties(int sound_uid, float obstruction);
};
#endif