ValveSoftware / halflife

Half-Life 1 engine based games
Other
3.66k stars 615 forks source link

[Feature] Record your own voice in dem-files when voice_loopback 0 #2712

Open 2010kohtep opened 4 years ago

2010kohtep commented 4 years ago

This report was inspired by #2414.

Implementing this feature would be very helpful. Long time ago, I really needed such functionality, and due to its absence, very valuable information from voice chat in dem files was irretrievably lost forever.

So, in one of my projects, I implemented this by intercepting the CL_WriteDemoMessage and the Voice_GetCompressedData functions. I will try to provide an algorithm that describes the implementation.

  1. Create a global buffer sizebuf_t voice_buf;.

  2. In Voice_GetCompressedData function, I put my own handler, which writes pchDest (that is filled in the original Voice_GetCompressedData function) data to the voice_buf buffer. It looks like this:

int hkVoice_GetCompressedData(char *pchDest, int nCount, qboolean bFinal)
{
    int ret = orgVoice_GetCompressedData(pchDest, nCount, bFinal);

    if (ret && cls.demorecording && !Voice_GetLoopback())
    {
        MSG_WriteBuf(&voice_buf, ret, pchDest);

        if (voice_buf.flags & SIZEBUF_OVERFLOWED)
        {
            SZ_Clear(&voice_buf);
        }
    }

    return ret;
}
  1. In CL_WriteDemoMessage function, I put my own handler, which writes data from voice_buf to the msg buffer, clearing it after. It looks like this:
void hkCL_WriteDemoMessage(int start, sizebuf_t *msg)
{
    if (voice_buf.cursize > 0)
    {
        cl_entity_t *ply = GET_LOCAL_PLAYER();
        if (ply)
        {
            MSG_WriteByte(msg, SVC_VOICEDATA);
            MSG_WriteByte(msg, ply->index - 1);
            MSG_WriteWord(msg, voice_buf.cursize);
            MSG_WriteBuf(msg, voice_buf.cursize, voice_buf.data);

            SZ_Clear(&voice_buf);
        }
    }

    orgCL_WriteDemoMessage(start, msg);
}
  1. The buffer needs to be initialized. I find the implementation below is acceptable:
unsigned char voice_buf_data[2048];

void VoiceBuf_Init()
{
    voice_buf.buffername = "Voice Buffer";
    voice_buf.flags = SIZEBUF_ALLOW_OVERFLOW;
    voice_buf.data = voice_buf_data;
    voice_buf.maxsize = sizeof(voice_buf_data);
    voice_buf.cursize = 0;
}

Now your own voice data will be recorded even with voice_loopback 0. @mikela-valve , I believe that such functionality is worthy of implementation due to its extreme usefulness. Can you provide its official implementation, please?

metita commented 4 years ago

Good idea.

tarsisd2 commented 3 years ago

so, are we getting this update anytime soon? this is great when analyzing player demos

Maxi605 commented 3 years ago

so, are we getting this update anytime soon? this is great when analyzing player demos

we can only hope.