Add support for pitch shifting to the QC sound sending implementation, apply pitch...
authorMario <mario.mario@y7mail.com>
Tue, 21 Jul 2020 19:07:09 +0000 (05:07 +1000)
committerMario <mario.mario@y7mail.com>
Tue, 21 Jul 2020 19:07:09 +0000 (05:07 +1000)
15 files changed:
qcsrc/common/effects/qc/globalsound.qc
qcsrc/common/effects/qc/globalsound.qh
qcsrc/common/gamemodes/gamemode/onslaught/sv_onslaught.qc
qcsrc/common/mapobjects/func/bobbing.qc
qcsrc/common/mapobjects/func/breakable.qc
qcsrc/common/mapobjects/func/fourier.qc
qcsrc/common/mapobjects/func/pendulum.qc
qcsrc/common/mapobjects/func/rotating.qc
qcsrc/common/mapobjects/func/vectormamamam.qc
qcsrc/common/mapobjects/target/speaker.qc
qcsrc/common/sounds/all.qc
qcsrc/common/t_items.qc
qcsrc/common/vehicles/vehicle/raptor.qc
qcsrc/server/miscfunctions.qh
qcsrc/server/weapons/tracing.qc

index 8ce2b6e..06b8baa 100644 (file)
@@ -17,7 +17,7 @@
                 * @param gs the global sound def
                 * @param r a random number in 0..1
                 */
-               void globalsound(int channel, entity from, entity gs, float r, int chan, float _vol, float _atten)
+               void globalsound(int channel, entity from, entity gs, float r, int chan, float _vol, float _atten, float _pitch)
                {
                        //assert(IS_PLAYER(from), eprint(from));
                        if (channel == MSG_ONE && !IS_REAL_CLIENT(msg_entity)) return;
                                string sample = GlobalSound_sample(gs.m_globalsoundstr, r);
                                switch (channel) {
                                        case MSG_ONE:
-                                               soundto(channel, from, chan, sample, _vol, _atten);
+                                               soundto(channel, from, chan, sample, _vol, _atten, _pitch);
                                                break;
                                        case MSG_ALL:
-                                               _sound(from, chan, sample, _vol, _atten);
+                                               if(sound_allowed(MSG_BROADCAST, from))
+                                                       sound7(from, chan, sample, _vol, _atten, _pitch, 0);
                                                break;
                                }
                                return;
                        }
+                       // FIXME: pitch not implemented
                        WriteHeader(channel, globalsound);
                        WriteByte(channel, gs.m_id);
                        WriteByte(channel, r * 255);
@@ -50,7 +52,7 @@
                * @param ps the player sound def
                * @param r a random number in 0..1
                */
-               void playersound(int channel, entity from, entity ps, float r, int chan, float _vol, float _atten)
+               void playersound(int channel, entity from, entity ps, float r, int chan, float _vol, float _atten, float _pitch)
                {
                        //assert(IS_PLAYER(from), eprint(from));
                        if (channel == MSG_ONE && !IS_REAL_CLIENT(msg_entity)) return;
                                string sample = GlobalSound_sample(s, r);
                                switch (channel) {
                                        case MSG_ONE:
-                                               soundto(channel, from, chan, sample, _vol, _atten);
+                                               soundto(channel, from, chan, sample, _vol, _atten, _pitch);
                                                break;
                                        case MSG_ALL:
-                                               _sound(from, chan, sample, _vol, _atten);
+                                               if(sound_allowed(MSG_BROADCAST, from))
+                                                       sound7(from, chan, sample, _vol, _atten, _pitch, 0);
                                                break;
                                }
                                return;
                        }
+                       // FIXME: pitch not implemented
                        WriteHeader(channel, playersound);
                        WriteByte(channel, ps.m_id);
                        WriteByte(channel, r * 255);
                return sample;
        }
 
+       float GlobalSound_pitch(float _pitch)
+       {
+               // customizable gradient function that crosses (0,a), (c,1) and asymptotically approaches b
+               float a = 1.5; // max pitch
+               float b = 0.75; // min pitch
+               float c = 100; // standard pitch (scale * 100)
+               float d = _pitch;
+               float pitch_shift = (b*d*(a-1) + a*c*(1-b)) / (d*(a-1) + c*(1-b));
+
+               return pitch_shift * 100;
+       }
+
        void PrecacheGlobalSound(string sample)
        {
                int n;
                        if (gs == NULL && ps == NULL && sample == "") return;
                        if(this.classname == "body") return;
                        float r = random();
+                       float myscale = ((this.scale) ? this.scale : 1); // safety net
+                       float thepitch = ((myscale == 1) ? 0 : GlobalSound_pitch(myscale * 100));
                        if (sample != "") sample = GlobalSound_sample(sample, r);
                        switch (voicetype)
                        {
                                                if (IS_REAL_CLIENT(msg_entity))
                                                {
                                                        float atten = (CS(msg_entity).cvar_cl_voice_directional == 1) ? ATTEN_MIN : ATTEN_NONE;
-                                                       if (gs) globalsound(MSG_ONE, this, gs, r, chan, vol, atten);
-                                                       else if (ps) playersound(MSG_ONE, this, ps, r, chan, vol, atten);
-                                                       else soundto(MSG_ONE, this, chan, sample, vol, atten);
+                                                       if (gs) globalsound(MSG_ONE, this, gs, r, chan, vol, atten, thepitch);
+                                                       else if (ps) playersound(MSG_ONE, this, ps, r, chan, vol, atten, thepitch);
+                                                       else soundto(MSG_ONE, this, chan, sample, vol, atten, thepitch);
                                                }
                                        }
                                        if (voicetype == VOICETYPE_LASTATTACKER_ONLY) break;
                                        msg_entity = this;
                                        if (IS_REAL_CLIENT(msg_entity))
                                        {
-                                               if (gs) globalsound(MSG_ONE, this, gs, r, chan, VOL_BASE, ATTEN_NONE);
-                                               else if (ps) playersound(MSG_ONE, this, ps, r, chan, VOL_BASE, ATTEN_NONE);
-                                               else soundto(MSG_ONE, this, chan, sample, VOL_BASE, ATTEN_NONE);
+                                               if (gs) globalsound(MSG_ONE, this, gs, r, chan, VOL_BASE, ATTEN_NONE, thepitch);
+                                               else if (ps) playersound(MSG_ONE, this, ps, r, chan, VOL_BASE, ATTEN_NONE, thepitch);
+                                               else soundto(MSG_ONE, this, chan, sample, VOL_BASE, ATTEN_NONE, thepitch);
                                        }
                                        break;
                                }
                                        #define X() \
                                                MACRO_BEGIN \
                                                        float atten = (CS(msg_entity).cvar_cl_voice_directional == 1) ? ATTEN_MIN : ATTEN_NONE; \
-                                                       if (gs) globalsound(MSG_ONE, this, gs, r, chan, vol, atten); \
-                                                       else if (ps) playersound(MSG_ONE, this, ps, r, chan, vol, atten); \
-                                                       else soundto(MSG_ONE, this, chan, sample, vol, atten); \
+                                                       if (gs) globalsound(MSG_ONE, this, gs, r, chan, vol, atten, thepitch); \
+                                                       else if (ps) playersound(MSG_ONE, this, ps, r, chan, vol, atten, thepitch); \
+                                                       else soundto(MSG_ONE, this, chan, sample, vol, atten, thepitch); \
                                                MACRO_END
 
                                        if (fake) { msg_entity = this; X(); }
                                                                        ? bound(ATTEN_MIN, CS(msg_entity).cvar_cl_voice_directional_taunt_attenuation, \
                                                                        ATTEN_MAX) \
                                                                        : ATTEN_NONE; \
-                                                               if (gs) globalsound(MSG_ONE, this, gs, r, chan, vol, atten); \
-                                                               else if (ps) playersound(MSG_ONE, this, ps, r, chan, vol, atten); \
-                                                               else soundto(MSG_ONE, this, chan, sample, vol, atten); \
+                                                               if (gs) globalsound(MSG_ONE, this, gs, r, chan, vol, atten, thepitch); \
+                                                               else if (ps) playersound(MSG_ONE, this, ps, r, chan, vol, atten, thepitch); \
+                                                               else soundto(MSG_ONE, this, chan, sample, vol, atten, thepitch); \
                                                        } \
                                                MACRO_END
                                        if (fake)
                                        msg_entity = this;
                                        if (fake)
                                        {
-                                               if (gs) globalsound(MSG_ONE, this, gs, r, chan, vol, ATTEN_NORM);
-                                               else if (ps) playersound(MSG_ONE, this, ps, r, chan, vol, ATTEN_NORM);
-                                               else soundto(MSG_ONE, this, chan, sample, vol, ATTEN_NORM);
+                                               if (gs) globalsound(MSG_ONE, this, gs, r, chan, vol, ATTEN_NORM, thepitch);
+                                               else if (ps) playersound(MSG_ONE, this, ps, r, chan, vol, ATTEN_NORM, thepitch);
+                                               else soundto(MSG_ONE, this, chan, sample, vol, ATTEN_NORM, thepitch);
                                        }
                                        else
                                        {
-                                               if (gs) globalsound(MSG_ALL, this, gs, r, chan, vol, ATTEN_NORM);
-                                               else if (ps) playersound(MSG_ALL, this, ps, r, chan, vol, ATTEN_NORM);
-                                               else _sound(this, chan, sample, vol, ATTEN_NORM);
+                                               if (gs) globalsound(MSG_ALL, this, gs, r, chan, vol, ATTEN_NORM, thepitch);
+                                               else if (ps) playersound(MSG_ALL, this, ps, r, chan, vol, ATTEN_NORM, thepitch);
+                                               else if (sound_allowed(MSG_BROADCAST, this)) sound7(this, chan, sample, vol, ATTEN_NORM, thepitch, 0);
                                        }
                                        break;
                                }
index 2b6b528..5460d72 100644 (file)
@@ -123,6 +123,8 @@ entity GetVoiceMessage(string type);
 
 string GlobalSound_sample(string pair, float r);
 
+float GlobalSound_pitch(float _pitch);
+
 #ifdef SVQC
 
        void _GlobalSound(entity this, entity gs, entity ps, string sample, float chan, float vol, float voicetype, bool fake);
index 9675634..1f3e433 100644 (file)
@@ -998,7 +998,7 @@ void ons_GeneratorThink(entity this)
                {
                        Send_Notification(NOTIF_ONE, it, MSG_CENTER, CENTER_ONS_NOTSHIELDED_TEAM);
                        msg_entity = it;
-                       soundto(MSG_ONE, this, CHAN_AUTO, SND(ONS_GENERATOR_ALARM), VOL_BASE, ATTEN_NONE);
+                       soundto(MSG_ONE, this, CHAN_AUTO, SND(ONS_GENERATOR_ALARM), VOL_BASE, ATTEN_NONE, 0);
                }
                else
                        Send_Notification(NOTIF_ONE, it, MSG_CENTER, APP_TEAM_NUM(this.team, CENTER_ONS_NOTSHIELDED));
index 60920fa..3c4229a 100644 (file)
@@ -35,7 +35,7 @@ spawnfunc(func_bobbing)
        if (this.noise != "")
        {
                precache_sound(this.noise);
-               soundto(MSG_INIT, this, CH_TRIGGER_SINGLE, this.noise, VOL_BASE, ATTEN_IDLE);
+               soundto(MSG_INIT, this, CH_TRIGGER_SINGLE, this.noise, VOL_BASE, ATTEN_IDLE, 0);
        }
        if (!this.speed)
                this.speed = 4;
index e92af67..24d7139 100644 (file)
@@ -187,7 +187,7 @@ void func_breakable_init_for_player(entity this, entity player)
        if (this.noise1 && this.state == STATE_ALIVE && IS_REAL_CLIENT(player))
        {
                msg_entity = player;
-               soundto (MSG_ONE, this, CH_TRIGGER_SINGLE, this.noise1, VOL_BASE, ATTEN_NORM);
+               soundto (MSG_ONE, this, CH_TRIGGER_SINGLE, this.noise1, VOL_BASE, ATTEN_NORM, 0);
        }
 }
 
index 28e0f0f..73bb605 100644 (file)
@@ -46,7 +46,7 @@ spawnfunc(func_fourier)
        if (this.noise != "")
        {
                precache_sound(this.noise);
-               soundto(MSG_INIT, this, CH_TRIGGER_SINGLE, this.noise, VOL_BASE, ATTEN_IDLE);
+               soundto(MSG_INIT, this, CH_TRIGGER_SINGLE, this.noise, VOL_BASE, ATTEN_IDLE, 0);
        }
 
        if (!this.speed)
index a59f7a9..c582f47 100644 (file)
@@ -28,7 +28,7 @@ spawnfunc(func_pendulum)
        if (this.noise != "")
        {
                precache_sound(this.noise);
-               soundto(MSG_INIT, this, CH_TRIGGER_SINGLE, this.noise, VOL_BASE, ATTEN_IDLE);
+               soundto(MSG_INIT, this, CH_TRIGGER_SINGLE, this.noise, VOL_BASE, ATTEN_IDLE, 0);
        }
 
        this.active = ACTIVE_ACTIVE;
index 35351ee..1864b6d 100644 (file)
@@ -47,7 +47,7 @@ void func_rotating_init_for_player(entity this, entity player)
        if (this.noise && this.noise != "" && this.active == ACTIVE_ACTIVE && IS_REAL_CLIENT(player))
        {
                msg_entity = player;
-               soundto (MSG_ONE, this, CH_AMBIENT_SINGLE, this.noise, VOL_BASE, ATTEN_IDLE);
+               soundto (MSG_ONE, this, CH_AMBIENT_SINGLE, this.noise, VOL_BASE, ATTEN_IDLE, 0);
        }
 }
 
index 61da52a..4882fe3 100644 (file)
@@ -128,7 +128,7 @@ void func_vectormamamam_init_for_player(entity this, entity player)
        if (this.noise && this.noise != "" && this.active == ACTIVE_ACTIVE && IS_REAL_CLIENT(player))
        {
                msg_entity = player;
-               soundto(MSG_ONE, this, CH_TRIGGER_SINGLE, this.noise, VOL_BASE, ATTEN_IDLE);
+               soundto(MSG_ONE, this, CH_TRIGGER_SINGLE, this.noise, VOL_BASE, ATTEN_IDLE, 0);
        }
 }
 
index e67f4b3..6766139 100644 (file)
@@ -28,7 +28,7 @@ void target_speaker_use_activator(entity this, entity actor, entity trigger)
        else
                snd = this.noise;
        msg_entity = actor;
-       soundto(MSG_ONE, this, CH_TRIGGER, snd, VOL_BASE * this.volume, this.atten);
+       soundto(MSG_ONE, this, CH_TRIGGER, snd, VOL_BASE * this.volume, this.atten, 0);
 }
 void target_speaker_use_on(entity this, entity actor, entity trigger)
 {
index fcd4d9a..fdbf411 100644 (file)
@@ -34,8 +34,9 @@ const int SND_VOLUME = BIT(0);
 const int SND_ATTENUATION = BIT(1);
 const int SND_LARGEENTITY = BIT(3);
 const int SND_LARGESOUND = BIT(4);
+const int SND_SPEEDUSHORT4000 = BIT(5);
 
-void soundtoat(int to, entity e, vector o, int chan, string samp, float vol, float attenu)
+void soundtoat(int to, entity e, vector o, int chan, string samp, float vol, float attenu, float _pitch)
 {
        if (!sound_allowed(to, e)) return;
        int entno = etof(e);
@@ -43,14 +44,17 @@ void soundtoat(int to, entity e, vector o, int chan, string samp, float vol, flo
        attenu = floor(attenu * 64);
        vol = floor(vol * 255);
        int sflags = 0;
+       int speed4000 = floor((_pitch * 0.01) * 4000 + 0.5);
        if (vol != 255) sflags |= SND_VOLUME;
        if (attenu != 64) sflags |= SND_ATTENUATION;
        if (entno >= 8192 || chan < 0 || chan > 7) sflags |= SND_LARGEENTITY;
        if (idx >= 256) sflags |= SND_LARGESOUND;
+       if (speed4000 && speed4000 != 4000) sflags |= SND_SPEEDUSHORT4000;
        WriteByte(to, SVC_SOUND);
        WriteByte(to, sflags);
        if (sflags & SND_VOLUME) WriteByte(to, vol);
        if (sflags & SND_ATTENUATION) WriteByte(to, attenu);
+       if (sflags & SND_SPEEDUSHORT4000) WriteShort(to, speed4000);
        if (sflags & SND_LARGEENTITY)
        {
                WriteShort(to, entno);
@@ -67,15 +71,15 @@ void soundtoat(int to, entity e, vector o, int chan, string samp, float vol, flo
        WriteCoord(to, o.z);
 }
 
-void soundto(int _dest, entity e, int chan, string samp, float vol, float _atten)
+void soundto(int _dest, entity e, int chan, string samp, float vol, float _atten, float _pitch)
 {
        if (!sound_allowed(_dest, e)) return;
        vector o = e.origin + 0.5 * (e.mins + e.maxs);
-       soundtoat(_dest, e, o, chan, samp, vol, _atten);
+       soundtoat(_dest, e, o, chan, samp, vol, _atten, _pitch);
 }
 void soundat(entity e, vector o, int chan, string samp, float vol, float _atten)
 {
-       soundtoat(((chan & 8) ? MSG_ALL : MSG_BROADCAST), e, o, chan, samp, vol, _atten);
+       soundtoat(((chan & 8) ? MSG_ALL : MSG_BROADCAST), e, o, chan, samp, vol, _atten, 0);
 }
 void stopsoundto(int _dest, entity e, int chan)
 {
@@ -112,7 +116,7 @@ void stopsound(entity e, int chan)
 void play2(entity e, string filename)
 {
        msg_entity = e;
-       soundtoat(MSG_ONE, NULL, '0 0 0', CH_INFO, filename, VOL_BASE, ATTEN_NONE);
+       soundtoat(MSG_ONE, NULL, '0 0 0', CH_INFO, filename, VOL_BASE, ATTEN_NONE, 0);
 }
 
 .float spamtime;
index 37cb77a..ef2923b 100644 (file)
@@ -540,7 +540,7 @@ void Item_RespawnCountdown(entity this)
                                if(this.waypointsprite_attached.waypointsprite_visible_for_player(this.waypointsprite_attached, it, it))
                                {
                                        msg_entity = it;
-                                       soundto(MSG_ONE, this, CH_TRIGGER, SND(ITEMRESPAWNCOUNTDOWN), VOL_BASE, ATTEN_NORM);    // play respawn sound
+                                       soundto(MSG_ONE, this, CH_TRIGGER, SND(ITEMRESPAWNCOUNTDOWN), VOL_BASE, ATTEN_NORM, 0); // play respawn sound
                                }
                        });
 
index 015f947..a868eb4 100644 (file)
@@ -422,7 +422,7 @@ bool raptor_frame(entity this, float dt)
                if(incoming)
                {
                        msg_entity = this;
-                       soundto(MSG_ONE, vehic, CH_PAIN_SINGLE, SND(VEH_MISSILE_ALARM), VOL_BASE, ATTEN_NONE);
+                       soundto(MSG_ONE, vehic, CH_PAIN_SINGLE, SND(VEH_MISSILE_ALARM), VOL_BASE, ATTEN_NONE, 0);
                }
 
                vehic.bomb1.cnt = time + 1;
index e94ee9c..c61dc1e 100644 (file)
@@ -35,7 +35,7 @@ void soundat(entity e, vector o, float chan, string samp, float vol, float _atte
 void InitializeEntitiesRun();
 
 void stopsoundto(float _dest, entity e, float chan);
-void soundtoat(float _dest, entity e, vector o, float chan, string samp, float vol, float _atten);
+void soundtoat(float _dest, entity e, vector o, float chan, string samp, float vol, float _atten, float _pitch);
 
 void droptofloor(entity this);
 
@@ -82,7 +82,7 @@ void remove_unsafely(entity e);
 
 void SetMovetypeFollow(entity ent, entity e);
 
-void soundto(float dest, entity e, float chan, string samp, float vol, float atten);
+void soundto(float dest, entity e, float chan, string samp, float vol, float atten, float _pitch);
 
 void stopsound(entity e, float chan);
 
index 6209710..3259523 100644 (file)
@@ -285,7 +285,7 @@ void FireRailgunBullet (entity this, .entity weaponentity, vector start, vector
 
                msg_entity = it;
                // we want this to be very loud when close but fall off quickly -> using max base volume and high attenuation
-               soundtoat(MSG_ONE, pseudoprojectile, beampos, CH_SHOTS, SND(NEXWHOOSH_RANDOM()), VOL_BASEVOICE, ATTEN_IDLE);
+               soundtoat(MSG_ONE, pseudoprojectile, beampos, CH_SHOTS, SND(NEXWHOOSH_RANDOM()), VOL_BASEVOICE, ATTEN_IDLE, 0);
        });
        if(pseudoprojectile)
                delete(pseudoprojectile);