/* =========================================================================== Copyright (C) 1999-2005 Id Software, Inc. Copyright (C) 2000-2013 Darklegion Development Copyright (C) 2015-2019 GrangerHub This file is part of Tremulous. Tremulous 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. Tremulous 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 Tremulous; if not, see =========================================================================== */ // snd_local.h -- private sound definations #ifndef _SND_LOCAL_H #define _SND_LOCAL_H #include "qcommon/q_shared.h" #include "qcommon/qcommon.h" #include "snd_public.h" typedef struct cvar_s cvar_t; #define PAINTBUFFER_SIZE 4096 // this is in samples #define SND_CHUNK_SIZE 1024 // samples #define SND_CHUNK_SIZE_FLOAT (SND_CHUNK_SIZE/2) // floats #define SND_CHUNK_SIZE_BYTE (SND_CHUNK_SIZE*2) // floats typedef struct { int left; // the final values will be clamped to +/- 0x00ffff00 and shifted down int right; } portable_samplepair_t; typedef struct adpcm_state { short sample; /* Previous output value */ char index; /* Index into stepsize table */ } adpcm_state_t; typedef struct sndBuffer_s { short sndChunk[SND_CHUNK_SIZE]; struct sndBuffer_s *next; int size; adpcm_state_t adpcm; } sndBuffer; typedef struct sfx_s { sndBuffer *soundData; bool defaultSound; // couldn't be loaded, so use buzz bool inMemory; // not in Memory bool soundCompressed; // not in Memory int soundCompressionMethod; int soundLength; int soundChannels; char soundName[MAX_QPATH]; int lastTimeUsed; int duration; struct sfx_s *next; } sfx_t; typedef struct { int channels; int samples; // mono samples in buffer int submission_chunk; // don't mix less than this # int samplebits; int speed; byte *buffer; } dma_t; #define START_SAMPLE_IMMEDIATE 0x7fffffff #define MAX_DOPPLER_SCALE 50.0f //arbitrary #define THIRD_PERSON_THRESHOLD_SQ (48.0f*48.0f) typedef struct loopSound_s { vec3_t origin; vec3_t velocity; sfx_t *sfx; int mergeFrame; bool active; bool kill; bool doppler; float dopplerScale; float oldDopplerScale; int framenum; } loopSound_t; typedef struct { sfx_t *thesfx; // sfx structure int allocTime; int startSample; // START_SAMPLE_IMMEDIATE = set immediately on next mix int entnum; // to allow overriding a specific sound int entchannel; // to allow overriding a specific sound int leftvol; // 0-255 volume after spatialization int rightvol; // 0-255 volume after spatialization int master_vol; // 0-255 volume before spatialization float dopplerScale; float oldDopplerScale; vec3_t origin; // only use if fixed_origin is set bool fixed_origin; // use origin instead of fetching entnum's origin bool doppler; bool fullVolume; } channel_t; #define WAV_FORMAT_PCM 1 typedef struct { int format; int rate; int width; int channels; int samples; int dataofs; // chunk starts this many bytes from file start } wavinfo_t; // Interface between Q3 sound "api" and the sound backend typedef struct { void (*Shutdown)(void); void (*StartSound)( vec3_t origin, int entnum, int entchannel, sfxHandle_t sfx ); void (*StartLocalSound)( sfxHandle_t sfx, int channelNum ); void (*StartBackgroundTrack)( const char *intro, const char *loop ); void (*StopBackgroundTrack)( void ); void (*RawSamples)(int stream, int samples, int rate, int width, int channels, const byte *data, float volume, int entityNum); void (*StopAllSounds)( void ); void (*ClearLoopingSounds)( bool killall ); void (*AddLoopingSound)( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx ); void (*AddRealLoopingSound)( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx ); void (*StopLoopingSound)(int entityNum ); void (*Respatialize)( int entityNum, const vec3_t origin, vec3_t axis[3], int inwater ); void (*UpdateEntityPosition)( int entityNum, const vec3_t origin ); void (*Update)( void ); void (*DisableSounds)( void ); void (*BeginRegistration)( void ); sfxHandle_t (*RegisterSound)( const char *sample, bool compressed ); int (*SoundDuration)( sfxHandle_t handle ); void (*ClearSoundBuffer)( void ); void (*SoundInfo)( void ); void (*SoundList)( void ); #ifdef USE_VOIP void (*StartCapture)( void ); int (*AvailableCaptureSamples)( void ); void (*Capture)( int samples, byte *data ); void (*StopCapture)( void ); void (*MasterGain)( float gain ); #endif } soundInterface_t; /* ==================================================================== SYSTEM SPECIFIC FUNCTIONS ==================================================================== */ // initializes cycling through a DMA buffer and returns information on it bool SNDDMA_Init(void); // gets the current DMA position int SNDDMA_GetDMAPos(void); // shutdown the DMA xfer. void SNDDMA_Shutdown(void); void SNDDMA_BeginPainting (void); void SNDDMA_Submit(void); //==================================================================== #define MAX_CHANNELS 96 extern channel_t s_channels[MAX_CHANNELS]; extern channel_t loop_channels[MAX_CHANNELS]; extern int numLoopChannels; extern int s_paintedtime; extern vec3_t listener_forward; extern vec3_t listener_right; extern vec3_t listener_up; extern dma_t dma; #define MAX_RAW_SAMPLES 16384 #define MAX_RAW_STREAMS (MAX_CLIENTS * 2 + 1) extern portable_samplepair_t s_rawsamples[MAX_RAW_STREAMS][MAX_RAW_SAMPLES]; extern int s_rawend[MAX_RAW_STREAMS]; extern cvar_t *s_volume; extern cvar_t *s_musicVolume; extern cvar_t *s_muted; extern cvar_t *s_doppler; extern cvar_t *s_testsound; bool S_LoadSound( sfx_t *sfx ); void SND_free(sndBuffer *v); sndBuffer* SND_malloc( void ); void SND_setup( void ); void SND_shutdown(void); void S_PaintChannels(int endtime); void S_memoryLoad(sfx_t *sfx); // spatializes a channel void S_Spatialize(channel_t *ch); // adpcm functions int S_AdpcmMemoryNeeded( const wavinfo_t *info ); void S_AdpcmEncodeSound( sfx_t *sfx, short *samples ); void S_AdpcmGetSamples(sndBuffer *chunk, short *to); // wavelet function #define SENTINEL_MULAW_ZERO_RUN 127 #define SENTINEL_MULAW_FOUR_BIT_RUN 126 void S_FreeOldestSound( void ); #define NXStream byte void encodeWavelet(sfx_t *sfx, short *packets); void decodeWavelet( sndBuffer *stream, short *packets); void encodeMuLaw( sfx_t *sfx, short *packets); extern short mulawToShort[256]; extern short *sfxScratchBuffer; extern sfx_t *sfxScratchPointer; extern int sfxScratchIndex; bool S_Base_Init( soundInterface_t *si ); // OpenAL stuff typedef enum { SRCPRI_AMBIENT = 0, // Ambient sound effects SRCPRI_ENTITY, // Entity sound effects SRCPRI_ONESHOT, // One-shot sounds SRCPRI_LOCAL, // Local sounds SRCPRI_STREAM // Streams (music, cutscenes) } alSrcPriority_t; typedef int srcHandle_t; bool S_AL_Init( soundInterface_t *si ); #endif