openmohaa/code/gamespy/Voice2/gvCodec.c

355 lines
7.5 KiB
C
Raw Permalink Normal View History

2023-02-04 21:00:01 +01:00
#include "gvCodec.h"
#include "gvFrame.h"
#if !defined(GV_NO_DEFAULT_CODEC)
#if defined(_PS2)
#include "gvLogitechPS2Codecs.h"
#elif defined(_PSP)
#include "gvGSM.h"
#else
#include "gvSpeex.h"
#endif
#endif
/************
** GLOBALS **
************/
#define GVI_RAW_BASE_SAMPLES_PER_FRAME 160
/************
** GLOBALS **
************/
int GVISamplesPerFrame;
int GVIBytesPerFrame;
int GVIEncodedFrameSize;
int GVISampleRate;
int GVIBytesPerSecond;
static GVCustomCodecInfo GVICodecInfo;
#if !defined(GV_NO_DEFAULT_CODEC)
static GVBool GVICleanupInternalCodec;
#endif
#ifndef _PSP
static GVBool GVIRawCodec;
#endif
/**************
** FUNCTIONS **
**************/
#if !defined(GV_NO_DEFAULT_CODEC)
static void gviCleanupCodec(void)
{
#if defined(_PS2)
gviLGCodecCleanup();
#elif defined(_PSP)
gviGSMCleanup();
#else
gviSpeexCleanup();
#endif
}
#endif
void gviCodecsInitialize(void)
{
//Set a default sample rate.
#if defined(_PSP)
gviSetSampleRate(GVRate_11KHz);
#else
gviSetSampleRate(GVRate_8KHz);
#endif
#if !defined(GV_NO_DEFAULT_CODEC)
GVICleanupInternalCodec = GVFalse;
#endif
}
void gviCodecsCleanup(void)
{
#if !defined(GV_NO_DEFAULT_CODEC)
if(GVICleanupInternalCodec)
{
gviCleanupCodec();
GVICleanupInternalCodec = GVFalse;
}
#endif
}
#if !defined(GV_NO_DEFAULT_CODEC)
#if defined(_PS2)
static GVBool gviSetInternalCodec(GVCodec codec)
{
GVCustomCodecInfo info;
const char * name;
// figure out the name of the codec to use
// goto gvLogitechPS2Codecs.h to see what the quality values mean
if(codec == GVCodecSuperHighQuality)
name = "uLaw";
else if(codec == GVCodecHighQuality)
name = "G723.24";
else if(codec == GVCodecAverage)
name = "GSM";
else if(codec == GVCodecLowBandwidth)
name = "SPEEX";
else if(codec == GVCodecSuperLowBandwidth)
name = "LPC10";
else
return GVFalse;
// init lgCodec
if(!gviLGCodecInitialize(name))
return GVFalse;
// setup the info
info.m_samplesPerFrame = gviLGCodecGetSamplesPerFrame();
info.m_encodedFrameSize = gviLGCodecGetEncodedFrameSize();
info.m_newDecoderCallback = NULL;
info.m_freeDecoderCallback = NULL;
info.m_encodeCallback = gviLGCodecEncode;
info.m_decodeAddCallback = gviLGCodecDecodeAdd;
info.m_decodeSetCallback = gviLGCodecDecodeSet;
// set it
gviSetCustomCodec(&info);
return GVTrue;
}
#elif defined(_PSP)
static GVBool gviSetInternalCodec(GVCodec codec)
{
GVCustomCodecInfo info;
// init gsm
if(!gviGSMInitialize())
return GVFalse;
// setup the info
info.m_samplesPerFrame = gviGSMGetSamplesPerFrame();
info.m_encodedFrameSize = gviGSMGetEncodedFrameSize();
info.m_newDecoderCallback = gviGSMNewDecoder;
info.m_freeDecoderCallback = gviGSMFreeDecoder;
info.m_encodeCallback = gviGSMEncode;
info.m_decodeAddCallback = gviGSMDecodeAdd;
info.m_decodeSetCallback = gviGSMDecodeSet;
// set it
gviSetCustomCodec(&info);
GSI_UNUSED(codec);
return GVTrue;
}
#else
static GVBool gviSetInternalCodec(GVCodec codec)
{
GVCustomCodecInfo info;
int quality;
// figure out the quality
// goto gvSpeex.h to see what the quality values mean
if(codec == GVCodecSuperHighQuality)
quality = 10;
else if(codec == GVCodecHighQuality)
quality = 7;
else if(codec == GVCodecAverage)
quality = 4;
else if(codec == GVCodecLowBandwidth)
quality = 2;
else if(codec == GVCodecSuperLowBandwidth)
quality = 1;
else
return GVFalse;
// init speex
if(!gviSpeexInitialize(quality, GVISampleRate))
return GVFalse;
// setup the info
info.m_samplesPerFrame = gviSpeexGetSamplesPerFrame();
info.m_encodedFrameSize = gviSpeexGetEncodedFrameSize();
info.m_newDecoderCallback = gviSpeexNewDecoder;
info.m_freeDecoderCallback = gviSpeexFreeDecoder;
info.m_encodeCallback = gviSpeexEncode;
info.m_decodeAddCallback = gviSpeexDecodeAdd;
info.m_decodeSetCallback = gviSpeexDecodeSet;
// set it
gviSetCustomCodec(&info);
return GVTrue;
}
#endif
#endif
static void gviRawEncode(GVByte * out, const GVSample * in)
{
GVSample * sampleOut = (GVSample *)out;
int i;
for(i = 0 ; i < GVISamplesPerFrame; i++)
sampleOut[i] = htons(in[i]);
}
static void gviRawDecodeAdd(GVSample * out, const GVByte * in, GVDecoderData data)
{
const GVSample * sampleIn = (const GVSample *)in;
int i;
for(i = 0 ; i < GVISamplesPerFrame; i++)
// Expanded to remove warnings in VS2K5
out[i] = out[i] + ntohs(sampleIn[i]);
GSI_UNUSED(data);
}
static void gviRawDecodeSet(GVSample * out, const GVByte * in, GVDecoderData data)
{
const GVSample * sampleIn = (const GVSample *)in;
int i;
for(i = 0 ; i < GVISamplesPerFrame; i++)
out[i] = ntohs(sampleIn[i]);
GSI_UNUSED(data);
}
static void gviSetRawCodec(void)
{
GVCustomCodecInfo info;
memset(&info, 0, sizeof(info));
// setup the info
if (GVISampleRate == GVRate_8KHz)
info.m_samplesPerFrame = GVI_RAW_BASE_SAMPLES_PER_FRAME;
// need to double the frame size since data has shorter wavelength
else if (GVISampleRate == GVRate_16KHz)
info.m_samplesPerFrame = GVI_RAW_BASE_SAMPLES_PER_FRAME * 2;
// the samples per frame should be set above
info.m_encodedFrameSize = (info.m_samplesPerFrame * GV_BYTES_PER_SAMPLE);
info.m_newDecoderCallback = NULL;
info.m_freeDecoderCallback = NULL;
info.m_encodeCallback = gviRawEncode;
info.m_decodeAddCallback = gviRawDecodeAdd;
info.m_decodeSetCallback = gviRawDecodeSet;
// set it
gviSetCustomCodec(&info);
}
GVBool gviSetCodec(GVCodec codec)
{
#if !defined(GV_NO_DEFAULT_CODEC)
// cleanup if we need to
if(GVICleanupInternalCodec)
{
gviCleanupCodec();
GVICleanupInternalCodec = GVFalse;
}
#endif
// raw codec is handled specially
if(codec == GVCodecRaw)
{
gviSetRawCodec();
#ifndef _PSP
GVIRawCodec = GVTrue;
#endif
return GVTrue;
}
else
#ifndef _PSP
GVIRawCodec = GVFalse;
#endif
#if !defined(GV_NO_DEFAULT_CODEC)
// do the actual set (based on which internal codec we are using)
if(!gviSetInternalCodec(codec))
return GVFalse;
// clean this up at some point
GVICleanupInternalCodec = GVTrue;
return GVTrue;
#else
return GVFalse;
#endif
}
void gviSetCustomCodec(GVCustomCodecInfo * info)
{
// store the info
memcpy(&GVICodecInfo, info, sizeof(GVCustomCodecInfo));
GVISamplesPerFrame = info->m_samplesPerFrame;
GVIEncodedFrameSize = info->m_encodedFrameSize;
// extra info
GVIBytesPerFrame = (GVISamplesPerFrame * (int)GV_BYTES_PER_SAMPLE);
// frames needs to be initialized with codec info
gviFramesStartup();
}
void gviSetSampleRate(GVRate sampleRate)
{
//Save the sample rate.
GVISampleRate = sampleRate;
GVIBytesPerSecond = GVISampleRate * GV_BYTES_PER_SAMPLE;
}
GVRate gviGetSampleRate(void)
{
return GVISampleRate;
}
GVBool gviNewDecoder(GVDecoderData * data)
{
if(!GVICodecInfo.m_newDecoderCallback)
{
*data = NULL;
return GVTrue;
}
return GVICodecInfo.m_newDecoderCallback(data);
}
void gviFreeDecoder(GVDecoderData data)
{
if(GVICodecInfo.m_freeDecoderCallback)
GVICodecInfo.m_freeDecoderCallback(data);
}
void gviEncode(GVByte * out, const GVSample * in)
{
GVICodecInfo.m_encodeCallback(out, in);
}
void gviDecodeAdd(GVSample * out, const GVByte * in, GVDecoderData data)
{
GVICodecInfo.m_decodeAddCallback(out, in, data);
}
void gviDecodeSet(GVSample * out, const GVByte * in, GVDecoderData data)
{
if(GVICodecInfo.m_decodeSetCallback)
{
GVICodecInfo.m_decodeSetCallback(out, in, data);
}
else
{
memset(out, 0, GVIBytesPerFrame);
GVICodecInfo.m_decodeAddCallback(out, in, data);
}
}
void gviResetEncoder(void)
{
#if !defined(GV_NO_DEFAULT_CODEC) && !defined(_PS2) && !defined(_PSP)
//If we are using the RawCodec, we have never set up Speex.
if (!GVIRawCodec)
gviSpeexResetEncoder();
#endif
}