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