~ubuntu-branches/ubuntu/lucid/mpg123/lucid

« back to all changes in this revision

Viewing changes to src/decode_ntom.c

Tags: upstream-0.60
ImportĀ upstreamĀ versionĀ 0.60

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
        decode_ntom.c: N->M down/up sampling. Not optimized for speed.
 
3
 
 
4
        copyright 1995-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
 
5
        see COPYING and AUTHORS files in distribution or http://mpg123.de
 
6
        initially written by Michael Hipp
 
7
*/
 
8
 
 
9
#include <stdlib.h>
 
10
#include <math.h>
 
11
#include <string.h>
 
12
 
 
13
#include "config.h"
 
14
#include "mpg123.h"
 
15
 
 
16
#define WRITE_SAMPLE(samples,sum,clip) \
 
17
  if( (sum) > 32767.0) { *(samples) = 0x7fff; (clip)++; } \
 
18
  else if( (sum) < -32768.0) { *(samples) = -0x8000; (clip)++; } \
 
19
  else { *(samples) = sum; }
 
20
 
 
21
#define NTOM_MUL (32768)
 
22
static unsigned long ntom_val[2] = { NTOM_MUL>>1,NTOM_MUL>>1 };
 
23
static unsigned long ntom_step = NTOM_MUL;
 
24
 
 
25
 
 
26
void synth_ntom_set_step(long m,long n)
 
27
{
 
28
        if(param.verbose > 1)
 
29
                fprintf(stderr,"Init rate converter: %ld->%ld\n",m,n);
 
30
 
 
31
        if(n >= 96000 || m >= 96000 || m == 0 || n == 0) {
 
32
                fprintf(stderr,"NtoM converter: illegal rates\n");
 
33
                exit(1);
 
34
        }
 
35
 
 
36
        n *= NTOM_MUL;
 
37
        ntom_step = n / m;
 
38
 
 
39
        if(ntom_step > 8*NTOM_MUL) {
 
40
                fprintf(stderr,"max. 1:8 conversion allowed!\n");
 
41
                exit(1);
 
42
        }
 
43
 
 
44
        ntom_val[0] = ntom_val[1] = NTOM_MUL>>1;
 
45
}
 
46
 
 
47
int synth_ntom_8bit(real *bandPtr,int channel,unsigned char *samples,int *pnt)
 
48
{
 
49
  short samples_tmp[8*64];
 
50
  short *tmp1 = samples_tmp + channel;
 
51
  int i,ret;
 
52
  int pnt1 = 0;
 
53
 
 
54
  ret = synth_ntom(bandPtr,channel,(unsigned char *) samples_tmp,&pnt1);
 
55
  samples += channel + *pnt;
 
56
 
 
57
  for(i=0;i<(pnt1>>2);i++) {
 
58
    *samples = conv16to8[*tmp1>>AUSHIFT];
 
59
    samples += 2;
 
60
    tmp1 += 2;
 
61
  }
 
62
  *pnt += pnt1>>1;
 
63
 
 
64
  return ret;
 
65
}
 
66
 
 
67
int synth_ntom_8bit_mono(real *bandPtr,unsigned char *samples,int *pnt)
 
68
{
 
69
  short samples_tmp[8*64];
 
70
  short *tmp1 = samples_tmp;
 
71
  int i,ret;
 
72
  int pnt1 = 0;
 
73
 
 
74
  ret = synth_ntom(bandPtr,0,(unsigned char *) samples_tmp,&pnt1);
 
75
  samples += *pnt;
 
76
 
 
77
  for(i=0;i<(pnt1>>2);i++) {
 
78
    *samples++ = conv16to8[*tmp1>>AUSHIFT];
 
79
    tmp1 += 2;
 
80
  }
 
81
  *pnt += pnt1 >> 2;
 
82
  
 
83
  return ret;
 
84
}
 
85
 
 
86
int synth_ntom_8bit_mono2stereo(real *bandPtr,unsigned char *samples,int *pnt)
 
87
{
 
88
  short samples_tmp[8*64];
 
89
  short *tmp1 = samples_tmp;
 
90
  int i,ret;
 
91
  int pnt1 = 0;
 
92
 
 
93
  ret = synth_ntom(bandPtr,0,(unsigned char *) samples_tmp,&pnt1);
 
94
  samples += *pnt;
 
95
 
 
96
  for(i=0;i<(pnt1>>2);i++) {
 
97
    *samples++ = conv16to8[*tmp1>>AUSHIFT];
 
98
    *samples++ = conv16to8[*tmp1>>AUSHIFT];
 
99
    tmp1 += 2;
 
100
  }
 
101
  *pnt += pnt1 >> 1;
 
102
 
 
103
  return ret;
 
104
}
 
105
 
 
106
int synth_ntom_mono(real *bandPtr,unsigned char *samples,int *pnt)
 
107
{
 
108
  short samples_tmp[8*64];
 
109
  short *tmp1 = samples_tmp;
 
110
  int i,ret;
 
111
  int pnt1 = 0;
 
112
 
 
113
  ret = synth_ntom(bandPtr,0,(unsigned char *) samples_tmp,&pnt1);
 
114
  samples += *pnt;
 
115
 
 
116
  for(i=0;i<(pnt1>>2);i++) {
 
117
    *( (short *)samples) = *tmp1;
 
118
    samples += 2;
 
119
    tmp1 += 2;
 
120
  }
 
121
  *pnt += pnt1 >> 1;
 
122
 
 
123
  return ret;
 
124
}
 
125
 
 
126
 
 
127
int synth_ntom_mono2stereo(real *bandPtr,unsigned char *samples,int *pnt)
 
128
{
 
129
  int i,ret;
 
130
  int pnt1 = *pnt;
 
131
 
 
132
  ret = synth_ntom(bandPtr,0,samples,pnt);
 
133
  samples += pnt1;
 
134
  
 
135
  for(i=0;i<((*pnt-pnt1)>>2);i++) {
 
136
    ((short *)samples)[1] = ((short *)samples)[0];
 
137
    samples+=4;
 
138
  }
 
139
 
 
140
  return ret;
 
141
}
 
142
 
 
143
 
 
144
int synth_ntom(real *bandPtr,int channel,unsigned char *out,int *pnt)
 
145
{
 
146
  static real buffs[2][2][0x110];
 
147
  static const int step = 2;
 
148
  static int bo = 1;
 
149
  short *samples = (short *) (out + *pnt);
 
150
 
 
151
  real *b0,(*buf)[0x110];
 
152
  int clip = 0; 
 
153
  int bo1;
 
154
  int ntom;
 
155
 
 
156
  if(have_eq_settings)
 
157
        do_equalizer(bandPtr,channel);
 
158
 
 
159
  if(!channel) {
 
160
    bo--;
 
161
    bo &= 0xf;
 
162
    buf = buffs[0];
 
163
    ntom = ntom_val[1] = ntom_val[0];
 
164
  }
 
165
  else {
 
166
    samples++;
 
167
    out += 2; /* to compute the right *pnt value */
 
168
    buf = buffs[1];
 
169
    ntom = ntom_val[1];
 
170
  }
 
171
 
 
172
  if(bo & 0x1) {
 
173
    b0 = buf[0];
 
174
    bo1 = bo;
 
175
    dct64(buf[1]+((bo+1)&0xf),buf[0]+bo,bandPtr);
 
176
  }
 
177
  else {
 
178
    b0 = buf[1];
 
179
    bo1 = bo+1;
 
180
    dct64(buf[0]+bo,buf[1]+bo+1,bandPtr);
 
181
  }
 
182
 
 
183
 
 
184
  {
 
185
    register int j;
 
186
    real *window = decwin + 16 - bo1;
 
187
 
 
188
    for (j=16;j;j--,window+=0x10)
 
189
    {
 
190
      real sum;
 
191
 
 
192
      ntom += ntom_step;
 
193
      if(ntom < NTOM_MUL) {
 
194
        window += 16;
 
195
        b0 += 16;
 
196
        continue;
 
197
      }
 
198
 
 
199
      sum  = *window++ * *b0++;
 
200
      sum -= *window++ * *b0++;
 
201
      sum += *window++ * *b0++;
 
202
      sum -= *window++ * *b0++;
 
203
      sum += *window++ * *b0++;
 
204
      sum -= *window++ * *b0++;
 
205
      sum += *window++ * *b0++;
 
206
      sum -= *window++ * *b0++;
 
207
      sum += *window++ * *b0++;
 
208
      sum -= *window++ * *b0++;
 
209
      sum += *window++ * *b0++;
 
210
      sum -= *window++ * *b0++;
 
211
      sum += *window++ * *b0++;
 
212
      sum -= *window++ * *b0++;
 
213
      sum += *window++ * *b0++;
 
214
      sum -= *window++ * *b0++;
 
215
 
 
216
      while(ntom >= NTOM_MUL) {
 
217
        WRITE_SAMPLE(samples,sum,clip);
 
218
        samples += step;
 
219
        ntom -= NTOM_MUL;
 
220
      }
 
221
    }
 
222
 
 
223
    ntom += ntom_step;
 
224
    if(ntom >= NTOM_MUL)
 
225
    {
 
226
      real sum;
 
227
      sum  = window[0x0] * b0[0x0];
 
228
      sum += window[0x2] * b0[0x2];
 
229
      sum += window[0x4] * b0[0x4];
 
230
      sum += window[0x6] * b0[0x6];
 
231
      sum += window[0x8] * b0[0x8];
 
232
      sum += window[0xA] * b0[0xA];
 
233
      sum += window[0xC] * b0[0xC];
 
234
      sum += window[0xE] * b0[0xE];
 
235
 
 
236
      while(ntom >= NTOM_MUL) {
 
237
        WRITE_SAMPLE(samples,sum,clip);
 
238
        samples += step;
 
239
        ntom -= NTOM_MUL;
 
240
      }
 
241
    }
 
242
 
 
243
    b0-=0x10,window-=0x20;
 
244
    window += bo1<<1;
 
245
 
 
246
    for (j=15;j;j--,b0-=0x20,window-=0x10)
 
247
    {
 
248
      real sum;
 
249
 
 
250
      ntom += ntom_step;
 
251
      if(ntom < NTOM_MUL) {
 
252
        window -= 16;
 
253
        b0 += 16;
 
254
        continue;
 
255
      }
 
256
 
 
257
      sum = -*(--window) * *b0++;
 
258
      sum -= *(--window) * *b0++;
 
259
      sum -= *(--window) * *b0++;
 
260
      sum -= *(--window) * *b0++;
 
261
      sum -= *(--window) * *b0++;
 
262
      sum -= *(--window) * *b0++;
 
263
      sum -= *(--window) * *b0++;
 
264
      sum -= *(--window) * *b0++;
 
265
      sum -= *(--window) * *b0++;
 
266
      sum -= *(--window) * *b0++;
 
267
      sum -= *(--window) * *b0++;
 
268
      sum -= *(--window) * *b0++;
 
269
      sum -= *(--window) * *b0++;
 
270
      sum -= *(--window) * *b0++;
 
271
      sum -= *(--window) * *b0++;
 
272
      sum -= *(--window) * *b0++;
 
273
 
 
274
      while(ntom >= NTOM_MUL) {
 
275
        WRITE_SAMPLE(samples,sum,clip);
 
276
        samples += step;
 
277
        ntom -= NTOM_MUL;
 
278
      }
 
279
    }
 
280
  }
 
281
 
 
282
  ntom_val[channel] = ntom;
 
283
  *pnt = ((unsigned char *) samples - out);
 
284
 
 
285
  return clip;
 
286
}
 
287
 
 
288