X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=snd_dma.c;h=6dbc1ea299b202619dcba20192876bbf96b03cc8;hb=a1e05a11f1c94c609e55a1a25d72e5ed2eaf5ecb;hp=29bb664b5a06e064273019fab6b51e40a513b5bb;hpb=182da1050452db7352b3e8c32b5c0cac065b698a;p=xonotic%2Fdarkplaces.git diff --git a/snd_dma.c b/snd_dma.c index 29bb664b..6dbc1ea2 100644 --- a/snd_dma.c +++ b/snd_dma.c @@ -22,10 +22,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" #ifdef _WIN32 -#include "winquake.h" +#include +#include +extern DWORD gSndBufSize; +extern LPDIRECTSOUND pDS; +extern LPDIRECTSOUNDBUFFER pDSBuf; #endif -#include "ogg.h" +#include "snd_ogg.h" void S_Play(void); @@ -41,11 +45,12 @@ void S_StopAllSoundsC(void); // ======================================================================= channel_t channels[MAX_CHANNELS]; -int total_channels; +unsigned int total_channels; int snd_blocked = 0; static qboolean snd_ambient = 1; cvar_t snd_initialized = { CVAR_READONLY, "snd_initialized", "0"}; +cvar_t snd_streaming = { CVAR_SAVE, "snd_streaming", "1"}; // pointer should go away volatile dma_t *shm = 0; @@ -118,17 +123,17 @@ void S_SoundInfo_f(void) { if (!sound_started || !shm) { - Con_Printf ("sound system not started\n"); + Con_Print("sound system not started\n"); return; } - Con_Printf("%5d stereo\n", shm->channels - 1); + Con_Printf("%5d stereo\n", shm->format.channels - 1); Con_Printf("%5d samples\n", shm->samples); Con_Printf("%5d samplepos\n", shm->samplepos); - Con_Printf("%5d samplebits\n", shm->samplebits); - Con_Printf("%5d speed\n", shm->speed); + Con_Printf("%5d samplebits\n", shm->format.width * 8); + Con_Printf("%5d speed\n", shm->format.speed); Con_Printf("0x%x dma buffer\n", shm->buffer); - Con_Printf("%5d total_channels\n", total_channels); + Con_Printf("%5u total_channels\n", total_channels); } void S_UnloadSounds(void) @@ -157,18 +162,18 @@ void S_Startup(void) if (fakedma) { - shm->samplebits = 16; - shm->speed = 22050; - shm->channels = 2; + shm->format.width = 2; + shm->format.speed = 22050; + shm->format.channels = 2; shm->samples = 32768; shm->samplepos = 0; - shm->buffer = Mem_Alloc(snd_mempool, shm->channels * shm->samples * (shm->samplebits / 8)); + shm->buffer = Mem_Alloc(snd_mempool, shm->format.channels * shm->samples * shm->format.width); } else { if (!SNDDMA_Init()) { - Con_Printf("S_Startup: SNDDMA_Init failed.\n"); + Con_Print("S_Startup: SNDDMA_Init failed.\n"); sound_started = 0; shm = NULL; return; @@ -177,7 +182,7 @@ void S_Startup(void) sound_started = 1; - Con_DPrintf("Sound sampling rate: %i\n", shm->speed); + Con_DPrintf("Sound sampling rate: %i\n", shm->format.speed); //S_LoadSounds(); @@ -213,7 +218,7 @@ S_Init */ void S_Init(void) { - Con_DPrintf("\nSound Initialization\n"); + Con_DPrint("\nSound Initialization\n"); S_RawSamples_ClearQueue(); @@ -240,6 +245,7 @@ void S_Init(void) Cvar_RegisterVariable(&nosound); Cvar_RegisterVariable(&snd_precache); Cvar_RegisterVariable(&snd_initialized); + Cvar_RegisterVariable(&snd_streaming); Cvar_RegisterVariable(&bgmbuffer); Cvar_RegisterVariable(&ambient_level); Cvar_RegisterVariable(&ambient_fade); @@ -271,7 +277,7 @@ void S_Init(void) /* ========= -S_IsCached +S_GetCached ========= */ @@ -325,7 +331,7 @@ sfx_t *S_FindName (char *name) sfx = &known_sfx[num_sfx++]; memset(sfx, 0, sizeof(*sfx)); - snprintf(sfx->name, sizeof(sfx->name), "%s", name); + strncpy(sfx->name, name, sizeof(sfx->name)); return sfx; } @@ -338,9 +344,53 @@ S_TouchSound */ void S_TouchSound (char *name) { - S_FindName(name); + sfx_t *sfx; + + sfx = S_FindName (name); + + // Set the "used" flag for this sound + if (sfx != NULL) + sfx->flags |= SFXFLAG_USED; +} + + +/* +================== +S_ClearUsed + +Reset the "used" flag of all precached sounds +================== +*/ +void S_ClearUsed (void) +{ + int i; + + for (i = 0; i < num_sfx; i++) + known_sfx[i].flags &= ~SFXFLAG_USED; } + +/* +================== +S_PurgeUnused + +Free all precached sounds without the "used" flag +================== +*/ +void S_PurgeUnused (void) +{ + int i; + sfx_t *sfx; + + for (i = 0; i < num_sfx; i++) + { + sfx = &known_sfx[i]; + if (! (sfx->flags & SFXFLAG_USED)) + S_UnloadSound (sfx); + } +} + + /* ================== S_PrecacheSound @@ -368,6 +418,8 @@ sfx_t *S_PrecacheSound (char *name, int complain) /* ================= SND_PickChannel + +Picks a channel based on priorities, empty slots, number of channels ================= */ channel_t *SND_PickChannel(int entnum, int entchannel) @@ -375,27 +427,33 @@ channel_t *SND_PickChannel(int entnum, int entchannel) int ch_idx; int first_to_die; int life_left; + channel_t* ch; // Check for replacement sound, or find the best one to replace first_to_die = -1; life_left = 0x7fffffff; for (ch_idx=NUM_AMBIENTS ; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS ; ch_idx++) { + ch = &channels[ch_idx]; if (entchannel != 0 // channel 0 never overrides - && channels[ch_idx].entnum == entnum - && (channels[ch_idx].entchannel == entchannel || entchannel == -1) ) + && ch->entnum == entnum + && (ch->entchannel == entchannel || entchannel == -1) ) { // always override sound from same entity first_to_die = ch_idx; break; } // don't let monster sounds override player sounds - if (channels[ch_idx].entnum == cl.viewentity && entnum != cl.viewentity && channels[ch_idx].sfx) + if (ch->entnum == cl.viewentity && entnum != cl.viewentity && ch->sfx) continue; - if (channels[ch_idx].end - paintedtime < life_left) + // don't override looped sounds + if (ch->forceloop || (ch->sfx != NULL && ch->sfx->loopstart >= 0)) + continue; + + if (ch->end - paintedtime < life_left) { - life_left = channels[ch_idx].end - paintedtime; + life_left = ch->end - paintedtime; first_to_die = ch_idx; } } @@ -412,6 +470,8 @@ channel_t *SND_PickChannel(int entnum, int entchannel) /* ================= SND_Spatialize + +Spatializes a channel ================= */ void SND_Spatialize(channel_t *ch, int isstatic) @@ -469,12 +529,11 @@ void SND_Spatialize(channel_t *ch, int isstatic) void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation) { channel_t *target_chan, *check; - sfxcache_t *sc; int vol; int ch_idx; - int skip; + size_t skip; - if (!sound_started || !sfx || nosound.integer) + if (!sound_started || !sfx || !sfx->fetcher || nosound.integer) return; vol = fvol*255; @@ -497,9 +556,8 @@ void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float f //if (!target_chan->leftvol && !target_chan->rightvol) // return; // not audible at all -// new channel - sc = S_LoadSound (sfx, true); - if (!sc) + // new channel + if (!S_LoadSound (sfx, true)) { target_chan->sfx = NULL; return; // couldn't load the sound's data @@ -507,7 +565,8 @@ void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float f target_chan->sfx = sfx; target_chan->pos = 0.0; - target_chan->end = paintedtime + sc->length; + target_chan->end = paintedtime + sfx->total_length; + target_chan->lastptime = paintedtime; // if an identical sound has also been started this frame, offset the pos // a bit to keep it from just making the first one louder @@ -519,9 +578,9 @@ void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float f if (check->sfx == sfx && !check->pos) { // LordHavoc: fixed skip calculations - skip = 0.1 * sc->speed; - if (skip > sc->length) - skip = sc->length; + skip = 0.1 * sfx->format.speed; + if (skip > sfx->total_length) + skip = sfx->total_length; if (skip > 0) skip = rand() % skip; target_chan->pos += skip; @@ -568,7 +627,7 @@ void S_ClearBuffer(void) if (!sound_started || !shm) return; - if (shm->samplebits == 8) + if (shm->format.width == 1) clear = 0x80; else clear = 0; @@ -583,24 +642,24 @@ void S_ClearBuffer(void) reps = 0; - while ((hresult = pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, &pData, &dwSize, NULL, NULL, 0)) != DS_OK) + while ((hresult = pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, (LPVOID*)&pData, &dwSize, NULL, NULL, 0)) != DS_OK) { if (hresult != DSERR_BUFFERLOST) { - Con_Printf ("S_ClearBuffer: DS::Lock Sound Buffer Failed\n"); + Con_Print("S_ClearBuffer: DS::Lock Sound Buffer Failed\n"); S_Shutdown (); return; } if (++reps > 10000) { - Con_Printf ("S_ClearBuffer: DS: couldn't restore buffer\n"); + Con_Print("S_ClearBuffer: DS: couldn't restore buffer\n"); S_Shutdown (); return; } } - memset(pData, clear, shm->samples * shm->samplebits/8); + memset(pData, clear, shm->samples * shm->format.width); pDSBuf->lpVtbl->Unlock(pDSBuf, pData, dwSize, NULL, 0); @@ -609,7 +668,7 @@ void S_ClearBuffer(void) #endif if (shm->buffer) { - int setsize = shm->samples * shm->samplebits / 8; + int setsize = shm->samples * shm->format.width; char *buf = shm->buffer; while (setsize--) @@ -631,22 +690,20 @@ S_StaticSound void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation) { channel_t *ss; - sfxcache_t *sc; if (!sfx) return; if (total_channels == MAX_CHANNELS) { - Con_Printf ("total_channels == MAX_CHANNELS\n"); + Con_Print("total_channels == MAX_CHANNELS\n"); return; } - sc = S_LoadSound (sfx, true); - if (!sc) + if (!S_LoadSound (sfx, true)) return; - if (sc->loopstart == -1) + if (sfx->loopstart == -1) Con_DPrintf("Quake compatibility warning: Static sound \"%s\" is not looped\n", sfx->name); ss = &channels[total_channels++]; @@ -656,7 +713,8 @@ void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation) VectorCopy (origin, ss->origin); ss->master_vol = vol; ss->dist_mult = (attenuation/64) / sound_nominal_clip_dist; - ss->end = paintedtime + sc->length; + ss->end = paintedtime + sfx->total_length; + ss->lastptime = paintedtime; SND_Spatialize (ss, true); } @@ -688,7 +746,8 @@ void S_UpdateAmbientSounds (void) // calc ambient sound levels for (ambient_channel = 0 ; ambient_channel< NUM_AMBIENTS ; ambient_channel++) { - if (ambient_sfx[ambient_channel] && ambient_sfx[ambient_channel]->silentlymissing) + if (ambient_sfx[ambient_channel] && + (ambient_sfx[ambient_channel]->flags & SFXFLAG_SILENTLYMISSING)) continue; chan = &channels[ambient_channel]; chan->forceloop = true; @@ -726,10 +785,8 @@ Called once each time through the main loop */ void S_Update(vec3_t origin, vec3_t forward, vec3_t left, vec3_t up) { - int i, j; - int total; - channel_t *ch; - channel_t *combine; + unsigned int i, j, total; + channel_t *ch, *combine; if (!snd_initialized.integer || (snd_blocked > 0)) return; @@ -799,7 +856,7 @@ void S_Update(vec3_t origin, vec3_t forward, vec3_t left, vec3_t up) if (ch->sfx && (ch->leftvol || ch->rightvol) ) total++; - Con_Printf ("----(%i)----\n", total); + Con_Printf("----(%u)----\n", total); } // mix some sound @@ -813,16 +870,12 @@ void GetSoundtime(void) static int oldsamplepos; int fullsamples; - fullsamples = shm->samples / shm->channels; + fullsamples = shm->samples / shm->format.channels; // it is possible to miscount buffers if it has wrapped twice between // calls to S_Update. Oh well. -#ifdef __sun__ - soundtime = SNDDMA_GetSamples(); -#else samplepos = SNDDMA_GetDMAPos(); - if (samplepos < oldsamplepos) { buffers++; // buffer wrapped @@ -836,8 +889,7 @@ void GetSoundtime(void) } oldsamplepos = samplepos; - soundtime = buffers*fullsamples + samplepos/shm->channels; -#endif + soundtime = buffers * fullsamples + samplepos / shm->format.channels; } void IN_Accumulate (void); @@ -870,8 +922,8 @@ void S_Update_(void) paintedtime = soundtime; // mix ahead of current position - endtime = soundtime + _snd_mixahead.value * shm->speed; - samps = shm->samples >> (shm->channels-1); + endtime = soundtime + _snd_mixahead.value * shm->format.speed; + samps = shm->samples >> (shm->format.channels - 1); if (endtime > (unsigned int)(soundtime + samps)) endtime = soundtime + samps; @@ -882,8 +934,8 @@ void S_Update_(void) if (pDSBuf) { - if (pDSBuf->lpVtbl->GetStatus (pDSBuf, &dwStatus) != DD_OK) - Con_Printf ("Couldn't get sound buffer status\n"); + if (pDSBuf->lpVtbl->GetStatus (pDSBuf, &dwStatus) != DS_OK) + Con_Print("Couldn't get sound buffer status\n"); if (dwStatus & DSBSTATUS_BUFFERLOST) pDSBuf->lpVtbl->Restore (pDSBuf); @@ -954,18 +1006,16 @@ void S_SoundList(void) { int i; sfx_t *sfx; - sfxcache_t *sc; int size, total; total = 0; for (sfx=known_sfx, i=0 ; isfxcache; - if (sc) + if (sfx->fetcher != NULL) { - size = sc->length*sc->width*(sc->stereo+1); + size = sfx->mempool->totalsize; total += size; - Con_Printf("%c(%2db) %6i : %s\n", sc->loopstart >= 0 ? 'L' : ' ',sc->width*8, size, sfx->name); + Con_Printf("%c(%2db) %7i : %s\n", sfx->loopstart >= 0 ? 'L' : ' ', sfx->format.width * 8, size, sfx->name); } } Con_Printf("Total resident: %i\n", total); @@ -982,32 +1032,17 @@ void S_LocalSound (char *sound) sfx = S_PrecacheSound (sound, true); if (!sfx) { - Con_Printf ("S_LocalSound: can't precache %s\n", sound); + Con_Printf("S_LocalSound: can't precache %s\n", sound); return; } S_StartSound (cl.viewentity, -1, sfx, vec3_origin, 1, 1); } -void S_ClearPrecache (void) -{ -} - - -void S_BeginPrecaching (void) -{ -} - - -void S_EndPrecaching (void) -{ -} - - #define RAWSAMPLESBUFFER 32768 short s_rawsamplesbuffer[RAWSAMPLESBUFFER * 2]; int s_rawsamplesbuffer_start; -int s_rawsamplesbuffer_count; +size_t s_rawsamplesbuffer_count; void S_RawSamples_Enqueue(short *samples, unsigned int length) { @@ -1029,7 +1064,8 @@ void S_RawSamples_Enqueue(short *samples, unsigned int length) void S_RawSamples_Dequeue(int *samples, unsigned int length) { - int b1, b2, l; + int b1, b2; + size_t l; int i; short *in; int *out; @@ -1073,7 +1109,7 @@ void S_RawSamples_ClearQueue(void) int S_RawSamples_QueueWantsMore(void) { - if (shm != NULL && s_rawsamplesbuffer_count < min(shm->speed >> 1, RAWSAMPLESBUFFER >> 1)) + if (shm != NULL && s_rawsamplesbuffer_count < min(shm->format.speed >> 1, RAWSAMPLESBUFFER >> 1)) return RAWSAMPLESBUFFER - s_rawsamplesbuffer_count; else return 0; @@ -1111,6 +1147,6 @@ void S_ResampleBuffer16Stereo(short *input, int inputlength, short *output, int int S_RawSamples_SampleRate(void) { - return shm != NULL ? shm->speed : 0; + return shm != NULL ? shm->format.speed : 0; }