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