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