]> icculus.org git repositories - taylor/freespace2.git/blob - src/vcodec/codec1.cpp
Initial revision
[taylor/freespace2.git] / src / vcodec / codec1.cpp
1 //                                  Codec1.cpp
2 //
3 // Contains C-style-C++ implementation of VoiCTech (Voice Communications
4 // Technology) voice encoder/decoder.
5 //
6 // Written by Matthew F. Storch, Ph.D., copyright (c) 1998 Volition Inc.
7
8 #include "pstypes.h"
9 #include <windows.h>
10
11 #include <math.h>
12 #include <assert.h>
13 #include "codec1.h"
14
15
16 //////////////////////////////////////////////////////////////////////////////
17 //
18 // Introduction to the VoiCTech encoder
19 // ------------------------------------
20 // The VoiCTech (short for Voice Communication Technology, pronounced
21 // "voice-tech") audio codec uses two separate algorithm suites: Codec1
22 // and LPC-10.  Codec1 does compression without using traditional signal 
23 // processing algorithms (expcept for a simple FIR low-pass filter).  As
24 // a result, it is extremely fast, and yields moderate-quality voice at a
25 // compression ratio of between 4-to-1 and 10-to-1, assuming 11KHz sampled
26 // data.  LPC-10 does significantly more analysis and is therefore slower
27 // (approximately 3 times slower than Codec1), but achieves substantially
28 // better compression (25-1) at a comparable quality.
29 //
30 // The externally-callable interface for both algorithm suites is through
31 // a simple, generic front-end that is prototyped in codec1.h.    
32 //
33 // This file contains the implementions of both the generic interface and
34 // Codec1. LPC-10 is implemented in a set of files in the LPC10 subdirectory.
35 //
36 //////////////////////////////////////////////////////////////////////////////
37
38
39 //////////////////////////////////////////////////////////////////////////////
40 // Low pass filter stuff.
41 //
42 // Number of points to convolve with.  Larger number means a better but
43 // slower low-pass filter.  Number should always be odd.  Useful range is
44 // 7 -> 31.
45 const int LPF_NUM_POINTS = 11; 
46 double Encoder_LPF_Coef[LPF_NUM_POINTS]; // convolution coefficents (weights)
47 // lookup table for coefficents * every possible sample value
48 char Encoder_LPF_CoefTimesSample[LPF_NUM_POINTS][256];
49 double Decoder_LPF_Coef[LPF_NUM_POINTS]; // convolution coefficents (weights)
50 // lookup table for coefficents * every possible sample value
51 char Decoder_LPF_CoefTimesSample[LPF_NUM_POINTS][256];
52 //////////////////////////////////////////////////////////////////////////////
53
54
55 //////////////////////////////////////////////////////////////////////////////
56 // Function prototypes for functions internal to Codec1
57
58 static void InitEncoder1(int QoS);
59 static void Smooth1(t_Sample* bufIn, t_Sample* bufOut, int size);
60 static double AutoGain1(t_Sample* bufIn, t_Sample* bufOut, int size);
61 static void UnAutoGain1(t_Sample* bufIn, t_Sample* bufOut, int size, 
62                                                 double gain);
63 static void Decode1(t_Sample* bufIn, t_Sample* bufOut, int size, int sizeOut);
64
65 #if defined(CODEC_DEMO)
66 static int Encode1(t_Sample* bufIn, t_Sample* bufOut, int sizeIn, int sizeOut,
67                    t_Sample* levels, int* modes, int samples[9], int storage[9]);
68 #else
69 static int Encode1(t_Sample* bufIn, t_Sample* bufOut, int sizeIn, int sizeOut);
70 #endif
71
72 static void SkipEveryOther(t_Sample* bufIn, t_Sample* bufOut, int size);
73 static void InterpolateEveryOther(t_Sample* bufIn, t_Sample* bufOut, int size);
74
75 #if defined(CODEC_DEMO)
76 static int DoEncode(int mode, BOOL& packetPos, t_Sample*& in, t_Sample*& out, 
77                     int& level, t_Sample*& levels, int*& modes, 
78                     int samples[9], int storage[9]);
79 #else
80 static int DoEncode(int mode, BOOL& packetPos, t_Sample*& in, t_Sample*& out, 
81                     int& level);
82 #endif
83
84 static void DecodeRL(BOOL packetPos, t_Sample*& p, t_Sample*& q, 
85                      t_Sample* bufEnd, t_Sample* bufOutEnd);
86 static void DecodeHF(BOOL packetPos, t_Sample*& p, t_Sample*& q, 
87                                          t_Sample* bufOutEnd);
88 static void DecodeNom(BOOL packetPos, t_Sample*& p, t_Sample*& q, 
89                       unsigned int mode, t_Sample* bufOutEnd);
90 static void DecodeMF(BOOL packetPos, t_Sample*& p, t_Sample*& q, 
91                                          t_Sample* bufOutEnd);
92 static void InitLowPassFilter(int QoS, double LPF_Coef[LPF_NUM_POINTS],
93                                                           char LPF_CoefTimesSample[LPF_NUM_POINTS][256]);
94 static void LowPassFilter(t_Sample* bufIn, t_Sample* bufOut, int size,
95                                                   char LPF_CoefTimesSample[LPF_NUM_POINTS][256]);
96
97 #if defined(USE_LPC10)
98 static void ConvertToLPC10(t_Sample* bufIn, t_Sample* bufOut, int size);
99 static void ConvertFromLPC10(t_Sample* bufIn, t_Sample* bufOut, int size);
100 extern "C"
101 {
102     // the following three functions are defined in lpc10\lpc10.c
103     void lpc10init();
104     int lpc10encode(unsigned char *in, unsigned char *out, int inlen);
105     int lpc10decode(unsigned char *in, unsigned char *out, int inlen);
106 }
107 #define AssertLPC10Available()
108 #else
109 #define ConvertToLPC10(bufIn, bufOut, size)
110 #define ConvertFromLPC10(bufIn, bufOut, size)
111 #define lpc10init()
112 #define lpc10encode(in, out, inlen) 0
113 #define lpc10decode(in, out, inlen) 0
114 #define AssertLPC10Available() assert(0)
115 #endif // defined(USE_LPC10)
116
117 //
118 ///////////////////////////////////////////////////////////////////////////////
119
120
121 ///////////////////////////////////////////////////////////////////////////////
122 // Generic high-level codec interface.
123
124 t_Code EncodeMode = e_cLPC10;
125
126 t_Sample* TempDecoderBuf = NULL;
127 t_Sample* TempEncoderBuf1 = NULL;
128 t_Sample* TempEncoderBuf2 = NULL;
129
130 ///////////////////////////////
131 // The following compile-time switches are applicable to Codec1 only.
132
133 // If SKIP_EVERY_OTHER is defined, every other sample will be thrown out
134 // after the low-pass filter has massaged the data but before the encoder
135 // goes at it.  The missing samples are then interpolated after decoding.
136 #define SKIP_EVERY_OTHER
137
138 // Don't define this ;)
139 //#define REMOVE_DC_BIAS
140
141 // Define this to use logarithmic gain (but linear gain works better).
142 //#define LOGARITHMIC_GAIN
143
144 // Define this to enable the low-pass filter.
145 #define USE_LOWPASS_FILTER
146
147 // End of compile-time switches
148 ///////////////////////////////
149
150 #if defined(SKIP_EVERY_OTHER)
151         const int SKIP_FACTOR = 2;
152 #else
153         const int SKIP_FACTOR = 1;
154 #endif
155
156
157 void InitDecoder(int QoS, t_Sample* tempBuf) 
158
159         QoS = QoS; // just to shut compiler up
160     TempDecoderBuf = tempBuf;
161     lpc10init(); // call unconditionally because we don't know what kind of
162                  // coded packets we might receive
163         InitLowPassFilter(8, Decoder_LPF_Coef, Decoder_LPF_CoefTimesSample);
164 }
165
166 void Decode(t_CodeInfo* ci, t_Sample* bufIn, t_Sample* bufOut, 
167             int encodeSize, int decodeSize)
168 {
169     if (ci->Code == e_cCodec1)
170     {
171         Decode1(bufIn, TempDecoderBuf, encodeSize, decodeSize/SKIP_FACTOR);
172           #if defined(SKIP_EVERY_OTHER)
173                 UnAutoGain1(TempDecoderBuf, TempDecoderBuf, decodeSize/SKIP_FACTOR, ci->Gain);
174         InterpolateEveryOther(TempDecoderBuf, bufOut, decodeSize/SKIP_FACTOR);
175           #else
176                 UnAutoGain1(TempDecoderBuf, bufOut, decodeSize, ci->Gain);
177           #endif
178                 LowPassFilter(bufOut, bufOut, decodeSize,Decoder_LPF_CoefTimesSample);
179     }
180     else
181     {
182                 AssertLPC10Available();
183         lpc10decode(bufIn, bufOut, encodeSize);
184         ConvertFromLPC10(bufOut, bufOut, decodeSize);
185     }
186 }
187
188 void InitEncoder(t_Code code, int QoS, t_Sample* tempBuf1, t_Sample* tempBuf2)
189 {
190     TempEncoderBuf1 = tempBuf1;
191     TempEncoderBuf2 = tempBuf2;
192     EncodeMode = code;
193     if (code == e_cCodec1)
194         {
195         InitEncoder1(QoS);
196                 InitLowPassFilter(QoS, Encoder_LPF_Coef, Encoder_LPF_CoefTimesSample);
197         }
198 }
199
200 #if defined(CODEC_DEMO)
201 #define EXTRA_CODEC_DEMO_ARGS4 , levels, modes, samples, storage
202 int Encode(t_Sample* bufIn, t_Sample* bufOut, int sizeIn, int sizeOut,
203                    t_CodeInfo* codeInfo,
204            t_Sample* levels, int* modes, int samples[9], int storage[9])
205 #else
206 #define EXTRA_CODEC_DEMO_ARGS4
207 int Encode(t_Sample* bufIn, t_Sample* bufOut, int sizeIn, int sizeOut, 
208                    t_CodeInfo* codeInfo)
209 #endif
210 {
211     int encodeSize;
212         codeInfo->Code = EncodeMode;
213     if (EncodeMode == e_cCodec1)
214     {
215           #if defined(SKIP_EVERY_OTHER)
216                 LowPassFilter(bufIn, TempEncoderBuf1, sizeIn,
217
218                                           Encoder_LPF_CoefTimesSample);
219         SkipEveryOther(TempEncoderBuf1, TempEncoderBuf1, sizeIn);
220           #else
221                 LowPassFilter(bufIn, TempEncoderBuf1, sizeIn,
222                                           Encoder_LPF_CoefTimesSample);
223
224           #endif
225         Smooth1(TempEncoderBuf1, TempEncoderBuf2, sizeIn/SKIP_FACTOR);
226                 codeInfo->Gain = AutoGain1(TempEncoderBuf2, TempEncoderBuf2, 
227                                                                    sizeIn/SKIP_FACTOR);
228       #if defined(CODEC_DEMO)
229         encodeSize = Encode1(TempEncoderBuf2, bufOut, sizeIn/SKIP_FACTOR, 
230                              sizeOut, levels, modes, samples, storage);
231       #else
232         encodeSize = Encode1(TempEncoderBuf2, bufOut, sizeIn/SKIP_FACTOR, 
233                              sizeOut);
234       #endif
235     }
236     else
237     {
238                 AssertLPC10Available();
239         ConvertToLPC10(bufIn, TempEncoderBuf2, sizeIn);
240         encodeSize = lpc10encode(TempEncoderBuf2, bufOut, sizeIn);
241     }
242     return encodeSize;
243 }
244
245 //
246 //////////////////////////////////////////////////////////////////////////////
247
248
249
250 // ********* EVERYTHING FROM THIS POINT ON IS SPECIFIC TO CODEC1. ************
251
252
253 //////////////////////////////////////////////////////////////////////////////
254 //
255 // Introduction to Codec1
256 // ----------------------
257 // Codec1 uses multiple encoders, including a highly modal primary
258 // encoder, to achieve a substantial degree of compression while
259 // accurately preserving the low-to-mid frequency components of human
260 // voice.  Higher frequency components are preserved less well, but
261 // usually acceptably.  The encoder works best with samples taken at
262 // low-to-moderate microphone volumes, though an additonal logarithmic
263 // compression pass has been added to give better performance at high
264 // volumes.
265 //
266 // The interface is very simple.  The externally-visible functions are:
267 //    InitEncoder1   -- initialize the encoder
268 //    LowPassFilter  -- get rid of unwanted high frequency data
269 //    SkipEveryOther -- throw out every other sample (optional)
270 //    Smooth1        -- smooth little bumps so run-length encoding works better
271 //    AutoGain1      -- reduce problematic high-volume samples
272 //    Encode1        -- primary encoder
273 //    ~~~~~~ transmission to remote machine ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
274 //    Decode1        -- primary decoder
275 //    UnAutoGain1    -- restore true volume
276 //    InterpolateEveryOther -- bring back missing samples
277 //
278 // All encoder and decoder algorithms have O(N) running time with
279 // respect to the number of samples (otherwise it would be hopelessly
280 // slow).  Decoding is extremely fast and should not have a
281 // significant impact on a modern computer.  The C implementation is
282 // most likely fine for production code.  The encoding is quite fast
283 // compared with other voice encoders, but it is of course substantially
284 // slower than the decoding.  Because of the "bit twiddling" nature of
285 // the algorithms, I would expect that a good assembly language 
286 // implementation could easily provide 2X-3X the execution time performance
287 // of this C implementation.  As of 12/97, I have implemented one key
288 // routine in assembly that increased performance substantially. 
289 // 
290 // The encoded format is novel and somewhat complex because of the
291 // desire for very high degrees of compression (4:1 to 10:1, nominally
292 // 8:1) with respectable sound quality.  In order to achieve such
293 // extraordinarily high compression rates, the exact format is
294 // (unfortunately) specific to 8-bit samples.  Ideas very similar to
295 // those used for the 8-bit codec could be used to develop 16 or
296 // 24-bit codecs, but the details would differ enough to require a
297 // mostly new implementation.
298 //
299 // A sequence of samples in the original data is encoded as a
300 // "packet".  A single packet may describe anywhere from a few samples
301 // to several thousand samples depending on the type of packet.  There
302 // are currently 4 major categories of packets: nominal packets,
303 // run-length packets, high-frequency packets, and medium-frequency
304 // packets.  An additional category, low-frequency packets, may be
305 // added later.
306 //
307 // The centerpiece of the encoding strategy is the category of nominal
308 // packets.  Nominal packets encode 9 contiguous 8-bit samples in 12
309 // bits, for a compression ratio of 6:1 and very high fidelity.  The
310 // encoded value of each sample is relative to the value of the
311 // previous sample, so this technique can only be effectively applied
312 // when contiguous samples have values that are not too different
313 // (i.e. for samples that contain only low-to-medium frequency
314 // components).  Detailed examination of actual voice samples revealed
315 // that monotonic upward (or downward) runs of several samples were
316 // common, so I decided that the encoding strategy would be as
317 // follows.  Each bit in a nominal packet corresponds to one sample,
318 // and the value of the bit determines what offset is added to the
319 // previous sample value to define the current sample value.  The
320 // actual offset values depend on the mode of the packet.  For
321 // example, in a mode 3 packet, a data bit of 0 means the offset is
322 // +1, while a data bit of 1 means the offset is +3.  On the other
323 // hand, in a mode 5 packet, a data bit of 0 means the offset is -1
324 // and a data bit of 1 means the offset is +1.
325 //
326 // The 12-bit packet size presents some challenges given that the
327 // natural data sizes of 80x86 processors are 8, 16, and 32 bits.
328 // However, the challenge is justified because none of the natural
329 // data sizes provided encoding opportunites as good.  The
330 // alternatives to the scheme I chose were to either encode 6 samples
331 // in 8 bits, or 12 samples in 16 bits.  6 samples in 8 bits leaves
332 // only 2 bits to assign the mode, which is inadequate.  12 bits in 16
333 // samples leaves plenty of mode bits (4) but then we are committed to
334 // the same mode for 12 bits, which I felt is too long for the voice
335 // data I examined.  So I chose the 9-in-12 "sweet spot" granularity
336 // as the basis for the encoding strategy.
337 //
338 // The 12-bit packets are encoded in pairs; each pair occupies 3
339 // bytes.  If all packets were nominal packets, a single 3-byte
340 // "packet pair" data structure could be used, and such a structure is
341 // in fact used when nominal packets are back-to-back.  However, all
342 // the samples in a typical voice sample buffer cannot be encoded
343 // using nominal packets, so other encoding schemes are used.  The
344 // 3 mode bits available in the 9-in-12 scheme allow us 8 modes.
345 // Modes 1 through 6 are used for nominal packets, while mode 0 is an
346 // escape to either run-length or high-frequency mode, and mode 7 is an
347 // escape to medium-frequency mode. 
348 //
349 // The data structures used for run-length (RL), high-frequency (HF),
350 // and medium-frequency (MF) modes are different depending on whether
351 // the previous packet is the first packet in a nominal packet pair
352 // (case 0), or is any of the following (case 1):
353 //   - the second packet in a nominal packet pair 
354 //   - a run-length, high-frequency, or medium-frequency packet
355 //   - the first packet in the buffer
356 // In case 0, the RL, HF, or MF packet is 12 bits, while in case 1 it
357 // is 16 bits (that is, we don't use 12 bit encoding for these modes
358 // unless we are forced to, because 16 bit packets are better all the
359 // way around for RL, HF, and MF modes.  Both the encoder and decoder
360 // maintain knowlege of case 0 vs. case 1 as a state variable called
361 // "packetPos".
362 //
363 // The only identical-value runs that occur frequently enough to be
364 // worth worrying about have a value of 0 (silence), so run length
365 // encoding uses 0 as the implicit data value.
366 //
367 // In high-frequency mode each sample is *not* relative to the
368 // previous sample (as it is in the nominal modes).  Instead it is an
369 // absolute value that is multiplied by a multiplier that is part of
370 // the HF packet.
371 //
372 // In medium-frequency mode, a sequence of 4 samples in the original
373 // data is approximated by a straight line.  This mode can also encode
374 // low-frequency data reasonably well, but not as well as the nominal
375 // modes, so the latter are used where possible.  However, medium
376 // frequency mode can be used when the total rise (or fall) of 4
377 // samples is up to 32, whereas the best total rise (or fall) the
378 // nominal modes can achieve over 4 samples is 3*4 = 12.
379 //
380 // Finally, there is a special "literal" mode that is used only for
381 // the very first sample in the buffer (which is implicitly literal
382 // mode) and the last few samples (signaled by a special "run length"
383 // packet that has a length of 0).  It adds a very slight inefficiency
384 // (since it does no compression) but it greatly simplifies dealing
385 // with the edge cases, which would otherwise be problematic.
386 //
387 //////////////////////////////////////////////////////////////////////////////
388 //
389 // Some details of the encoding scheme are summarized below:
390 //
391 // Encoding Modes
392 // --------------
393 // Mode number   Description
394 //        0      run-length or high-frequency mode
395 //        1       0, +1
396 //        2       0, -1
397 //        3      +1, +3
398 //        4      -1, -3
399 //        5      +1, -1
400 //        6      +2, -2
401 //        7      medium-frequency mode
402 //
403 // Packet Layout
404 // -------------
405 // Run-length/high-frequency in first packet of packet pair (case 1)
406 // 0000 nnnn nnnn nnnn -- run length, n = length of run (1st nibble low-order)
407 // 0001 mmmm xxxx yyyy -- high frequency, m = multiplier
408 //                        x, y and succeeding nibbles until 0 byte
409 //                            = absolute sample values
410 //
411 // Run-length/high-frequency in second packet of packet pair (case 0)
412 // ---- ---- ---- 0000 nnnn nnnn -- run length, n = length of run
413 // ---- ---- ---- 0001 mmmm xxxx -- high frequency, m = multiplier
414 //                                  x, y and succeeding nibbles until 0 byte
415 //                                      = absolute sample values
416 //
417 // mmmm = 0 is not a useful value so we can use it as an escape indicator for
418 // other modes
419 //
420 //////////////////////////////////////////////////////////////////////////////
421 //
422 // Misc notes
423 // 
424 // CODEC_DEMO
425 // ----
426 // CODEC_DEMO is a compile-time flag that adds/alters code for use with the demo/
427 // experiment program.  If CODEC_DEMO is not defined, the codec routines will be
428 // compiled for general-purpose use outside of the demo/experiment program.
429 // (Like in a GAME maybe...what a NOVEL concept!)
430 //
431 // Packing Problems
432 // ----------------
433 // Even with #pragma pack(1), sizeof returns 4 for 3 byte structures.  In
434 // some places in the code, structure sizes had to be hardwired to get around
435 // this problem.
436
437
438 ///////////////////////////////////////////////////////////////////////////////
439 // Data structures
440
441 // Not sure if there is a point in using unions somehow to make one big struct;
442 // for now just forget it and cast to totally different structs which is
443 // theoretically evil but is not really all that dangerous in practice...
444
445 // disable compiler padding of structures
446 #pragma pack(push, packet_declarations)
447 #pragma pack(1)
448
449 // most general notion of a packet pair
450 struct t_PacketPair
451 {
452     unsigned long Mode1   : 3;
453     unsigned long Mode1Ex : 1;
454     unsigned long Data1   : 8;
455     unsigned long Mode0   : 3;
456     unsigned long Mode0Ex : 1;
457     unsigned long Data0   : 8;
458 };
459
460 // nominal packet pair
461 struct t_PacketPairNom
462 {
463     unsigned long Mode1 : 3;
464     unsigned long Data1 : 9;
465     unsigned long Mode0 : 3;
466     unsigned long Data0 : 9;
467 };
468
469 // run-length packet, case 1 
470 struct t_PacketRL1
471 {
472     unsigned short Mode   : 3;
473     unsigned short ModeEx : 1;  // extra mode bit to distinguish RL & HF
474     unsigned short Length : 12;
475 };
476
477 // high-frequency packet, case 1
478 struct t_PacketHF1
479 {
480     unsigned short Mode   : 3;
481     unsigned short ModeEx : 1; // extra mode bit to distinguish RL & HF
482         unsigned short Table  : 3; // lookup table number
483         unsigned short Data2  : 3; // absolute sample data
484         unsigned short Data1  : 3; // absolute sample data
485         unsigned short Data0  : 3; // absolute sample data
486 };
487
488 // high-frequency data packet, only used immediately after an HF packet, or
489 // after another HF data packet
490 struct t_PacketHFData
491 {
492         unsigned short Table : 1; // 1 ==> DataT is lookup table number
493         unsigned short Data3 : 3; // absolute sample data
494         unsigned short Data2 : 3; // absolute sample data
495         unsigned short Data1 : 3; // absolute sample data
496         unsigned short Data0 : 3; // absolute sample data
497         unsigned short DataT : 3; // absolute sample data or lookup table number
498 };
499
500 // run-length packet, case 0
501 struct t_PacketRL0
502 {
503     unsigned long Mode1   : 3; // mode of previous packet in pair
504     unsigned long Data1   : 9; // data of previous packet in pair
505     unsigned long Mode0   : 3; // mode of this packet (always 0)
506     unsigned long Mode0Ex : 1; // extra bit to distinguish RL & HF (always 0)
507     unsigned long Length  : 8; // length of run
508 };
509
510 // high-frequency packet, case 0
511 struct t_PacketHF0
512 {
513     unsigned long Mode1   : 3; // mode of previous packet in pair
514     unsigned long Data1   : 9; // data of previous packet in pair
515     unsigned long Mode0   : 3; // mode of this packet (always 0)
516     unsigned long Mode0Ex : 1; // extra bit to distinguish RL & HF (always 1)
517         unsigned long Table   : 1; // 1 ==> DataT is lookup table number
518         unsigned long Data0   : 3; // absolute sample data
519         unsigned long DataT   : 3; // absolute sample data or lookup table number
520         unsigned long Unused  : 1;
521 };
522
523 // medium-frequency packet, case 1
524 struct t_PacketMF1
525 {
526     unsigned short Mode  : 3; // mode of this packet (always 7)
527     unsigned short Mult  : 1; // 0 ==> mult data by 1, 1 ==> mult data by 2
528     short          Data1 : 6; // total rise or fall over current 4 samples
529     short          Data0 : 6; // total rise or fall over next 4 samples
530 };
531
532 // medium-frequency packet, case 0
533 struct t_PacketMF0
534 {
535     unsigned long  Mode1 : 3; // mode of previous packet in pair
536     unsigned long  Data1 : 9; // data of previous packet in pair
537     unsigned long  Mode0 : 3; // mode of this packet (always 7)
538     unsigned long  Mult  : 1; // 0 ==> mult data by 1, 1 ==> mult data by 2
539     long           DataX : 2; // not currently used
540     long           Data0 : 6; // total rise or fall over next 4 samples
541 };
542
543 // restore state of compiler padding of structures
544 #pragma pack(pop, packet_declarations)
545
546
547
548
549 ////////////////////////////////////////////////////////////////////////////////
550 // Constants, enums, and data tables
551 //
552 // These are not all delclared "const", but all are constant after the code is
553 // initialized.
554
555 // For the second packet of a packet pair, the breakeven point for run length 
556 // vs. normal encoding is 9 bits, because in that case we are using exactly
557 // the packet in both cases (we resolve the tie in favor of RL because it's
558 // encoding and decoding is faster).  For the first packet, RL uses a minimum
559 // of 16 bits whereas normal encoding commits us to 12 bits, so the breakeven
560 // point is with somewhat longer runs.  Using the compression ratio as the 
561 // figure of merit, breakeven is at x/16 = 9/12, or x = 12 bits. 
562 const int MIN_RUN_LEN[2] = { 9, 12 };
563
564 const int ZERO = 128; // the value of silence ;)
565
566 // some quality-of-service tuning parameters
567 int BIG_MOVE2;  // useful values 4..32
568 int FUDGE;      // useful values 1..5
569
570 // some tuning parameters to help decide which mode to use when
571 const int BIG_MOVE = 8;
572 const int SMALL_MOVE1 = 2;
573 const int SMALL_MOVE2 = 2;
574 const int SMALL_MOVE3 = 2;
575
576 // enum DecodeState { e_dsFirst, e_dsSecond };
577 enum EncodeMode 
578
579     e_emRL_HF = 0, // run-length/high-frequency
580     e_emZ_P1  = 1, // nominal:  0 or +1
581     e_em0_N1  = 2, // nominal:  0 or -1
582     e_emP1_P3 = 3, // nominal: +1 or +3
583     e_emN1_N3 = 4, // nominal: -1 or -3
584     e_emP1_N1 = 5, // nominal: +1 or -1
585     e_emP2_N2 = 6, // nominal: +2 or -2
586     e_emMF    = 7  // medium-frequency
587 };
588
589 // offsets for modes 1 through 6 (bogus first entry)
590 const int Deltas[7][2] = 
591 {
592     {  0,  0 },
593     {  0, +1 },
594     { -1,  0 },
595     { +1, +3 },
596     { -3, -1 },
597     { -1, +1 },
598     { -2, +2 }
599 };
600
601 double Log2[256]; // lookup table for log-base-2 (i.e. log(x) / log(2))
602
603
604 // HF encoding table
605 #if 0
606 unsigned int EncTable[8][256] =
607 {
608         {
609                 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
610                 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
611                 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
612                 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
613                 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
614                 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
615                 1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,  2,  2,  2,
616                 2,  2,  2,  2,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  
617
618                 4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  5,  5,  
619         5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  6,  6,  6,  6,  
620                 6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  
621                 6,  6,  6,  6,  6,  6,  6,  6,  7,  7,  7,  7,  7,  7,  7,  7,  
622                 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  
623                 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  
624                 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  
625                 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7
626         },
627         {
628                 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
629                 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
630                 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
631                 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
632                 0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,
633                 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
634                 1,  1,  1,  1,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
635                 2,  2,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  
636
637                 4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  
638         5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  
639                 6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  
640                 6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  
641                 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  
642                 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  
643                 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  
644                 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7
645         },
646 };
647 #else
648 unsigned int EncTable[8][256];
649 #endif
650
651 // HF decoding table
652 int DecTable[8][8] =
653 {
654         { -12,  -6,  -3,  -1,  1,  3,  6, 12 },
655         { -24, -12,  -6,  -3,  3,  6, 12, 24 },
656         { -36, -18,  -9,  -5,  5,  9, 18, 36 },
657         { -48, -24, -12,  -6,  6, 12, 24, 48 },
658         { -60, -30, -15,  -7,  7, 15, 30, 60 },
659         { -72, -36, -18,  -9,  9, 18, 36, 72 },
660         { -84, -42, -21, -10, 10, 21, 42, 84 },
661         { -96, -48, -24, -12, 12, 24, 48, 96 }
662 };
663
664
665 ///////////////////////////////////////////////////////////////////////////////
666 // Decoder
667
668 // Decode1 is the main decoder entry point.
669 // Input: 
670 //     bufIn    - encoded data to decode
671 //     bufOut   - empty buffer in which to place decoded data
672 //     size     - size of bufIn in bytes
673 //     sizeOut  - size of bufOut in bytes
674 // Output:
675 //     bufOut   - decoded data written here
676 //     returns  - nothing
677 //
678 static void Decode1(t_Sample* bufIn, t_Sample* bufOut, int size, int sizeOut)
679 {
680     unsigned int mode, modeEx;
681     BOOL packetPos = 1; // 1 = first packet of packet pair, 0 = second
682     t_Sample* bufEnd = bufIn + size - 1;
683     t_Sample* bufOutEnd = bufOut + sizeOut - 1;
684     t_Sample* p = bufIn;  // current position in input buffer
685     t_Sample* q = bufOut; // current position in output buffer
686
687     *q++ = *p++; // first sample is in literal mode
688
689     // Main decoding loop.  Look at the mode of the packet and call the
690     // appropriate decoder.
691     while (p <= bufEnd && q <= bufOutEnd)
692     {
693         if (packetPos)
694         {
695             mode   = ((t_PacketPair*)p)->Mode1;
696             modeEx = ((t_PacketPair*)p)->Mode1Ex;
697         }
698         else
699         {
700             mode   = ((t_PacketPair*)p)->Mode0;
701             modeEx = ((t_PacketPair*)p)->Mode0Ex;
702         }
703         switch (mode)
704         {
705             case e_emRL_HF:
706                 if (modeEx) // modeEx differentiates HF vs RL modes
707                     DecodeHF(packetPos, p, q, bufOutEnd);
708                 else
709                     DecodeRL(packetPos, p, q, bufEnd, bufOutEnd);
710                 packetPos = 1;
711                 break;
712
713             case e_emZ_P1: case e_em0_N1: case e_emP1_P3: case e_emN1_N3: 
714             case e_emP1_N1: case e_emP2_N2: 
715                 DecodeNom(packetPos, p, q, mode, bufOutEnd);
716                 packetPos = !packetPos;
717                 break;
718
719             case e_emMF:
720                 DecodeMF(packetPos, p, q, bufOutEnd);
721                 packetPos = 1;
722                 break;
723         }
724     }
725
726     //assert(p == bufEnd && q == bufOutEnd);
727
728   #if defined(CODEC_DEMO)
729     // Do some extra error checking in CODEC_DEMO mode.
730     if (abs(bufEnd - p) > 1 || abs(bufOutEnd - q) > 1)
731     {
732         int leftIn = bufEnd - p,
733             leftOut = bufOutEnd - q;
734         char str[80];
735         sprintf(str, "%d bytes left in source, %d bytes left in dest", 
736                 leftIn, leftOut);
737         AfxMessageBox(str);
738         
739     }
740   #endif
741 }
742
743 // Run-length decoder.  Very straightforward.
744 static void DecodeRL(BOOL packetPos, t_Sample*& p, t_Sample*& q, 
745                      t_Sample* bufEnd, t_Sample* bufOutEnd)
746 {
747     int len;
748     if (packetPos)
749     {
750         len = ((t_PacketRL1*)p)->Length;
751         p += sizeof(t_PacketRL1);
752     }
753     else
754     {
755         len = ((t_PacketRL0*)p)->Length;
756         p += 3; //sizeof(t_PacketRL0); // see "Packing Problems" comment above
757     }
758
759         // q + len-1 is where the last sample in this run will be written
760         if (q + len-1 > bufOutEnd)
761         {
762                 q = bufOutEnd + 1; // cause decoder to immediately abort
763                 return;
764         }
765
766     for (int i = 0; i < len; i++)
767         *q++ = ZERO;
768
769     if (len == 0) // check for literal-mode marker near end of data
770     {
771         // remaining data is in literal mode
772         for (int remaining = *p++; remaining > 0 && q<=bufOutEnd; remaining--)
773             *q++ = *p++;
774 //        assert(p == bufEnd+1);
775     }
776 }
777
778 // High-frequency decoder.  Each sample is the data value for that sample
779 // multiplied by the current multiplier.
780 static void DecodeHF(BOOL packetPos, t_Sample*& p, t_Sample*& q, 
781                                          t_Sample* bufOutEnd)
782 {
783     static unsigned int table = 1;
784     int data;
785     // t_Sample* pstart = p;
786
787         if (q > bufOutEnd - 3)
788         {
789                 q = bufOutEnd + 1; // cause decoder to immediately abort
790                 return;
791         }
792
793     if (packetPos)
794     {
795         table = ((t_PacketHF1*)p)->Table;
796         data = ((t_PacketHF1*)p)->Data2; 
797         *q++ = t_Sample(DecTable[table][data] + ZERO);
798         data = ((t_PacketHF1*)p)->Data1;
799         *q++ = t_Sample(DecTable[table][data] + ZERO);
800         data = ((t_PacketHF1*)p)->Data0;
801         *q++ = t_Sample(DecTable[table][data] + ZERO);
802         p += sizeof(t_PacketHF1);
803     }
804     else
805     {
806                 if (((t_PacketHF0*)p)->Table == 1)
807                         table = ((t_PacketHF0*)p)->DataT;
808         data = ((t_PacketHF0*)p)->Data0;
809         *q++ = t_Sample(DecTable[table][data] + ZERO);
810                 if (((t_PacketHF0*)p)->Table == 0)
811                 {
812                         data = ((t_PacketHF0*)p)->DataT;
813                         *q++ = t_Sample(DecTable[table][data] + ZERO);
814                 }
815         p += 3; //sizeof(t_PacketHF0); // see "Packing Problems" comment above
816     }
817
818     while (*(char*)p != 0)
819     {
820                 if (q > bufOutEnd - 5)
821                 {
822                         q = bufOutEnd + 1; // cause decoder to immediately abort
823                         return;
824                 }
825                 if (((t_PacketHFData*)p)->Table == 1)
826                         table = ((t_PacketHFData*)p)->DataT;
827         data = ((t_PacketHFData*)p)->Data3;
828                 *q++ = t_Sample(DecTable[table][data] + ZERO);
829         data = ((t_PacketHFData*)p)->Data2;
830                 *q++ = t_Sample(DecTable[table][data] + ZERO);
831         data = ((t_PacketHFData*)p)->Data1;
832                 *q++ = t_Sample(DecTable[table][data] + ZERO);
833         data = ((t_PacketHFData*)p)->Data0;
834                 *q++ = t_Sample(DecTable[table][data] + ZERO);
835                 if (((t_PacketHFData*)p)->Table == 0)
836                 {
837                         data = ((t_PacketHFData*)p)->DataT;
838                         *q++ = t_Sample(DecTable[table][data] + ZERO);
839                 }
840         p += sizeof(t_PacketHFData);
841     }
842
843     p += sizeof(char); //sizeof(t_PacketHFData); // to cover final "0" packet
844 }
845
846 // Nominal packet decoder.  Each sample is equal to the previous sample
847 // +/- an offset.
848 static void DecodeNom(BOOL packetPos, t_Sample*& p, t_Sample*& q,
849                       unsigned int mode, t_Sample* bufOutEnd)
850 {
851     unsigned int data;
852     t_Sample delta0 = t_Sample(Deltas[mode][0]), // offset for "0" bits
853              delta1 = t_Sample(Deltas[mode][1]), // offset for "1" bits
854              last = *(q-1);
855
856         if (q > bufOutEnd - 9)
857         {
858                 q = bufOutEnd + 1;
859                 return;
860         }
861
862     if (packetPos)
863     {
864         data = ((t_PacketPairNom*)p)->Data1;
865     }
866     else
867     {
868         data = ((t_PacketPairNom*)p)->Data0;
869         p += 3; // sizeof(t_PacketPairNom);
870     }
871     
872     for (int i = 0; i < 9; i++)
873     {
874         if (data & 0x100)
875                 {
876                         last = t_Sample(last + delta1); // using += causes level 4 warning
877             *q++ = last;
878                 }
879         else
880                 {
881                         last = t_Sample(last + delta0); // using += causes level 4 warning
882             *q++ = last;
883                 }
884         data <<= 1;
885     }
886 }
887
888 // Medium-frequency decoder.  Uses a straight line to approximate 4 
889 // consecutive samples.
890 static void DecodeMF(BOOL packetPos, t_Sample*& p, t_Sample*& q, 
891                                          t_Sample* bufOutEnd)
892 {
893     unsigned int mult, data;
894     t_Sample level = *(q-1);
895
896         if (q > bufOutEnd - 4)
897         {
898                 q = bufOutEnd + 1;
899                 return;
900         }
901
902     if (packetPos)
903     {
904         mult = ((t_PacketMF1*)p)->Mult; // currently unused
905         data = ((t_PacketMF1*)p)->Data1; 
906         // Make each of the 4 points is computed in a way equivalent to that
907         // used in the encoder.
908                                    level = t_Sample(level + data / 4);  *q++ = level;
909         data -= data / 4;  level = t_Sample(level + data / 3);  *q++ = level;
910         data -= data / 3;  level = t_Sample(level + data / 2);  *q++ = level;
911         data -= data / 2;  level = t_Sample(level + data    );  *q++ = level;
912
913         data = ((t_PacketMF1*)p)->Data0; 
914
915         p += sizeof(t_PacketMF1);
916     }
917     else
918     {
919         mult = ((t_PacketMF0*)p)->Mult; // currently unused
920         data = ((t_PacketMF0*)p)->Data0;
921
922         p += sizeof(t_PacketMF0);
923     }
924                        level = t_Sample(level + data / 4);  *q++ = level;
925     data -= data / 4;  level = t_Sample(level + data / 3);  *q++ = level;
926     data -= data / 3;  level = t_Sample(level + data / 2);  *q++ = level;
927     data -= data / 2;  level = t_Sample(level + data    );  *q++ = level;
928 }
929
930
931
932 ///////////////////////////////////////////////////////////////////////////////
933 // Encoder
934
935 int QualityOfService;
936
937 // InitEncoder1 must be called once to initialize the encoder.  May safely be
938 // called again to change tuning parameters.
939 // Input: 
940 //     QoS      - Quality of Service: 1..10, 1 = highest compression/lowest
941 //                quality, 10 = worst compression/best quality
942 // Output:
943 //     initializes global variables
944 //
945 static void InitEncoder1(int QoS)
946 {
947         int i, j, table, in, ip, vn, vp;
948         QualityOfService = QoS;
949     // There is nothing magic about the folowing 2 formulas, they're just one
950     // way to translate from a semantic notion of "quality of service" to
951     // reasonable values of the tuning parameters.  Each parameter is
952     // orthogonal to the others, so the only reason to tie them to a single
953     // input parameter is simplicity.
954     BIG_MOVE2 = 8 + (10 - QoS) * 2;
955     FUDGE = (12 - QoS) / 2;
956     
957     // initilize log-base-2 lookup table
958     for (i = 1; i < 256; i++)
959         Log2[i] = log((double)i) / log(2.0);
960
961         for (table = 7; table >= 0; table--)
962         {
963                 vn = 3, vp = 4;
964                 in = ZERO-1, ip = ZERO;
965                 for (i = 0; i < 16 * (table+1)/8.0; i++)
966                         EncTable[table][in--] = vn,  EncTable[table][ip++] = vp;
967
968                 for (j = 1; j < 4; j++)
969                 {
970                         vn--, vp++;
971                         for (i = 0; i < pow(2.0, 3.0+j) * (table+1)/8.0; i++)
972                                 EncTable[table][in--] = vn,  EncTable[table][ip++] = vp;
973                 }
974                 while (in >= 0)
975                         EncTable[table][in--] = vn,  EncTable[table][ip++] = vp;
976         }
977         table = 0;
978 #if 0
979         for (table = 0; table < 8; table++)
980         for (i = 0; i < 256; i++)
981                 {
982                         s = abs(i - ZERO);
983                         if (s < 128*(table+1)/8.0)
984                                 EncTable[table][i] = (unsigned int)log(s*8.0/(table+1)) 
985                                                          / log(2.0);
986                         else
987                                 EncTable[table][i] = (unsigned int)log(128*8.0/(table+1));
988     }
989     
990         for (table = 0; table < 8; table++)
991                 for (i = 0; i < 8; i++)
992                         DecTable[table][i] = pow(2.0, i);
993 #endif
994
995 }
996
997
998
999
1000 // Encode1 is the main Encoder entry point.
1001 // Input: 
1002 //     bufIn    - encoded data to decode
1003 //     bufOut   - empty buffer in which to place decoded data
1004 //     size     - size of bufIn in bytes
1005 //     sizeOut  - size of bufOut in bytes
1006 // Output:
1007 //     bufOut   - encoded data written here
1008 //     returns  - number of bytes written to bufOut
1009 //
1010 #if defined(CODEC_DEMO)
1011 #define EXTRA_CODEC_DEMO_ARGS4 , levels, modes, samples, storage
1012 static int Encode1(t_Sample* bufIn, t_Sample* bufOut, int size, int sizeOut,
1013                    t_Sample* levels, int* modes, int samples[9], int storage[9])
1014 #else
1015 #define EXTRA_CODEC_DEMO_ARGS4
1016 static int Encode1(t_Sample* bufIn, t_Sample* bufOut, int size, int sizeOut)
1017 #endif
1018 {
1019     const int CUTOFF = 4;
1020     t_Sample *in = bufIn,   // current position in input buffer
1021              *out = bufOut, // current position in output buffer
1022              *p,            // temporary pointer 
1023              *end = bufIn + size,        // end of input buffer
1024              *endOut = bufOut + sizeOut; // end of output buffer
1025     int i,     // loop counter
1026         level, // current "true" sample value
1027         s0,    // first of two samples
1028         s1,    // second of two samples
1029         smin, smax,         // min and max of current set of samples
1030         hist[CUTOFF*2 + 1], // histogram of sample-to-sample deltas
1031         upMove, downMove;   // total up/down deltas
1032     BOOL packetPos = 1; // 1 = first packet of packet pair, 0 = second
1033         int tableNum = 0;
1034
1035
1036     assert(sizeof(t_PacketRL1) == 2);
1037     assert(sizeof(t_PacketHF1) == 2);
1038     assert(sizeof(t_PacketHFData) == 2);
1039     assert(sizeof(t_PacketHF0) == 4);
1040
1041     // First byte in encoded data is unencoded (literal mode) initial level.
1042     level = *out++ = *in++; 
1043
1044   #if defined(CODEC_DEMO)
1045     // Remove *levels++ to make level 1 pixel offset.
1046     *levels++ = t_Sample(level);
1047     // For statistics, pretend that literal mode is high-frequency mode. 
1048     *modes++ = 8;
1049     samples[8] += 1;  storage[8] += 2*sizeof(t_Sample);
1050   #endif
1051
1052     // Main encoding loop.  General strategy is to compute a histogram and
1053     // some other stats about the next 9 samples, then decide which is the
1054     // best encoding mode (that's the hard part), and finally encode the
1055     // data.  Note that if we decide on run-length or high-frequency mode,
1056     // we may encode more than 9 samples before going around this loop
1057     // again.
1058     while (in < end && out < endOut)
1059     {
1060                 // Use current level rather than last sample for histogram etc. 
1061                 // because level is where we are really starting from.  In the case
1062                 // where we are starting with significant error (e.g. just coming out
1063                 // of HF mode), we may very well pick a different mode starting from
1064                 // level than we would starting from the last sample.
1065         //smin = smax = s0 = *(in-1);
1066         smin = smax = s0 = level;
1067
1068         //int sstart = (s0 + *in) / 2,
1069         //  send = (in[7] + in[8]) / 2;
1070
1071         // Compute histogram.
1072         // Do 9 bits at a time, ensuring we don't go off end of bufIn.
1073         for (i = 0; i < CUTOFF*2 + 1; i++)
1074             hist[i] = 0;
1075         upMove = downMove = 0;
1076         for (i = 0; i < 9 && in+i < end; i++)
1077         {
1078             s1 = in[i];
1079             if (s1 < smin) smin = s1;
1080             if (s1 > smax) smax = s1;
1081             int diff = s1 - s0;
1082             if (diff < 0) downMove -= diff;
1083             if (diff > 0) upMove += diff;
1084             if (diff > CUTOFF) diff = CUTOFF;
1085             if (diff < -CUTOFF) diff = -CUTOFF;
1086             hist[diff+CUTOFF]++;
1087             s0 = s1;
1088         }
1089         
1090         // it's faster to do this in the loop above...
1091         //for (i = 0, downMove = 0; i < CUTOFF; i++)
1092         //  downMove += hist[i] * (CUTOFF-i);
1093         //for (i = CUTOFF+1, upMove = 0; i < CUTOFF*2 + 1; i++)
1094         //  upMove += hist[i] * (i-CUTOFF);
1095
1096
1097         short delta = short(in[3] - level); // for medium-frequency mode
1098
1099         // First check if we need to switch to literal mode.
1100         if (in+9 >= end)
1101         {
1102             // We are near the end of the data.  Put marker indicating
1103             // the final mode switch to literal mode.  The marker is a
1104             // run-length mode packet of length 0.  Literal mode
1105             // encoding is a single byte indicating the number of
1106             // literal mode samples followed by the original samples.
1107             if (packetPos)
1108             {
1109                 t_PacketRL1 packet;
1110                 packet.Mode   = e_emRL_HF;
1111                 packet.ModeEx = 0;
1112                 packet.Length = 0;
1113                 *(t_PacketRL1*)out = packet;
1114                 out += sizeof(t_PacketRL1);
1115             }
1116             else
1117             {
1118                 t_PacketRL0 packet = *(t_PacketRL0*)out;
1119                 packet.Mode0   = e_emRL_HF;
1120                 packet.Mode0Ex = 0;
1121                 packet.Length = 0;
1122                 *(t_PacketRL0*)out = packet;
1123                 out += 3; //sizeof(t_PacketRL0); // see "Packing Problems"
1124             }
1125
1126             i = *out++ = t_Sample(end - in);
1127
1128           #if defined(CODEC_DEMO)
1129             int remaining = i;
1130             while (i-- > 0)
1131                 *levels++ = *out++ = *in++;
1132
1133             // For statistical purposes, pretend that literal mode is high-
1134             // frequency mode since high frequency mode is the most similar
1135             // in terms of bits per sample.  In any case, literal mode will
1136             // have very little impact on any of the statistics.
1137             for (i = remaining; i > 0; i--) *modes++ = 8;
1138             samples[8] += remaining;  storage[8] += 2*remaining;
1139           #else
1140             while (i-- > 0)
1141                 *out++ = *in++;
1142           #endif
1143         }
1144         // Check if low frequency mode applies; if so, use it because it
1145         // is the most efficient.
1146         else if (upMove <= SMALL_MOVE3 && downMove <= SMALL_MOVE3)
1147         { // low frequency mode
1148             BOOL runLengthMode = FALSE;
1149             if (hist[CUTOFF] == 9)
1150             { // possible 0-run starting; check ahead
1151
1152                 // packet1 can handle runs of 2^12-1 = 4095 samples
1153                 // packet0 can handle runs of 2^8-1 = 255 samples
1154                 int len, maxLen = packetPos ? 4095 : 255;
1155                 for (p = &in[9], len = 9; p < end && len < maxLen; p++, len++)
1156                     if (*p != ZERO)
1157                         break;
1158
1159                 if (len > MIN_RUN_LEN[packetPos])
1160                 { // encode region in-to-p as run-length
1161                     runLengthMode = TRUE;
1162                     if (packetPos)
1163                     {
1164                         t_PacketRL1 packet;
1165                         packet.Mode = e_emRL_HF;
1166                         packet.ModeEx = 0;
1167                         packet.Length = unsigned short(len);
1168                         *(t_PacketRL1*)out = packet;
1169                         out += sizeof packet;
1170                         // packetPos remains at 1
1171                       #if defined(CODEC_DEMO)
1172                         samples[0] += len;  storage[0] += 2*sizeof packet;
1173                       #endif
1174                     }
1175                     else
1176                     {
1177                         t_PacketRL0 packet = *(t_PacketRL0*)out;
1178                         packet.Mode0 = e_emRL_HF;
1179                         packet.Mode0Ex = 0;
1180                         packet.Length = len;
1181                         *(t_PacketRL0*)out = packet;
1182                         out += 3; // sizeof packet;
1183                         packetPos = 1;
1184                       #if defined(CODEC_DEMO)
1185                         samples[0] += len;  storage[0] += 3; // sizeof packet;
1186                       #endif
1187                     }
1188                     in += len;
1189
1190                   #if defined(CODEC_DEMO)
1191                     for (int j = 0; j < len; j++)
1192                         *levels++ = ZERO, *modes++ = 0;
1193                   #endif
1194                 }
1195             }
1196             if (!runLengthMode)
1197             { // normal low-frequency mode
1198                 //!!! Need to implement a low-frequency mode for real.  In the
1199                 // meantime, use the appropriate nominal mode in its place.
1200                 if (upMove > 0 && downMove > 0)
1201                 { 
1202                     out += DoEncode(e_emP1_N1, packetPos, in, out, level 
1203                                     EXTRA_CODEC_DEMO_ARGS4);
1204                 }
1205                 else if (upMove > 0)
1206                 { 
1207                     out += DoEncode(e_emZ_P1, packetPos, in, out, level 
1208                                     EXTRA_CODEC_DEMO_ARGS4);
1209                 }
1210                 else
1211                 { 
1212                     out += DoEncode(e_em0_N1, packetPos, in, out, level 
1213                                     EXTRA_CODEC_DEMO_ARGS4);
1214                 }
1215             }
1216         }
1217         // Check if nominal modes apply; if so, use one of them.
1218         // Given 9 bits with a maximum per-bit delta of 3, we can keep up
1219         // with an end-to-end delta of 3 * 9 in nominal mode, plus we add
1220         // in a little fudge factor because we would really rather avoid
1221         // medium or high-frequency modes if possible.
1222         //else if (hist[CUTOFF*2] <= 2 && hist[0] <= 2 && 
1223         //       upMove < 3 * 9 + 5 && downMove < 3 * 9 + 5)
1224         else if (hist[CUTOFF*2] + hist[0] <= 2 && 
1225                  upMove < 3 * 9 + FUDGE && downMove < 3 * 9 + FUDGE)
1226         {
1227             if (upMove >= BIG_MOVE)
1228             { // lot of up movement, use mode 3 or 6
1229                 //  mode 3 unless nontrivial down move
1230                 if (downMove <= SMALL_MOVE1) 
1231                     out += DoEncode(e_emP1_P3, packetPos, in, out, level 
1232                                     EXTRA_CODEC_DEMO_ARGS4);
1233                 else
1234                     out += DoEncode(e_emP2_N2, packetPos, in, out, 
1235                                     level EXTRA_CODEC_DEMO_ARGS4);
1236             }
1237             else if (downMove >= BIG_MOVE)
1238             { // lot of down movement, use mode 4 or 6
1239                 if (upMove <= SMALL_MOVE1) //  mode 4 unless nontrivial up move
1240                     out += DoEncode(e_emN1_N3, packetPos, in, out, level
1241                                     EXTRA_CODEC_DEMO_ARGS4);
1242                 else
1243                     out += DoEncode(e_emP2_N2, packetPos, in, out, level 
1244                                     EXTRA_CODEC_DEMO_ARGS4);
1245             }
1246             else if (upMove >= SMALL_MOVE2 && downMove >= SMALL_MOVE2)
1247             { 
1248                 out += DoEncode(e_emP1_N1, packetPos, in, out, level 
1249                                 EXTRA_CODEC_DEMO_ARGS4);
1250             }
1251             else if (upMove >= SMALL_MOVE2)
1252             { 
1253                 out += DoEncode(e_emZ_P1, packetPos, in, out, level 
1254                                 EXTRA_CODEC_DEMO_ARGS4);
1255             }
1256             else
1257             { 
1258                 out += DoEncode(e_em0_N1, packetPos, in, out, level 
1259                                 EXTRA_CODEC_DEMO_ARGS4);
1260             }
1261         }
1262         // Last chance to avoid dreaded high-frequency mode.  In medium-
1263         // frequency mode, a sequence of 4 samples is encoded as a straight-
1264         // line approximation.  There are 6 bits available to encode the
1265         // total rise/fall of the line, so we can track a total rise of 
1266         // +(2^5-1) = +31 and a total fall of -(2^5) = -32.
1267         //else if (delta <= 31 && delta >= -32)
1268         else if ((upMove < BIG_MOVE2 || downMove < BIG_MOVE2) 
1269                  && delta <= 31 && delta >= -32)
1270         { // medium frequency mode
1271           #if defined(CODEC_DEMO)
1272             int temp1;
1273           #endif
1274             int temp2;
1275             in += 4;
1276             if (packetPos)
1277             {
1278                 t_PacketMF1 packet;
1279                 packet.Mode = e_emMF;
1280                 packet.Mult = 0; //!!! should implement .Mult
1281                 packet.Data1 = delta;
1282                 temp2 = level;
1283                 level += packet.Data1;
1284                 delta = short(in[3] - level);
1285                 if (delta > 31)       packet.Data0 = 31;
1286                 else if (delta < -32) packet.Data0 = -32;
1287                 else                  packet.Data0 = delta;
1288                 *(t_PacketMF1*)out = packet;
1289                 out += sizeof packet;
1290                 in += 4;
1291
1292               #if defined(CODEC_DEMO)
1293                 temp1 = packet.Data1; *levels++ = t_Sample(temp2 += temp1 / 4);
1294                 temp1 -= temp1 / 4;   *levels++ = t_Sample(temp2 += temp1 / 3);
1295                 temp1 -= temp1 / 3;   *levels++ = t_Sample(temp2 += temp1 / 2);
1296                 temp1 -= temp1 / 2;   *levels++ = t_Sample(temp2 += temp1);
1297                 assert(temp2 == level);
1298                 temp1 = packet.Data0; *levels++ = t_Sample(temp2 += temp1 / 4);
1299                 temp1 -= temp1 / 4;   *levels++ = t_Sample(temp2 += temp1 / 3);
1300                 temp1 -= temp1 / 3;   *levels++ = t_Sample(temp2 += temp1 / 2);
1301                 temp1 -= temp1 / 2;   *levels++ = t_Sample(temp2 += temp1);
1302                 assert(temp2 == level + packet.Data0);
1303
1304                 for (i = 0; i < 8; i++) *modes++ = 7;
1305                 samples[7] += 8;  storage[7] += 2*sizeof packet;
1306               #endif
1307
1308                 level += packet.Data0;
1309             }
1310             else
1311             {
1312                 t_PacketMF0 packet = *(t_PacketMF0*)out;
1313                 packet.Mode0 = e_emMF;
1314                 packet.DataX = 0;
1315                 packet.Data0 = delta;
1316                 *(t_PacketMF0*)out = packet;
1317                 out += sizeof packet;
1318
1319               #if defined(CODEC_DEMO)
1320                 temp2 = level;
1321                 temp1 = packet.Data0; *levels++ = t_Sample(temp2 += temp1 / 4);
1322                 temp1 -= temp1 / 4;   *levels++ = t_Sample(temp2 += temp1 / 3);
1323                 temp1 -= temp1 / 3;   *levels++ = t_Sample(temp2 += temp1 / 2);
1324                 temp1 -= temp1 / 2;   *levels++ = t_Sample(temp2 += temp1);
1325                 assert(temp2 == level + packet.Data0);
1326
1327                 for (i = 0; i < 4; i++) *modes++ = 7;
1328                 samples[7] += 4;  storage[7] += 3; // sizeof packet;
1329               #endif
1330
1331                 level += packet.Data0; 
1332             }
1333             packetPos = 1;
1334         }
1335         else // No choice but to use bit-gobbling high frequency mode.
1336         { // high frequency mode
1337             // need abs because smax is not guaranteed to be > ZERO and smin
1338             // is not guaranteed to be < ZERO
1339                         int temp1 = abs((smax - ZERO) / 16), 
1340                                 temp2 = abs((ZERO - smin - 1) / 16);
1341                         // "table" is our new preferred table
1342                         int table = temp1 > temp2 ? temp1 : temp2;
1343                         int data4, data3, data2, data1, data0, datat, val3, val2, val1, val0;
1344                         int max;
1345                         int finalPacketData;
1346
1347             if (packetPos)
1348             {
1349                 t_PacketHF1 packet;
1350                 packet.Mode = e_emRL_HF;
1351                 packet.ModeEx = 1;
1352                                 // HF1 packets include table number unconditionally
1353                                 packet.Table = unsigned short(tableNum = table);
1354                                 packet.Data2 = unsigned short(EncTable[table][*in++]);
1355                                 packet.Data1 = unsigned short(EncTable[table][*in++]);
1356                                 finalPacketData = 
1357                                 packet.Data0 = unsigned short(EncTable[table][*in]);
1358                                 data0 = *in++;
1359                 *(t_PacketHF1*)out = packet;
1360                 out += sizeof packet;
1361
1362               #if defined(CODEC_DEMO)
1363                                 *levels++ = t_Sample(DecTable[table][packet.Data2] + ZERO);
1364                                 *levels++ = t_Sample(DecTable[table][packet.Data1] + ZERO);
1365                                 *levels++ = t_Sample(DecTable[table][packet.Data0] + ZERO);
1366                 *modes++ = 8; 
1367                                 *modes++ = 8;
1368                                 *modes++ = 8;
1369                                 samples[8] += 3;  storage[8] += 2*sizeof packet;
1370               #endif
1371             }
1372             else
1373             {
1374                 t_PacketHF0 packet = *(t_PacketHF0*)out;
1375                 packet.Mode0 = e_emRL_HF;
1376                 packet.Mode0Ex = 1;
1377
1378                                 finalPacketData = packet.Data0 = EncTable[table][*in++];
1379                                 // "tableNum-1" in order to introduce a little hysteresis in 
1380                                 // going to a smaller table.  No such trick in the other 
1381                                 // direction since the consequences of using a table that is
1382                                 // too small is worse than using one that is to large.
1383                                 if (table > tableNum || table < tableNum-1)
1384                                 {
1385                                         packet.Table = 1;
1386                                         packet.DataT = tableNum = table;
1387                                 }
1388                                 else // use previous table
1389                                 {
1390                                         packet.Table = 0;
1391                                         finalPacketData = packet.DataT = EncTable[table = tableNum][*in++];
1392                                 }
1393                 *(t_PacketHF0*)out = packet;
1394                 out += 3; // sizeof packet;
1395
1396               #if defined(CODEC_DEMO)
1397                                 *levels++ = t_Sample(DecTable[table][packet.Data0] + ZERO);
1398                 *modes++ = 8;
1399                 samples[8] += 1;  storage[8] += 3; // sizeof packet;
1400                                 if (packet.Table == 0)
1401                                 {
1402                                         *levels++ = t_Sample(DecTable[table][packet.DataT] + ZERO);
1403                                         *modes++ = 8;
1404                                         samples[8] += 1;
1405                                 }
1406               #endif
1407             }
1408             
1409             t_PacketHFData packet;
1410                         for (;;)
1411                         {
1412                                 if (in+5 >= end)
1413                                 {
1414                     *(char*)out = 0;
1415                     out += sizeof(char);
1416                   #if defined(CODEC_DEMO)
1417                     storage[8] += 2*sizeof(char);
1418                   #endif
1419                                 }
1420                 data4 = *(in-1) - ZERO;
1421                                 data3 = *in++ - ZERO;
1422                                 data2 = *in++ - ZERO;
1423                                 data1 = *in++ - ZERO;
1424                                 data0 = *in++ - ZERO;
1425                                 datat = *in - ZERO;
1426                                 max = abs(data3) > abs(data2) ? abs(data3) : abs(data2);
1427                                 max = abs(data1) > max ? abs(data1) : max;
1428                                 max = abs(data0) > max ? abs(data0) : max;
1429                                 max = abs(datat) > max ? abs(datat) : max;
1430                                 table = (max-1) / 16;
1431
1432                                 if (table > tableNum || table < tableNum-1)
1433                                 {
1434                                         packet.Table = 1;
1435                                         packet.DataT = unsigned short(table);
1436                                 }
1437                                 else // use previous table
1438                                 {
1439                                         packet.Table = 0;
1440                                         table = tableNum;
1441                                         packet.DataT = unsigned short(EncTable[table][datat+ZERO]);
1442                                         in++;
1443                                 }
1444
1445                                 packet.Data3 = unsigned short(val3 = EncTable[table][data3+ZERO]);
1446                                 packet.Data2 = unsigned short(val2 = EncTable[table][data2+ZERO]);
1447                                 packet.Data1 = unsigned short(val1 = EncTable[table][data1+ZERO]);
1448                                 packet.Data0 = unsigned short(val0 = EncTable[table][data0+ZERO]);
1449
1450                                 // break if the data is relatively smooth or if we encounter
1451                                 // data (two 0's) that would cause us to encode a packet that
1452                                 // looks like a HF termination byte
1453                                 if ((abs(data2 - data3) + abs(data1 - data2) + 
1454                      abs(data0 - data1) + abs(data3 - data4) <= 12) ||
1455                     (val3 == 0 && val2 == 0))
1456                 {
1457                     *(char*)out = 0;
1458                     out += sizeof(char);
1459                   #if defined(CODEC_DEMO)
1460                     storage[8] += 2*sizeof(char);
1461                   #endif
1462                                         if (packet.Table == 1)
1463                                                 in -= 4;
1464                                         else
1465                                                 in -= 5;
1466                     break;
1467                 }
1468
1469                                 // now that we know for certain that this packet, will be 
1470                                 // used, set persistent state to indicate the last used
1471                                 // table & last encoded data value
1472                                 finalPacketData = packet.Table ? packet.Data0 : packet.DataT;
1473                                 tableNum = table;
1474
1475                 *(t_PacketHFData*)out = packet;
1476                 out += sizeof packet;
1477
1478               #if defined(CODEC_DEMO)
1479                                 *levels++ = t_Sample(DecTable[table][packet.Data3] + ZERO);
1480                                 *levels++ = t_Sample(DecTable[table][packet.Data2] + ZERO);
1481                                 *levels++ = t_Sample(DecTable[table][packet.Data1] + ZERO);
1482                                 *levels++ = t_Sample(DecTable[table][packet.Data0] + ZERO);
1483                 *modes++ = 8; *modes++ = 8; *modes++ = 8; *modes++ = 8;
1484                 samples[8] += 4;  storage[8] += 2*sizeof packet;
1485                                 if (packet.Table == 0)
1486                                 {
1487                                         *levels++ = t_Sample(DecTable[table][packet.DataT] + ZERO);
1488                                         *modes++ = 8;
1489                                         samples[8] += 1;
1490                                 }
1491               #endif
1492             }
1493             // be sure to set level here so it stays in sync
1494                         level = DecTable[tableNum][finalPacketData] + ZERO;
1495             packetPos = 1;
1496         }
1497     }
1498
1499     return out - bufOut; 
1500 }
1501
1502 /*
1503 #if defined(CODEC_DEMO)
1504 static int ComputeNomData(t_Sample*& in, const int deltas[], int& level,
1505                           t_Sample*& levels)
1506 #else
1507 static int ComputeNomData(t_Sample*& in, const int deltas[], int& level)
1508 #endif
1509 {
1510     int data = 0;
1511
1512     for (int i = 0; i < 9; i++, in++)
1513     {
1514         if (level+deltas[0] < *in)
1515         {
1516             data = (data << 1) | 1;
1517             level += deltas[1];
1518         }
1519         else
1520         {
1521             data <<= 1;
1522             level += deltas[0];
1523         }
1524         #if defined(CODEC_DEMO)
1525             *levels++ = t_Sample(level);
1526         #endif
1527     }
1528     return data;
1529 }
1530 */
1531
1532 // ecx i
1533 // eax temp
1534 // edx level
1535 // ebx deltas[0]
1536 // edi deltas[1]
1537 // esi in
1538 // ebp data
1539
1540 #if defined(CODEC_DEMO)
1541 static int ComputeNomDataF(t_Sample*& inp, const int deltas[], int& level,
1542                           t_Sample*& levels)
1543 #else
1544 static int ComputeNomDataF(t_Sample*& inp, const int deltas[], int& level)
1545 #endif
1546 {
1547     int data;
1548     __asm
1549     {
1550         push ebp
1551         mov esi, [inp]          // esi = &inp
1552         mov esi, [esi]          // esi = inp
1553         mov ebx, deltas[0]      // ebx = &deltas[0]
1554         mov edi, [ebx+4]        // edi = deltas[1]
1555         mov ebx, [ebx]          // ebx = deltas[0]
1556         mov edx, [level]        // edx = &level
1557         mov edx, [edx]          // edx = level
1558         mov ebp, 0
1559
1560         mov eax, edx            // temp = level
1561         mov ecx, 9              // loop count = 9
1562
1563       DO_9_SAMPLES:
1564         add eax, ebx            // temp += deltas[0]
1565         cmp al, byte ptr [esi]  // level+deltas[0] < *in ?
1566         rcl ebp, 1              // shift right bit into data
1567         jge SUM_GE_IN           // if (level+deltas[0] >= *in) goto SUM_GE_IN
1568         add edx, edi            // level+deltas[0] < *in -> level += deltas[1]
1569         mov eax, edx            // temp = level (for next iteration)
1570         jmp SUM_LT_IN
1571       SUM_GE_IN:
1572         mov edx, eax            // level = temp
1573       SUM_LT_IN:
1574
1575       #if defined(CODEC_DEMO)
1576         push eax                // ran out of registers
1577         push ebp                // we will need the real ebp to get at levels
1578         mov ebp,[esp+8]         // get real (frame ptr) value of ebp
1579         mov eax, levels         // eax = &levels (implicitly uses ebp)
1580         //mov al, byte ptr ss:[levels]      
1581         // eax = &levels
1582         mov ebp, eax            // ebp = &levels
1583         mov eax, [eax]          // eax = levels
1584         mov [eax], dl           // *levels = level
1585         inc eax                 // eax = levels + 1
1586         mov [ebp], eax          // levels = eax
1587         pop ebp
1588         pop eax
1589       #endif
1590         inc esi
1591         loop DO_9_SAMPLES
1592
1593         mov ebx, ebp
1594         pop ebp
1595         mov eax, [level]        // eax = &level
1596         mov [eax], edx          // level = edx
1597         mov eax, [inp]          // eax = &inp
1598         mov [eax], esi          // inp = esi
1599         mov [data], ebx
1600     }
1601     return data;
1602 }
1603
1604 #define VERIFY_ASM
1605
1606 // Nominal packet encoder.  Each encoded sample is equal to the previous sample
1607 // +/- an offset.  The mode has been decided by the routine that calls DoEncode
1608 // so the mode is passed in.
1609 #if defined(CODEC_DEMO)
1610 #define EXTRA_CODEC_DEMO_ARGS1 , levels
1611 static int DoEncode(int mode, BOOL& packetPos, t_Sample*& in, t_Sample*& out, 
1612                     int& level, t_Sample*& levels, int*& modes, 
1613                     int samples[9], int storage[9])
1614 #else
1615 #define EXTRA_CODEC_DEMO_ARGS1
1616 static int DoEncode(int mode, BOOL& packetPos, t_Sample*& in, t_Sample*& out, 
1617                     int& level)
1618 #endif
1619 {
1620     t_PacketPairNom packet;
1621     int advanceOutput = 0;
1622
1623     if (packetPos)
1624     {
1625         #if defined(VERIFY_ASM) && defined(CODEC_DEMO)
1626             t_Sample *inT1 = in, *inT2 = in, *levelsT = levels;
1627             int levelT1 = level, levelT2 = level;
1628         #endif
1629         packet.Mode1 = mode;
1630         packet.Data1 = ComputeNomDataF(in,Deltas[mode], level EXTRA_CODEC_DEMO_ARGS1);
1631         #if defined(VERIFY_ASM) && defined(CODEC_DEMO)
1632             levels = levelsT;
1633             unsigned int dataT = ComputeNomData(inT1, Deltas[mode], levelT1 EXTRA_CODEC_DEMO_ARGS1);
1634             if (dataT != packet.Data1)
1635             {
1636                 inT1 = inT2, levelT1 = levelT2;
1637                 levels = levelsT;
1638                 dataT = ComputeNomData(inT1, Deltas[mode], levelT1 EXTRA_CODEC_DEMO_ARGS1);
1639                 levels = levelsT;
1640                 dataT = ComputeNomDataF(inT2, Deltas[mode], levelT2 EXTRA_CODEC_DEMO_ARGS1);
1641             }
1642         #endif
1643     }
1644     else
1645     {
1646         packet = *(t_PacketPairNom*)out;
1647         packet.Mode0 = mode;
1648         packet.Data0 = ComputeNomDataF(in,Deltas[mode], level EXTRA_CODEC_DEMO_ARGS1);
1649         advanceOutput = 3; // sizeof packet;
1650     }
1651     *(t_PacketPairNom*)out = packet;
1652     packetPos = !packetPos;
1653
1654   #if defined(CODEC_DEMO)
1655     for (int i = 0; i < 9; i++) *modes++ = mode;
1656     samples[mode] += 9;  storage[mode] += 3; // sizeof packet;
1657   #endif
1658
1659     return advanceOutput;
1660 }
1661
1662
1663 static void Smooth1(t_Sample* bufIn, t_Sample* bufOut, int size)
1664 {
1665     int i;
1666     bufOut[0] = bufIn[0];
1667     bufOut[size-1] = bufIn[size-1];
1668     for (i = 2; i < size; i++)
1669     {
1670         int s0 = bufIn[i-2], s1 = bufIn[i-1], s2 = bufIn[i];
1671         if (s0 == s2 && abs(s1 - s0) < 3)
1672             bufOut[i-1] = bufIn[i];
1673         else
1674             bufOut[i-1] = bufIn[i-1];
1675         if (abs(s0 - ZERO) < 2 && abs(s1 - ZERO) < 3)
1676             bufOut[i-2] = ZERO;
1677     }
1678 }
1679
1680 // can operate in place
1681 static double AutoGain1(t_Sample* bufIn, t_Sample* bufOut, int size)
1682 {
1683     register int i, s;
1684         int hist[17], sum, silenceSize = 0;
1685         const int TARGET_MAX = 32, BUCKET_SIZE = 3;
1686         double x;
1687
1688         for (i = 0; i < 17; i++)
1689                 hist[i] = 0;
1690         for (i = 0; i < size; i++)
1691         {
1692         s = abs(bufIn[i] - ZERO);
1693                 hist[s >> BUCKET_SIZE]++;
1694                 if (s == 0 || s == 1 || s == -1)
1695                         silenceSize++;
1696         }
1697         // ignore silence data when computing significant_data_above_this
1698         for (i = 15, sum = hist[16]; i >= 0 && sum < ((size - silenceSize) >> 4);
1699                  i--)
1700                 sum += hist[i];
1701
1702         int significant_data_above_this = i << BUCKET_SIZE;
1703
1704   #if LOGARITHMIC_GAIN
1705         if (significant_data_above_this > TARGET_MAX)
1706         {
1707                 x = ((double)Log2[significant_data_above_this]) / TARGET_MAX;
1708
1709                 for (i = 0; i < size; i++)
1710                 {
1711                     s = abs(bufIn[i] - ZERO);
1712                     s = int(Log2[s] / x);
1713                     bufOut[i] = bufIn[i] < ZERO ? t_Sample(ZERO - s) : t_Sample(s + ZERO);
1714                 }
1715         }
1716         else
1717                 x = 0.0;
1718         return x;
1719   #else
1720         // linearly scale data such that a value of significant_data_above_this
1721         // will become a value of TARGET_MAX
1722         if (significant_data_above_this > TARGET_MAX)
1723         {
1724                 x = ((double)TARGET_MAX) / significant_data_above_this;
1725                 for (i = 0; i < size; i++)
1726                 {
1727                     s = abs(bufIn[i] - ZERO);
1728                     s = int(((double)s) * x + .5);
1729                     bufOut[i] = bufIn[i] < ZERO ? t_Sample(ZERO - s) : t_Sample(s + ZERO);
1730                 }
1731                 x  = 1 / x; // inverse for UnAutoGain() (no danger of x being 0)
1732         }
1733         else if (significant_data_above_this > 0)
1734                 x = ((double)TARGET_MAX) / significant_data_above_this;
1735         else
1736                 x = 4.0;
1737
1738         // Do a little extra volume boost for low QoS situations.  There is 
1739         // nothing magic about the constants in the following, they're just
1740         // reasonable heuristic values.
1741         if (QualityOfService <= 3)
1742                 x = (x * 6) / (QualityOfService+2);
1743         if (QualityOfService == 1)
1744                 x *= 1.5;
1745         return x;
1746   #endif
1747 }
1748
1749 // can operate in place
1750 static void UnAutoGain1(t_Sample* bufIn, t_Sample* bufOut, int size, 
1751                                                 double gain)
1752 {
1753     register int i;
1754         if (gain == 0.0)
1755         {
1756                 if (bufIn != bufOut)
1757                         for (i = 0; i < size; i++)
1758                                 bufOut[i] = bufIn[i];
1759                 return;
1760         }
1761
1762     for (i = 0; i < size; i++)
1763     {
1764         int s = abs(bufIn[i] - ZERO);
1765       #if defined(LOGARITHMIC_GAIN)
1766         s = int(pow(2.0, s * gain)); //!!! could use some optimization
1767       #else
1768                 s =  int(((double)s) * gain + .5);
1769       #endif
1770                 if (s > 127) s = 127;
1771         bufOut[i] = bufIn[i] < ZERO ? t_Sample(ZERO - s) : t_Sample(s + ZERO);
1772     }
1773 }
1774
1775 static void InitLowPassFilter(int QoS, double LPF_Coef[], 
1776                                                           char LPF_CoefTimesSample[LPF_NUM_POINTS][256])
1777 {
1778         // QoS==10 ==> cutoff frequency is 5500Hz (filter is a noop)
1779         // QoS==1  ==> cutoff frequency is  550Hz
1780         int N = 19, K = 2 * QoS - 1, kshift = LPF_NUM_POINTS/2, k;
1781     for (k = 0; k < LPF_NUM_POINTS; k++)
1782     {
1783         if (k != kshift)
1784             LPF_Coef[k] = sin(PI * (k-kshift) * K / (double)N) / 
1785                         ( sin(PI * (k-kshift) / (double)N) * N );
1786         else
1787             LPF_Coef[k] = ((double)K) / N;
1788         for (int i = 0; i < 256; i++)
1789             LPF_CoefTimesSample[k][i] = (char)(LPF_Coef[k] * i + .5);
1790     }
1791 }
1792
1793 // can now operate in place
1794 static void LowPassFilter(t_Sample* bufIn, t_Sample* bufOut, int size,
1795                                                   char LPF_CoefTimesSample[LPF_NUM_POINTS][256])
1796 {
1797     register int j;
1798
1799   #if !defined(USE_LOWPASS_FILTER)
1800         if (bufIn != bufOut)
1801                 for (j = 0; j < size; j++)
1802                         bufOut[j] = bufIn[j];
1803         return;
1804   #endif
1805
1806     for (j = LPF_NUM_POINTS-1; j < size; j++)
1807     {
1808         register int i, sum = 0;
1809         for (i = 0; i < LPF_NUM_POINTS; i++)
1810                 {
1811                         int temp1 = bufIn[ i + (j-(LPF_NUM_POINTS-1)) ]; //    0 -> 255
1812                         temp1 -= ZERO;                                   // -128 -> 127
1813                         // lookup based on abs value
1814                         int temp2 = LPF_CoefTimesSample[i][abs(temp1)];   
1815             if (temp1 < 0)
1816                                 sum -= temp2;
1817                         else
1818                                 sum += temp2;
1819                 }
1820
1821                 // depending on the exact values of the coefficients, there is a
1822                 // chance that sum may become slightly larger (or smaller) than the
1823                 // maximum (mimimum) allowable values, so truncate it before it does
1824                 // any damage
1825                 if (sum >  127) sum =  127;
1826                 if (sum < -128) sum = -128;
1827
1828         bufOut[j-(LPF_NUM_POINTS-1)] = t_Sample(sum + ZERO);
1829     }
1830
1831   #if 0
1832     //for (j = 0; j < LPF_NUM_POINTS-1; j++)
1833     //  bufOut[j] = 0;  // clear unused buffer entries
1834
1835         // fade in the samples to avoid pops & clicks
1836     int level = bufOut[LPF_NUM_POINTS-1];
1837     for (j = LPF_NUM_POINTS-2; j >= 0; j--)
1838         bufOut[j] = level = ((level-ZERO) >> 1) + ZERO;
1839   #else
1840         // fade out the samples to avoid pops & clicks
1841     int level = bufOut[size - LPF_NUM_POINTS];
1842     for (j = size-(LPF_NUM_POINTS+1); j < size; j++)
1843                 bufOut[j] = t_Sample(level = ((level-ZERO) >> 1) + ZERO);
1844   #endif
1845   #if defined(REMOVE_DC_BIAS)
1846         int sum, bias;
1847         // remove DC bias
1848         for (j = 0, sum = 0; j < size; j++)
1849                 sum += bufOut[j] - ZERO;
1850         bias = sum / size;
1851         for (j = 0; j < size; j++)
1852                 bufOut[j] -= bias;
1853   #endif
1854 }
1855
1856 // can operate in place (i.e. bufIn == bufOut is ok)
1857 static void SkipEveryOther(t_Sample* bufIn, t_Sample* bufOut, int size)
1858 {
1859     for (int i = 0; i < size; i += 2)
1860         bufOut[i/2] = bufIn[i];
1861 }
1862
1863 static void InterpolateEveryOther(t_Sample* bufIn, t_Sample* bufOut, int size)
1864 {
1865     for (int i = 0; i < size; i++)
1866     {
1867         *bufOut++ = *bufIn;
1868         *bufOut++ = t_Sample((*bufIn + *(bufIn+1)) / 2);
1869         bufIn++;
1870     }
1871 }
1872
1873
1874 #if defined(USE_LPC10)
1875 extern "C"
1876 {
1877     #include "lpc10\ulaw.h" // it's the LAW
1878 };
1879 // can operate in place
1880 static void ConvertToLPC10(t_Sample* bufIn, t_Sample* bufOut, int size)
1881 {
1882 #if 0
1883     unsigned short s;
1884     for (int i = 0; i < size; i++)
1885     {
1886         s = bufIn[i]-ZERO;
1887         s <<= 8;
1888         s >>= 3;
1889         bufOut[i] = s2u[s];
1890     }
1891 #else
1892
1893     for (int i = 0; i < size; i++)
1894         bufOut[i] = audio_c2u(bufIn[i]);
1895 #endif
1896 }
1897
1898 // can operate in place
1899 static void ConvertFromLPC10(t_Sample* bufIn, t_Sample* bufOut, int size)
1900 {
1901     for (int i = 0; i < size; i++)
1902         bufOut[i] = t_Sample(audio_u2c(bufIn[i]));
1903 }
1904 #endif // defined(USE_LPC10)
1905
1906
1907 //////////////////////////////////////////////////////////////////////////////
1908 // Only unused junk below.  Being kept around for reference only.
1909
1910 #if 0
1911     for (i = 0; i < 256; i++)
1912     {
1913         s = abs(i - ZERO);
1914         if (s > 22)
1915             s = (log((double)s) / log(2.0)) * 5 + .5;
1916         s = i < ZERO ? ZERO - s : s + ZERO;
1917         unsigned char junk = s;
1918         if (junk > ZERO+35 || junk < ZERO-36)
1919             junk = 127;
1920     }
1921
1922 static void Log1(t_Sample* bufIn, t_Sample* bufOut, int size)
1923 {
1924     register int i, s;
1925     for (i = 0; i < size; i++)
1926     {
1927         s = abs(bufIn[i] - ZERO);
1928         if (s > 22)
1929             s = Log2[s] * 5.0 + .5;
1930         bufOut[i] = bufIn[i] < ZERO ? ZERO - s : s + ZERO;
1931         if (bufOut[i] > ZERO+35 || bufOut[i] < ZERO-36)
1932             bufOut[i] = 127;
1933     }
1934 }
1935
1936 static void UnLog1(t_Sample* bufIn, t_Sample* bufOut, int size)
1937 {
1938     int i;
1939     for (i = 0; i < size; i++)
1940     {
1941         int s = abs(bufIn[i] - ZERO);
1942         
1943         if (s > 22)
1944             s = pow(2.0, s / 5.0); //!!! could use some optimization
1945         bufOut[i] = bufIn[i] < ZERO ? ZERO - s : s + ZERO;
1946     }
1947 }
1948
1949 // from InitLowPassFilter():
1950     //int K = LPF_NUM_POINTS;
1951     //double cutoffFrequency = 1100.0*QoS,
1952     //       bandwidthPerBucket = cutoffFrequency / (K/2);
1953     //int N = (int)(11000.0 / bandwidthPerBucket), k,
1954     //    kshift = K/2;
1955
1956     // cutoff fraction = cutoff freq / sample freq
1957     // ==> cutoff fraction = LPF_NUM_POINTS / N
1958     // ==> N = LPF_NUM_POINTS / cutoff fraction
1959     //int i, k, N = (int)(LPF_NUM_POINTS / ((1100.0*QoS) / 11000.0)), 
1960     //    kshift = LPF_NUM_POINTS/2;
1961
1962
1963 #endif
1964