~ubuntu-branches/debian/squeeze/stella/squeeze

« back to all changes in this revision

Viewing changes to src/ui/sound/TIASound.c

  • Committer: Bazaar Package Importer
  • Author(s): Tom Lear
  • Date: 1999-11-06 16:41:05 UTC
  • Revision ID: james.westby@ubuntu.com-19991106164105-iygopamo5mpcozvx
Tags: upstream-1.1
ImportĀ upstreamĀ versionĀ 1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************/
 
2
/*                                                                           */
 
3
/* Module:  TIA Chip Sound Simulator                                         */
 
4
/* Purpose: To emulate the sound generation hardware of the Atari TIA chip.  */
 
5
/* Author:  Ron Fries                                                        */
 
6
/*                                                                           */
 
7
/* Revision History:                                                         */
 
8
/*    10-Sep-96 - V1.0 - Initial Release                                     */
 
9
/*    14-Jan-97 - V1.1 - Cleaned up sound output by eliminating counter      */
 
10
/*                       reset.                                              */
 
11
/*                                                                           */
 
12
/*****************************************************************************/
 
13
/*                                                                           */
 
14
/*                 License Information and Copyright Notice                  */
 
15
/*                 ========================================                  */
 
16
/*                                                                           */
 
17
/* TiaSound is Copyright(c) 1996 by Ron Fries                                */
 
18
/*                                                                           */
 
19
/* This library is free software; you can redistribute it and/or modify it   */
 
20
/* under the terms of version 2 of the GNU Library General Public License    */
 
21
/* as published by the Free Software Foundation.                             */
 
22
/*                                                                           */
 
23
/* This library is distributed in the hope that it will be useful, but       */
 
24
/* WITHOUT ANY WARRANTY; without even the implied warranty of                */
 
25
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library */
 
26
/* General Public License for more details.                                  */
 
27
/* To obtain a copy of the GNU Library General Public License, write to the  */
 
28
/* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   */
 
29
/*                                                                           */
 
30
/* Any permitted reproduction of these routines, in whole or in part, must   */
 
31
/* bear this legend.                                                         */
 
32
/*                                                                           */
 
33
/*****************************************************************************/
 
34
 
 
35
#include <stdio.h>
 
36
#include <stdlib.h>
 
37
#include <time.h>
 
38
 
 
39
 
 
40
/* define some data types to keep it platform independent */
 
41
#ifdef WIN32
 
42
#define int8  char
 
43
#define int16 short
 
44
#define int32 int
 
45
#else
 
46
#define int8  char
 
47
#define int16 int
 
48
#define int32 long
 
49
#endif
 
50
 
 
51
#define uint8  unsigned int8 
 
52
#define uint16 unsigned int16
 
53
#define uint32 unsigned int32
 
54
 
 
55
 
 
56
/* CONSTANT DEFINITIONS */
 
57
 
 
58
/* definitions for AUDCx (15, 16) */
 
59
#define SET_TO_1     0x00      /* 0000 */
 
60
#define POLY4        0x01      /* 0001 */
 
61
#define DIV31_POLY4  0x02      /* 0010 */
 
62
#define POLY5_POLY4  0x03      /* 0011 */
 
63
#define PURE         0x04      /* 0100 */
 
64
#define PURE2        0x05      /* 0101 */
 
65
#define DIV31_PURE   0x06      /* 0110 */
 
66
#define POLY5_2      0x07      /* 0111 */
 
67
#define POLY9        0x08      /* 1000 */
 
68
#define POLY5        0x09      /* 1001 */
 
69
#define DIV31_POLY5  0x0a      /* 1010 */
 
70
#define POLY5_POLY5  0x0b      /* 1011 */
 
71
#define DIV3_PURE    0x0c      /* 1100 */
 
72
#define DIV3_PURE2   0x0d      /* 1101 */
 
73
#define DIV93_PURE   0x0e      /* 1110 */
 
74
#define DIV3_POLY5   0x0f      /* 1111 */
 
75
                 
 
76
#define DIV3_MASK    0x0c                 
 
77
                 
 
78
#define AUDC0        0x15
 
79
#define AUDC1        0x16
 
80
#define AUDF0        0x17
 
81
#define AUDF1        0x18
 
82
#define AUDV0        0x19
 
83
#define AUDV1        0x1a
 
84
 
 
85
/* the size (in entries) of the 4 polynomial tables */
 
86
#define POLY4_SIZE  0x000f
 
87
#define POLY5_SIZE  0x001f
 
88
#define POLY9_SIZE  0x01ff
 
89
 
 
90
/* channel definitions */
 
91
#define CHAN1       0
 
92
#define CHAN2       1
 
93
 
 
94
#define FALSE       0
 
95
#define TRUE        1
 
96
 
 
97
 
 
98
/* LOCAL GLOBAL VARIABLE DEFINITIONS */
 
99
 
 
100
/* structures to hold the 6 tia sound control bytes */
 
101
static uint8 AUDC[2];    /* AUDCx (15, 16) */
 
102
static uint8 AUDF[2];    /* AUDFx (17, 18) */
 
103
static uint8 AUDV[2];    /* AUDVx (19, 1A) */
 
104
 
 
105
static uint8 Outvol[2];  /* last output volume for each channel */
 
106
 
 
107
 
 
108
/* Initialze the bit patterns for the polynomials. */
 
109
 
 
110
/* The 4bit and 5bit patterns are the identical ones used in the tia chip. */
 
111
/* Though the patterns could be packed with 8 bits per byte, using only a */
 
112
/* single bit per byte keeps the math simple, which is important for */
 
113
/* efficient processing. */
 
114
 
 
115
static uint8 Bit4[POLY4_SIZE] =
 
116
      { 1,1,0,1,1,1,0,0,0,0,1,0,1,0,0 };
 
117
 
 
118
static uint8 Bit5[POLY5_SIZE] =
 
119
      { 0,0,1,0,1,1,0,0,1,1,1,1,1,0,0,0,1,1,0,1,1,1,0,1,0,1,0,0,0,0,1 };
 
120
 
 
121
/* I've treated the 'Div by 31' counter as another polynomial because of */
 
122
/* the way it operates.  It does not have a 50% duty cycle, but instead */
 
123
/* has a 13:18 ratio (of course, 13+18 = 31).  This could also be */
 
124
/* implemented by using counters. */
 
125
 
 
126
static uint8 Div31[POLY5_SIZE] =
 
127
      { 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0 };
 
128
 
 
129
/* Rather than have a table with 511 entries, I use a random number */
 
130
/* generator. */
 
131
 
 
132
static uint8 Bit9[POLY9_SIZE];
 
133
 
 
134
static uint8  P4[2]; /* Position pointer for the 4-bit POLY array */
 
135
static uint8  P5[2]; /* Position pointer for the 5-bit POLY array */
 
136
static uint16 P9[2]; /* Position pointer for the 9-bit POLY array */
 
137
 
 
138
static uint8 Div_n_cnt[2];  /* Divide by n counter. one for each channel */
 
139
static uint8 Div_n_max[2];  /* Divide by n maximum, one for each channel */
 
140
 
 
141
 
 
142
/* In my routines, I treat the sample output as another divide by N counter. */
 
143
/* For better accuracy, the Samp_n_cnt has a fixed binary decimal point */
 
144
/* which has 8 binary digits to the right of the decimal point. */
 
145
 
 
146
static uint16 Samp_n_max; /* Sample max, multiplied by 256 */
 
147
static uint16 Samp_n_cnt; /* Sample cnt. */
 
148
 
 
149
 
 
150
 
 
151
/*****************************************************************************/
 
152
/* Module:  Tia_sound_init()                                                 */
 
153
/* Purpose: to handle the power-up initialization functions                  */
 
154
/*          these functions should only be executed on a cold-restart        */
 
155
/*                                                                           */
 
156
/* Author:  Ron Fries                                                        */
 
157
/* Date:    September 10, 1996                                               */
 
158
/*                                                                           */
 
159
/* Inputs:  sample_freq - the value for the '30 Khz' Tia audio clock         */
 
160
/*          playback_freq - the playback frequency in samples per second     */
 
161
/*                                                                           */
 
162
/* Outputs: Adjusts local globals - no return value                          */
 
163
/*                                                                           */
 
164
/*****************************************************************************/
 
165
 
 
166
void Tia_sound_init (uint16 sample_freq, uint16 playback_freq)
 
167
{
 
168
   uint8 chan;
 
169
   int16 n;
 
170
 
 
171
   /* fill the 9bit polynomial with random bits */
 
172
   for (n=0; n<POLY9_SIZE; n++)
 
173
   {
 
174
      Bit9[n] = rand() & 0x01;       /* fill poly9 with random bits */
 
175
   }
 
176
 
 
177
   /* calculate the sample 'divide by N' value based on the playback freq. */
 
178
   Samp_n_max = (uint16)(((uint32)sample_freq<<8)/playback_freq);
 
179
   Samp_n_cnt = 0;  /* initialize all bits of the sample counter */
 
180
 
 
181
   /* initialize the local globals */
 
182
   for (chan = CHAN1; chan <= CHAN2; chan++)
 
183
   {
 
184
      Outvol[chan] = 0;
 
185
      Div_n_cnt[chan] = 0;
 
186
      Div_n_max[chan] = 0;
 
187
      AUDC[chan] = 0;
 
188
      AUDF[chan] = 0;
 
189
      AUDV[chan] = 0;
 
190
      P4[chan] = 0;
 
191
      P5[chan] = 0;
 
192
      P9[chan] = 0;
 
193
   }
 
194
}
 
195
 
 
196
 
 
197
/*****************************************************************************/
 
198
/* Module:  Update_tia_sound()                                               */
 
199
/* Purpose: To process the latest control values stored in the AUDF, AUDC,   */
 
200
/*          and AUDV registers.  It pre-calculates as much information as    */
 
201
/*          possible for better performance.  This routine has not been      */
 
202
/*          optimized.                                                       */
 
203
/*                                                                           */
 
204
/* Author:  Ron Fries                                                        */
 
205
/* Date:    January 14, 1997                                                 */
 
206
/*                                                                           */
 
207
/* Inputs:  addr - the address of the parameter to be changed                */
 
208
/*          val - the new value to be placed in the specified address        */
 
209
/*                                                                           */
 
210
/* Outputs: Adjusts local globals - no return value                          */
 
211
/*                                                                           */
 
212
/*****************************************************************************/
 
213
 
 
214
void Update_tia_sound (uint16 addr, uint8 val)
 
215
{
 
216
    uint16 new_val = 0;
 
217
    uint8 chan;
 
218
 
 
219
    /* determine which address was changed */
 
220
    switch (addr)
 
221
    {
 
222
       case AUDC0:
 
223
          AUDC[0] = val & 0x0f;
 
224
          chan = 0;
 
225
          break;
 
226
 
 
227
       case AUDC1:
 
228
          AUDC[1] = val & 0x0f;
 
229
          chan = 1;
 
230
          break;
 
231
 
 
232
       case AUDF0:
 
233
          AUDF[0] = val & 0x1f;
 
234
          chan = 0;
 
235
          break;
 
236
 
 
237
       case AUDF1:
 
238
          AUDF[1] = val & 0x1f;
 
239
          chan = 1;
 
240
          break;
 
241
 
 
242
       case AUDV0:
 
243
          AUDV[0] = (val & 0x0f) << 3;
 
244
          chan = 0;
 
245
          break;
 
246
 
 
247
       case AUDV1:
 
248
          AUDV[1] = (val & 0x0f) << 3;
 
249
          chan = 1;
 
250
          break;
 
251
 
 
252
       default:
 
253
          chan = 255;
 
254
          break;
 
255
    }
 
256
 
 
257
    /* if the output value changed */
 
258
    if (chan != 255)
 
259
    {
 
260
       /* an AUDC value of 0 is a special case */
 
261
       if (AUDC[chan] == SET_TO_1)
 
262
       {
 
263
          /* indicate the clock is zero so no processing will occur */
 
264
          new_val = 0;
 
265
 
 
266
          /* and set the output to the selected volume */
 
267
          Outvol[chan] = AUDV[chan];
 
268
       }
 
269
       else
 
270
       {
 
271
          /* otherwise calculate the 'divide by N' value */
 
272
          new_val = AUDF[chan] + 1;
 
273
 
 
274
          /* if bits 2 & 3 are set, then multiply the 'div by n' count by 3 */
 
275
          if ((AUDC[chan] & DIV3_MASK) == DIV3_MASK)
 
276
          {
 
277
             new_val *= 3;
 
278
          }
 
279
       }
 
280
 
 
281
       /* only reset those channels that have changed */
 
282
       if (new_val != Div_n_max[chan])
 
283
       {
 
284
          /* reset the divide by n counters */
 
285
          Div_n_max[chan] = new_val;
 
286
 
 
287
          /* if the channel is now volume only or was volume only */
 
288
          if ((Div_n_cnt[chan] == 0) || (new_val == 0))
 
289
          {
 
290
             /* reset the counter (otherwise let it complete the previous) */
 
291
             Div_n_cnt[chan] = new_val;
 
292
          }
 
293
       }
 
294
    }
 
295
}
 
296
 
 
297
 
 
298
/*****************************************************************************/
 
299
/* Module:  Tia_process_2()                                                  */
 
300
/* Purpose: To fill the output buffer with the sound output based on the     */
 
301
/*          tia chip parameters.  This routine has not been optimized.       */
 
302
/*          Though it is not used by the program, I've left it for reference.*/
 
303
/*                                                                           */
 
304
/* Author:  Ron Fries                                                        */
 
305
/* Date:    September 10, 1996                                               */
 
306
/*                                                                           */
 
307
/* Inputs:  *buffer - pointer to the buffer where the audio output will      */
 
308
/*                    be placed                                              */
 
309
/*          n - size of the playback buffer                                  */
 
310
/*                                                                           */
 
311
/* Outputs: the buffer will be filled with n bytes of audio - no return val  */
 
312
/*                                                                           */
 
313
/*****************************************************************************/
 
314
 
 
315
void Tia_process_2 (register unsigned char *buffer, register uint16 n)
 
316
{
 
317
    register uint8 chan;
 
318
 
 
319
    /* loop until the buffer is filled */
 
320
    while (n)
 
321
    {
 
322
       /* loop through the channels */
 
323
       for (chan = CHAN1; chan <= CHAN2; chan++)
 
324
       {
 
325
          /* NOTE: this routine intentionally does not count down to zero */
 
326
          /* since 0 is used as a special case - no clock */
 
327
 
 
328
          /* if the divide by N counter can count down */
 
329
          if (Div_n_cnt[chan] > 1)
 
330
          {
 
331
             /* decrement and loop */
 
332
             Div_n_cnt[chan]--;
 
333
          }
 
334
          /* otherwise if we've reached the bottom */
 
335
          else if (Div_n_cnt[chan] == 1)
 
336
          {
 
337
             /* reset the counter */
 
338
             Div_n_cnt[chan] = Div_n_max[chan];
 
339
 
 
340
             /* the P5 counter has multiple uses, so we inc it here */
 
341
             P5[chan]++;
 
342
             if (P5[chan] == POLY5_SIZE)
 
343
                P5[chan] = 0;
 
344
 
 
345
             /* check clock modifier for clock tick */
 
346
 
 
347
             /* if we're using pure tones OR
 
348
                   we're using DIV31 and the DIV31 bit is set OR
 
349
                   we're using POLY5 and the POLY5 bit is set */
 
350
             if  (((AUDC[chan] & 0x02) == 0) ||
 
351
                 (((AUDC[chan] & 0x01) == 0) && Div31[P5[chan]]) ||
 
352
                 (((AUDC[chan] & 0x01) == 1) &&  Bit5[P5[chan]]))
 
353
             {
 
354
                if (AUDC[chan] & 0x04)       /* pure modified clock selected */
 
355
                {
 
356
                   if (Outvol[chan])         /* if the output was set */
 
357
                      Outvol[chan] = 0;      /* turn it off */
 
358
                   else
 
359
                      Outvol[chan] = AUDV[chan];   /* else turn it on */
 
360
                }
 
361
                else if (AUDC[chan] & 0x08)  /* check for p5/p9 */
 
362
                {
 
363
                   if (AUDC[chan] == POLY9)  /* check for poly9 */
 
364
                   {
 
365
                      /* inc the poly9 counter */
 
366
                      P9[chan]++;
 
367
                      if (P9[chan] == POLY9_SIZE)
 
368
                         P9[chan] = 0;
 
369
 
 
370
                      if (Bit9[P9[chan]])    /* if poly9 bit is set */
 
371
                         Outvol[chan] = AUDV[chan];
 
372
                      else
 
373
                         Outvol[chan] = 0;
 
374
                   }
 
375
                   else                      /* must be poly5 */
 
376
                   {
 
377
                      if (Bit5[P5[chan]])
 
378
                         Outvol[chan] = AUDV[chan];
 
379
                      else
 
380
                         Outvol[chan] = 0;
 
381
                   }
 
382
                }
 
383
                else  /* poly4 is the only remaining option */
 
384
                {
 
385
                   /* inc the poly4 counter */
 
386
                   P4[chan]++;
 
387
                   if (P4[chan] == POLY4_SIZE)
 
388
                      P4[chan] = 0;
 
389
 
 
390
                   if (Bit4[P4[chan]])
 
391
                      Outvol[chan] = AUDV[chan];
 
392
                   else
 
393
                      Outvol[chan] = 0;
 
394
                }
 
395
             }
 
396
          }
 
397
       }
 
398
 
 
399
       /* decrement the sample counter - value is 256 since the lower
 
400
          byte contains the fractional part */
 
401
       Samp_n_cnt -= 256;
 
402
 
 
403
       /* if the count down has reached zero */
 
404
       if (Samp_n_cnt < 256)
 
405
       {
 
406
          /* adjust the sample counter */
 
407
          Samp_n_cnt += Samp_n_max;
 
408
 
 
409
          /* calculate the latest output value and place in buffer */
 
410
          *(buffer++) = Outvol[0] + Outvol[1];
 
411
 
 
412
          /* and indicate one less byte to process */
 
413
          n--;
 
414
       }
 
415
    }
 
416
}
 
417
 
 
418
 
 
419
/*****************************************************************************/
 
420
/* Module:  Tia_process()                                                    */
 
421
/* Purpose: To fill the output buffer with the sound output based on the     */
 
422
/*          tia chip parameters.  This routine has been optimized.           */
 
423
/*                                                                           */
 
424
/* Author:  Ron Fries                                                        */
 
425
/* Date:    September 10, 1996                                               */
 
426
/*                                                                           */
 
427
/* Inputs:  *buffer - pointer to the buffer where the audio output will      */
 
428
/*                    be placed                                              */
 
429
/*          n - size of the playback buffer                                  */
 
430
/*                                                                           */
 
431
/* Outputs: the buffer will be filled with n bytes of audio - no return val  */
 
432
/*                                                                           */
 
433
/*****************************************************************************/
 
434
 
 
435
void Tia_process (register unsigned char *buffer, register uint16 n)
 
436
{
 
437
    register uint8 audc0,audv0,audc1,audv1;
 
438
    register uint8 div_n_cnt0,div_n_cnt1;
 
439
    register uint8 p5_0, p5_1,outvol_0,outvol_1;
 
440
 
 
441
    audc0 = AUDC[0];
 
442
    audv0 = AUDV[0];
 
443
    audc1 = AUDC[1];
 
444
    audv1 = AUDV[1];
 
445
 
 
446
    /* make temporary local copy */
 
447
    p5_0 = P5[0];
 
448
    p5_1 = P5[1];
 
449
    outvol_0 = Outvol[0];
 
450
    outvol_1 = Outvol[1];
 
451
    div_n_cnt0 = Div_n_cnt[0];
 
452
    div_n_cnt1 = Div_n_cnt[1];
 
453
 
 
454
    /* loop until the buffer is filled */
 
455
    while (n)
 
456
    {
 
457
       /* Process channel 0 */
 
458
       if (div_n_cnt0 > 1)
 
459
       {
 
460
          div_n_cnt0--;
 
461
       }
 
462
       else if (div_n_cnt0 == 1)
 
463
       {
 
464
          div_n_cnt0 = Div_n_max[0];
 
465
 
 
466
          /* the P5 counter has multiple uses, so we inc it here */
 
467
          p5_0++;
 
468
          if (p5_0 == POLY5_SIZE)
 
469
             p5_0 = 0;
 
470
 
 
471
          /* check clock modifier for clock tick */
 
472
          if  (((audc0 & 0x02) == 0) ||
 
473
              (((audc0 & 0x01) == 0) && Div31[p5_0]) ||
 
474
              (((audc0 & 0x01) == 1) &&  Bit5[p5_0]))
 
475
          {
 
476
             if (audc0 & 0x04)       /* pure modified clock selected */
 
477
             {
 
478
                if (outvol_0)        /* if the output was set */
 
479
                   outvol_0 = 0;     /* turn it off */
 
480
                else
 
481
                   outvol_0 = audv0; /* else turn it on */
 
482
             }
 
483
             else if (audc0 & 0x08)    /* check for p5/p9 */
 
484
             {
 
485
                if (audc0 == POLY9)    /* check for poly9 */
 
486
                {
 
487
                   /* inc the poly9 counter */
 
488
                   P9[0]++;
 
489
                   if (P9[0] == POLY9_SIZE)
 
490
                      P9[0] = 0;
 
491
 
 
492
                   if (Bit9[P9[0]])
 
493
                      outvol_0 = audv0;
 
494
                   else
 
495
                      outvol_0 = 0;
 
496
                }
 
497
                else                        /* must be poly5 */
 
498
                {
 
499
                   if (Bit5[p5_0])
 
500
                      outvol_0 = audv0;
 
501
                   else
 
502
                      outvol_0 = 0;
 
503
                }
 
504
             }
 
505
             else  /* poly4 is the only remaining option */
 
506
             {
 
507
                /* inc the poly4 counter */
 
508
                P4[0]++;
 
509
                if (P4[0] == POLY4_SIZE)
 
510
                   P4[0] = 0;
 
511
 
 
512
                if (Bit4[P4[0]])
 
513
                   outvol_0 = audv0;
 
514
                else
 
515
                   outvol_0 = 0;
 
516
             }
 
517
          }
 
518
       }
 
519
 
 
520
 
 
521
       /* Process channel 1 */
 
522
       if (div_n_cnt1 > 1)
 
523
       {
 
524
          div_n_cnt1--;
 
525
       }
 
526
       else if (div_n_cnt1 == 1)
 
527
       {
 
528
          div_n_cnt1 = Div_n_max[1];
 
529
 
 
530
          /* the P5 counter has multiple uses, so we inc it here */
 
531
          p5_1++;
 
532
          if (p5_1 == POLY5_SIZE)
 
533
             p5_1 = 0;
 
534
 
 
535
          /* check clock modifier for clock tick */
 
536
          if  (((audc1 & 0x02) == 0) ||
 
537
              (((audc1 & 0x01) == 0) && Div31[p5_1]) ||
 
538
              (((audc1 & 0x01) == 1) &&  Bit5[p5_1]))
 
539
          {
 
540
             if (audc1 & 0x04)       /* pure modified clock selected */
 
541
             {
 
542
                if (outvol_1)        /* if the output was set */
 
543
                   outvol_1 = 0;     /* turn it off */
 
544
                else
 
545
                   outvol_1 = audv1; /* else turn it on */
 
546
             }
 
547
             else if (audc1 & 0x08)    /* check for p5/p9 */
 
548
             {
 
549
                if (audc1 == POLY9)    /* check for poly9 */
 
550
                {
 
551
                   /* inc the poly9 counter */
 
552
                   P9[1]++;
 
553
                   if (P9[1] == POLY9_SIZE)
 
554
                      P9[1] = 0;
 
555
 
 
556
                   if (Bit9[P9[1]])
 
557
                      outvol_1 = audv1;
 
558
                   else
 
559
                      outvol_1 = 0;
 
560
                }
 
561
                else                        /* must be poly5 */
 
562
                {
 
563
                   if (Bit5[p5_1])
 
564
                      outvol_1 = audv1;
 
565
                   else
 
566
                      outvol_1 = 0;
 
567
                }
 
568
             }
 
569
             else  /* poly4 is the only remaining option */
 
570
             {
 
571
                /* inc the poly4 counter */
 
572
                P4[1]++;
 
573
                if (P4[1] == POLY4_SIZE)
 
574
                   P4[1] = 0;
 
575
 
 
576
                if (Bit4[P4[1]])
 
577
                   outvol_1 = audv1;
 
578
                else
 
579
                   outvol_1 = 0;
 
580
             }
 
581
          }
 
582
       }
 
583
 
 
584
       /* decrement the sample counter - value is 256 since the lower
 
585
          byte contains the fractional part */
 
586
       Samp_n_cnt -= 256;
 
587
 
 
588
       /* if the count down has reached zero */
 
589
       if (Samp_n_cnt < 256)
 
590
       {
 
591
          /* adjust the sample counter */
 
592
          Samp_n_cnt += Samp_n_max;
 
593
 
 
594
          /* calculate the latest output value and place in buffer */
 
595
          *(buffer++) = outvol_0 + outvol_1;
 
596
 
 
597
          /* and indicate one less byte to process */
 
598
          n--;
 
599
       }
 
600
    }
 
601
 
 
602
    /* save for next round */
 
603
    P5[0] = p5_0;
 
604
    P5[1] = p5_1;
 
605
    Outvol[0] = outvol_0;
 
606
    Outvol[1] = outvol_1;
 
607
    Div_n_cnt[0] = div_n_cnt0;
 
608
    Div_n_cnt[1] = div_n_cnt1;
 
609
 
 
610
}
 
611
 
 
612