summaryrefslogtreecommitdiff
path: root/engine/audio/public
diff options
context:
space:
mode:
Diffstat (limited to 'engine/audio/public')
-rw-r--r--engine/audio/public/ivoicecodec.h61
-rw-r--r--engine/audio/public/ivoicerecord.h40
-rw-r--r--engine/audio/public/snd_audio_source.h526
-rw-r--r--engine/audio/public/snd_device.h127
-rw-r--r--engine/audio/public/snd_io.h16
-rw-r--r--engine/audio/public/sound.h150
-rw-r--r--engine/audio/public/soundservice.h135
-rw-r--r--engine/audio/public/voice.h138
-rw-r--r--engine/audio/public/vox.h46
9 files changed, 1239 insertions, 0 deletions
diff --git a/engine/audio/public/ivoicecodec.h b/engine/audio/public/ivoicecodec.h
new file mode 100644
index 0000000..f7c43b3
--- /dev/null
+++ b/engine/audio/public/ivoicecodec.h
@@ -0,0 +1,61 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Define the IVoiceCodec interface.
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef IVOICECODEC_H
+#define IVOICECODEC_H
+#pragma once
+
+
+#include "interface.h"
+
+
+#define BYTES_PER_SAMPLE 2
+
+
+// This interface is for voice codecs to implement.
+
+// Codecs are guaranteed to be called with the exact output from Compress into Decompress (ie:
+// data won't be stuck together and sent to Decompress).
+
+// Decompress is not guaranteed to be called in any specific order relative to Compress, but
+// Codecs maintain state between calls, so it is best to call Compress with consecutive voice data
+// and decompress likewise. If you call it out of order, it will sound wierd.
+
+// In the same vein, calling Decompress twice with the same data is a bad idea since the state will be
+// expecting the next block of data, not the same block.
+
+class IVoiceCodec
+{
+protected:
+ virtual ~IVoiceCodec() {}
+
+public:
+ // Initialize the object. The uncompressed format is always 8-bit signed mono.
+ virtual bool Init( int quality )=0;
+
+ // Use this to delete the object.
+ virtual void Release()=0;
+
+
+ // Compress the voice data.
+ // pUncompressed - 16-bit signed mono voice data.
+ // maxCompressedBytes - The length of the pCompressed buffer. Don't exceed this.
+ // bFinal - Set to true on the last call to Compress (the user stopped talking).
+ // Some codecs like big block sizes and will hang onto data you give them in Compress calls.
+ // When you call with bFinal, the codec will give you compressed data no matter what.
+ // Return the number of bytes you filled into pCompressed.
+ virtual int Compress(const char *pUncompressed, int nSamples, char *pCompressed, int maxCompressedBytes, bool bFinal)=0;
+
+ // Decompress voice data. pUncompressed is 16-bit signed mono.
+ virtual int Decompress(const char *pCompressed, int compressedBytes, char *pUncompressed, int maxUncompressedBytes)=0;
+
+ // Some codecs maintain state between Compress and Decompress calls. This should clear that state.
+ virtual bool ResetState()=0;
+};
+
+
+#endif // IVOICECODEC_H
diff --git a/engine/audio/public/ivoicerecord.h b/engine/audio/public/ivoicerecord.h
new file mode 100644
index 0000000..9f830ff
--- /dev/null
+++ b/engine/audio/public/ivoicerecord.h
@@ -0,0 +1,40 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef IVOICERECORD_H
+#define IVOICERECORD_H
+#pragma once
+
+
+// This is the voice recording interface. It provides 16-bit signed mono data from
+// a mic at some sample rate.
+abstract_class IVoiceRecord
+{
+protected:
+
+ virtual ~IVoiceRecord() {}
+
+
+public:
+
+ // Use this to delete the object.
+ virtual void Release()=0;
+
+ // Start/stop capturing.
+ virtual bool RecordStart() = 0;
+ virtual void RecordStop() = 0;
+
+ // Idle processing.
+ virtual void Idle()=0;
+
+ // Get the most recent N samples. If nSamplesWanted is less than the number of
+ // available samples, it discards the first samples and gives you the last ones.
+ virtual int GetRecordedData(short *pOut, int nSamplesWanted)=0;
+};
+
+
+#endif // IVOICERECORD_H
diff --git a/engine/audio/public/snd_audio_source.h b/engine/audio/public/snd_audio_source.h
new file mode 100644
index 0000000..b8ac6b9
--- /dev/null
+++ b/engine/audio/public/snd_audio_source.h
@@ -0,0 +1,526 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $Workfile: $
+// $Date: $
+//
+//-----------------------------------------------------------------------------
+// $Log: $
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef SND_AUDIO_SOURCE_H
+#define SND_AUDIO_SOURCE_H
+#pragma once
+
+#if !defined( _X360 )
+#define MP3_SUPPORT 1
+#endif
+
+#define AUDIOSOURCE_COPYBUF_SIZE 4096
+
+struct channel_t;
+class CSentence;
+class CSfxTable;
+
+class CAudioSource;
+class IAudioDevice;
+class CUtlBuffer;
+
+#include "tier0/vprof.h"
+
+//-----------------------------------------------------------------------------
+// Purpose: This is an instance of an audio source.
+// Mixers are attached to channels and reference an audio source.
+// Mixers are specific to the sample format and source format.
+// Mixers are never re-used, so they can track instance data like
+// sample position, fractional sample, stream cache, faders, etc.
+//-----------------------------------------------------------------------------
+abstract_class CAudioMixer
+{
+public:
+ virtual ~CAudioMixer( void ) {}
+
+ // return number of samples mixed
+ virtual int MixDataToDevice( IAudioDevice *pDevice, channel_t *pChannel, int sampleCount, int outputRate, int outputOffset ) = 0;
+ virtual int SkipSamples( channel_t *pChannel, int sampleCount, int outputRate, int outputOffset ) = 0;
+ virtual bool ShouldContinueMixing( void ) = 0;
+
+ virtual CAudioSource *GetSource( void ) = 0;
+
+ // get the current position (next sample to be mixed)
+ virtual int GetSamplePosition( void ) = 0;
+
+ // Allow the mixer to modulate pitch and volume.
+ // returns a floating point modulator
+ virtual float ModifyPitch( float pitch ) = 0;
+ virtual float GetVolumeScale( void ) = 0;
+
+ // NOTE: Playback is optimized for linear streaming. These calls will usually cost performance
+ // It is currently optimal to call them before any playback starts, but some audio sources may not
+ // guarantee this. Also, some mixers may choose to ignore these calls for internal reasons (none do currently).
+
+ // Move the current position to newPosition
+ // BUGBUG: THIS CALL DOES NOT SUPPORT MOVING BACKWARD, ONLY FORWARD!!!
+ virtual void SetSampleStart( int newPosition ) = 0;
+
+ // End playback at newEndPosition
+ virtual void SetSampleEnd( int newEndPosition ) = 0;
+
+ // How many samples to skip before commencing actual data reading ( to allow sub-frametime sound
+ // offsets and avoid synchronizing sounds to various 100 msec clock intervals throughout the
+ // engine and game code)
+ virtual void SetStartupDelaySamples( int delaySamples ) = 0;
+ virtual int GetMixSampleSize() = 0;
+
+ // Certain async loaded sounds lazilly load into memory in the background, use this to determine
+ // if the sound is ready for mixing
+ virtual bool IsReadyToMix() = 0;
+
+ // NOTE: The "saved" position can be different than the "sample" position
+ // NOTE: Allows mixer to save file offsets, loop info, etc
+ virtual int GetPositionForSave() = 0;
+ virtual void SetPositionFromSaved( int savedPosition ) = 0;
+};
+
+inline int CalcSampleSize( int bitsPerSample, int _channels )
+{
+ return (bitsPerSample >> 3) * _channels;
+}
+
+#include "UtlCachedFileData.h"
+
+class CSentence;
+class CSfxTable;
+class CAudioSourceCachedInfo : public IBaseCacheInfo
+{
+public:
+ CAudioSourceCachedInfo();
+ CAudioSourceCachedInfo( const CAudioSourceCachedInfo& src );
+
+ virtual ~CAudioSourceCachedInfo();
+
+ CAudioSourceCachedInfo& operator =( const CAudioSourceCachedInfo& src );
+
+ void Clear();
+ void RemoveData();
+
+ virtual void Save( CUtlBuffer& buf );
+ virtual void Restore( CUtlBuffer& buf );
+ virtual void Rebuild( char const *filename );
+
+ // A hack, but will work okay
+ static int s_CurrentType;
+ static CSfxTable *s_pSfx;
+ static bool s_bIsPrecacheSound;
+
+ inline int Type() const
+ {
+ return info.m_Type;
+ }
+ void SetType( int type )
+ {
+ info.m_Type = type;
+ }
+
+ inline int Bits() const
+ {
+ return info.m_bits;
+ }
+ void SetBits( int bits )
+ {
+ info.m_bits = bits;
+ }
+
+ inline int Channels() const
+ {
+ return info.m_channels;
+ }
+ void SetChannels( int _channels )
+ {
+ info.m_channels = _channels;
+ }
+
+ inline int SampleSize() const
+ {
+ return info.m_sampleSize;
+ }
+ void SetSampleSize( int size )
+ {
+ info.m_sampleSize = size;
+ }
+
+ inline int Format() const
+ {
+ return info.m_format;
+ }
+ void SetFormat( int format )
+ {
+ info.m_format = format;
+ }
+
+ inline int SampleRate() const
+ {
+ return info.m_rate;
+ }
+ void SetSampleRate( int rate )
+ {
+ info.m_rate = rate;
+ }
+
+ inline int CachedDataSize() const
+ {
+ return (int)m_usCachedDataSize;
+ }
+
+ void SetCachedDataSize( int size )
+ {
+ m_usCachedDataSize = (unsigned short)size;
+ }
+
+ inline const byte *CachedData() const
+ {
+ return m_pCachedData;
+ }
+
+ void SetCachedData( const byte *data )
+ {
+ m_pCachedData = ( byte * )data;
+ flags.m_bCachedData = ( data != NULL ) ? true : false;
+ }
+
+ inline int HeaderSize() const
+ {
+ return (int)m_usHeaderSize;
+ }
+
+ void SetHeaderSize( int size )
+ {
+ m_usHeaderSize = (unsigned short)size;
+ }
+
+ inline const byte *HeaderData() const
+ {
+ return m_pHeader;
+ }
+
+ void SetHeaderData( const byte *data )
+ {
+ m_pHeader = ( byte * )data;
+ flags.m_bHeader = ( data != NULL ) ? true : false;
+ }
+
+ inline int LoopStart() const
+ {
+ return m_loopStart;
+ }
+ void SetLoopStart( int start )
+ {
+ m_loopStart = start;
+ }
+
+ inline int SampleCount() const
+ {
+ return m_sampleCount;
+ }
+
+ void SetSampleCount( int count )
+ {
+ m_sampleCount = count;
+ }
+ inline int DataStart() const
+ {
+ return m_dataStart;
+ }
+ void SetDataStart( int start )
+ {
+ m_dataStart = start;
+ }
+ inline int DataSize() const
+ {
+ return m_dataSize;
+ }
+ void SetDataSize( int size )
+ {
+ m_dataSize = size;
+ }
+ inline CSentence *Sentence() const
+ {
+ return m_pSentence;
+ }
+ void SetSentence( CSentence *sentence )
+ {
+ m_pSentence = sentence;
+ flags.m_bSentence = ( sentence != NULL ) ? true : false;
+ }
+
+private:
+
+ union
+ {
+ unsigned int infolong;
+ struct
+ {
+ unsigned int m_Type : 2; // 0 1 2 or 3
+ unsigned int m_bits : 5; // 0 to 31
+ unsigned int m_channels : 2; // 1 or 2
+ unsigned int m_sampleSize : 3; // 1 2 or 4
+ unsigned int m_format : 2; // 1 == PCM, 2 == ADPCM
+ unsigned int m_rate : 17; // 0 to 64 K
+ } info;
+ };
+
+ union
+ {
+ byte flagsbyte;
+ struct
+ {
+ bool m_bSentence : 1;
+ bool m_bCachedData : 1;
+ bool m_bHeader : 1;
+ } flags;
+ };
+
+ int m_loopStart;
+ int m_sampleCount;
+ int m_dataStart; // offset of wave data chunk
+ int m_dataSize; // size of wave data chunk
+
+ unsigned short m_usCachedDataSize;
+ unsigned short m_usHeaderSize;
+
+ CSentence *m_pSentence;
+ byte *m_pCachedData;
+ byte *m_pHeader;
+};
+
+class IAudioSourceCache
+{
+public:
+ virtual bool Init( unsigned int memSize ) = 0;
+ virtual void Shutdown() = 0;
+ virtual void LevelInit( char const *mapname ) = 0;
+ virtual void LevelShutdown() = 0;
+
+ // This invalidates the cached size/date info for sounds so it'll regenerate that next time it's accessed.
+ // Used when you connect to a pure server.
+ virtual void ForceRecheckDiskInfo() = 0;
+
+ virtual CAudioSourceCachedInfo *GetInfo( int audiosourcetype, bool soundisprecached, CSfxTable *sfx ) = 0;
+ virtual void RebuildCacheEntry( int audiosourcetype, bool soundisprecached, CSfxTable *sfx ) = 0;
+};
+
+extern IAudioSourceCache *audiosourcecache;
+
+FORWARD_DECLARE_HANDLE( memhandle_t );
+
+typedef int StreamHandle_t;
+enum
+{
+ INVALID_STREAM_HANDLE = (StreamHandle_t)~0
+};
+
+typedef int BufferHandle_t;
+enum
+{
+ INVALID_BUFFER_HANDLE = (BufferHandle_t)~0
+};
+
+typedef unsigned int streamFlags_t;
+enum
+{
+ STREAMED_FROMDVD = 0x00000001, // stream buffers are compliant to dvd sectors
+ STREAMED_SINGLEPLAY = 0x00000002, // non recurring data, buffers don't need to persist and can be recycled
+ STREAMED_QUEUEDLOAD = 0x00000004, // hint the streamer to load using the queued loader system
+};
+
+abstract_class IAsyncWavDataCache
+{
+public:
+ virtual bool Init( unsigned int memSize ) = 0;
+ virtual void Shutdown() = 0;
+
+ // implementation that treats file as monolithic
+ virtual memhandle_t AsyncLoadCache( char const *filename, int datasize, int startpos, bool bIsPrefetch = false ) = 0;
+ virtual void PrefetchCache( char const *filename, int datasize, int startpos ) = 0;
+ virtual bool CopyDataIntoMemory( char const *filename, int datasize, int startpos, void *buffer, int bufsize, int copystartpos, int bytestocopy, bool *pbPostProcessed ) = 0;
+ virtual bool CopyDataIntoMemory( memhandle_t& handle, char const *filename, int datasize, int startpos, void *buffer, int bufsize, int copystartpos, int bytestocopy, bool *pbPostProcessed ) = 0;
+ virtual bool IsDataLoadCompleted( memhandle_t handle, bool *pIsValid ) = 0;
+ virtual void RestartDataLoad( memhandle_t *pHandle, const char *pFilename, int dataSize, int startpos ) = 0;
+ virtual bool GetDataPointer( memhandle_t& handle, char const *filename, int datasize, int startpos, void **pData, int copystartpos, bool *pbPostProcessed ) = 0;
+ virtual void SetPostProcessed( memhandle_t handle, bool proc ) = 0;
+ virtual void Unload( memhandle_t handle ) = 0;
+
+ // alternate multi-buffer streaming implementation
+ virtual StreamHandle_t OpenStreamedLoad( char const *pFileName, int dataSize, int dataStart, int startPos, int loopPos, int bufferSize, int numBuffers, streamFlags_t flags ) = 0;
+ virtual void CloseStreamedLoad( StreamHandle_t hStream ) = 0;
+ virtual int CopyStreamedDataIntoMemory( StreamHandle_t hStream, void *pBuffer, int buffSize, int copyStartPos, int bytesToCopy ) = 0;
+ virtual bool IsStreamedDataReady( StreamHandle_t hStream ) = 0;
+ virtual void MarkBufferDiscarded( BufferHandle_t hBuffer ) = 0;
+ virtual void *GetStreamedDataPointer( StreamHandle_t hStream, bool bSync ) = 0;
+ virtual bool IsDataLoadInProgress( memhandle_t handle ) = 0;
+ virtual void Flush() = 0;
+ virtual void OnMixBegin() = 0;
+ virtual void OnMixEnd() = 0;
+};
+
+extern IAsyncWavDataCache *wavedatacache;
+
+struct CAudioSourceCachedInfoHandle_t
+{
+ CAudioSourceCachedInfoHandle_t() :
+ info( NULL ),
+ m_FlushCount( 0 )
+ {
+ }
+
+ CAudioSourceCachedInfo *info;
+ unsigned int m_FlushCount;
+
+ inline CAudioSourceCachedInfo *Get( int audiosourcetype, bool soundisprecached, CSfxTable *sfx, int *pcacheddatasize )
+ {
+ VPROF("CAudioSourceCachedInfoHandle_t::Get");
+
+ if ( m_FlushCount != s_nCurrentFlushCount )
+ {
+ // Reacquire
+ info = audiosourcecache->GetInfo( audiosourcetype, soundisprecached, sfx );
+
+ if ( pcacheddatasize )
+ {
+ *pcacheddatasize = info ? info->CachedDataSize() : 0;
+ }
+
+ // Tag as current
+ m_FlushCount = s_nCurrentFlushCount;
+ }
+ return info;
+ }
+
+ inline bool IsValid()
+ {
+ return !!( m_FlushCount == s_nCurrentFlushCount );
+ }
+
+ inline CAudioSourceCachedInfo *FastGet()
+ {
+ VPROF("CAudioSourceCachedInfoHandle_t::FastGet");
+
+ if ( m_FlushCount != s_nCurrentFlushCount )
+ {
+ return NULL;
+ }
+ return info;
+ }
+
+ static void InvalidateCache();
+ static unsigned int s_nCurrentFlushCount;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: A source is an abstraction for a stream, cached file, or procedural
+// source of audio.
+//-----------------------------------------------------------------------------
+abstract_class CAudioSource
+{
+public:
+ enum
+ {
+ AUDIO_SOURCE_UNK = 0,
+ AUDIO_SOURCE_WAV,
+ AUDIO_SOURCE_MP3,
+ AUDIO_SOURCE_VOICE,
+
+ AUDIO_SOURCE_MAXTYPE,
+ };
+
+ enum
+ {
+ AUDIO_NOT_LOADED = 0,
+ AUDIO_IS_LOADED = 1,
+ AUDIO_LOADING = 2,
+ };
+
+ virtual ~CAudioSource( void ) {}
+
+ // Create an instance (mixer) of this audio source
+ virtual CAudioMixer *CreateMixer( int initialStreamPosition = 0 ) = 0;
+
+ // Serialization for caching
+ virtual int GetType( void ) = 0;
+ virtual void GetCacheData( CAudioSourceCachedInfo *info ) = 0;
+
+ // Provide samples for the mixer. You can point pData at your own data, or if you prefer to copy the data,
+ // you can copy it into copyBuf and set pData to copyBuf.
+ virtual int GetOutputData( void **pData, int samplePosition, int sampleCount, char copyBuf[AUDIOSOURCE_COPYBUF_SIZE] ) = 0;
+
+ virtual int SampleRate( void ) = 0;
+
+ // Returns true if the source is a voice source.
+ // This affects the voice_overdrive behavior (all sounds get quieter when
+ // someone is speaking).
+ virtual bool IsVoiceSource() = 0;
+
+ // Sample size is in bytes. It will not be accurate for compressed audio. This is a best estimate.
+ // The compressed audio mixers understand this, but in general do not assume that SampleSize() * SampleCount() = filesize
+ // or even that SampleSize() is 100% accurate due to compression.
+ virtual int SampleSize( void ) = 0;
+
+ // Total number of samples in this source. NOTE: Some sources are infinite (mic input), they should return
+ // a count equal to one second of audio at their current rate.
+ virtual int SampleCount( void ) = 0;
+
+ virtual int Format( void ) = 0;
+ virtual int DataSize( void ) = 0;
+
+ virtual bool IsLooped( void ) = 0;
+ virtual bool IsStereoWav( void ) = 0;
+ virtual bool IsStreaming( void ) = 0;
+ virtual int GetCacheStatus( void ) = 0;
+ int IsCached( void ) { return GetCacheStatus() == AUDIO_IS_LOADED ? true : false; }
+ virtual void CacheLoad( void ) = 0;
+ virtual void CacheUnload( void ) = 0;
+ virtual CSentence *GetSentence( void ) = 0;
+
+ // these are used to find good splice/loop points.
+ // If not implementing these, simply return sample
+ virtual int ZeroCrossingBefore( int sample ) = 0;
+ virtual int ZeroCrossingAfter( int sample ) = 0;
+
+ // mixer's references
+ virtual void ReferenceAdd( CAudioMixer *pMixer ) = 0;
+ virtual void ReferenceRemove( CAudioMixer *pMixer ) = 0;
+
+ // check reference count, return true if nothing is referencing this
+ virtual bool CanDelete( void ) = 0;
+
+ virtual void Prefetch() = 0;
+
+ virtual bool IsAsyncLoad() = 0;
+
+ // Make sure our data is rebuilt into the per-level cache
+ virtual void CheckAudioSourceCache() = 0;
+
+ virtual char const *GetFileName() = 0;
+
+ virtual void SetPlayOnce( bool ) = 0;
+ virtual bool IsPlayOnce() = 0;
+
+ // Used to identify a word that is part of a sentence mixing operation
+ virtual void SetSentenceWord( bool bIsWord ) = 0;
+ virtual bool IsSentenceWord() = 0;
+
+ virtual int SampleToStreamPosition( int samplePosition ) = 0;
+ virtual int StreamToSamplePosition( int streamPosition ) = 0;
+};
+
+// Fast method for determining duration of .wav/.mp3, exposed to server as well
+extern float AudioSource_GetSoundDuration( char const *pName );
+
+// uses wave file cached in memory already
+extern float AudioSource_GetSoundDuration( CSfxTable *pSfx );
+
+#endif // SND_AUDIO_SOURCE_H
diff --git a/engine/audio/public/snd_device.h b/engine/audio/public/snd_device.h
new file mode 100644
index 0000000..9c844b6
--- /dev/null
+++ b/engine/audio/public/snd_device.h
@@ -0,0 +1,127 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: This abstracts the various hardware dependent implementations of sound
+// At the time of this writing there are Windows WAVEOUT, Direct Sound,
+// and Null implementations.
+//
+//=====================================================================================//
+
+#ifndef SND_DEVICE_H
+#define SND_DEVICE_H
+#pragma once
+
+#include "snd_fixedint.h"
+#include "snd_mix_buf.h"
+
+// sound engine rate defines
+#define SOUND_DMA_SPEED 44100 // hardware playback rate
+
+#define SOUND_11k 11025 // 11khz sample rate
+#define SOUND_22k 22050 // 22khz sample rate
+#define SOUND_44k 44100 // 44khz sample rate
+#define SOUND_ALL_RATES 1 // mix all sample rates
+
+#define SOUND_MIX_WET 0 // mix only samples that don't have channel set to 'dry' or 'speaker' (default)
+#define SOUND_MIX_DRY 1 // mix only samples with channel set to 'dry' (ie: music)
+#define SOUND_MIX_SPEAKER 2 // mix only samples with channel set to 'speaker'
+#define SOUND_MIX_SPECIAL_DSP 3 // mix only samples with channel set to 'special dsp'
+
+#define SOUND_BUSS_ROOM (1<<0) // mix samples using channel dspmix value (based on distance from player)
+#define SOUND_BUSS_FACING (1<<1) // mix samples using channel dspface value (source facing)
+#define SOUND_BUSS_FACINGAWAY (1<<2) // mix samples using 1-dspface
+#define SOUND_BUSS_SPEAKER (1<<3) // mix ch->bspeaker samples in mono to speaker buffer
+#define SOUND_BUSS_DRY (1<<4) // mix ch->bdry samples into dry buffer
+#define SOUND_BUSS_SPECIAL_DSP (1<<5) // mix ch->bspecialdsp samples into special dsp buffer
+
+class Vector;
+struct channel_t;
+
+// UNDONE: Create a simulated audio device to replace the old -simsound functionality?
+
+// General interface to an audio device
+abstract_class IAudioDevice
+{
+public:
+ // Add a virtual destructor to silence the clang warning.
+ // This is harmless but not important since the only derived class
+ // doesn't have a destructor.
+ virtual ~IAudioDevice() {}
+
+ // Detect the sound hardware and create a compatible device
+ // NOTE: This should NEVER fail. There is a function called Audio_GetNullDevice
+ // which will create a "null" device that makes no sound. If we can't create a real
+ // sound device, this will return a device of that type. All of the interface
+ // functions can be called on the null device, but it will not, of course, make sound.
+ static IAudioDevice *AutoDetectInit( bool waveOnly );
+
+ // This is needed by some of the routines to avoid doing work when you've got a null device
+ virtual bool IsActive( void ) = 0;
+ // This initializes the sound hardware. true on success, false on failure
+ virtual bool Init( void ) = 0;
+ // This releases all sound hardware
+ virtual void Shutdown( void ) = 0;
+ // stop outputting sound, but be ready to resume on UnPause
+ virtual void Pause( void ) = 0;
+ // return to normal operation after a Pause()
+ virtual void UnPause( void ) = 0;
+ // The volume of the "dry" mix (no effects).
+ // This should return 0 on all implementations that don't need a separate dry mix
+ virtual float MixDryVolume( void ) = 0;
+ // Should we mix sounds to a 3D (quadraphonic) sound buffer (front/rear both stereo)
+ virtual bool Should3DMix( void ) = 0;
+
+ // This is called when the application stops all sounds
+ // NOTE: Stopping each channel and clearing the sound buffer are done separately
+ virtual void StopAllSounds( void ) = 0;
+
+ // Called before painting channels, must calculated the endtime and return it (once per frame)
+ virtual int PaintBegin( float, int soundtime, int paintedtime ) = 0;
+ // Called when all channels are painted (once per frame)
+ virtual void PaintEnd( void ) = 0;
+
+ // Called to set the volumes on a channel with the given gain & dot parameters
+ virtual void SpatializeChannel( int volume[6], int master_vol, const Vector& sourceDir, float gain, float mono ) = 0;
+
+ // The device should apply DSP up to endtime in the current paint buffer
+ // this is called during painting
+ virtual void ApplyDSPEffects( int idsp, portable_samplepair_t *pbuffront, portable_samplepair_t *pbufrear, portable_samplepair_t *pbufcenter, int samplecount ) = 0;
+
+ // replaces SNDDMA_GetDMAPos, gets the output sample position for tracking
+ virtual int GetOutputPosition( void ) = 0;
+
+ // Fill the output buffer with silence (e.g. during pause)
+ virtual void ClearBuffer( void ) = 0;
+
+ // Called each frame with the listener's coordinate system
+ virtual void UpdateListener( const Vector& position, const Vector& forward, const Vector& right, const Vector& up ) = 0;
+
+ // Called each time a new paint buffer is mixed (may be multiple times per frame)
+ virtual void MixBegin( int sampleCount ) = 0;
+ virtual void MixUpsample( int sampleCount, int filtertype ) = 0;
+
+ // sink sound data
+ virtual void Mix8Mono( channel_t *pChannel, char *pData, int outputOffset, int inputOffset, fixedint rateScaleFix, int outCount, int timecompress ) = 0;
+ virtual void Mix8Stereo( channel_t *pChannel, char *pData, int outputOffset, int inputOffset, fixedint rateScaleFix, int outCount, int timecompress ) = 0;
+ virtual void Mix16Mono( channel_t *pChannel, short *pData, int outputOffset, int inputOffset, fixedint rateScaleFix, int outCount, int timecompress ) = 0;
+ virtual void Mix16Stereo( channel_t *pChannel, short *pData, int outputOffset, int inputOffset, fixedint rateScaleFix, int outCount, int timecompress ) = 0;
+
+ // Reset a channel
+ virtual void ChannelReset( int entnum, int channelIndex, float distanceMod ) = 0;
+ virtual void TransferSamples( int end ) = 0;
+
+ // device parameters
+ virtual const char *DeviceName( void ) = 0;
+ virtual int DeviceChannels( void ) = 0; // 1 = mono, 2 = stereo
+ virtual int DeviceSampleBits( void ) = 0; // bits per sample (8 or 16)
+ virtual int DeviceSampleBytes( void ) = 0; // above / 8
+ virtual int DeviceDmaSpeed( void ) = 0; // Actual DMA speed
+ virtual int DeviceSampleCount( void ) = 0; // Total samples in buffer
+
+ virtual bool IsSurround( void ) = 0; // surround enabled, could be quad or 5.1
+ virtual bool IsSurroundCenter( void ) = 0; // surround enabled as 5.1
+ virtual bool IsHeadphone( void ) = 0;
+};
+
+extern IAudioDevice *Audio_GetNullDevice( void );
+
+#endif // SND_DEVICE_H
diff --git a/engine/audio/public/snd_io.h b/engine/audio/public/snd_io.h
new file mode 100644
index 0000000..dd74798
--- /dev/null
+++ b/engine/audio/public/snd_io.h
@@ -0,0 +1,16 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef SND_IO_H
+#define SND_IO_H
+#pragma once
+
+class IFileReadBinary;
+
+extern IFileReadBinary *g_pSndIO;
+
+#endif // SND_IO_H
diff --git a/engine/audio/public/sound.h b/engine/audio/public/sound.h
new file mode 100644
index 0000000..64b4f9d
--- /dev/null
+++ b/engine/audio/public/sound.h
@@ -0,0 +1,150 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: client sound i/o functions
+//
+//===========================================================================//
+#ifndef SOUND_H
+#define SOUND_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "basetypes.h"
+#include "datamap.h"
+#include "mathlib/vector.h"
+#include "mathlib/mathlib.h"
+#include "tier1/strtools.h"
+#include "soundflags.h"
+#include "utlvector.h"
+#include "engine/SndInfo.h"
+
+#define MAX_SFX 2048
+
+#define AUDIOSOURCE_CACHE_ROOTDIR "maps/soundcache"
+
+class CSfxTable;
+enum soundlevel_t;
+struct SoundInfo_t;
+struct AudioState_t;
+class IFileList;
+
+void S_Init (void);
+void S_Shutdown (void);
+bool S_IsInitted();
+
+void S_StopAllSounds(bool clear);
+void S_Update( const AudioState_t *pAudioState );
+void S_ExtraUpdate (void);
+void S_ClearBuffer (void);
+void S_BlockSound (void);
+void S_UnblockSound (void);
+float S_GetMasterVolume( void );
+void S_SoundFade( float percent, float holdtime, float intime, float outtime );
+void S_OnLoadScreen(bool value);
+void S_EnableThreadedMixing( bool bEnable );
+void S_EnableMusic( bool bEnable );
+
+struct StartSoundParams_t
+{
+ StartSoundParams_t() :
+ staticsound( false ),
+ userdata( 0 ),
+ soundsource( 0 ),
+ entchannel( CHAN_AUTO ),
+ pSfx( 0 ),
+ bUpdatePositions( true ),
+ fvol( 1.0f ),
+ soundlevel( SNDLVL_NORM ),
+ flags( SND_NOFLAGS ),
+ pitch( PITCH_NORM ),
+ specialdsp( 0 ),
+ fromserver( false ),
+ delay( 0.0f ),
+ speakerentity( -1 ),
+ suppressrecording( false ),
+ initialStreamPosition( 0 )
+ {
+ origin.Init();
+ direction.Init();
+ }
+
+ bool staticsound;
+ int userdata;
+ int soundsource;
+ int entchannel;
+ CSfxTable *pSfx;
+ Vector origin;
+ Vector direction;
+ bool bUpdatePositions;
+ float fvol;
+ soundlevel_t soundlevel;
+ int flags;
+ int pitch;
+ int specialdsp;
+ bool fromserver;
+ float delay;
+ int speakerentity;
+ bool suppressrecording;
+ int initialStreamPosition;
+};
+
+int S_StartSound( StartSoundParams_t& params );
+void S_StopSound ( int entnum, int entchannel );
+enum clocksync_index_t
+{
+ CLOCK_SYNC_CLIENT = 0,
+ CLOCK_SYNC_SERVER,
+ NUM_CLOCK_SYNCS
+};
+
+extern float S_ComputeDelayForSoundtime( float soundtime, clocksync_index_t syncIndex );
+
+void S_StopSoundByGuid( int guid );
+float S_SoundDurationByGuid( int guid );
+int S_GetGuidForLastSoundEmitted();
+bool S_IsSoundStillPlaying( int guid );
+void S_GetActiveSounds( CUtlVector< SndInfo_t >& sndlist );
+void S_SetVolumeByGuid( int guid, float fvol );
+float S_GetElapsedTimeByGuid( int guid );
+bool S_IsLoopingSoundByGuid( int guid );
+void S_ReloadSound( const char *pSample );
+float S_GetMono16Samples( const char *pszName, CUtlVector< short >& sampleList );
+
+CSfxTable *S_DummySfx( const char *name );
+CSfxTable *S_PrecacheSound (const char *sample );
+void S_PrefetchSound( char const *name, bool bPlayOnce );
+void S_MarkUISound( CSfxTable *pSfx );
+void S_ReloadFilesInList( IFileList *pFilesToReload );
+
+vec_t S_GetNominalClipDist();
+
+extern bool TestSoundChar(const char *pch, char c);
+extern char *PSkipSoundChars(const char *pch);
+
+#include "soundchars.h"
+
+// for recording movies
+void SND_MovieStart( void );
+void SND_MovieEnd( void );
+
+//-------------------------------------
+
+int S_GetCurrentStaticSounds( SoundInfo_t *pResult, int nSizeResult, int entchannel );
+
+//-----------------------------------------------------------------------------
+
+float S_GetGainFromSoundLevel( soundlevel_t soundlevel, vec_t dist );
+
+struct musicsave_t
+{
+ DECLARE_SIMPLE_DATADESC();
+
+ char songname[ 128 ];
+ int sampleposition;
+ short master_volume;
+};
+
+void S_GetCurrentlyPlayingMusic( CUtlVector< musicsave_t >& list );
+void S_RestartSong( const musicsave_t *song );
+
+#endif // SOUND_H
diff --git a/engine/audio/public/soundservice.h b/engine/audio/public/soundservice.h
new file mode 100644
index 0000000..b1fb4df
--- /dev/null
+++ b/engine/audio/public/soundservice.h
@@ -0,0 +1,135 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Applicaton-level hooks for clients of the audio subsystem
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef SOUNDSERVICE_H
+#define SOUNDSERVICE_H
+
+#if defined( _WIN32 )
+#pragma once
+#endif
+
+class Vector;
+class QAngle;
+class CAudioSource;
+typedef int SoundSource;
+struct SpatializationInfo_t;
+typedef void *FileNameHandle_t;
+struct StartSoundParams_t;
+
+#include "utlrbtree.h"
+
+//-----------------------------------------------------------------------------
+// Purpose: Services required by the audio system to function, this facade
+// defines the bridge between the audio code and higher level
+// systems.
+//
+// Note that some of these currently suggest that certain
+// functionality would like to exist at a deeper layer so
+// systems like audio can take advantage of them
+// diectly (toml 05-02-02)
+//-----------------------------------------------------------------------------
+
+abstract_class ISoundServices
+{
+public:
+ //---------------------------------
+ // Allocate a block of memory that will be automatically
+ // cleaned up on level change
+ //---------------------------------
+ virtual void *LevelAlloc( int nBytes, const char *pszTag ) = 0;
+
+ //---------------------------------
+ // Notification that someone called S_ExtraUpdate()
+ //---------------------------------
+ virtual void OnExtraUpdate() = 0;
+
+ //---------------------------------
+ // Return false if the entity doesn't exist or is out of the PVS, in which case the sound shouldn't be heard.
+ //---------------------------------
+ virtual bool GetSoundSpatialization( int entIndex, SpatializationInfo_t& info ) = 0;
+
+ //---------------------------------
+ // This is the client's clock, which follows the servers and thus isn't 100% smooth all the time (it is in single player)
+ //---------------------------------
+ virtual float GetClientTime() = 0;
+
+ //---------------------------------
+ // This is the engine's filtered timer, it's pretty smooth all the time
+ //---------------------------------
+ virtual float GetHostTime() = 0;
+
+ //---------------------------------
+ //---------------------------------
+ virtual int GetViewEntity() = 0;
+
+ //---------------------------------
+ //---------------------------------
+ virtual float GetHostFrametime() = 0;
+ virtual void SetSoundFrametime( float realDt, float hostDt ) = 0;
+
+ //---------------------------------
+ //---------------------------------
+ virtual int GetServerCount() = 0;
+
+ //---------------------------------
+ //---------------------------------
+ virtual bool IsPlayer( SoundSource source ) = 0;
+
+ //---------------------------------
+ //---------------------------------
+ virtual void OnChangeVoiceStatus( int entity, bool status) = 0;
+
+ // Is the player fully connected (don't do DSP processing if not)
+ virtual bool IsConnected() = 0;
+
+ // Calls into client .dll with list of close caption tokens to construct a caption out of
+ virtual void EmitSentenceCloseCaption( char const *tokenstream ) = 0;
+ // Calls into client .dll with list of close caption tokens to construct a caption out of
+ virtual void EmitCloseCaption( char const *captionname, float duration ) = 0;
+
+ virtual char const *GetGameDir() = 0;
+
+ // If the game is paused, certain audio will pause, too (anything with phoneme/sentence data for now)
+ virtual bool IsGamePaused() = 0;
+
+ // If the game is not active, certain audio will pause
+ virtual bool IsGameActive() = 0;
+
+ // restarts the sound system externally
+ virtual void RestartSoundSystem() = 0;
+
+ virtual void GetAllSoundFilesReferencedInReslists( CUtlRBTree< FileNameHandle_t, int >& list ) = 0;
+ virtual void GetAllManifestFiles( CUtlRBTree< FileNameHandle_t, int >& list ) = 0;
+ virtual void GetAllSoundFilesInManifest( CUtlRBTree< FileNameHandle_t, int >& list, char const *manifestfile ) = 0;
+
+ virtual void CacheBuildingStart() = 0;
+ virtual void CacheBuildingUpdateProgress( float percent, char const *cachefile ) = 0;
+ virtual void CacheBuildingFinish() = 0;
+
+ // For building sound cache manifests
+ virtual int GetPrecachedSoundCount() = 0;
+ virtual char const *GetPrecachedSound( int index ) = 0;
+
+ virtual void OnSoundStarted( int guid, StartSoundParams_t& params, char const *soundname ) = 0;
+ virtual void OnSoundStopped( int guid, int soundsource, int channel, char const *soundname ) = 0;
+
+ virtual bool GetToolSpatialization( int iUserData, int guid, SpatializationInfo_t& info ) = 0;
+
+#if defined( _XBOX )
+ virtual bool ShouldSuppressNonUISounds() = 0;
+#endif
+
+ virtual char const *GetUILanguage() = 0;
+};
+
+//-------------------------------------
+
+extern ISoundServices *g_pSoundServices;
+
+//=============================================================================
+
+#endif // SOUNDSERVICE_H
diff --git a/engine/audio/public/voice.h b/engine/audio/public/voice.h
new file mode 100644
index 0000000..2bfea81
--- /dev/null
+++ b/engine/audio/public/voice.h
@@ -0,0 +1,138 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef VOICE_H
+#define VOICE_H
+#pragma once
+
+
+#include "ivoicetweak.h"
+
+
+/*! @defgroup Voice Voice
+Defines the engine's interface to the voice code.
+@{
+*/
+
+// Voice_Init will pick a sample rate, it must be within RATE_MAX
+#define VOICE_OUTPUT_SAMPLE_RATE_LOW 11025 // Sample rate that we feed to the mixer.
+#define VOICE_OUTPUT_SAMPLE_RATE_HIGH 22050 // Sample rate that we feed to the mixer.
+#define VOICE_OUTPUT_SAMPLE_RATE_MAX 22050 // Sample rate that we feed to the mixer.
+
+
+//! Returned on error from certain voice functions.
+#define VOICE_CHANNEL_ERROR -1
+#define VOICE_CHANNEL_IN_TWEAK_MODE -2 // Returned by AssignChannel if currently in tweak mode (not an error).
+
+
+//! Initialize the voice code.
+bool Voice_Init( const char *pCodec, int nSampleRate );
+
+//! Inits voice with defaults if it is not initialized normally, e.g. for local mixer use.
+void Voice_ForceInit();
+
+//! Get the default sample rate to use for this codec
+inline int Voice_GetDefaultSampleRate( const char *pCodec ) // Inline for DEDICATED builds
+{
+ // Use legacy lower rate for speex
+ if ( Q_stricmp( pCodec, "vaudio_speex" ) == 0 )
+ {
+ return VOICE_OUTPUT_SAMPLE_RATE_LOW;
+ }
+ else if ( Q_stricmp( pCodec, "steam" ) == 0 )
+ {
+ return 0; // For the steam codec, 0 passed to voice_init means "use optimal steam voice rate"
+ }
+
+ // Use high sample rate by default for other codecs.
+ return VOICE_OUTPUT_SAMPLE_RATE_HIGH;
+}
+
+//! Shutdown the voice code.
+void Voice_Deinit();
+
+//! Returns true if the client has voice enabled
+bool Voice_Enabled( void );
+
+//! The codec voice was initialized with. Empty string if voice is not initialized.
+const char *Voice_ConfiguredCodec();
+
+//! The sample rate voice was initialized with. -1 if voice is not initialized.
+int Voice_ConfiguredSampleRate();
+
+//! Returns true if the user can hear themself speak.
+bool Voice_GetLoopback();
+
+
+//! This is called periodically by the engine when the server acks the local player talking.
+//! This tells the client DLL that the local player is talking and fades after about 200ms.
+void Voice_LocalPlayerTalkingAck();
+
+
+//! Call every frame to update the voice stuff.
+void Voice_Idle(float frametime);
+
+
+//! Returns true if mic input is currently being recorded.
+bool Voice_IsRecording();
+
+//! Begin recording input from the mic.
+bool Voice_RecordStart(
+ //! Filename to store incoming mic data, or NULL if none.
+ const char *pUncompressedFile,
+
+ //! Filename to store the output of compression and decompressiong with the codec, or NULL if none.
+ const char *pDecompressedFile,
+
+ //! If this is non-null, the voice manager will use this file for input instead of the mic.
+ const char *pMicInputFile
+ );
+
+// User wants to stop recording
+void Voice_UserDesiresStop();
+
+//! Stop recording from the mic.
+bool Voice_RecordStop();
+
+
+//! Get the most recent N bytes of compressed data. If nCount is less than the number of
+//! available bytes, it discards the first bytes and gives you the last ones.
+//! Set bFinal to true on the last call to this (it will flush out any stored voice data).
+int Voice_GetCompressedData(char *pchData, int nCount, bool bFinal);
+
+
+
+//! Pass incoming data from the server into here.
+//! The data should have been compressed and gotten through a Voice_GetCompressedData call.
+int Voice_AddIncomingData(
+ //! Channel index.
+ int nChannel,
+ //! Compressed data to add to the channel.
+ const char *pchData,
+ //! Number of bytes in pchData.
+ int nCount,
+ //! Sequence number. If a packet is missed, it adds padding so the time isn't squashed.
+ int iSequenceNumber
+ );
+
+//! Call this to reserve a voice channel for the specified entity to talk into.
+//! \return A channel index for use with Voice_AddIncomingData or VOICE_CHANNEL_ERROR on error.
+int Voice_AssignChannel(int nEntity, bool bProximity );
+
+//! Call this to get the channel index that the specified entity is talking into.
+//! \return A channel index for use with Voice_AddIncomingData or VOICE_CHANNEL_ERROR if the entity isn't talking.
+int Voice_GetChannel(int nEntity);
+
+#if !defined( NO_VOICE )
+extern IVoiceTweak g_VoiceTweakAPI;
+extern bool g_bUsingSteamVoice;
+#endif
+
+/*! @} */
+
+
+#endif // VOICE_H
diff --git a/engine/audio/public/vox.h b/engine/audio/public/vox.h
new file mode 100644
index 0000000..6b50008
--- /dev/null
+++ b/engine/audio/public/vox.h
@@ -0,0 +1,46 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $Workfile: $
+// $Date: $
+//
+//-----------------------------------------------------------------------------
+// $Log: $
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef VOX_H
+#define VOX_H
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct sfxcache_t;
+struct channel_t;
+
+class CUtlSymbol;
+
+extern void VOX_Init( void );
+extern void VOX_Shutdown( void );
+extern void VOX_ReadSentenceFile( const char *psentenceFileName );
+extern int VOX_SentenceCount( void );
+extern void VOX_LoadSound( channel_t *pchan, const char *psz );
+// UNDONE: Improve the interface of this call, it returns sentence data AND the sentence index
+extern char *VOX_LookupString( const char *pSentenceName, int *psentencenum, bool *pbEmitCaption = NULL, CUtlSymbol *pCaptionSymbol = NULL, float * pflDuration = NULL );
+extern void VOX_PrecacheSentenceGroup( class IEngineSound *pSoundSystem, const char *pGroupName, const char *pPathOverride = NULL );
+extern const char *VOX_SentenceNameFromIndex( int sentencenum );
+extern float VOX_SentenceLength( int sentence_num );
+extern const char *VOX_GroupNameFromIndex( int groupIndex );
+extern int VOX_GroupIndexFromName( const char *pGroupName );
+extern int VOX_GroupPick( int isentenceg, char *szfound, int strLen );
+extern int VOX_GroupPickSequential( int isentenceg, char *szfound, int szfoundLen, int ipick, int freset );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // VOX_H