Mercurial > mplayer.hg
annotate libmpcodecs/ad_twin.c @ 22478:3501ae650b23
Add alternative way to create command.c to svn history,
created by Rathann. Having this in the repository history
probably won't have much more than symbolic value but shouldn't
hurt either beyond bloating history size.
author | uau |
---|---|
date | Fri, 09 Mar 2007 12:30:14 +0000 |
parents | a1807995e2ab |
children | a033e5519802 |
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" |
14276 | 9 #include "wine/windef.h" |
17012 | 10 #include "libaf/af_format.h" |
14276 | 11 |
12 #include "help_mp.h" | |
13 | |
14 static ad_info_t info = | |
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 | |
17977
f70772d02eaa
Convert printfs in aviprint.c to mp_msg and give the information printing
diego
parents:
17932
diff
changeset
|
91 extern 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; | |
141 sh_audio->a_in_buffer=malloc(sh_audio->a_in_buffer_size); | |
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 | |
187 int control(sh_audio_t *sh_audio,int cmd,void* arg, ...) | |
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; | |
207 | |
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 */ | |
219 return(retval); | |
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 */ | |
226 | |
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 } | |
238 return(retval); | |
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; | |
252 | |
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; | |
269 return(retval); | |
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; | |
349 | |
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 } | |
358 | |
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 } | |
375 | |
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; | |
388 | |
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; | |
406 | |
407 /* Interleaved vector quantization */ | |
408 bitcount += GetVqInfo( cfg, priv->bits_0[btype], priv->bits_1[btype], variableBits, index, sh ); | |
409 | |
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 } | |
424 | |
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; | |
437 | |
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; | |
464 | |
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 } |