void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation) { channel_t *ss; sfxcache_t *sc; if (!shm || !sfx || s_nosound.value) return; if (total_channels == MAX_CHANNELS) { Com_Printf ("total_channels == MAX_CHANNELS\n"); return; } ss = &channels[total_channels]; total_channels++; sc = S_LoadSound (sfx); if (!sc) return; if (sc->loopstart == -1) { Com_Printf ("Sound %s not looped\n", sfx->name); return; } ss->sfx = sfx; VectorCopy (origin, ss->origin); ss->master_vol = (int) vol; ss->dist_mult = (attenuation/64) / sound_nominal_clip_dist; ss->end = paintedtime + (int) sc->total_length; SND_Spatialize (ss); }
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 ch_idx, skip; if (!shm || !sfx || s_nosound.value) return; // pick a channel to play on target_chan = SND_PickChannel(entnum, entchannel); if (!target_chan) return; // spatialize memset (target_chan, 0, sizeof(*target_chan)); VectorCopy(origin, target_chan->origin); target_chan->dist_mult = attenuation / sound_nominal_clip_dist; target_chan->master_vol = (int) (fvol * 255); target_chan->entnum = entnum; target_chan->entchannel = entchannel; SND_Spatialize(target_chan); if (!target_chan->leftvol && !target_chan->rightvol) return; // not audible at all // new channel sc = S_LoadSound (sfx); if (!sc) { target_chan->sfx = NULL; return; // couldn't load the sound's data } target_chan->sfx = sfx; target_chan->pos = 0.0; target_chan->end = paintedtime + (int) sc->total_length; // 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 check = &channels[NUM_AMBIENTS]; for (ch_idx=NUM_AMBIENTS; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS; ch_idx++, check++) { if (check == target_chan) continue; if (check->sfx == sfx && !check->pos) { skip = rand () % (int)(0.1 * shm->format.speed); if (skip >= target_chan->end) skip = target_chan->end - 1; target_chan->pos += skip; target_chan->end -= skip; break; } } }
/* ================= 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 ("StaticSound: MAX_CHANNELS reached\n"); Con_Printf (" failed at (%.2f, %.2f, %.2f)\n",origin[0],origin[1],origin[2]); return; } ss = &channels[total_channels]; total_channels++; sc = S_LoadSound (sfx); if (!sc) return; if (sc->loopstart == -1) { Con_Printf ("Sound %s not looped\n", sfx->name); return; } 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; SND_Spatialize (ss); }
/* ============ 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) { int i, j; int total; channel_t *ch; channel_t *combine; if (!sound_started || (snd_blocked > 0)) return; VectorCopy(origin, listener_origin); VectorCopy(forward, listener_forward); VectorCopy(right, listener_right); VectorCopy(up, listener_up); // update general area ambient sound sources S_UpdateAmbientSounds (); combine = NULL; // update spatialization for static and dynamic sounds ch = channels+NUM_AMBIENTS; for (i=NUM_AMBIENTS ; i<total_channels; i++, ch++) { if (!ch->sfx) continue; SND_Spatialize(ch); // respatialize channel if (!ch->leftvol && !ch->rightvol) continue; // try to combine static sounds with a previous channel of the same // sound effect so we don't mix five torches every frame if (i >= MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS) { // see if it can just use the last one if (combine && combine->sfx == ch->sfx) { combine->leftvol += ch->leftvol; combine->rightvol += ch->rightvol; ch->leftvol = ch->rightvol = 0; continue; } // search for one combine = channels+MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; for (j=MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS ; j<i; j++, combine++) if (combine->sfx == ch->sfx) break; if (j == total_channels) { combine = NULL; } else { if (combine != ch) { combine->leftvol += ch->leftvol; combine->rightvol += ch->rightvol; ch->leftvol = ch->rightvol = 0; } continue; } } } // // debugging output // if (snd_show.value) { total = 0; ch = channels; for (i=0 ; i<total_channels; i++, ch++) if (ch->sfx && (ch->leftvol || ch->rightvol) ) { Con_Printf ("%s %3i %3i\n", ch->sfx->name, ch->leftvol, ch->rightvol); total++; } Con_Printf ("----(%i)----\n", total); } // mix some sound S_Update_(); }