// S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation) public static void StartSound(int entnum, int entchannel, SFX sfx, ref Vector3 origin, float fvol, float attenuation) { if (!_SoundStarted || sfx == null) { return; } if (_NoSound.Value != 0) { return; } int vol = (int)(fvol * 255); // pick a channel to play on channel_t target_chan = PickChannel(entnum, entchannel); if (target_chan == null) { return; } // spatialize //memset (target_chan, 0, sizeof(*target_chan)); target_chan.origin = origin; target_chan.dist_mult = attenuation / _SoundNominalClipDist; target_chan.master_vol = vol; target_chan.entnum = entnum; target_chan.entchannel = entchannel; Spatialize(target_chan); if (target_chan.leftvol == 0 && target_chan.rightvol == 0) { return; // not audible at all } // new channel sfxcache_t sc = LoadSound(sfx); if (sc == null) { target_chan.sfx = null; return; // couldn't load the sound's data } target_chan.sfx = sfx; target_chan.pos = 0; target_chan.end = _PaintedTime + sc.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 for (int i = Ambients.NUM_AMBIENTS; i < Ambients.NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS; i++) { channel_t check = _Channels[i]; if (check == target_chan) { continue; } if (check.sfx == sfx && check.pos == 0) { int skip = Sys.Random((int)(0.1 * _shm.speed));// rand() % (int)(0.1 * shm->speed); if (skip >= target_chan.end) { skip = target_chan.end - 1; } target_chan.pos += skip; target_chan.end -= skip; break; } } }
// ResampleSfx static void ResampleSfx(SFX sfx, int inrate, int inwidth, ByteArraySegment data) { sfxcache_t sc = (sfxcache_t)Cache.Check(sfx.cache); if (sc == null) { return; } float stepscale = (float)inrate / _shm.speed; // this is usually 0.5, 1, or 2 int outcount = (int)(sc.length / stepscale); sc.length = outcount; if (sc.loopstart != -1) { sc.loopstart = (int)(sc.loopstart / stepscale); } sc.speed = _shm.speed; if (_LoadAs8bit.Value != 0) { sc.width = 1; } else { sc.width = inwidth; } sc.stereo = 0; sc.data = new byte[outcount * sc.width]; // uze: check this later!!! // resample / decimate to the current source rate byte[] src = data.Data; if (stepscale == 1 && inwidth == 1 && sc.width == 1) { // fast special case for (int i = 0; i < outcount; i++) { int v = src[data.StartIndex + i] - 128; sc.data[i] = (byte)((sbyte)v); //((signed char *)sc.data)[i] = (int)( (unsigned char)(data[i]) - 128); } } else { // general case int samplefrac = 0; int fracstep = (int)(stepscale * 256); int sample; short[] sa = new short[1]; for (int i = 0; i < outcount; i++) { int srcsample = samplefrac >> 8; samplefrac += fracstep; if (inwidth == 2) { Buffer.BlockCopy(src, data.StartIndex + srcsample * 2, sa, 0, 2); sample = Common.LittleShort(sa[0]);// ((short *)data)[srcsample] ); } else { sample = (int)(src[data.StartIndex + srcsample] - 128) << 8; //sample = (int)( (unsigned char)(data[srcsample]) - 128) << 8; } if (sc.width == 2) { sa[0] = (short)sample; Buffer.BlockCopy(sa, 0, sc.data, i * 2, 2); //((short *)sc->data)[i] = sample; } else { sc.data[i] = (byte)(sbyte)(sample >> 8); //((signed char *)sc->data)[i] = sample >> 8; } } } }