File: gvCodec.c

package info (click to toggle)
openmohaa 0.81.1%2Bdfsg-2
  • links: PTS, VCS
  • area: contrib
  • in suites: trixie
  • size: 29,124 kB
  • sloc: ansic: 270,865; cpp: 250,173; sh: 234; asm: 141; xml: 64; makefile: 7
file content (354 lines) | stat: -rw-r--r-- 7,662 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
#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
}