X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=snd_dma.c;h=5825fc6246659142554af18d837c995ea634734b;hb=acb576bdab16f8244b87f7c12f85924154e83c5f;hp=071710e204fe16f43807817eb2e3c5cc27ac5ec3;hpb=af4d8d7892ace10b13321577a55dc0630e315129;p=xonotic%2Fdarkplaces.git diff --git a/snd_dma.c b/snd_dma.c index 071710e2..5825fc62 100644 --- a/snd_dma.c +++ b/snd_dma.c @@ -21,10 +21,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" -#ifdef _WIN32 -#include "winquake.h" +#ifdef USE_DSOUND +#include +#include +extern DWORD gSndBufSize; +extern LPDIRECTSOUND pDS; +extern LPDIRECTSOUNDBUFFER pDSBuf; #endif +#include "snd_ogg.h" + + void S_Play(void); void S_PlayVol(void); void S_Play2(void); @@ -33,25 +40,26 @@ void S_Update_(); void S_StopAllSounds(qboolean clear); void S_StopAllSoundsC(void); +void S_ClearBuffer (void); + + // ======================================================================= // Internal sound data & structures // ======================================================================= channel_t channels[MAX_CHANNELS]; -int total_channels; +unsigned int total_channels; int snd_blocked = 0; -static qboolean snd_ambient = 1; -qboolean snd_initialized = false; +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; volatile dma_t sn; vec3_t listener_origin; -vec3_t listener_forward; -vec3_t listener_right; -vec3_t listener_up; +matrix4x4_t listener_matrix; vec_t sound_nominal_clip_dist=1000.0; mempool_t *snd_mempool; @@ -99,33 +107,21 @@ qboolean fakedma = false; int fakedma_updates = 15; -void S_AmbientOff (void) -{ - snd_ambient = false; -} - - -void S_AmbientOn (void) -{ - snd_ambient = true; -} - - 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("0x%x dma buffer\n", shm->buffer); - Con_Printf("%5d total_channels\n", total_channels); + Con_Printf("%5d samplebits\n", shm->format.width * 8); + Con_Printf("%5d speed\n", shm->format.speed); + Con_Printf("%p dma buffer\n", shm->buffer); + Con_Printf("%5u total_channels\n", total_channels); } void S_UnloadSounds(void) @@ -144,7 +140,7 @@ void S_LoadSounds(void) void S_Startup(void) { - if (!snd_initialized) + if (!snd_initialized.integer) return; shm = &sn; @@ -154,18 +150,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; @@ -174,7 +170,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(); @@ -210,9 +206,7 @@ S_Init */ void S_Init(void) { - Con_DPrintf("\nSound Initialization\n"); - - S_RawSamples_ClearQueue(); + Con_DPrint("\nSound Initialization\n"); Cvar_RegisterVariable(&volume); Cvar_RegisterVariable(&bgmvolume); @@ -221,7 +215,7 @@ void S_Init(void) if (COM_CheckParm("-nosound") || COM_CheckParm("-safe")) return; - snd_mempool = Mem_AllocPool("sound"); + snd_mempool = Mem_AllocPool("sound", 0, NULL); if (COM_CheckParm("-simsound")) fakedma = true; @@ -236,6 +230,8 @@ 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); @@ -244,18 +240,20 @@ void S_Init(void) Cvar_RegisterVariable(&_snd_mixahead); Cvar_RegisterVariable(&snd_swapstereo); // LordHavoc: for people with backwards sound wiring - snd_initialized = true; + Cvar_SetValueQuick(&snd_initialized, true); known_sfx = Mem_Alloc(snd_mempool, MAX_SFX*sizeof(sfx_t)); num_sfx = 0; SND_InitScaletable (); - ambient_sfx[AMBIENT_WATER] = S_PrecacheSound ("ambience/water1.wav", false); - ambient_sfx[AMBIENT_SKY] = S_PrecacheSound ("ambience/wind2.wav", false); + ambient_sfx[AMBIENT_WATER] = S_PrecacheSound ("ambience/water1.wav", false, true); + ambient_sfx[AMBIENT_SKY] = S_PrecacheSound ("ambience/wind2.wav", false, true); total_channels = MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; // no statics memset(channels, 0, MAX_CHANNELS * sizeof(channel_t)); + + OGG_OpenLibrary (); } @@ -264,33 +262,60 @@ void S_Init(void) // ======================================================================= /* -================== -S_FindName +========= +S_GetCached -================== +========= */ -sfx_t *S_FindName (char *name) +sfx_t *S_GetCached (const char *name, qboolean stdpath) { + char namebuffer [MAX_QPATH]; + size_t len; int i; - sfx_t *sfx; + + if (!snd_initialized.integer) + return NULL; if (!name) - Host_Error("S_FindName: NULL\n"); + Host_Error("S_GetCached: NULL"); - if (strlen(name) >= MAX_QPATH) - Host_Error("Sound name too long: %s", name); + // Add the default sound directory to the path + len = snprintf (namebuffer, sizeof (namebuffer), stdpath ? "sound/%s" : "%s", name); + if (len >= sizeof (namebuffer)) + Host_Error ("S_GetCached: sound name too long (%s)", name); -// see if already loaded - for (i = 0;i < num_sfx;i++) - if (!strcmp(known_sfx[i].name, name)) + for(i = 0;i < num_sfx;i++) + if(!strcmp(known_sfx[i].name, namebuffer)) return &known_sfx[i]; - if (num_sfx == MAX_SFX) - Sys_Error("S_FindName: out of sfx_t"); + return NULL; +} + +/* +================== +S_FindName - sfx = &known_sfx[num_sfx++]; - memset(sfx, 0, sizeof(*sfx)); - snprintf(sfx->name, sizeof(sfx->name), "%s", name); +================== +*/ +sfx_t *S_FindName (const char *name, qboolean stdpath) +{ + sfx_t *sfx; + + if (!snd_initialized.integer) + return NULL; + + sfx = S_GetCached (name, stdpath); + + // If we haven't allocated a sfx_t struct for it yet + if (sfx == NULL) + { + if (num_sfx == MAX_SFX) + Sys_Error ("S_FindName: out of sfx_t"); + + sfx = &known_sfx[num_sfx++]; + memset (sfx, 0, sizeof(*sfx)); + snprintf (sfx->name, sizeof (sfx->name), stdpath ? "sound/%s" : "%s", name); + } return sfx; } @@ -301,24 +326,71 @@ S_TouchSound ================== */ -void S_TouchSound (char *name) +void S_TouchSound (const char *name, qboolean stdpath) { - S_FindName(name); + sfx_t *sfx; + + sfx = S_FindName (name, stdpath); + + // 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 ================== */ -sfx_t *S_PrecacheSound (char *name, int complain) +sfx_t *S_PrecacheSound (const char *name, qboolean complain, qboolean stdpath) { sfx_t *sfx; - sfx = S_FindName(name); + if (!snd_initialized.integer) + return NULL; + + sfx = S_FindName (name, stdpath); - if (snd_initialized && !nosound.integer && snd_precache.integer) + if (!nosound.integer && snd_precache.integer) S_LoadSound(sfx, complain); return sfx; @@ -330,6 +402,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) @@ -337,27 +411,34 @@ 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; + + // don't override looped sounds + if ((ch->flags & CHANNELFLAG_FORCELOOP) != 0 || + (ch->sfx != NULL && ch->sfx->loopstart >= 0)) continue; - if (channels[ch_idx].end - paintedtime < life_left) + if (ch->end - paintedtime < life_left) { - life_left = channels[ch_idx].end - paintedtime; + life_left = ch->end - paintedtime; first_to_die = ch_idx; } } @@ -374,6 +455,8 @@ channel_t *SND_PickChannel(int entnum, int entchannel) /* ================= SND_Spatialize + +Spatializes a channel ================= */ void SND_Spatialize(channel_t *ch, int isstatic) @@ -395,20 +478,20 @@ void SND_Spatialize(channel_t *ch, int isstatic) { //Con_Printf("-- entnum %i origin %f %f %f neworigin %f %f %f\n", ch->entnum, ch->origin[0], ch->origin[1], ch->origin[2], cl_entities[ch->entnum].state_current.origin[0], cl_entities[ch->entnum].state_current.origin[1], cl_entities[ch->entnum].state_current.origin[2]); VectorCopy(cl_entities[ch->entnum].state_current.origin, ch->origin); - if (cl_entities[ch->entnum].state_current.modelindex && cl.model_precache[cl_entities[ch->entnum].state_current.modelindex]->brush.TraceBox) + if (cl_entities[ch->entnum].state_current.modelindex && cl.model_precache[cl_entities[ch->entnum].state_current.modelindex]->soundfromcenter) VectorMAMAM(1.0f, ch->origin, 0.5f, cl.model_precache[cl_entities[ch->entnum].state_current.modelindex]->normalmins, 0.5f, cl.model_precache[cl_entities[ch->entnum].state_current.modelindex]->normalmaxs, ch->origin); } // calculate stereo seperation and distance attenuation - VectorSubtract(ch->origin, listener_origin, source_vec); + Matrix4x4_Transform(&listener_matrix, ch->origin, source_vec); dist = VectorNormalizeLength(source_vec); // distance scale = ch->master_vol * (1.0 - (dist * ch->dist_mult)); // panning - pan = scale * DotProduct(listener_right, source_vec); + pan = scale * source_vec[1]; // calculate the volumes - ch->leftvol = (int) (scale - pan); - ch->rightvol = (int) (scale + pan); + ch->leftvol = (int) (scale + pan); + ch->rightvol = (int) (scale - pan); } // LordHavoc: allow adjusting volume of static sounds @@ -428,23 +511,22 @@ void SND_Spatialize(channel_t *ch, int isstatic) // Start a sound effect // ======================================================================= -void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation) +int 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) - return; + if (!sound_started || !sfx || !sfx->fetcher || nosound.integer) + return -1; vol = fvol*255; // pick a channel to play on target_chan = SND_PickChannel(entnum, entchannel); if (!target_chan) - return; + return -1; // spatialize memset (target_chan, 0, sizeof(*target_chan)); @@ -455,20 +537,22 @@ void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float f target_chan->entchannel = entchannel; SND_Spatialize(target_chan, false); - if (!target_chan->leftvol && !target_chan->rightvol) - return; // not audible at all + // LordHavoc: spawn the sound anyway because the player might teleport to it + //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 + return -1; // couldn't load the sound's data } target_chan->sfx = sfx; + target_chan->flags = CHANNELFLAG_NONE; 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 @@ -480,9 +564,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; @@ -490,26 +574,66 @@ void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float f break; } } + + return (target_chan - channels); } -void S_StopSound(int entnum, int entchannel) +void S_StopChannel (unsigned int channel_ind) { - int i; + channel_t *ch; + + if (channel_ind >= total_channels) + return; - for (i=0 ; isfx != NULL) { - if (channels[i].entnum == entnum - && channels[i].entchannel == entchannel) + if (ch->sfx->fetcher != NULL) { - channels[i].end = 0; - channels[i].sfx = NULL; - return; + snd_fetcher_end_t fetcher_end = ch->sfx->fetcher->end; + if (fetcher_end != NULL) + fetcher_end (ch); } + ch->sfx = NULL; } + ch->end = 0; +} + +void S_PauseChannel (unsigned int channel_ind, qboolean toggle) +{ + if (toggle) + channels[channel_ind].flags |= CHANNELFLAG_PAUSED; + else + channels[channel_ind].flags &= ~CHANNELFLAG_PAUSED; +} + +void S_LoopChannel (unsigned int channel_ind, qboolean toggle) +{ + if (toggle) + channels[channel_ind].flags |= CHANNELFLAG_FORCELOOP; + else + channels[channel_ind].flags &= ~CHANNELFLAG_FORCELOOP; +} + +void S_StopSound(int entnum, int entchannel) +{ + unsigned int i; + + for (i = 0; i < MAX_DYNAMIC_CHANNELS; i++) + if (channels[i].entnum == entnum && channels[i].entchannel == entchannel) + { + S_StopChannel (i); + return; + } } void S_StopAllSounds(qboolean clear) { + unsigned int i; + + for (i = 0; i < total_channels; i++) + S_StopChannel (i); + total_channels = MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; // no statics memset(channels, 0, MAX_CHANNELS * sizeof(channel_t)); @@ -522,6 +646,40 @@ void S_StopAllSoundsC(void) S_StopAllSounds(true); } +void S_PauseGameSounds (void) +{ + unsigned int i; + + for (i = 0; i < total_channels; i++) + { + channel_t *ch; + + ch = &channels[i]; + if (ch->sfx != NULL && ! (ch->flags & CHANNELFLAG_LOCALSOUND)) + ch->flags |= CHANNELFLAG_PAUSED; + } +} + +void S_ResumeGameSounds (void) +{ + unsigned int i; + + for (i = 0; i < total_channels; i++) + { + channel_t *ch; + + ch = &channels[i]; + if (ch->sfx != NULL && ! (ch->flags & CHANNELFLAG_LOCALSOUND)) + ch->flags &= ~CHANNELFLAG_PAUSED; + } +} + +void S_SetChannelVolume (unsigned int ch_ind, float fvol) +{ + channels[ch_ind].master_vol = fvol * 255; +} + + void S_ClearBuffer(void) { int clear; @@ -529,12 +687,12 @@ void S_ClearBuffer(void) if (!sound_started || !shm) return; - if (shm->samplebits == 8) + if (shm->format.width == 1) clear = 0x80; else clear = 0; -#ifdef _WIN32 +#ifdef USE_DSOUND if (pDSBuf) { DWORD dwSize; @@ -544,24 +702,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); @@ -570,7 +728,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--) @@ -592,32 +750,31 @@ 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++]; memset(ss, 0, sizeof(*ss)); - ss->forceloop = true; + ss->flags = CHANNELFLAG_FORCELOOP; ss->sfx = sfx; 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); } @@ -641,7 +798,7 @@ void S_UpdateAmbientSounds (void) for (ambient_channel = 0 ; ambient_channel < NUM_AMBIENTS;ambient_channel++) channels[ambient_channel].sfx = NULL; - if (!snd_ambient || ambient_level.value <= 0 || !cl.worldmodel || !cl.worldmodel->brush.AmbientSoundLevelsForPoint) + if (ambient_level.value <= 0 || !cl.worldmodel || !cl.worldmodel->brush.AmbientSoundLevelsForPoint) return; cl.worldmodel->brush.AmbientSoundLevelsForPoint(cl.worldmodel, listener_origin, ambientlevels, sizeof(ambientlevels)); @@ -649,10 +806,11 @@ 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; + chan->flags |= CHANNELFLAG_FORCELOOP; chan->sfx = ambient_sfx[ambient_channel]; vol = ambient_level.value * ambientlevels[ambient_channel]; @@ -685,20 +843,16 @@ S_Update Called once each time through the main loop ============ */ -void S_Update(vec3_t origin, vec3_t forward, vec3_t right, vec3_t up) +void S_Update(const matrix4x4_t *listenermatrix) { - int i, j; - int total; - channel_t *ch; - channel_t *combine; + unsigned int i, j, total; + channel_t *ch, *combine; - if (!snd_initialized || (snd_blocked > 0)) + if (!snd_initialized.integer || (snd_blocked > 0)) return; - VectorCopy(origin, listener_origin); - VectorCopy(forward, listener_forward); - VectorCopy(right, listener_right); - VectorCopy(up, listener_up); + Matrix4x4_Invert_Simple(&listener_matrix, listenermatrix); + Matrix4x4_OriginFromMatrix(listenermatrix, listener_origin); // update general area ambient sound sources S_UpdateAmbientSounds (); @@ -760,7 +914,7 @@ void S_Update(vec3_t origin, vec3_t forward, vec3_t right, vec3_t up) if (ch->sfx && (ch->leftvol || ch->rightvol) ) total++; - Con_Printf ("----(%i)----\n", total); + Con_Printf("----(%u)----\n", total); } // mix some sound @@ -774,16 +928,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 @@ -797,8 +947,7 @@ void GetSoundtime(void) } oldsamplepos = samplepos; - soundtime = buffers*fullsamples + samplepos/shm->channels; -#endif + soundtime = buffers * fullsamples + samplepos / shm->format.channels; } void IN_Accumulate (void); @@ -806,7 +955,7 @@ void IN_Accumulate (void); void S_ExtraUpdate (void) { -#ifdef _WIN32 +#ifdef USE_DSOUND IN_Accumulate (); #endif @@ -831,20 +980,20 @@ 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; -#ifdef _WIN32 +#ifdef USE_DSOUND // if the buffer was lost or stopped, restore it and/or restart it { DWORD dwStatus; 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); @@ -868,9 +1017,9 @@ console functions =============================================================================== */ -void S_Play(void) +static void S_Play_Common(float fvol, float attenuation) { - int i; + int i, ch_ind; char name[256]; sfx_t *sfx; @@ -878,225 +1027,83 @@ void S_Play(void) while (i= 0) + channels[ch_ind].flags |= CHANNELFLAG_LOCALSOUND; } } -void S_Play2(void) +void S_Play(void) { - int i; - char name[256]; - sfx_t *sfx; + S_Play_Common (1.0f, 1.0f); +} - i = 1; - while (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%c(%2db, %6s) %8i : %s\n", + (sfx->loopstart >= 0) ? 'L' : ' ', + (sfx->flags & SFXFLAG_STREAMED) ? 'S' : ' ', + sfx->format.width * 8, + (sfx->format.channels == 2) ? "stereo" : "mono", + size, + sfx->name); } } Con_Printf("Total resident: %i\n", total); } -void S_LocalSound (char *sound) +void S_LocalSound (const char *sound, qboolean stdpath) { sfx_t *sfx; + int ch_ind; - if (!snd_initialized || nosound.integer) + if (!snd_initialized.integer || nosound.integer) return; - sfx = S_PrecacheSound (sound, true); + sfx = S_PrecacheSound (sound, true, stdpath); if (!sfx) { - 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; - -void S_RawSamples_Enqueue(short *samples, unsigned int length) -{ - int b2, b3; - //Con_Printf("S_RawSamples_Enqueue: %i samples\n", length); - if (s_rawsamplesbuffer_count + length > RAWSAMPLESBUFFER) + Con_Printf("S_LocalSound: can't precache %s\n", sound); return; - b2 = (s_rawsamplesbuffer_start + s_rawsamplesbuffer_count) % RAWSAMPLESBUFFER; - if (b2 + length > RAWSAMPLESBUFFER) - { - b3 = (b2 + length) % RAWSAMPLESBUFFER; - memcpy(s_rawsamplesbuffer + b2 * 2, samples, (RAWSAMPLESBUFFER - b2) * sizeof(short[2])); - memcpy(s_rawsamplesbuffer, samples + (RAWSAMPLESBUFFER - b2) * 2, b3 * sizeof(short[2])); - } - else - memcpy(s_rawsamplesbuffer + b2 * 2, samples, length * sizeof(short[2])); - s_rawsamplesbuffer_count += length; -} - -void S_RawSamples_Dequeue(int *samples, unsigned int length) -{ - int b1, b2, l; - int i; - short *in; - int *out; - int count; - l = length; - if (l > s_rawsamplesbuffer_count) - l = s_rawsamplesbuffer_count; - b1 = (s_rawsamplesbuffer_start) % RAWSAMPLESBUFFER; - if (b1 + l > RAWSAMPLESBUFFER) - { - b2 = (b1 + l) % RAWSAMPLESBUFFER; - //memcpy(samples, s_rawsamplesbuffer + b1 * 2, (RAWSAMPLESBUFFER - b1) * sizeof(short[2])); - //memcpy(samples + (RAWSAMPLESBUFFER - b1) * 2, s_rawsamplesbuffer, b2 * sizeof(short[2])); - for (out = samples, in = s_rawsamplesbuffer + b1 * 2, count = (RAWSAMPLESBUFFER - b1) * 2, i = 0;i < count;i++) - out[i] = in[i]; - for (out = samples + (RAWSAMPLESBUFFER - b1) * 2, in = s_rawsamplesbuffer, count = b2 * 2, i = 0;i < count;i++) - out[i] = in[i]; - //Con_Printf("S_RawSamples_Dequeue: buffer wrap %i %i\n", (RAWSAMPLESBUFFER - b1), b2); } - else - { - //memcpy(samples, s_rawsamplesbuffer + b1 * 2, l * sizeof(short[2])); - for (out = samples, in = s_rawsamplesbuffer + b1 * 2, count = l * 2, i = 0;i < count;i++) - out[i] = in[i]; - //Con_Printf("S_RawSamples_Dequeue: normal %i\n", l); - } - if (l < (int)length) - { - memset(samples + l * 2, 0, (length - l) * sizeof(int[2])); - //Con_Printf("S_RawSamples_Dequeue: padding with %i samples\n", length - l); - } - s_rawsamplesbuffer_start = (s_rawsamplesbuffer_start + l) % RAWSAMPLESBUFFER; - s_rawsamplesbuffer_count -= l; -} -void S_RawSamples_ClearQueue(void) -{ - s_rawsamplesbuffer_count = 0; - s_rawsamplesbuffer_start = 0; + ch_ind = S_StartSound (cl.viewentity, 0, sfx, vec3_origin, 1, 1); + if (ch_ind >= 0) + channels[ch_ind].flags |= CHANNELFLAG_LOCALSOUND; } - -int S_RawSamples_QueueWantsMore(void) -{ - if (shm != NULL && s_rawsamplesbuffer_count < min(shm->speed >> 1, RAWSAMPLESBUFFER >> 1)) - return RAWSAMPLESBUFFER - s_rawsamplesbuffer_count; - else - return 0; -} - -void S_ResampleBuffer16Stereo(short *input, int inputlength, short *output, int outputlength) -{ - if (inputlength != outputlength) - { - int i, position, stopposition, step; - short *in, *out; - step = (float) inputlength * 256.0f / (float) outputlength; - position = 0; - stopposition = (inputlength - 1) << 8; - out = output; - for (i = 0;i < outputlength && position < stopposition;i++, position += step) - { - in = input + ((position >> 8) << 1); - out[0] = (((in[1] - in[0]) * (position & 255)) >> 8) + in[0]; - out[1] = (((in[3] - in[2]) * (position & 255)) >> 8) + in[2]; - out += 2; - } - stopposition = inputlength << 8; - for (i = 0;i < outputlength && position < stopposition;i++, position += step) - { - in = input + ((position >> 8) << 1); - out[0] = in[0]; - out[1] = in[2]; - out += 2; - } - } - else - memcpy(output, input, inputlength * sizeof(short[2])); -} - -int S_RawSamples_SampleRate(void) -{ - return shm != NULL ? shm->speed : 0; -} -