~ubuntu-branches/ubuntu/wily/hedgewars/wily

« back to all changes in this revision

Viewing changes to misc/libtremor/mapping0.c

  • Committer: Package Import Robot
  • Author(s): Dmitry E. Oboukhov
  • Date: 2011-09-23 10:16:55 UTC
  • mfrom: (1.2.11 upstream)
  • Revision ID: package-import@ubuntu.com-20110923101655-3977th2gc5n0a3pv
Tags: 0.9.16-1
* New upstream version.
 + Downloadable content! Simply click to install any content.
   New voices, hats, maps, themes, translations, music, scripts...
   Hedgewars is now more customisable than ever before! As time goes
   by we will be soliciting community content to feature on this page,
   so remember to check it from time to time. If you decide you want
   to go back to standard Hedgewars, just remove the Data directory
   from your Hedgewars config directory.
 + 3-D rendering! Diorama-like rendering of the game in a variety
   of 3D modes. Let us know which ones work best for you, we didn't
   really have the equipment to test them all.
 + Resizable game window.
 + New utilities! The Time Box will remove one of your hedgehogs
   from the game for a while, protecting from attack until it returns,
   somewhere else on the map. Land spray will allow you to build bridges,
   seal up holes, or just make life unpleasant for your enemies.
 + New single player: Bamboo Thicket, That Sinking Feeling, Newton and
   the Tree and multi-player: The Specialists, Space Invaders,
   Racer - scripts! And a ton more script hooks for scripters
 + New twists on old weapons. Drill strike, seduction and fire have
   been adjusted. Defective mines have been added, rope can attach to
   hogs/crates/barrels again, grenades now have variable bounce (use
   precise key + 1-5). Portal gun is now more usable in flight and
   all game actions are a lot faster.
 + New theme - Golf, dozens of new community hats and a new
   localised Default voice, Ukranian.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/********************************************************************
 
2
 *                                                                  *
 
3
 * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE.   *
 
4
 *                                                                  *
 
5
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
 
6
 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
 
7
 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
 
8
 *                                                                  *
 
9
 * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002    *
 
10
 * BY THE Xiph.Org FOUNDATION http://www.xiph.org/                  *
 
11
 *                                                                  *
 
12
 ********************************************************************
 
13
 
 
14
 function: channel mapping 0 implementation
 
15
 
 
16
 ********************************************************************/
 
17
 
 
18
#include <stdlib.h>
 
19
#include <stdio.h>
 
20
#include <string.h>
 
21
#include <math.h>
 
22
#include "ogg.h"
 
23
#include "ivorbiscodec.h"
 
24
#include "mdct.h"
 
25
#include "codec_internal.h"
 
26
#include "codebook.h"
 
27
#include "window.h"
 
28
#include "registry.h"
 
29
#include "misc.h"
 
30
 
 
31
/* simplistic, wasteful way of doing this (unique lookup for each
 
32
   mode/submapping); there should be a central repository for
 
33
   identical lookups.  That will require minor work, so I'm putting it
 
34
   off as low priority.
 
35
 
 
36
   Why a lookup for each backend in a given mode?  Because the
 
37
   blocksize is set by the mode, and low backend lookups may require
 
38
   parameters from other areas of the mode/mapping */
 
39
 
 
40
typedef struct {
 
41
  vorbis_info_mode *mode;
 
42
  vorbis_info_mapping0 *map;
 
43
 
 
44
  vorbis_look_floor **floor_look;
 
45
 
 
46
  vorbis_look_residue **residue_look;
 
47
 
 
48
  vorbis_func_floor **floor_func;
 
49
  vorbis_func_residue **residue_func;
 
50
 
 
51
  int ch;
 
52
  long lastframe; /* if a different mode is called, we need to 
 
53
                     invalidate decay */
 
54
} vorbis_look_mapping0;
 
55
 
 
56
static void mapping0_free_info(vorbis_info_mapping *i){
 
57
  vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)i;
 
58
  if(info){
 
59
    memset(info,0,sizeof(*info));
 
60
    _ogg_free(info);
 
61
  }
 
62
}
 
63
 
 
64
static void mapping0_free_look(vorbis_look_mapping *look){
 
65
  int i;
 
66
  vorbis_look_mapping0 *l=(vorbis_look_mapping0 *)look;
 
67
  if(l){
 
68
 
 
69
    for(i=0;i<l->map->submaps;i++){
 
70
      l->floor_func[i]->free_look(l->floor_look[i]);
 
71
      l->residue_func[i]->free_look(l->residue_look[i]);
 
72
    }
 
73
 
 
74
    _ogg_free(l->floor_func);
 
75
    _ogg_free(l->residue_func);
 
76
    _ogg_free(l->floor_look);
 
77
    _ogg_free(l->residue_look);
 
78
    memset(l,0,sizeof(*l));
 
79
    _ogg_free(l);
 
80
  }
 
81
}
 
82
 
 
83
static vorbis_look_mapping *mapping0_look(vorbis_dsp_state *vd,vorbis_info_mode *vm,
 
84
                          vorbis_info_mapping *m){
 
85
  int i;
 
86
  vorbis_info          *vi=vd->vi;
 
87
  codec_setup_info     *ci=(codec_setup_info *)vi->codec_setup;
 
88
  vorbis_look_mapping0 *look=(vorbis_look_mapping0 *)_ogg_calloc(1,sizeof(*look));
 
89
  vorbis_info_mapping0 *info=look->map=(vorbis_info_mapping0 *)m;
 
90
  look->mode=vm;
 
91
  
 
92
  look->floor_look=(vorbis_look_floor **)_ogg_calloc(info->submaps,sizeof(*look->floor_look));
 
93
 
 
94
  look->residue_look=(vorbis_look_residue **)_ogg_calloc(info->submaps,sizeof(*look->residue_look));
 
95
 
 
96
  look->floor_func=(vorbis_func_floor **)_ogg_calloc(info->submaps,sizeof(*look->floor_func));
 
97
  look->residue_func=(vorbis_func_residue **)_ogg_calloc(info->submaps,sizeof(*look->residue_func));
 
98
  
 
99
  for(i=0;i<info->submaps;i++){
 
100
    int floornum=info->floorsubmap[i];
 
101
    int resnum=info->residuesubmap[i];
 
102
 
 
103
    look->floor_func[i]=_floor_P[ci->floor_type[floornum]];
 
104
    look->floor_look[i]=look->floor_func[i]->
 
105
      look(vd,vm,ci->floor_param[floornum]);
 
106
    look->residue_func[i]=_residue_P[ci->residue_type[resnum]];
 
107
    look->residue_look[i]=look->residue_func[i]->
 
108
      look(vd,vm,ci->residue_param[resnum]);
 
109
    
 
110
  }
 
111
 
 
112
  look->ch=vi->channels;
 
113
 
 
114
  return(look);
 
115
}
 
116
 
 
117
static int ilog(unsigned int v){
 
118
  int ret=0;
 
119
  if(v)--v;
 
120
  while(v){
 
121
    ret++;
 
122
    v>>=1;
 
123
  }
 
124
  return(ret);
 
125
}
 
126
 
 
127
/* also responsible for range checking */
 
128
static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb){
 
129
  int i;
 
130
  vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)_ogg_calloc(1,sizeof(*info));
 
131
  codec_setup_info     *ci=(codec_setup_info *)vi->codec_setup;
 
132
  memset(info,0,sizeof(*info));
 
133
 
 
134
  if(oggpack_read(opb,1))
 
135
    info->submaps=oggpack_read(opb,4)+1;
 
136
  else
 
137
    info->submaps=1;
 
138
 
 
139
  if(oggpack_read(opb,1)){
 
140
    info->coupling_steps=oggpack_read(opb,8)+1;
 
141
 
 
142
    for(i=0;i<info->coupling_steps;i++){
 
143
      int testM=info->coupling_mag[i]=oggpack_read(opb,ilog(vi->channels));
 
144
      int testA=info->coupling_ang[i]=oggpack_read(opb,ilog(vi->channels));
 
145
 
 
146
      if(testM<0 || 
 
147
         testA<0 || 
 
148
         testM==testA || 
 
149
         testM>=vi->channels ||
 
150
         testA>=vi->channels) goto err_out;
 
151
    }
 
152
 
 
153
  }
 
154
 
 
155
  if(oggpack_read(opb,2)>0)goto err_out; /* 2,3:reserved */
 
156
    
 
157
  if(info->submaps>1){
 
158
    for(i=0;i<vi->channels;i++){
 
159
      info->chmuxlist[i]=oggpack_read(opb,4);
 
160
      if(info->chmuxlist[i]>=info->submaps)goto err_out;
 
161
    }
 
162
  }
 
163
  for(i=0;i<info->submaps;i++){
 
164
    int temp=oggpack_read(opb,8);
 
165
    if(temp>=ci->times)goto err_out;
 
166
    info->floorsubmap[i]=oggpack_read(opb,8);
 
167
    if(info->floorsubmap[i]>=ci->floors)goto err_out;
 
168
    info->residuesubmap[i]=oggpack_read(opb,8);
 
169
    if(info->residuesubmap[i]>=ci->residues)goto err_out;
 
170
  }
 
171
 
 
172
  return info;
 
173
 
 
174
 err_out:
 
175
  mapping0_free_info(info);
 
176
  return(NULL);
 
177
}
 
178
 
 
179
static int seq=0;
 
180
static int mapping0_inverse(vorbis_block *vb,vorbis_look_mapping *l){
 
181
  vorbis_dsp_state     *vd=vb->vd;
 
182
  vorbis_info          *vi=vd->vi;
 
183
  codec_setup_info     *ci=(codec_setup_info *)vi->codec_setup;
 
184
  private_state        *b=(private_state *)vd->backend_state;
 
185
  vorbis_look_mapping0 *look=(vorbis_look_mapping0 *)l;
 
186
  vorbis_info_mapping0 *info=look->map;
 
187
 
 
188
  int                   i,j;
 
189
  long                  n=vb->pcmend=ci->blocksizes[vb->W];
 
190
 
 
191
  ogg_int32_t **pcmbundle=(ogg_int32_t **)alloca(sizeof(*pcmbundle)*vi->channels);
 
192
  int    *zerobundle=(int *)alloca(sizeof(*zerobundle)*vi->channels);
 
193
  
 
194
  int   *nonzero  =(int *)alloca(sizeof(*nonzero)*vi->channels);
 
195
  void **floormemo=(void **)alloca(sizeof(*floormemo)*vi->channels);
 
196
  
 
197
  /* time domain information decode (note that applying the
 
198
     information would have to happen later; we'll probably add a
 
199
     function entry to the harness for that later */
 
200
  /* NOT IMPLEMENTED */
 
201
 
 
202
  /* recover the spectral envelope; store it in the PCM vector for now */
 
203
  for(i=0;i<vi->channels;i++){
 
204
    int submap=info->chmuxlist[i];
 
205
    floormemo[i]=look->floor_func[submap]->
 
206
      inverse1(vb,look->floor_look[submap]);
 
207
    if(floormemo[i])
 
208
      nonzero[i]=1;
 
209
    else
 
210
      nonzero[i]=0;      
 
211
    memset(vb->pcm[i],0,sizeof(*vb->pcm[i])*n/2);
 
212
  }
 
213
 
 
214
  /* channel coupling can 'dirty' the nonzero listing */
 
215
  for(i=0;i<info->coupling_steps;i++){
 
216
    if(nonzero[info->coupling_mag[i]] ||
 
217
       nonzero[info->coupling_ang[i]]){
 
218
      nonzero[info->coupling_mag[i]]=1; 
 
219
      nonzero[info->coupling_ang[i]]=1; 
 
220
    }
 
221
  }
 
222
 
 
223
  /* recover the residue into our working vectors */
 
224
  for(i=0;i<info->submaps;i++){
 
225
    int ch_in_bundle=0;
 
226
    for(j=0;j<vi->channels;j++){
 
227
      if(info->chmuxlist[j]==i){
 
228
        if(nonzero[j])
 
229
          zerobundle[ch_in_bundle]=1;
 
230
        else
 
231
          zerobundle[ch_in_bundle]=0;
 
232
        pcmbundle[ch_in_bundle++]=vb->pcm[j];
 
233
      }
 
234
    }
 
235
    
 
236
    look->residue_func[i]->inverse(vb,look->residue_look[i],
 
237
                                   pcmbundle,zerobundle,ch_in_bundle);
 
238
  }
 
239
 
 
240
  //for(j=0;j<vi->channels;j++)
 
241
  //_analysis_output("coupled",seq+j,vb->pcm[j],-8,n/2,0,0);
 
242
 
 
243
 
 
244
  /* channel coupling */
 
245
  for(i=info->coupling_steps-1;i>=0;i--){
 
246
    ogg_int32_t *pcmM=vb->pcm[info->coupling_mag[i]];
 
247
    ogg_int32_t *pcmA=vb->pcm[info->coupling_ang[i]];
 
248
    
 
249
    for(j=0;j<n/2;j++){
 
250
      ogg_int32_t mag=pcmM[j];
 
251
      ogg_int32_t ang=pcmA[j];
 
252
      
 
253
      if(mag>0)
 
254
        if(ang>0){
 
255
          pcmM[j]=mag;
 
256
          pcmA[j]=mag-ang;
 
257
        }else{
 
258
          pcmA[j]=mag;
 
259
          pcmM[j]=mag+ang;
 
260
        }
 
261
      else
 
262
        if(ang>0){
 
263
          pcmM[j]=mag;
 
264
          pcmA[j]=mag+ang;
 
265
        }else{
 
266
          pcmA[j]=mag;
 
267
          pcmM[j]=mag-ang;
 
268
        }
 
269
    }
 
270
  }
 
271
 
 
272
  //for(j=0;j<vi->channels;j++)
 
273
  //_analysis_output("residue",seq+j,vb->pcm[j],-8,n/2,0,0);
 
274
 
 
275
  /* compute and apply spectral envelope */
 
276
  for(i=0;i<vi->channels;i++){
 
277
    ogg_int32_t *pcm=vb->pcm[i];
 
278
    int submap=info->chmuxlist[i];
 
279
    look->floor_func[submap]->
 
280
      inverse2(vb,look->floor_look[submap],floormemo[i],pcm);
 
281
  }
 
282
 
 
283
  //for(j=0;j<vi->channels;j++)
 
284
  //_analysis_output("mdct",seq+j,vb->pcm[j],-24,n/2,0,1);
 
285
 
 
286
  /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */
 
287
  /* only MDCT right now.... */
 
288
  for(i=0;i<vi->channels;i++){
 
289
    ogg_int32_t *pcm=vb->pcm[i];
 
290
    mdct_backward(n,pcm,pcm);
 
291
  }
 
292
 
 
293
  //for(j=0;j<vi->channels;j++)
 
294
  //_analysis_output("imdct",seq+j,vb->pcm[j],-24,n,0,0);
 
295
 
 
296
  /* window the data */
 
297
  for(i=0;i<vi->channels;i++){
 
298
    ogg_int32_t *pcm=vb->pcm[i];
 
299
    if(nonzero[i])
 
300
      _vorbis_apply_window(pcm,b->window,ci->blocksizes,vb->lW,vb->W,vb->nW);
 
301
    else
 
302
      for(j=0;j<n;j++)
 
303
        pcm[j]=0;
 
304
    
 
305
  }
 
306
 
 
307
  //for(j=0;j<vi->channels;j++)
 
308
  //_analysis_output("window",seq+j,vb->pcm[j],-24,n,0,0);
 
309
 
 
310
  seq+=vi->channels;
 
311
  /* all done! */
 
312
  return(0);
 
313
}
 
314
 
 
315
/* export hooks */
 
316
vorbis_func_mapping mapping0_exportbundle={
 
317
  &mapping0_unpack,
 
318
  &mapping0_look,
 
319
  &mapping0_free_info,
 
320
  &mapping0_free_look,
 
321
  &mapping0_inverse
 
322
};