~ubuntu-branches/ubuntu/hoary/kvirc/hoary

« back to all changes in this revision

Viewing changes to src/kvilib/kvi_adpcm.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Robin Verduijn
  • Date: 2004-12-14 15:32:19 UTC
  • mfrom: (0.2.1 upstream) (1.1.1 warty)
  • Revision ID: james.westby@ubuntu.com-20041214153219-fdink3gyp2s20b6g
Tags: 2:2.1.3.1-2
* Change Recommends on xmms to a Suggests.
* Rebuild against KDE 3.3.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//
2
 
//   File : kvi_adpcm.cpp (/usr/build/NEW_kvirc/kvirc/src/kvilib/kvi_adpcm.cpp)
3
 
//   Last major modification : Mon Jun 20 1999 16:03:28 by Szymon Stefanek
4
 
//
5
 
//   This file is part of the KVirc irc client distribution
 
1
// =============================================================================
 
2
//
 
3
//      --- kvi_adpcm.cpp ---
 
4
//
 
5
//   This file is part of the KVIrc IRC client distribution
6
6
//
7
7
//   Code derived from adpcm.c : Intel ADPCM coder/decoder
8
 
//   Adapted for the KVirc distribution by Szymon Stefanek (stefanek@tin.it)
 
8
//   Adapted for the KVIrc distribution by Szymon Stefanek (stefanek@tin.it)
9
9
//   Last revision : 20 Sep 1999
10
10
//
11
11
// Copyright 1992 by Stichting Mathematisch Centrum, Amsterdam, The Netherlands.
12
12
//                           All Rights Reserved
13
13
//
14
 
// Permission to use, copy, modify, and distribute this software and its 
15
 
// documentation for any purpose and without fee is hereby granted, 
 
14
// Permission to use, copy, modify, and distribute this software and its
 
15
// documentation for any purpose and without fee is hereby granted,
16
16
// provided that the above copyright notice appear in all copies and that
17
 
// both that copyright notice and this permission notice appear in 
 
17
// both that copyright notice and this permission notice appear in
18
18
// supporting documentation, and that the names of Stichting Mathematisch
19
19
// Centrum or CWI not be used in advertising or publicity pertaining to
20
20
// distribution of the software without specific, written prior permission.
27
27
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
28
28
// OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29
29
//
 
30
// =============================================================================
30
31
//
31
32
// Intel/DVI ADPCM coder/decoder.
32
33
//
36
37
// Version 1.2, 18-Dec-92.
37
38
//
38
39
 
 
40
#define _KVI_DEBUG_CHECK_RANGE_
 
41
#define _KVI_DEBUG_CLASS_NAME_ "KviADPCM"
 
42
 
39
43
#define _KVI_ADPCM_CPP_
 
44
 
40
45
#include "kvi_adpcm.h"
41
 
 
42
 
#include <stdio.h> /*DBG*/
 
46
#include "kvi_debug.h"
43
47
 
44
48
#ifndef __STDC__
45
49
        #define signed
46
50
#endif
47
51
 
48
 
// Intel ADPCM step variation table */
49
 
static int indexTable[16] = {
50
 
    -1, -1, -1, -1, 2, 4, 6, 8,
51
 
    -1, -1, -1, -1, 2, 4, 6, 8,
52
 
};
53
 
 
54
 
static int stepsizeTable[89] = {
55
 
    7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
56
 
    19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
57
 
    50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
58
 
    130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
59
 
    337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
60
 
    876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
61
 
    2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
62
 
    5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
63
 
    15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
64
 
};
65
 
 
66
 
 
67
 
void ADPCM_compress(short indata[],char outdata[],int len,ADPCM_state *state)
68
 
{
69
 
    short *lpIn;          /* Input buffer pointer */
70
 
    signed char *lpOut;   /* output buffer pointer */
71
 
    int val;              /* Current input sample value */
72
 
    int sign;             /* Current adpcm sign bit */
73
 
    int delta;            /* Current adpcm output value */
74
 
    int diff;             /* Difference between val and valprev */
75
 
    int step;             /* Stepsize */
76
 
    int valpred;          /* Predicted output value */
77
 
    int vpdiff;           /* Current change to valpred */
78
 
    int index;            /* Current step change index */
79
 
    int outputbuffer = 0; /* place to keep previous 4-bit value */
80
 
    int bufferstep;           /* toggle between outputbuffer/output */
81
 
 
82
 
    lpOut = (signed char *)outdata;
83
 
    lpIn  = indata;
84
 
 
85
 
    valpred = state->valprev;
86
 
    index = state->index;
87
 
    step = stepsizeTable[index];
88
 
    
89
 
    bufferstep = 1;
90
 
 
91
 
    for ( ;len > 0;len-- ) {
92
 
                val = *lpIn++;
 
52
// Intel ADPCM step variation table
 
53
static int indexTable[16] =
 
54
{
 
55
        -1, -1, -1, -1, 2, 4, 6, 8,
 
56
        -1, -1, -1, -1, 2, 4, 6, 8,
 
57
};
 
58
 
 
59
static int stepsizeTable[89] =
 
60
{
 
61
        7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
 
62
        19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
 
63
        50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
 
64
        130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
 
65
        337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
 
66
        876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
 
67
        2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
 
68
        5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
 
69
        15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
 
70
};
 
71
 
 
72
void ADPCM_compress(short indata[], char outdata[], int len, ADPCM_state *state)
 
73
{
 
74
        short *lpIn;          // Input buffer pointer
 
75
        signed char *lpOut;   // Output buffer pointer
 
76
        int val;              // Current input sample value
 
77
        int sign;             // Current adpcm sign bit
 
78
        int delta;            // Current adpcm output value
 
79
        int diff;             // Difference between val and valprev
 
80
        int step;             // Stepsize
 
81
        int valpred;          // Predicted output value
 
82
        int vpdiff;           // Current change to valpred
 
83
        int index;            // Current step change index
 
84
        int outputbuffer = 0; // Place to keep previous 4-bit value
 
85
        int bufferstep;       // Toggle between outputbuffer/output
 
86
 
 
87
        lpOut = (signed char *) outdata;
 
88
        lpIn  = indata;
 
89
 
 
90
        valpred = state->valprev;
 
91
        index = state->index;
 
92
        step = stepsizeTable[index];
 
93
 
 
94
        bufferstep = 1;
 
95
        for( ; len > 0; len-- ) {
 
96
                val = *lpIn;
 
97
                lpIn++;
93
98
                // Step 1 - compute difference with previous value
94
99
                diff = val - valpred;
95
100
                sign = (diff < 0) ? 8 : 0;
96
 
                if(sign)diff=(-diff);
97
 
                // Step 2 - Divide and clamp 
 
101
                if( sign ) diff = -diff;
 
102
                // Step 2 - Divide and clamp
98
103
                // Note:
99
104
                // This code *approximately* computes:
100
 
                //    delta = diff*4/step;
101
 
                //    vpdiff = (delta+0.5)*step/4;
 
105
                //    delta  = diff * 4 / step;
 
106
                //    vpdiff = (delta + 0.5) * step / 4;
102
107
                // but in shift step bits are dropped. The net result of this is
103
108
                // that even if you have fast mul/div hardware you cannot put it to
104
109
                // good use since the fixup would be too expensive.
105
110
                //
106
111
                delta = 0;
107
112
                vpdiff = (step >> 3);
108
 
                if (diff >=step){
109
 
                    delta = 4;
110
 
                    diff -= step;
111
 
                    vpdiff += step;
112
 
                }
113
 
                step >>= 1;
114
 
                if (diff >= step) {
115
 
                    delta |= 2;
116
 
                    diff -= step;
117
 
                    vpdiff += step;
118
 
                }
119
 
                step >>= 1;
120
 
                if ( diff >= step ) {
121
 
                    delta |= 1;
122
 
                    vpdiff += step;
 
113
                if( diff >=step ) {
 
114
                        delta = 4;
 
115
                        diff -= step;
 
116
                        vpdiff += step;
 
117
                }
 
118
                step >>= 1;
 
119
                if( diff >= step ) {
 
120
                        delta |= 2;
 
121
                        diff -= step;
 
122
                        vpdiff += step;
 
123
                }
 
124
                step >>= 1;
 
125
                if( diff >= step ) {
 
126
                        delta |= 1;
 
127
                        vpdiff += step;
123
128
                }
124
129
                // Step 3 - Update previous value
125
 
                if(sign)valpred -= vpdiff;
126
 
                else valpred += vpdiff;
 
130
                if( sign ) valpred -= vpdiff;
 
131
                else       valpred += vpdiff;
127
132
                // Step 4 - Clamp previous value to 16 bits
128
 
                if ( valpred > 32767 )valpred = 32767;
129
 
                else if ( valpred < -32768 )valpred = -32768;
 
133
                if( valpred > 32767 )
 
134
                        valpred = 32767;
 
135
                else if( valpred < -32768 )
 
136
                        valpred = -32768;
130
137
                // Step 5 - Assemble value, update index and step values
131
 
                delta |= sign;  
 
138
                delta |= sign;
132
139
                index += indexTable[delta];
133
 
                if ( index < 0 ) index = 0;
134
 
                if ( index > 88 ) index = 88;
 
140
                if( index <  0 ) index =  0;
 
141
                if( index > 88 ) index = 88;
135
142
                step = stepsizeTable[index];
136
143
                // Step 6 - Output value
137
 
                if ( bufferstep )outputbuffer = (delta << 4) & 0xf0;
138
 
                else *lpOut++ = (delta & 0x0f) | outputbuffer;
 
144
                if( bufferstep )
 
145
                        outputbuffer = (delta << 4) & 0xf0;
 
146
                else {
 
147
                        *lpOut = (delta & 0x0f) | outputbuffer;
 
148
                        lpOut++;
 
149
                }
139
150
                bufferstep = !bufferstep;
140
 
    }
141
 
    // Output last step, if needed
142
 
    if (!bufferstep)*lpOut++ = outputbuffer;
143
 
    state->valprev = valpred;
144
 
    state->index = index;
 
151
        }
 
152
        // Output last step, if needed
 
153
        if( !bufferstep ) {
 
154
                *lpOut = outputbuffer;
 
155
                lpOut++;
 
156
        }
 
157
        state->valprev = valpred;
 
158
        state->index = index;
145
159
}
146
160
 
147
 
void ADPCM_uncompress(char indata[],short outdata[],int len,ADPCM_state *state)
 
161
void ADPCM_uncompress(char indata[], short outdata[], int len, ADPCM_state *state)
148
162
{
149
 
    signed char *inp;           /* Input buffer pointer */
150
 
    short *outp;                /* output buffer pointer */
151
 
    int sign;                   /* Current adpcm sign bit */
152
 
    int delta;                  /* Current adpcm output value */
153
 
    int step;                   /* Stepsize */
154
 
    int valpred;                /* Predicted value */
155
 
    int vpdiff;                 /* Current change to valpred */
156
 
    int index;                  /* Current step change index */
157
 
    int inputbuffer=0;  /* place to keep next 4-bit value */
158
 
    int bufferstep;             /* toggle between inputbuffer/input */
159
 
 
160
 
    outp = outdata;
161
 
    inp = (signed char *)indata;
162
 
 
163
 
    valpred = state->valprev;
164
 
    index = state->index;
165
 
    step = stepsizeTable[index];
166
 
 
167
 
    bufferstep = 0;
168
 
    
169
 
    for ( ; len > 0 ; len-- ) {
170
 
        
171
 
                /* Step 1 - get the delta value */
172
 
                if ( bufferstep )delta = inputbuffer & 0xf;
 
163
        signed char *inp;     // Input buffer pointer
 
164
        short *outp;          // Output buffer pointer
 
165
        int sign;             // Current adpcm sign bit
 
166
        int delta;            // Current adpcm output value
 
167
        int step;             // Stepsize
 
168
        int valpred;          // Predicted value
 
169
        int vpdiff;           // Current change to valpred
 
170
        int index;            // Current step change index
 
171
        int inputbuffer = 0;  // Place to keep next 4-bit value
 
172
        int bufferstep;       // Toggle between inputbuffer/input
 
173
 
 
174
        outp = outdata;
 
175
        inp = (signed char *) indata;
 
176
 
 
177
        valpred = state->valprev;
 
178
        index = state->index;
 
179
        step = stepsizeTable[index];
 
180
 
 
181
        bufferstep = 0;
 
182
        for( ; len > 0; len-- ) {
 
183
                // Step 1 - get the delta value
 
184
                if( bufferstep )
 
185
                        delta = inputbuffer & 0xf;
173
186
                else {
174
 
                        inputbuffer = *inp++;
 
187
                        inputbuffer = *inp;
 
188
                        inp++;
175
189
                        delta = (inputbuffer >> 4) & 0xf;
176
190
                }
177
191
                bufferstep = !bufferstep;
178
192
 
179
 
                /* Step 2 - Find new index value (for later) */
 
193
                // Step 2 - Find new index value (for later)
180
194
                index += indexTable[delta];
181
 
                if ( index < 0 ) index = 0;
182
 
                if ( index > 88 ) index = 88;
 
195
                if( index <  0 ) index =  0;
 
196
                if( index > 88 ) index = 88;
183
197
 
184
 
                /* Step 3 - Separate sign and magnitude */
 
198
                // Step 3 - Separate sign and magnitude
185
199
                sign = delta & 8;
186
200
                delta = delta & 7;
187
201
 
188
 
                /* Step 4 - Compute difference and new predicted value */
189
 
                /*
190
 
                ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
191
 
                ** in adpcm_coder.
192
 
                */
 
202
                // Step 4 - Compute difference and new predicted value
 
203
                //
 
204
                // Computes 'vpdiff = (delta+0.5)*step/4', but see comment
 
205
                // in adpcm_coder.
 
206
                //
193
207
                vpdiff = step >> 3;
194
 
                if( delta & 4 )vpdiff += step;
195
 
                if( delta & 2 )vpdiff += step>>1;
196
 
                if( delta & 1 )vpdiff += step>>2;
197
 
 
198
 
                if(sign)valpred -= vpdiff;
199
 
                else valpred += vpdiff;
200
 
 
201
 
                /* Step 5 - clamp output value */
202
 
                if(valpred > 32767)valpred = 32767;
203
 
                else if(valpred < -32768)valpred = -32768;
204
 
 
205
 
                /* Step 6 - Update step value */
 
208
                if( delta & 4 ) vpdiff += step;
 
209
                if( delta & 2 ) vpdiff += step>>1;
 
210
                if( delta & 1 ) vpdiff += step>>2;
 
211
 
 
212
                if( sign )
 
213
                        valpred -= vpdiff;
 
214
                else
 
215
                        valpred += vpdiff;
 
216
 
 
217
                // Step 5 - clamp output value
 
218
                if( valpred > 32767 )
 
219
                        valpred = 32767;
 
220
                else if( valpred < -32768 )
 
221
                        valpred = -32768;
 
222
 
 
223
                // Step 6 - Update step value
206
224
                step = stepsizeTable[index];
207
225
 
208
 
                /* Step 7 - Output value */
209
 
                *outp++ = valpred;
210
 
    }
 
226
                // Step 7 - Output value
 
227
                *outp = valpred;
 
228
                outp++;
 
229
        }
211
230
 
212
 
    state->valprev = valpred;
213
 
    state->index = index;
 
231
        state->valprev = valpred;
 
232
        state->index = index;
214
233
}