[英]Decoded CELT audio to WAV
我需要从 CS:GO 游戏服务器中提取语音数据。 引擎给了我压缩音频片段 stream,然后我通过 celt 库 (IVoiceCodec::Decompress) 解压缩,就像在这个源代码中所做的一样: https://github.com/perilouswithadollarsign/cstrike15_src/blob/f82112a2388b841d72cb612ca46fcc188 /engine/audio/private/voice.cpp
该接口没有提供任何有关解码数据的信息,但从源代码中我可以猜测它应该是单通道 16bit/22050KHz PCM 音频
static std::vector<char> buffer;
char decompressedData[MAX_UNCOMPRESSED_VOICE_BUFFER_SIZE];
const int decompressedBytes = g_pCodec->Decompress(data.data(),
data.size(),
decompressedData,
MAX_UNCOMPRESSED_VOICE_BUFFER_SIZE);
if(decompressedBytes > 0)
buffer.insert(buffer.end(),
decompressedData,
decompressedData + decompressedBytes);
if(buffer.size() > 50000)
{
static int fileIndex = 0;
const std::string fileName("wav/test_" + std::to_string(clientIndex) + "_" + std::to_string(fileIndex) + ".wav");
const bool result = WriteWaveFile(fileName.c_str(),
buffer.data(),
buffer.size(),
16, // Bits per sample
1, // Channels
22050 // Samples per sec
);
buffer.clear();
++fileIndex;
}
解码器工作时没有错误并输出正确的数据(解码后我可以辨认出声音)。 然后我将这些片段保存为单通道 16 位/22050KHz PCM WAV 文件而没有任何更改。 从技术上讲,我在数据前添加了 42 个字节的 WAV header。 然后我合并文件。 这是我得到的示例: https://drive.google.com/file/d/16iSC-GXzzl5wwYsvAQN1Hkk93LuSyRYG/view?usp=share_link音调听起来正确,但播放速度太快,我能听到噪音。
这是我编写wav文件的代码(我也是从引擎源代码中得到的):
void WriteDWord(FileHandle_t fp, unsigned long val)
{
g_pFileSystem->Write(&val, 4, fp);
}
void WriteWord(FileHandle_t fp, unsigned short val)
{
g_pFileSystem->Write(&val, 2, fp);
}
bool WriteWaveFile(
const char *pFilename,
const char *pData,
int nBytes,
int wBitsPerSample,
int nChannels,
int nSamplesPerSec)
{
FileHandle_t fp = g_pFileSystem->Open(pFilename, "wb");
if(!fp)
return false;
// Write the RIFF chunk.
g_pFileSystem->Write("RIFF", 4, fp);
WriteDWord(fp, 0);
g_pFileSystem->Write("WAVE", 4, fp);
// Write the FORMAT chunk.
g_pFileSystem->Write("fmt ", 4, fp);
WriteDWord(fp, 0x10);
WriteWord(fp, WAVE_FORMAT_PCM);
WriteWord(fp, (unsigned short)nChannels);
WriteDWord(fp, (unsigned long)nSamplesPerSec);
WriteDWord(fp, (unsigned long)((wBitsPerSample / 8) * nChannels * nSamplesPerSec));
WriteWord(fp, (unsigned short)((wBitsPerSample / 8) * nChannels));
WriteWord(fp, (unsigned long)wBitsPerSample);
// Write the DATA chunk.
g_pFileSystem->Write("data", 4, fp);
WriteDWord(fp, (unsigned long)nBytes);
g_pFileSystem->Write(pData, nBytes, fp);
// Go back and write the length of the riff file.
unsigned long dwVal = g_pFileSystem->Tell(fp) - 8;
g_pFileSystem->Seek(fp, 4, FILESYSTEM_SEEK_HEAD);
WriteDWord(fp, dwVal);
g_pFileSystem->Close(fp);
return true;
}
我尝试更改采样率和每个样本的位数,但仍然得到错误的结果。 wav 文件有什么问题?
IVoiceCodec::Decompress 似乎返回样本数而不是写入的字节数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.