zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
psytune.c
Go to the documentation of this file.
1 /********************************************************************
2  * *
3  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
4  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
7  * *
8  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
9  * by the Xiph.Org Foundation http://www.xiph.org/ *
10  * *
11  ********************************************************************
12 
13  function: simple utility that runs audio through the psychoacoustics
14  without encoding
15  last mod: $Id: psytune.c 16037 2009-05-26 21:10:58Z xiphmont $
16 
17  ********************************************************************/
18 
19 /* NB: this is dead code, retained purely for doc and reference value
20  don't try to compile it */
21 
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <math.h>
26 
27 #include "vorbis/codec.h"
28 #include "codec_internal.h"
29 #include "os.h"
30 #include "misc.h"
31 #include "psy.h"
32 #include "mdct.h"
33 #include "smallft.h"
34 #include "window.h"
35 #include "scales.h"
36 #include "lpc.h"
37 #include "lsp.h"
38 #include "masking.h"
39 #include "registry.h"
40 
42  0, /* decaydBpms */
43  8, /* lines per eighth octave */
44 
45  /* thresh sample period, preecho clamp trigger threshhold, range, minenergy */
46  256, {26.f,26.f,26.f,30.f}, {-90.f,-90.f,-90.f,-90.f}, -90.f,
47  -6.f,
48 
49  0,
50 
51  0.,
52  0.,
53 };
54 
55 static vp_part _vp_part0[]={
56  { 1,9e10f, 9e10f, 1.f,9999.f},
57  { 9999, .75f, 9e10f, .5f,9999.f},
58 /*{ 9999, 1.5f, 9e10f, .5f,9999.f},*/
59  { 18,9e10f, 9e10f, .5f, 30.f},
60  { 9999,9e10f, 9e10f, .5f, 30.f}
61 };
62 
63 static vp_couple _vp_couple0[]={
64  { 1, {9e10f,9e10f,0}, { 0.f, 0.f,0}, { 0.f, 0.f,0}, {0.f,0.f,0}},
65  { 18, {9e10f,9e10f,0}, { 0.f, 0.f,0}, { 0.f, 0.f,0}, {0.f,0.f,0}},
66  { 9999, {9e10f,9e10f,0}, { 0.f, 9e10f,0}, { 0.f,22.f,1}, {0.f,0.f,0}}
67 };
68 
70  ATH_Bark_dB_lineaggressive,
71 
72  -100.f,
73  -140.f,
74  6.f, /* floor master att */
75 
76  /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */
77  /* x: 63 88 125 175 250 350 500 700 1k 1.4k 2k 2.8k 4k 5.6k 8k 11.5k 16k Hz */
78  /* y: 0 10 20 30 40 50 60 70 80 90 100 dB */
79  1, /* tonemaskp */
80  0.f, /* tone master att */
81  /* 0 10 20 30 40 50 60 70 80 90 100 */
82  {
83  {-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f}, /*63*/
84  {-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f}, /*88*/
85  {-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f}, /*125*/
86 
87  {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*175*/
88  {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*250*/
89  {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*350*/
90  {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*500*/
91  {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*700*/
92  {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*1000*/
93  {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*1400*/
94  {-40.f,-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*2000*/
95  {-40.f,-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*2800*/
96  {-40.f,-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*4000*/
97 
98  {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*5600*/
99 
100  {-30.f,-30.f,-33.f,-35.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*8000*/
101  {-30.f,-30.f,-33.f,-35.f,-40.f,-45.f,-50.f,-60.f,-70.f,-85.f,-100.f}, /*11500*/
102  {-24.f,-24.f,-26.f,-32.f,-32.f,-42.f,-50.f,-60.f,-70.f,-85.f,-100.f}, /*16000*/
103 
104  },
105 
106  1,/* peakattp */
107  {{-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*63*/
108  {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*88*/
109  {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*125*/
110  {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*175*/
111  {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*250*/
112  {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*350*/
113  {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*500*/
114  {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*700*/
115  {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*1000*/
116  {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*1400*/
117  {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*2000*/
118  {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*2800*/
119  {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*4000*/
120  {-10.f,-12.f,-14.f,-16.f,-16.f,-20.f,-24.f,-30.f,-32.f,-40.f,-40.f},/*5600*/
121  {-10.f,-12.f,-14.f,-16.f,-16.f,-20.f,-24.f,-30.f,-32.f,-40.f,-40.f},/*8000*/
122  {-10.f,-10.f,-10.f,-12.f,-14.f,-18.f,-22.f,-28.f,-32.f,-40.f,-40.f},/*11500*/
123  {-10.f,-10.f,-10.f,-12.f,-14.f,-18.f,-22.f,-28.f,-32.f,-40.f,-40.f},/*16000*/
124  },
125 
126  1,/*noisemaskp */
127  -10.f, /* suppress any noise curve over maxspec+n */
128  .5f, /* low window */
129  .5f, /* high window */
130  10,
131  10,
132  25,
133  {.000f, 0.f, /*63*/
134  .000f, 0.f, /*88*/
135  .000f, 0.f, /*125*/
136  .000f, 0.f, /*175*/
137  .000f, 0.f, /*250*/
138  .000f, 0.f, /*350*/
139  .000f, 0.f, /*500*/
140  .000f, 0.f, /*700*/
141  .000f, 0.f, /*1000*/
142  .300f, 0.f, /*1400*/
143  .300f, 0.f, /*2000*/
144  .300f, 0.f, /*2800*/
145  .500f, 0.f, /*4000*/
146  .700f, 0.f, /*5600*/
147  .850f, 0.f, /*8000*/
148  .900f, 0.f, /*11500*/
149  .900f, 1.f, /*16000*/
150  },
151 
152  95.f, /* even decade + 5 is important; saves an rint() later in a
153  tight loop) */
154  -44.,
155 
156  32,
158 };
159 
161  {0},
162 
163  {32},
164  {0},
165  {0},
166  {{-1}},
167 
168  2,
169  {0,1024,
170 
171  88,31,243,
172 
173  14,54,143,460,
174 
175  6,3,10, 22,18,26, 41,36,47,
176  69,61,78, 112,99,126, 185,162,211,
177  329,282,387, 672,553,825
178  },
179 
180  60,30,400,
181  20,8,1,18.,
182  20,600,
183  960};
184 
185 
186 static vorbis_info_mapping0 mapping_info={1,{0,1},{0},{0},{0},0, 1, {0},{1}};
188  1,1,1,1,1,0,1,
189  {NULL},
190  {0},{&mapping_info},
191  {0},{NULL},
192  {1},{&_floor_set0},
193  {2},{NULL},
194  {NULL},
195  {&_psy_set0},
196  &_psy_set0G};
197 
198 static int noisy=0;
199 void analysis(char *base,int i,float *v,int n,int bark,int dB){
200  if(noisy){
201  int j;
202  FILE *of;
203  char buffer[80];
204  sprintf(buffer,"%s_%d.m",base,i);
205  of=fopen(buffer,"w");
206 
207  for(j=0;j<n;j++){
208  if(dB && v[j]==0)
209  fprintf(of,"\n\n");
210  else{
211  if(bark)
212  fprintf(of,"%g ",toBARK(22050.f*j/n));
213  else
214  fprintf(of,"%g ",(float)j);
215 
216  if(dB){
217  fprintf(of,"%g\n",todB(v+j));
218  }else{
219  fprintf(of,"%g\n",v[j]);
220  }
221  }
222  }
223  fclose(of);
224  }
225 }
226 
227 long frameno=0;
228 
229 /****************************************************************/
230 
231 int main(int argc,char *argv[]){
232  int eos=0;
233  float nonz=0.f;
234  float acc=0.f;
235  float tot=0.f;
236  float ampmax=-9999,newmax;
237  float local_ampmax[2];
238 
239  int framesize=2048;
240  float ampmax_att_per_sec=-6.;
241 
242  float *pcm[2],*out[2],*window,*flr[2],*mask[2],*work[2];
243  signed char *buffer,*buffer2;
244  mdct_lookup m_look;
245  drft_lookup f_look;
246  vorbis_look_psy p_look;
247  vorbis_look_psy_global *pg_look;
248  vorbis_look_floor *floor_look;
249  vorbis_info vi;
250  long i,j,k;
251 
252  int ath=0;
253  int decayp=0;
254 
255  argv++;
256  while(*argv){
257  if(*argv[0]=='-'){
258  /* option */
259  if(argv[0][1]=='v'){
260  noisy=0;
261  }
262  }else
263  if(*argv[0]=='+'){
264  /* option */
265  if(argv[0][1]=='v'){
266  noisy=1;
267  }
268  }else
269  framesize=atoi(argv[0]);
270  argv++;
271  }
272 
273  vi.channels=2;
275 
276  pcm[0]=_ogg_malloc(framesize*sizeof(float));
277  pcm[1]=_ogg_malloc(framesize*sizeof(float));
278  out[0]=_ogg_calloc(framesize/2,sizeof(float));
279  out[1]=_ogg_calloc(framesize/2,sizeof(float));
280  work[0]=_ogg_calloc(framesize,sizeof(float));
281  work[1]=_ogg_calloc(framesize,sizeof(float));
282  flr[0]=_ogg_calloc(framesize/2,sizeof(float));
283  flr[1]=_ogg_calloc(framesize/2,sizeof(float));
284  buffer=_ogg_malloc(framesize*4);
285  buffer2=buffer+framesize*2;
286  window=_vorbis_window_create(0,framesize,framesize/2,framesize/2);
287  mdct_init(&m_look,framesize);
288  drft_init(&f_look,framesize);
289  _vp_psy_init(&p_look,&_psy_set0,&_psy_set0G,framesize/2,44100);
290  pg_look=_vp_global_look(&vi);
291  floor_look=_floor_P[1]->look(NULL,NULL,&_floor_set0);
292 
293  /* we cheat on the WAV header; we just bypass 44 bytes and never
294  verify that it matches 16bit/stereo/44.1kHz. */
295 
296  fread(buffer,1,44,stdin);
297  fwrite(buffer,1,44,stdout);
298  memset(buffer,0,framesize*2);
299 
300  analysis("window",0,window,framesize,0,0);
301 
302  fprintf(stderr,"Processing for frame size %d...\n",framesize);
303 
304  while(!eos){
305  long bytes=fread(buffer2,1,framesize*2,stdin);
306  if(bytes<framesize*2)
307  memset(buffer2+bytes,0,framesize*2-bytes);
308 
309  if(bytes!=0){
310  int nonzero[2];
311 
312  /* uninterleave samples */
313  for(i=0;i<framesize;i++){
314  pcm[0][i]=((buffer[i*4+1]<<8)|
315  (0x00ff&(int)buffer[i*4]))/32768.f;
316  pcm[1][i]=((buffer[i*4+3]<<8)|
317  (0x00ff&(int)buffer[i*4+2]))/32768.f;
318  }
319 
320  {
321  float secs=framesize/44100.;
322 
323  ampmax+=secs*ampmax_att_per_sec;
324  if(ampmax<-9999)ampmax=-9999;
325  }
326 
327  for(i=0;i<2;i++){
328  float scale=4.f/framesize;
329  float *fft=work[i];
330  float *mdct=pcm[i];
331  float *logmdct=mdct+framesize/2;
332 
333  analysis("pre",frameno+i,pcm[i],framesize,0,0);
334 
335  /* fft and mdct transforms */
336  for(j=0;j<framesize;j++)
337  fft[j]=pcm[i][j]*=window[j];
338 
339  drft_forward(&f_look,fft);
340 
341  local_ampmax[i]=-9999.f;
342  fft[0]*=scale;
343  fft[0]=todB(fft);
344  for(j=1;j<framesize-1;j+=2){
345  float temp=scale*FAST_HYPOT(fft[j],fft[j+1]);
346  temp=fft[(j+1)>>1]=todB(&temp);
347  if(temp>local_ampmax[i])local_ampmax[i]=temp;
348  }
349  if(local_ampmax[i]>ampmax)ampmax=local_ampmax[i];
350 
351  mdct_forward(&m_look,pcm[i],mdct);
352  for(j=0;j<framesize/2;j++)
353  logmdct[j]=todB(mdct+j);
354 
355  analysis("mdct",frameno+i,logmdct,framesize/2,1,0);
356  analysis("fft",frameno+i,fft,framesize/2,1,0);
357  }
358 
359  for(i=0;i<2;i++){
360  float amp;
361  float *fft=work[i];
362  float *logmax=fft;
363  float *mdct=pcm[i];
364  float *logmdct=mdct+framesize/2;
365  float *mask=fft+framesize/2;
366 
367  /* floor psychoacoustics */
368  _vp_compute_mask(&p_look,
369  pg_look,
370  i,
371  fft,
372  logmdct,
373  mask,
374  ampmax,
375  local_ampmax[i],
376  framesize/2);
377 
378  analysis("mask",frameno+i,mask,framesize/2,1,0);
379 
380  {
381  vorbis_block vb;
382  vorbis_dsp_state vd;
383  memset(&vd,0,sizeof(vd));
384  vd.vi=&vi;
385  vb.vd=&vd;
386  vb.pcmend=framesize;
387 
388  /* floor quantization/application */
389  nonzero[i]=_floor_P[1]->forward(&vb,floor_look,
390  mdct,
391  logmdct,
392  mask,
393  logmax,
394 
395  flr[i]);
396  }
397 
398  _vp_remove_floor(&p_look,
399  pg_look,
400  logmdct,
401  mdct,
402  flr[i],
403  pcm[i],
404  local_ampmax[i]);
405 
406  for(j=0;j<framesize/2;j++)
407  if(fabs(pcm[i][j])>1500)
408  fprintf(stderr,"%ld ",frameno+i);
409 
410  analysis("res",frameno+i,pcm[i],framesize/2,1,0);
411  analysis("codedflr",frameno+i,flr[i],framesize/2,1,1);
412  }
413 
414  /* residue prequantization */
415  _vp_partition_prequant(&p_look,
416  &vi,
417  pcm,
418  nonzero);
419 
420  for(i=0;i<2;i++)
421  analysis("quant",frameno+i,pcm[i],framesize/2,1,0);
422 
423  /* channel coupling / stereo quantization */
424 
425  _vp_couple(&p_look,
426  &mapping_info,
427  pcm,
428  nonzero);
429 
430  for(i=0;i<2;i++)
431  analysis("coupled",frameno+i,pcm[i],framesize/2,1,0);
432 
433  /* decoupling */
434  for(i=mapping_info.coupling_steps-1;i>=0;i--){
435  float *pcmM=pcm[mapping_info.coupling_mag[i]];
436  float *pcmA=pcm[mapping_info.coupling_ang[i]];
437 
438  for(j=0;j<framesize/2;j++){
439  float mag=pcmM[j];
440  float ang=pcmA[j];
441 
442  if(mag>0)
443  if(ang>0){
444  pcmM[j]=mag;
445  pcmA[j]=mag-ang;
446  }else{
447  pcmA[j]=mag;
448  pcmM[j]=mag+ang;
449  }
450  else
451  if(ang>0){
452  pcmM[j]=mag;
453  pcmA[j]=mag+ang;
454  }else{
455  pcmA[j]=mag;
456  pcmM[j]=mag-ang;
457  }
458  }
459  }
460 
461  for(i=0;i<2;i++)
462  analysis("decoupled",frameno+i,pcm[i],framesize/2,1,0);
463 
464  for(i=0;i<2;i++){
465  float amp;
466 
467  for(j=0;j<framesize/2;j++)
468  pcm[i][j]*=flr[i][j];
469 
470  analysis("final",frameno+i,pcm[i],framesize/2,1,1);
471 
472  /* take it back to time */
473  mdct_backward(&m_look,pcm[i],pcm[i]);
474 
475  for(j=0;j<framesize/2;j++)
476  out[i][j]+=pcm[i][j]*window[j];
477 
478  analysis("out",frameno+i,out[i],framesize/2,0,0);
479 
480 
481  }
482 
483  /* write data. Use the part of buffer we're about to shift out */
484  for(i=0;i<2;i++){
485  char *ptr=buffer+i*2;
486  float *mono=out[i];
487  int flag=0;
488  for(j=0;j<framesize/2;j++){
489  int val=mono[j]*32767.;
490  /* might as well guard against clipping */
491  if(val>32767){
492  if(!flag)fprintf(stderr,"clipping in frame %ld ",frameno+i);
493  flag=1;
494  val=32767;
495  }
496  if(val<-32768){
497  if(!flag)fprintf(stderr,"clipping in frame %ld ",frameno+i);
498  flag=1;
499  val=-32768;
500  }
501  ptr[0]=val&0xff;
502  ptr[1]=(val>>8)&0xff;
503  ptr+=4;
504  }
505  }
506 
507  fprintf(stderr,"*");
508  fwrite(buffer,1,framesize*2,stdout);
509  memmove(buffer,buffer2,framesize*2);
510 
511  for(i=0;i<2;i++){
512  for(j=0,k=framesize/2;j<framesize/2;j++,k++)
513  out[i][j]=pcm[i][k]*window[k];
514  }
515  frameno+=2;
516  }else
517  eos=1;
518  }
519  fprintf(stderr,"average raw bits of entropy: %.03g/sample\n",acc/tot);
520  fprintf(stderr,"average nonzero samples: %.03g/%d\n",nonz/tot*framesize/2,
521  framesize/2);
522  fprintf(stderr,"Done\n\n");
523  return 0;
524 }
GLuint const GLfloat * val
Definition: glew.h:2715
void analysis(char *base, int i, float *v, int n, int bark, int dB)
Definition: psytune.c:199
vorbis_look_floor *(* look)(vorbis_dsp_state *, vorbis_info_floor *)
Definition: backends.h:33
int main(int argc, char **argv)
Definition: bootstrap.cpp:102
#define NULL
Definition: ftobjs.h:61
GLclampf f
Definition: glew.h:3390
int32_t k
Definition: e_log.c:102
GLclampd n
Definition: glew.h:7287
static vp_couple _vp_couple0[]
Definition: psytune.c:63
#define memmove
Definition: SDL_qsort.c:81
static codec_setup_info codec_setup0
Definition: psytune.c:187
void mdct_init(mdct_lookup *lookup, int n)
Definition: mdct.c:52
void mdct_forward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out)
Definition: mdct.c:493
vorbis_dsp_state * vd
Definition: codec.h:102
int32_t j
Definition: e_log.c:102
#define memset
Definition: SDL_malloc.c:633
static int noisy
Definition: psytune.c:198
void drft_init(drft_lookup *l, int n)
Definition: smallft.c:1242
vorbis_look_psy_global * _vp_global_look(vorbis_info *vi)
Definition: psy.c:36
vorbis_info * vi
Definition: codec.h:61
void mdct_backward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out)
Definition: mdct.c:397
#define FAST_HYPOT
Definition: os.h:61
const vorbis_func_floor *const _floor_P[]
Definition: registry.c:32
void * codec_setup
Definition: codec.h:53
EGLContext EGLenum EGLClientBuffer buffer
Definition: eglext.h:87
int channels
Definition: codec.h:30
static vorbis_info_psy _psy_set0
Definition: psytune.c:69
const GLdouble * v
Definition: glew.h:1377
static float todB(const float *x)
Definition: scales.h:44
void _vp_psy_init(vorbis_look_psy *p, vorbis_info_psy *vi, vorbis_info_psy_global *gi, int n, long rate)
Definition: psy.c:267
void vorbis_look_floor
#define toBARK(n)
Definition: scales.h:79
int pcmend
Definition: codec.h:96
static vp_part _vp_part0[]
Definition: psytune.c:55
GLenum GLenum GLenum GLenum GLenum scale
Definition: glew.h:12632
int coupling_mag[256]
Definition: backends.h:139
static vorbis_info_psy_global _psy_set0G
Definition: psytune.c:41
XVisualInfo * vi
int coupling_ang[256]
Definition: backends.h:140
#define _ogg_calloc
Definition: os_types.h:23
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
Definition: gl2ext.h:961
static vorbis_info_floor1 _floor_set0
Definition: psytune.c:160
int i
Definition: pngrutil.c:1377
static vorbis_info_mapping0 mapping_info
Definition: psytune.c:186
double fabs(double x)
Definition: s_fabs.c:29
void drft_forward(drft_lookup *l, float *data)
Definition: smallft.c:1232
#define _ogg_malloc
Definition: os_types.h:22
long frameno
Definition: psytune.c:227