Mercurial > mplayer.hg
annotate libmpcodecs/ad_twin.c @ 30088:4977e04f3a18
Add support for parsing audio streams (though should be easy to extend to video)
via libavcodec.
Parsing can be done at the demuxer stage (currently disabled) or at the decoder
(ad_ffmpeg, enabled).
Should allow using the libavcodec AAC, DTS, ... decoders independent of container
format.
author | reimar |
---|---|
date | Sun, 27 Dec 2009 15:28:01 +0000 |
parents | 28fb967d78d8 |
children | bbb6ebec87a0 |
rev | line source |
---|---|
14276 | 1 #include <stdio.h> |
2 #include <stdlib.h> | |
3 #include <unistd.h> | |
4 #include "config.h" | |
5 | |
6 #include "ad_internal.h" | |
7 #include "vqf.h" | |
17012 | 8 #include "loader/ldt_keeper.h" |
22577
a033e5519802
Include loader/ prefix in #include path everywhere.
diego
parents:
18771
diff
changeset
|
9 #include "loader/wine/windef.h" |
17012 | 10 #include "libaf/af_format.h" |
14276 | 11 |
12 #include "help_mp.h" | |
13 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
14 static ad_info_t info = |
14276 | 15 { |
16 "TWinVQ decoder", | |
17 "vqf", | |
18 "Roberto Togni", | |
19 "Nick Kurshev", | |
20 "Ported from MPlayerXP" | |
21 }; | |
22 | |
23 LIBAD_EXTERN(twin) | |
24 | |
25 void* WINAPI LoadLibraryA(char* name); | |
26 void* WINAPI GetProcAddress(void* handle, char* func); | |
27 int WINAPI FreeLibrary(void* handle); | |
28 | |
29 static int (*TvqInitialize)( headerInfo *setupInfo, INDEX *index, int dispErrorMessageBox ); | |
30 static void (*TvqTerminate)( INDEX *index ); | |
31 static void (*TvqGetVectorInfo)(int *bits0[], int *bits1[]); | |
32 | |
33 static void (*TvqDecodeFrame)(INDEX *indexp, float out[]); | |
34 static int (*TvqWtypeToBtype)( int w_type, int *btype ); | |
35 static void (*TvqUpdateVectorInfo)(int varbits, int *ndiv, int bits0[], int bits1[]); | |
36 | |
37 static int (*TvqCheckVersion)(char *versionID); | |
38 static void (*TvqGetConfInfo)(tvqConfInfo *cf); | |
39 static int (*TvqGetFrameSize)(); | |
40 static int (*TvqGetNumFixedBitsPerFrame)(); | |
41 | |
42 #define BYTE_BIT 8 | |
43 #define BBUFSIZ 1024 /* Bit buffer size (bytes) */ | |
44 #define BBUFLEN (BBUFSIZ*BYTE_BIT) /* Bit buffer length (bits) */ | |
45 typedef struct vqf_priv_s | |
46 { | |
47 float pts; | |
48 WAVEFORMATEX o_wf; // out format | |
49 INDEX index; | |
50 tvqConfInfo cf; | |
51 headerInfo hi; | |
52 int *bits_0[N_INTR_TYPE], *bits_1[N_INTR_TYPE]; | |
53 unsigned framesize; | |
54 /* stream related */ | |
55 int readable; | |
56 int ptr; /* current point in the bit buffer */ | |
57 int nbuf; /* bit buffer size */ | |
58 char buf[BBUFSIZ]; /* the bit buffer */ | |
59 int skip_cnt; | |
60 }vqf_priv_t; | |
61 | |
62 static void* vqf_dll; | |
63 | |
64 static int load_dll( char *libname ) | |
65 { | |
66 #ifdef WIN32_LOADER | |
67 Setup_LDT_Keeper(); | |
68 #endif | |
69 vqf_dll = LoadLibraryA(libname); | |
70 if( vqf_dll == NULL ) | |
71 { | |
72 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "failed loading dll\n" ); | |
73 return 0; | |
74 } | |
75 TvqInitialize = GetProcAddress(vqf_dll,"TvqInitialize"); | |
76 TvqTerminate = GetProcAddress(vqf_dll,"TvqTerminate"); | |
77 TvqGetVectorInfo = GetProcAddress(vqf_dll,"TvqGetVectorInfo"); | |
78 TvqDecodeFrame = GetProcAddress(vqf_dll,"TvqDecodeFrame"); | |
79 TvqWtypeToBtype = GetProcAddress(vqf_dll,"TvqWtypeToBtype"); | |
80 TvqUpdateVectorInfo = GetProcAddress(vqf_dll,"TvqUpdateVectorInfo"); | |
81 TvqCheckVersion = GetProcAddress(vqf_dll,"TvqCheckVersion"); | |
82 TvqGetConfInfo = GetProcAddress(vqf_dll,"TvqGetConfInfo"); | |
83 TvqGetFrameSize = GetProcAddress(vqf_dll,"TvqGetFrameSize"); | |
84 TvqGetNumFixedBitsPerFrame = GetProcAddress(vqf_dll,"TvqGetNumFixedBitsPerFrame"); | |
85 return TvqInitialize && TvqTerminate && TvqGetVectorInfo && | |
86 TvqDecodeFrame && TvqWtypeToBtype && TvqUpdateVectorInfo && | |
87 TvqCheckVersion && TvqGetConfInfo && TvqGetFrameSize && | |
88 TvqGetNumFixedBitsPerFrame; | |
89 } | |
90 | |
28051 | 91 void print_wave_header(WAVEFORMATEX *h, int verbose_level); |
14276 | 92 static int init_vqf_audio_codec(sh_audio_t *sh_audio){ |
93 WAVEFORMATEX *in_fmt=sh_audio->wf; | |
94 vqf_priv_t*priv=sh_audio->context; | |
95 int ver; | |
96 mp_msg(MSGT_DECAUDIO, MSGL_INFO, "======= Win32 (TWinVQ) AUDIO Codec init =======\n"); | |
97 | |
98 sh_audio->channels=in_fmt->nChannels; | |
99 sh_audio->samplerate=in_fmt->nSamplesPerSec; | |
100 sh_audio->sample_format=AF_FORMAT_S16_NE; | |
101 // sh_audio->sample_format=AF_FORMAT_FLOAT_NE; | |
102 sh_audio->samplesize=af_fmt2bits(sh_audio->sample_format)/8; | |
103 priv->o_wf.nChannels=in_fmt->nChannels; | |
104 priv->o_wf.nSamplesPerSec=in_fmt->nSamplesPerSec; | |
105 priv->o_wf.nBlockAlign=sh_audio->samplesize*in_fmt->nChannels; | |
106 priv->o_wf.nAvgBytesPerSec=in_fmt->nBlockAlign*in_fmt->nChannels; | |
107 priv->o_wf.wFormatTag=0x01; | |
108 priv->o_wf.wBitsPerSample=in_fmt->wBitsPerSample; | |
109 priv->o_wf.cbSize=0; | |
110 | |
17932 | 111 if( mp_msg_test(MSGT_DECAUDIO,MSGL_V) ) |
14276 | 112 { |
17932 | 113 mp_msg(MSGT_DECAUDIO, MSGL_V, "Input format:\n"); |
17977
f70772d02eaa
Convert printfs in aviprint.c to mp_msg and give the information printing
diego
parents:
17932
diff
changeset
|
114 print_wave_header(in_fmt, MSGL_V); |
17932 | 115 mp_msg(MSGT_DECAUDIO, MSGL_V, "Output fmt:\n"); |
17977
f70772d02eaa
Convert printfs in aviprint.c to mp_msg and give the information printing
diego
parents:
17932
diff
changeset
|
116 print_wave_header(&priv->o_wf, MSGL_V); |
14276 | 117 } |
118 memcpy(&priv->hi,&in_fmt[1],sizeof(headerInfo)); | |
119 if((ver=TvqInitialize(&priv->hi,&priv->index,0))){ | |
120 const char *tvqe[]={ | |
121 "No errors", | |
122 "General error", | |
123 "Wrong version", | |
124 "Channel setting error", | |
125 "Wrong coding mode", | |
126 "Inner parameter setting error", | |
127 "Wrong number of VQ pre-selection candidates, used only in encoder" }; | |
128 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Tvq initialization error: %s\n",ver>=0&&ver<7?tvqe[ver]:"Unknown"); | |
129 return 0; | |
130 } | |
131 ver=TvqCheckVersion(priv->hi.ID); | |
132 if(ver==TVQ_UNKNOWN_VERSION){ | |
133 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Tvq unknown version of stream\n" ); | |
134 return 0; | |
135 } | |
136 TvqGetConfInfo(&priv->cf); | |
137 TvqGetVectorInfo(priv->bits_0,priv->bits_1); | |
138 priv->framesize=TvqGetFrameSize(); | |
139 sh_audio->audio_in_minsize=priv->framesize*in_fmt->nChannels; | |
140 sh_audio->a_in_buffer_size=4*sh_audio->audio_in_minsize; | |
27765
03bb6c3945ff
Use av_malloc/av_free for audio-related buffers to avoid crashes due to
reimar
parents:
26754
diff
changeset
|
141 sh_audio->a_in_buffer=av_malloc(sh_audio->a_in_buffer_size); |
14276 | 142 sh_audio->a_in_buffer_len=0; |
143 | |
144 | |
145 return 1; | |
146 } | |
147 | |
148 static int close_vqf_audio_codec(sh_audio_t *sh_audio) | |
149 { | |
150 vqf_priv_t*priv=sh_audio->context; | |
151 TvqTerminate(&priv->index); | |
152 return 1; | |
153 } | |
154 | |
155 int init(sh_audio_t *sh_audio) | |
156 { | |
157 return 1; | |
158 } | |
159 | |
160 int preinit(sh_audio_t *sh_audio) | |
161 { | |
162 /* Win32 VQF audio codec: */ | |
163 vqf_priv_t *priv; | |
164 if(!(sh_audio->context=malloc(sizeof(vqf_priv_t)))) return 0; | |
165 priv=sh_audio->context; | |
166 if(!load_dll(sh_audio->codec->dll)) | |
167 { | |
168 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "win32.dll looks broken :(\n"); | |
169 return 0; | |
170 } | |
171 if(!init_vqf_audio_codec(sh_audio)){ | |
172 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "TWinVQ initialization fail\n"); | |
173 return 0; | |
174 } | |
175 mp_msg(MSGT_DECAUDIO, MSGL_INFO, "INFO: TWinVQ (%s) audio codec init OK!\n",sh_audio->codec->dll); | |
176 priv->skip_cnt = 2; | |
177 return 1; | |
178 } | |
179 | |
180 void uninit(sh_audio_t *sh) | |
181 { | |
182 close_vqf_audio_codec(sh); | |
183 free(sh->context); | |
184 FreeLibrary(vqf_dll); | |
185 } | |
186 | |
29702
28fb967d78d8
Mark some functions that do not need external visibility as static.
diego
parents:
29263
diff
changeset
|
187 static int control(sh_audio_t *sh_audio,int cmd,void* arg, ...) |
14276 | 188 { |
189 switch(cmd) { | |
190 case ADCTRL_QUERY_FORMAT: | |
191 return CONTROL_TRUE; | |
192 default: | |
193 return CONTROL_UNKNOWN; | |
194 } | |
195 } | |
196 | |
197 static int bread(char *data, /* Output: Output data array */ | |
198 int size, /* Input: Length of each data */ | |
199 int nbits, /* Input: Number of bits to write */ | |
200 sh_audio_t *sh) /* Input: File pointer */ | |
201 { | |
202 /*--- Variables ---*/ | |
203 int ibits, iptr, idata, ibufadr, ibufbit, icl; | |
204 unsigned char mask, tmpdat; | |
205 int retval; | |
206 vqf_priv_t *priv=sh->context; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
207 |
14276 | 208 /*--- Main operation ---*/ |
209 retval = 0; | |
210 mask = 0x1; | |
211 for ( ibits=0; ibits<nbits; ibits++ ){ | |
212 if ( priv->readable == 0 ){ /* when the file data buffer is empty */ | |
213 priv->nbuf = demux_read_data(sh->ds, priv->buf, BBUFSIZ); | |
214 priv->nbuf *= 8; | |
215 priv->readable = 1; | |
216 } | |
217 iptr = priv->ptr; /* current file data buffer pointer */ | |
218 if ( iptr >= priv->nbuf ) /* If data file is empty then return */ | |
26754
63630c09e237
cosmetics: Remove pointless parentheses from return calls.
diego
parents:
22577
diff
changeset
|
219 return retval; |
14276 | 220 ibufadr = iptr/BYTE_BIT; /* current file data buffer address */ |
221 ibufbit = iptr%BYTE_BIT; /* current file data buffer bit */ | |
222 /* tmpdat = stream->buf[ibufadr] >> (BYTE_BIT-ibufbit-1); */ | |
223 tmpdat = (unsigned char)priv->buf[ibufadr]; | |
224 tmpdat >>= (BYTE_BIT-ibufbit-1); | |
225 /* current data bit */ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
226 |
14276 | 227 idata = ibits*size; /* output data address */ |
228 data[idata] = (char)(tmpdat & mask); /* set output data */ | |
229 for (icl=1; icl<size; icl++) | |
230 data[idata+icl] = 0; /* clear the rest output data buffer */ | |
231 priv->ptr += 1; /* update data buffer pointer */ | |
232 if (priv->ptr == BBUFLEN){ | |
233 priv->ptr = 0; | |
234 priv->readable = 0; | |
235 } | |
236 ++retval; | |
237 } | |
26754
63630c09e237
cosmetics: Remove pointless parentheses from return calls.
diego
parents:
22577
diff
changeset
|
238 return retval; |
14276 | 239 } |
240 | |
241 #define BITS_INT (sizeof(int)*8) | |
242 | |
243 static int get_bstm(int *data, /* Input: input data */ | |
244 unsigned nbits, /* Input: number of bits */ | |
245 sh_audio_t *sh) /* Input: bit file pointer */ | |
246 { | |
247 unsigned ibit; | |
248 unsigned mask; | |
249 unsigned work; | |
250 char tmpbit[BITS_INT]; | |
251 int retval; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
252 |
14276 | 253 if ( nbits > BITS_INT ){ |
254 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "get_bstm(): %d: %d Error.\n", | |
255 nbits, BITS_INT); | |
256 exit(1); | |
257 } | |
258 retval = bread(tmpbit, sizeof(*tmpbit), nbits, sh); | |
259 for (ibit=retval; ibit<nbits; ibit++){ | |
260 tmpbit[ibit] = 0; | |
261 } | |
262 mask = 0x1<<(nbits-1); | |
263 work=0; | |
264 for ( ibit=0; ibit<nbits; ibit++ ){ | |
265 work += mask*tmpbit[ibit]; | |
266 mask >>= 1; | |
267 } | |
268 *data = work; | |
26754
63630c09e237
cosmetics: Remove pointless parentheses from return calls.
diego
parents:
22577
diff
changeset
|
269 return retval; |
14276 | 270 } |
271 | |
272 static int GetVqInfo( tvqConfInfoSubBlock *cfg, | |
273 int bits0[], | |
274 int bits1[], | |
275 int variableBits, | |
276 INDEX *index, | |
277 sh_audio_t *sh) | |
278 { | |
279 int idiv; | |
280 int bitcount = 0; | |
281 | |
282 if ( index->btype == BLK_LONG ){ | |
283 TvqUpdateVectorInfo( variableBits, &cfg->ndiv, bits0, bits1 ); // re-calculate VQ bits | |
284 } | |
285 for ( idiv=0; idiv<cfg->ndiv; idiv++ ){ | |
286 bitcount += get_bstm(&index->wvq[idiv],bits0[idiv],sh); /* CB 0 */ | |
287 bitcount += get_bstm(&index->wvq[idiv+cfg->ndiv],bits1[idiv],sh); /* CB 1 */ | |
288 } | |
289 return bitcount; | |
290 } | |
291 | |
292 static int GetBseInfo( tvqConfInfo *cf, tvqConfInfoSubBlock *cfg, INDEX *index, sh_audio_t *sh) | |
293 { | |
294 int i_sup, isf, itmp, idiv; | |
295 int bitcount = 0; | |
296 | |
297 for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){ | |
298 for ( isf=0; isf<cfg->nsf; isf++ ){ | |
299 for ( idiv=0; idiv<cfg->fw_ndiv; idiv++ ){ | |
300 itmp = idiv + ( isf + i_sup * cfg->nsf ) * cfg->fw_ndiv; | |
301 bitcount += get_bstm(&index->fw[itmp],cfg->fw_nbit,sh); | |
302 } | |
303 } | |
304 } | |
305 for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){ | |
306 for ( isf=0; isf<cfg->nsf; isf++ ){ | |
307 bitcount += get_bstm(&index->fw_alf[i_sup * cfg->nsf + isf],cf->FW_ARSW_BITS,sh); | |
308 } | |
309 } | |
310 return bitcount; | |
311 } | |
312 | |
313 static int GetGainInfo(tvqConfInfo *cf, tvqConfInfoSubBlock *cfg, INDEX *index, sh_audio_t *sh ) | |
314 { | |
315 int i_sup, iptop, isf; | |
316 int bitcount = 0; | |
317 | |
318 for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){ | |
319 iptop = ( cfg->nsubg + 1 ) * i_sup; | |
320 bitcount += get_bstm(&index->pow[iptop], cf->GAIN_BITS,sh); | |
321 for ( isf=0; isf<cfg->nsubg; isf++ ){ | |
322 bitcount += get_bstm(&index->pow[iptop+isf+1], cf->SUB_GAIN_BITS,sh); | |
323 } | |
324 } | |
325 return bitcount; | |
326 } | |
327 | |
328 static int GetLspInfo( tvqConfInfo *cf, INDEX *index, sh_audio_t *sh ) | |
329 { | |
330 int i_sup, itmp; | |
331 int bitcount = 0; | |
332 | |
333 for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){ | |
334 bitcount += get_bstm(&index->lsp[i_sup][0], cf->LSP_BIT0,sh); /* pred. switch */ | |
335 bitcount += get_bstm(&index->lsp[i_sup][1], cf->LSP_BIT1,sh); /* first stage */ | |
336 for ( itmp=0; itmp<cf->LSP_SPLIT; itmp++ ){ /* second stage */ | |
337 bitcount += get_bstm(&index->lsp[i_sup][itmp+2], cf->LSP_BIT2,sh); | |
338 } | |
339 } | |
340 | |
341 return bitcount; | |
342 } | |
343 | |
344 static int GetPpcInfo( tvqConfInfo *cf, INDEX *index, sh_audio_t *sh) | |
345 { | |
346 int idiv, i_sup; | |
347 int bitcount = 0; | |
348 vqf_priv_t*priv=sh->context; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
349 |
14276 | 350 for ( idiv=0; idiv<cf->N_DIV_P; idiv++ ){ |
351 bitcount += get_bstm(&(index->pls[idiv]), priv->bits_0[BLK_PPC][idiv],sh); /*CB0*/ | |
352 bitcount += get_bstm(&(index->pls[idiv+cf->N_DIV_P]), priv->bits_1[BLK_PPC][idiv],sh);/*CB1*/ | |
353 } | |
354 for (i_sup=0; i_sup<cf->N_CH; i_sup++){ | |
355 bitcount += get_bstm(&(index->pit[i_sup]), cf->BASF_BIT,sh); | |
356 bitcount += get_bstm(&(index->pgain[i_sup]), cf->PGAIN_BIT,sh); | |
357 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
358 |
14276 | 359 return bitcount; |
360 } | |
361 | |
362 static int GetEbcInfo( tvqConfInfo *cf, tvqConfInfoSubBlock *cfg, INDEX *index, sh_audio_t *sh) | |
363 { | |
364 int i_sup, isf, itmp; | |
365 int bitcount = 0; | |
366 | |
367 for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){ | |
368 for ( isf=0; isf<cfg->nsf; isf++){ | |
369 int indexSfOffset = isf * ( cfg->ncrb - cfg->ebc_crb_base ) - cfg->ebc_crb_base; | |
370 for ( itmp=cfg->ebc_crb_base; itmp<cfg->ncrb; itmp++ ){ | |
371 bitcount += get_bstm(&index->bc[i_sup][itmp+indexSfOffset], cfg->ebc_bits,sh); | |
372 } | |
373 } | |
374 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
375 |
14276 | 376 return bitcount; |
377 } | |
378 | |
379 static int vqf_read_frame(sh_audio_t *sh,INDEX *index) | |
380 { | |
381 /*--- Variables ---*/ | |
382 tvqConfInfoSubBlock *cfg; | |
383 int variableBits; | |
384 int bitcount; | |
385 int numFixedBitsPerFrame = TvqGetNumFixedBitsPerFrame(); | |
386 int btype; | |
387 vqf_priv_t *priv=sh->context; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
388 |
14276 | 389 /*--- Initialization ---*/ |
390 variableBits = 0; | |
391 bitcount = 0; | |
392 | |
393 /*--- read block independent factors ---*/ | |
394 /* Window type */ | |
395 bitcount += get_bstm( &index->w_type, priv->cf.BITS_WTYPE, sh ); | |
396 if ( TvqWtypeToBtype( index->w_type, &index->btype ) ) { | |
397 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Error: unknown window type: %d\n", index->w_type); | |
398 return 0; | |
399 } | |
400 btype = index->btype; | |
401 | |
402 /*--- read block dependent factors ---*/ | |
403 cfg = &priv->cf.cfg[btype]; // set the block dependent paremeters table | |
404 | |
405 bitcount += variableBits; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
406 |
14276 | 407 /* Interleaved vector quantization */ |
408 bitcount += GetVqInfo( cfg, priv->bits_0[btype], priv->bits_1[btype], variableBits, index, sh ); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
409 |
14276 | 410 /* Bark-scale envelope */ |
411 bitcount += GetBseInfo( &priv->cf, cfg, index, sh ); | |
412 /* Gain */ | |
413 bitcount += GetGainInfo( &priv->cf, cfg, index, sh ); | |
414 /* LSP */ | |
415 bitcount += GetLspInfo( &priv->cf, index, sh ); | |
416 /* PPC */ | |
417 if ( cfg->ppc_enable ){ | |
418 bitcount += GetPpcInfo( &priv->cf, index, sh ); | |
419 } | |
420 /* Energy Balance Calibration */ | |
421 if ( cfg->ebc_enable ){ | |
422 bitcount += GetEbcInfo( &priv->cf, cfg, index, sh ); | |
423 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
424 |
14276 | 425 return bitcount == numFixedBitsPerFrame ? bitcount/8 : 0; |
426 } | |
427 | |
428 static void frtobuf_s16(float out[], /* Input --- input data frame */ | |
429 short bufout[], /* Output --- output data buffer array */ | |
430 unsigned frameSize, /* Input --- frame size */ | |
431 unsigned numChannels) /* Input --- number of channels */ | |
432 { | |
433 /*--- Variables ---*/ | |
434 unsigned ismp, ich; | |
435 float *ptr; | |
436 float dtmp; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
437 |
14276 | 438 for ( ich=0; ich<numChannels; ich++ ){ |
439 ptr = out+ich*frameSize; | |
440 for ( ismp=0; ismp<frameSize; ismp++ ){ | |
441 dtmp = ptr[ismp]; | |
442 if ( dtmp >= 0. ) { | |
443 if ( dtmp > 32700. ) | |
444 dtmp = 32700.; | |
445 bufout[ismp*numChannels+ich] = (short)(dtmp+0.5); | |
446 } else { | |
447 if ( dtmp < -32700. ) | |
448 dtmp = -32700.; | |
449 bufout[ismp*numChannels+ich] = (short)(dtmp-0.5); | |
450 } | |
451 } | |
452 } | |
453 } | |
454 | |
455 static void frtobuf_float(float out[], /* Input --- input data frame */ | |
456 float bufout[], /* Output --- output data buffer array */ | |
457 unsigned frameSize, /* Input --- frame size */ | |
458 unsigned numChannels) /* Input --- number of channels */ | |
459 { | |
460 /*--- Variables ---*/ | |
461 unsigned ismp, ich; | |
462 float *ptr; | |
463 float dtmp; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
464 |
14276 | 465 for ( ich=0; ich<numChannels; ich++ ){ |
466 ptr = out+ich*frameSize; | |
467 for ( ismp=0; ismp<frameSize; ismp++ ){ | |
468 dtmp = ptr[ismp]; | |
469 if ( dtmp >= 0. ) { | |
470 if ( dtmp > 32700. ) | |
471 dtmp = 32700.; | |
472 bufout[ismp*numChannels+ich] = dtmp/32767.; | |
473 } else { | |
474 if ( dtmp < -32700. ) | |
475 dtmp = -32700.; | |
476 bufout[ismp*numChannels+ich] = dtmp/32767.; | |
477 } | |
478 } | |
479 } | |
480 } | |
481 | |
482 int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen) | |
483 { | |
484 int l, len=0; | |
485 vqf_priv_t *priv=sh_audio->context; | |
486 while(len<minlen) | |
487 { | |
488 float out[priv->framesize*sh_audio->channels]; | |
489 l=vqf_read_frame(sh_audio,&priv->index); | |
490 if(!l) break; | |
491 TvqDecodeFrame(&priv->index, out); | |
492 if (priv->skip_cnt) { | |
493 // Ingnore first two frames, replace them with silence | |
494 priv->skip_cnt--; | |
495 memset(buf, 0, priv->framesize*sh_audio->channels*sh_audio->samplesize); | |
496 } else { | |
497 if (sh_audio->sample_format == AF_FORMAT_S16_NE) | |
498 frtobuf_s16(out, (short *)buf, priv->framesize, sh_audio->channels); | |
499 else | |
500 frtobuf_float(out, (float *)buf, priv->framesize, sh_audio->channels); | |
501 } | |
502 len += priv->framesize*sh_audio->channels*sh_audio->samplesize; | |
503 buf += priv->framesize*sh_audio->channels*sh_audio->samplesize; | |
504 } | |
505 return len; | |
506 } |