// SND_PaintChannelFrom8
        static void PaintChannelFrom8(channel_t ch, sfxcache_t sc, int count)
        {
            if (ch.leftvol > 255)
            {
                ch.leftvol = 255;
            }
            if (ch.rightvol > 255)
            {
                ch.rightvol = 255;
            }

            int lscale = ch.leftvol >> 3;
            int rscale = ch.rightvol >> 3;

            byte[] sfx    = sc.data;
            int    offset = ch.pos;

            for (int i = 0; i < count; i++)
            {
                int data = sfx[offset + i];
                _PaintBuffer[i].left  += _ScaleTable[lscale, data];
                _PaintBuffer[i].right += _ScaleTable[rscale, data];
            }
            ch.pos += count;
        }
Exemple #2
0
        // S_UpdateAmbientSounds
        static void UpdateAmbientSounds()
        {
            if (!_Ambient)
            {
                return;
            }

            // calc ambient sound levels
            if (Client.Cl.worldmodel == null)
            {
                return;
            }

            mleaf_t l = Mod.PointInLeaf(ref _ListenerOrigin, Client.Cl.worldmodel);

            if (l == null || _AmbientLevel.Value == 0)
            {
                for (int i = 0; i < Ambients.NUM_AMBIENTS; i++)
                {
                    _Channels[i].sfx = null;
                }

                return;
            }

            for (int i = 0; i < Ambients.NUM_AMBIENTS; i++)
            {
                channel_t chan = _Channels[i];
                chan.sfx = _AmbientSfx[i];

                float vol = _AmbientLevel.Value * l.ambient_sound_level[i];
                if (vol < 8)
                {
                    vol = 0;
                }

                // don't adjust volume too fast
                if (chan.master_vol < vol)
                {
                    chan.master_vol += (int)(Host.FrameTime * _AmbientFade.Value);
                    if (chan.master_vol > vol)
                    {
                        chan.master_vol = (int)vol;
                    }
                }
                else if (chan.master_vol > vol)
                {
                    chan.master_vol -= (int)(Host.FrameTime * _AmbientFade.Value);
                    if (chan.master_vol < vol)
                    {
                        chan.master_vol = (int)vol;
                    }
                }

                chan.leftvol = chan.rightvol = chan.master_vol;
            }
        }
Exemple #3
0
        // SND_Spatialize
        private static void Spatialize(channel_t ch)
        {
            // anything coming from the view entity will allways be full volume
            if (ch.entnum == client.cl.viewentity)
            {
                ch.leftvol  = ch.master_vol;
                ch.rightvol = ch.master_vol;
                return;
            }

            // calculate stereo seperation and distance attenuation
            sfx_t   snd        = ch.sfx;
            Vector3 source_vec = ch.origin - _ListenerOrigin;

            float dist = mathlib.Normalize(ref source_vec) * ch.dist_mult;
            float dot  = Vector3.Dot(_ListenerRight, source_vec);

            float rscale, lscale;

            if (_shm.channels == 1)
            {
                rscale = 1.0f;
                lscale = 1.0f;
            }
            else
            {
                rscale = 1.0f + dot;
                lscale = 1.0f - dot;
            }

            // add in distance effect
            float scale = (1.0f - dist) * rscale;

            ch.rightvol = (int)(ch.master_vol * scale);
            if (ch.rightvol < 0)
            {
                ch.rightvol = 0;
            }

            scale      = (1.0f - dist) * lscale;
            ch.leftvol = (int)(ch.master_vol * scale);
            if (ch.leftvol < 0)
            {
                ch.leftvol = 0;
            }
        }
        // SND_PaintChannelFrom16
        static void PaintChannelFrom16(channel_t ch, sfxcache_t sc, int count)
        {
            int leftvol  = ch.leftvol;
            int rightvol = ch.rightvol;

            byte[] sfx    = sc.data;
            int    offset = ch.pos * 2; // sfx = (signed short *)sc->data + ch->pos;

            for (int i = 0; i < count; i++)
            {
                int data  = (short)((ushort)sfx[offset] + ((ushort)sfx[offset + 1] << 8)); // Uze: check is this is right!!!
                int left  = (data * leftvol) >> 8;
                int right = (data * rightvol) >> 8;
                _PaintBuffer[i].left  += left;
                _PaintBuffer[i].right += right;
                offset += 2;
            }

            ch.pos += count;
        }
Exemple #5
0
        // S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation)
        public static void StaticSound(sfx_t sfx, ref Vector3 origin, float vol, float attenuation)
        {
            if (sfx == null)
            {
                return;
            }

            if (_TotalChannels == MAX_CHANNELS)
            {
                Con.Print("total_channels == MAX_CHANNELS\n");
                return;
            }

            channel_t ss = _Channels[_TotalChannels];

            _TotalChannels++;

            sfxcache_t sc = LoadSound(sfx);

            if (sc == null)
            {
                return;
            }

            if (sc.loopstart == -1)
            {
                Con.Print("Sound {0} not looped\n", sfx.name);
                return;
            }

            ss.sfx        = sfx;
            ss.origin     = origin;
            ss.master_vol = (int)vol;
            ss.dist_mult  = (attenuation / 64) / _SoundNominalClipDist;
            ss.end        = _PaintedTime + sc.length;

            Spatialize(ss);
        }
Exemple #6
0
        private static int _PlayVolHash = 543;                              // hash S_PlayVol

        // S_Init (void)
        public static void Init()
        {
            Con.Print("\nSound Initialization\n");

            if (common.HasParam("-nosound"))
            {
                return;
            }

            for (int i = 0; i < _Channels.Length; i++)
            {
                _Channels[i] = new channel_t();
            }

            cmd.Add("play", Play);
            cmd.Add("playvol", PlayVol);
            cmd.Add("stopsound", StopAllSoundsCmd);
            cmd.Add("soundlist", SoundList);
            cmd.Add("soundinfo", SoundInfo_f);

            _IsInitialized = true;

            Startup();

            InitScaletable();

            _NumSfx = 0;

            Con.Print("Sound sampling rate: {0}\n", _shm.speed);

            // provides a tick sound until washed clean
            _AmbientSfx[Ambients.AMBIENT_WATER] = PrecacheSound("ambience/water1.wav");
            _AmbientSfx[Ambients.AMBIENT_SKY]   = PrecacheSound("ambience/wind2.wav");

            StopAllSounds(true);
        }
Exemple #7
0
        // void S_Update (vec3_t origin, vec3_t v_forward, vec3_t v_right, vec3_t v_up)
        //
        // Called once each time through the main loop
        public static void Update(ref Vector3 origin, ref Vector3 forward, ref Vector3 right, ref Vector3 up)
        {
            if (!_IsInitialized || (_SoundBlocked > 0))
            {
                return;
            }

            _ListenerOrigin  = origin;
            _ListenerForward = forward;
            _ListenerRight   = right;
            _ListenerUp      = up;

            // update general area ambient sound sources
            UpdateAmbientSounds();

            channel_t combine = null;

            // update spatialization for static and dynamic sounds
            //channel_t ch = channels + NUM_AMBIENTS;
            for (int i = Ambients.NUM_AMBIENTS; i < _TotalChannels; i++)
            {
                channel_t ch = _Channels[i];// channels + NUM_AMBIENTS;
                if (ch.sfx == null)
                {
                    continue;
                }

                Spatialize(ch);    // respatialize channel
                if (ch.leftvol == 0 && ch.rightvol == 0)
                {
                    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 + Ambients.NUM_AMBIENTS)
                {
                    // see if it can just use the last one
                    if (combine != null && 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 + Ambients.NUM_AMBIENTS];// channels + MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS;
                    int j;
                    for (j = MAX_DYNAMIC_CHANNELS + Ambients.NUM_AMBIENTS; j < i; j++)
                    {
                        combine = _Channels[j];
                        if (combine.sfx == ch.sfx)
                        {
                            break;
                        }
                    }

                    if (j == _TotalChannels)
                    {
                        combine = null;
                    }
                    else
                    {
                        if (combine != ch)
                        {
                            combine.leftvol  += ch.leftvol;
                            combine.rightvol += ch.rightvol;
                            ch.leftvol        = ch.rightvol = 0;
                        }
                        continue;
                    }
                }
            }

            //
            // debugging output
            //
            if (_Show.Value != 0)
            {
                int total = 0;
                for (int i = 0; i < _TotalChannels; i++)
                {
                    channel_t ch = _Channels[i];
                    if (ch.sfx != null && (ch.leftvol > 0 || ch.rightvol > 0))
                    {
                        total++;
                    }
                }
                Con.Print("----({0})----\n", total);
            }

            // mix some sound
            Update();
        }
Exemple #8
0
        // 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_t 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;
                }
            }
        }
        // S_PaintChannels
        static void PaintChannels(int endtime)
        {
            while (_PaintedTime < endtime)
            {
                // if paintbuffer is smaller than DMA buffer
                int end = endtime;
                if (endtime - _PaintedTime > PAINTBUFFER_SIZE)
                {
                    end = _PaintedTime + PAINTBUFFER_SIZE;
                }

                // clear the paint buffer
                Array.Clear(_PaintBuffer, 0, end - _PaintedTime);

                // paint in the channels.
                for (int i = 0; i < _TotalChannels; i++)
                {
                    channel_t ch = _Channels[i];

                    if (ch.sfx == null)
                    {
                        continue;
                    }
                    if (ch.leftvol == 0 && ch.rightvol == 0)
                    {
                        continue;
                    }

                    sfxcache_t sc = LoadSound(ch.sfx);
                    if (sc == null)
                    {
                        continue;
                    }

                    int count, ltime = _PaintedTime;

                    while (ltime < end)
                    {
                        // paint up to end
                        if (ch.end < end)
                        {
                            count = ch.end - ltime;
                        }
                        else
                        {
                            count = end - ltime;
                        }

                        if (count > 0)
                        {
                            if (sc.width == 1)
                            {
                                PaintChannelFrom8(ch, sc, count);
                            }
                            else
                            {
                                PaintChannelFrom16(ch, sc, count);
                            }

                            ltime += count;
                        }

                        // if at end of loop, restart
                        if (ltime >= ch.end)
                        {
                            if (sc.loopstart >= 0)
                            {
                                ch.pos = sc.loopstart;
                                ch.end = ltime + sc.length - ch.pos;
                            }
                            else
                            {   // channel just stopped
                                ch.sfx = null;
                                break;
                            }
                        }
                    }
                }

                // transfer out according to DMA format
                TransferPaintBuffer(end);
                _PaintedTime = end;
            }
        }