1 {
2 	int i;
3 	DATATYPE *buf = (DATATYPE *)buffer;
4 	struct SN76496 *R = &sn[chip];
5 
6 
7 	/* If the volume is 0, increase the counter */
8 	for (i = 0;i < 4;i++)
9 	{
10 		if (R->Volume[i] == 0)
11 		{
12 			/* note that I do count += length, NOT count = length + 1. You might think */
13 			/* it's the same since the volume is 0, but doing the latter could cause */
14 			/* interferencies when the program is rapidly modulating the volume. */
15 			if (R->Count[i] <= length*STEP) R->Count[i] += length*STEP;
16 		}
17 	}
18 
19 	while (length > 0)
20 	{
21 		int vol[4];
22 		unsigned int out;
23 		int left;
24 		DATATYPE tmp;
25 
26 		/* vol[] keeps track of how long each square wave stays */
27 		/* in the 1 position during the sample period. */
28 		vol[0] = vol[1] = vol[2] = vol[3] = 0;
29 
30 		for (i = 0;i < 3;i++)
31 		{
32 			if (R->Output[i]) vol[i] += R->Count[i];
33 			R->Count[i] -= STEP;
34 			/* Period[i] is the half period of the square wave. Here, in each */
35 			/* loop I add Period[i] twice, so that at the end of the loop the */
36 			/* square wave is in the same status (0 or 1) it was at the start. */
37 			/* vol[i] is also incremented by Period[i], since the wave has been 1 */
38 			/* exactly half of the time, regardless of the initial position. */
39 			/* If we exit the loop in the middle, Output[i] has to be inverted */
40 			/* and vol[i] incremented only if the exit status of the square */
41 			/* wave is 1. */
42 			while (R->Count[i] <= 0)
43 			{
44 				R->Count[i] += R->Period[i];
45 				if (R->Count[i] > 0)
46 				{
47 					R->Output[i] ^= 1;
48 					if (R->Output[i]) vol[i] += R->Period[i];
49 					break;
50 				}
51 				R->Count[i] += R->Period[i];
52 				vol[i] += R->Period[i];
53 			}
54 			if (R->Output[i]) vol[i] -= R->Count[i];
55 		}
56 
57 		left = STEP;
58 		do
59 		{
60 			int nextevent;
61 
62 
63 			if (R->Count[3] < left) nextevent = R->Count[3];
64 			else nextevent = left;
65 
66 			if (R->Output[3]) vol[3] += R->Count[3];
67 			R->Count[3] -= nextevent;
68 			if (R->Count[3] <= 0)
69 			{
70 				if (R->RNG & 1) R->RNG ^= R->NoiseFB;
71 				R->RNG >>= 1;
72 				R->Output[3] = R->RNG & 1;
73 				R->Count[3] += R->Period[3];
74 				if (R->Output[3]) vol[3] += R->Period[3];
75 			}
76 			if (R->Output[3]) vol[3] -= R->Count[3];
77 
78 			left -= nextevent;
79 		} while (left > 0);
80 
81 		out = vol[0] * R->Volume[0] + vol[1] * R->Volume[1] +
82 				vol[2] * R->Volume[2] + vol[3] * R->Volume[3];
83 
84 		if (out > MAX_OUTPUT * STEP) out = MAX_OUTPUT * STEP;
85 
86 		tmp = ((DATACONV(out) * 3) >> 3); /* Dave: a bit quieter */
87 
88 		/* Both channels */
89 		*(buf++) = tmp;
90 		*(buf++) = tmp;
91 
92 		length--;
93 	}
94 }
95