1 #include "burnint.h"
2 #include "dac.h"
3
4 #define DAC_NUM (8) // Maximum DAC chips
5
6 struct dac_info
7 {
8 INT16 Output;
9 INT16 Output2;
10 INT32 Stereo;
11 double nVolume;
12 INT32 nCurrentPosition;
13 INT32 Initialized;
14 INT32 OutputDir;
15 INT32 (*pSyncCallback)();
16 };
17
18 static struct dac_info dac_table[DAC_NUM];
19
20 static INT16 UnsignedVolTable[256];
21 static INT16 SignedVolTable[256];
22
23 static INT16 *lBuffer = NULL;
24 static INT16 *rBuffer = NULL;
25
26 static INT32 NumChips;
27
28 static INT32 bAddSignal;
29
30 static INT32 (*pCPUTotalCycles)() = NULL;
31 static UINT32 nDACCPUMHZ = 0;
32
33 // single-order dc blocking filter
34 static INT32 dac_dcblock = 0; // enable
35 static INT16 dac_lastin_r = 0;
36 static INT16 dac_lastout_r = 0;
37 static INT16 dac_lastin_l = 0;
38 static INT16 dac_lastout_l = 0;
39
DACDCBlock(INT32 enable)40 void DACDCBlock(INT32 enable)
41 {
42 dac_dcblock = enable;
43 }
44
dc_blockR(INT16 sam)45 static INT16 dc_blockR(INT16 sam)
46 {
47 if (!dac_dcblock) return sam;
48 INT16 outr = sam - dac_lastin_r + 0.998 * dac_lastout_r;
49 dac_lastin_r = sam;
50 dac_lastout_r = outr;
51
52 return outr;
53 }
54
dc_blockL(INT16 sam)55 static INT16 dc_blockL(INT16 sam)
56 {
57 if (!dac_dcblock) return sam;
58 INT16 outl = sam - dac_lastin_l + 0.998 * dac_lastout_l;
59 dac_lastin_l = sam;
60 dac_lastout_l = outl;
61
62 return outl;
63 }
64
DACSyncInternal()65 static INT32 DACSyncInternal()
66 {
67 return (INT32)(float)(nBurnSoundLen * (pCPUTotalCycles() / (nDACCPUMHZ / (nBurnFPS / 100.0000))));
68 }
69
UpdateStream(INT32 chip,INT32 length)70 static void UpdateStream(INT32 chip, INT32 length)
71 {
72 struct dac_info *ptr;
73
74 if (lBuffer == NULL) { // delay buffer allocation for cases when fps is not 60
75 lBuffer = (INT16*)BurnMalloc(nBurnSoundLen * sizeof(INT16));
76 memset (lBuffer, 0, nBurnSoundLen * sizeof(INT16));
77 }
78 if (rBuffer == NULL) { // delay buffer allocation for cases when fps is not 60
79 rBuffer = (INT16*)BurnMalloc(nBurnSoundLen * sizeof(INT16));
80 memset (rBuffer, 0, nBurnSoundLen * sizeof(INT16));
81 }
82
83 ptr = &dac_table[chip];
84 if (ptr->Initialized == 0) return;
85
86 if (length > nBurnSoundLen) length = nBurnSoundLen;
87 length -= ptr->nCurrentPosition;
88 if (length <= 0) return;
89
90 INT16 *lbuf = lBuffer + ptr->nCurrentPosition;
91 INT16 *rbuf = rBuffer + ptr->nCurrentPosition;
92
93 INT16 lOut = ((ptr->OutputDir & BURN_SND_ROUTE_LEFT ) == BURN_SND_ROUTE_LEFT ) ? ptr->Output : 0;
94 INT16 rOut = ((ptr->OutputDir & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) ? ((ptr->Stereo) ? ptr->Output2 : ptr->Output) : 0;
95
96 ptr->nCurrentPosition += length;
97
98 if (rOut && lOut) {
99 while (length--) {
100 *lbuf = BURN_SND_CLIP((INT32)(*lbuf + lOut));
101 *rbuf = BURN_SND_CLIP((INT32)(*rbuf + rOut));
102 lbuf++,rbuf++;
103 }
104 } else if (lOut) {
105 while (length--) {
106 *lbuf = BURN_SND_CLIP((INT32)(*lbuf + lOut));
107 lbuf++;
108 }
109 } else if (rOut) {
110 while (length--) {
111 *rbuf = BURN_SND_CLIP((INT32)(*rbuf + rOut));
112 rbuf++;
113 }
114 }
115 }
116
DACUpdate(INT16 * Buffer,INT32 Length)117 void DACUpdate(INT16* Buffer, INT32 Length)
118 {
119 #if defined FBA_DEBUG
120 if (!DebugSnd_DACInitted) bprintf(PRINT_ERROR, _T("DACUpdate called without init\n"));
121 #endif
122
123 struct dac_info *ptr;
124
125 for (INT32 i = 0; i < NumChips; i++) {
126 UpdateStream(i, nBurnSoundLen);
127 }
128
129 INT16 *lbuf = lBuffer;
130 INT16 *rbuf = rBuffer;
131
132 if (bAddSignal) {
133 while (Length--) {
134 Buffer[0] = BURN_SND_CLIP((INT32)(dc_blockL(lbuf[0]) + Buffer[0]));
135 Buffer[1] = BURN_SND_CLIP((INT32)(dc_blockR(rbuf[0]) + Buffer[1]));
136 Buffer += 2;
137 lbuf[0] = 0; // clear buffer
138 rbuf[0] = 0; // clear buffer
139 lbuf++;
140 rbuf++;
141 }
142 } else {
143 while (Length--) {
144 Buffer[0] = dc_blockL(lbuf[0]);
145 Buffer[1] = dc_blockR(rbuf[0]);
146 Buffer += 2;
147 lbuf[0] = 0; // clear buffer
148 rbuf[0] = 0; // clear buffer
149 lbuf++;
150 rbuf++;
151 }
152 }
153
154 for (INT32 i = 0; i < NumChips; i++) {
155 ptr = &dac_table[i];
156 ptr->nCurrentPosition = 0;
157 }
158 }
159
DACWrite(INT32 Chip,UINT8 Data)160 void DACWrite(INT32 Chip, UINT8 Data)
161 {
162 #if defined FBA_DEBUG
163 if (!DebugSnd_DACInitted) bprintf(PRINT_ERROR, _T("DACWrite called without init\n"));
164 if (Chip > NumChips) bprintf(PRINT_ERROR, _T("DACWrite called with invalid chip number %x\n"), Chip);
165 #endif
166
167 struct dac_info *ptr;
168
169 ptr = &dac_table[Chip];
170
171 UpdateStream(Chip, ptr->pSyncCallback());
172
173 ptr->Output = (INT32)(UnsignedVolTable[Data] * ptr->nVolume);
174 }
175
DACWrite16(INT32 Chip,INT16 Data)176 void DACWrite16(INT32 Chip, INT16 Data)
177 {
178 #if defined FBA_DEBUG
179 if (!DebugSnd_DACInitted) bprintf(PRINT_ERROR, _T("DACWrite16 called without init\n"));
180 if (Chip > NumChips) bprintf(PRINT_ERROR, _T("DACWrite16 called with invalid chip number %x\n"), Chip);
181 #endif
182
183 struct dac_info *ptr;
184
185 ptr = &dac_table[Chip];
186
187 Data = (INT32)(Data * ptr->nVolume);
188
189 if (Data != ptr->Output) {
190 UpdateStream(Chip, ptr->pSyncCallback());
191 ptr->Output = Data;
192 }
193 }
194
DACWrite16Stereo(INT32 Chip,INT16 Data,INT16 Data2)195 void DACWrite16Stereo(INT32 Chip, INT16 Data, INT16 Data2)
196 {
197 #if defined FBA_DEBUG
198 if (!DebugSnd_DACInitted) bprintf(PRINT_ERROR, _T("DACWrite16Stereo called without init\n"));
199 if (Chip > NumChips) bprintf(PRINT_ERROR, _T("DACWrite16Stereo called with invalid chip number %x\n"), Chip);
200 #endif
201
202 struct dac_info *ptr;
203
204 ptr = &dac_table[Chip];
205
206 Data = (INT32)(Data * ptr->nVolume);
207 Data2 = (INT32)(Data2 * ptr->nVolume);
208
209 if (Data != ptr->Output || Data2 != ptr->Output2) {
210 UpdateStream(Chip, ptr->pSyncCallback());
211 ptr->Output = Data;
212 ptr->Output2 = Data2;
213 }
214 }
215
DACWrite16Signed(INT32 Chip,UINT16 Data)216 void DACWrite16Signed(INT32 Chip, UINT16 Data)
217 {
218 #if defined FBA_DEBUG
219 if (!DebugSnd_DACInitted) bprintf(PRINT_ERROR, _T("DACWrite16 called without init\n"));
220 if (Chip > NumChips) bprintf(PRINT_ERROR, _T("DACWrite16 called with invalid chip number %x\n"), Chip);
221 #endif
222
223 struct dac_info *ptr;
224
225 ptr = &dac_table[Chip];
226
227 INT16 Signed = Data - 0x8000;
228
229 Data = (INT32)(Signed * ptr->nVolume);
230
231 if (Data != ptr->Output) {
232 UpdateStream(Chip, ptr->pSyncCallback());
233 ptr->Output = Data;
234 }
235 }
236
DACSignedWrite(INT32 Chip,UINT8 Data)237 void DACSignedWrite(INT32 Chip, UINT8 Data)
238 {
239 #if defined FBA_DEBUG
240 if (!DebugSnd_DACInitted) bprintf(PRINT_ERROR, _T("DACSignedWrite called without init\n"));
241 if (Chip > NumChips) bprintf(PRINT_ERROR, _T("DACSignedWrite called with invalid chip number %x\n"), Chip);
242 #endif
243 struct dac_info *ptr;
244
245 ptr = &dac_table[Chip];
246
247 UpdateStream(Chip, ptr->pSyncCallback());
248
249 ptr->Output = (INT32)(SignedVolTable[Data] * ptr->nVolume);
250 }
251
DACBuildVolTables()252 static void DACBuildVolTables()
253 {
254 for (INT32 i = 0;i < 256;i++) {
255 UnsignedVolTable[i] = i * 0x101 / 2;
256 SignedVolTable[i] = i * 0x101 - 0x8000;
257 }
258 }
259
DACStereoMode(INT32 Chip)260 void DACStereoMode(INT32 Chip)
261 {
262 #if defined FBA_DEBUG
263 if (!DebugSnd_DACInitted) bprintf(PRINT_ERROR, _T("DACStereoMode called without init\n"));
264 if (Chip > NumChips) bprintf(PRINT_ERROR, _T("DACStereoMode called with invalid chip number %x\n"), Chip);
265 #endif
266
267 struct dac_info *ptr;
268 ptr = &dac_table[Chip];
269
270 ptr->Stereo = 1;
271 }
272
DACInit(INT32 Num,UINT32 Clock,INT32 bAdd,INT32 (* pCPUCyclesCB)(),INT32 nCpuMHZ)273 void DACInit(INT32 Num, UINT32 Clock, INT32 bAdd, INT32 (*pCPUCyclesCB)(), INT32 nCpuMHZ)
274 {
275 if (pCPUCyclesCB == NULL) {
276 bprintf(PRINT_ERROR, _T("DACInit pCPUCyclesCB is NULL.\n"));
277 }
278 if (nCpuMHZ == 0) {
279 bprintf(PRINT_ERROR, _T("DACInit nCPUMHZ is 0.\n"));
280 }
281
282 pCPUTotalCycles = pCPUCyclesCB;
283 nDACCPUMHZ = nCpuMHZ;
284
285 DACInit(Num, Clock, bAdd, DACSyncInternal);
286 }
287
288
DACInit(INT32 Num,UINT32,INT32 bAdd,INT32 (* pSyncCB)())289 void DACInit(INT32 Num, UINT32 /*Clock*/, INT32 bAdd, INT32 (*pSyncCB)())
290 {
291 #if defined FBA_DEBUG
292 if (Num >= DAC_NUM) bprintf (PRINT_ERROR, _T("DACInit called for too many chips (%d)! Change DAC_NUM (%d)!\n"), Num, DAC_NUM);
293 if (pSyncCB == NULL) bprintf (PRINT_ERROR, _T("DACInit called with NULL callback!\n"));
294 #endif
295
296 struct dac_info *ptr;
297
298 DebugSnd_DACInitted = 1;
299
300 NumChips = Num + 1;
301
302 ptr = &dac_table[Num];
303
304 memset (ptr, 0, sizeof(dac_info));
305
306 ptr->Initialized = 1;
307 ptr->nVolume = 1.00;
308 ptr->OutputDir = BURN_SND_ROUTE_BOTH;
309 ptr->Stereo = 0;
310 ptr->pSyncCallback = pSyncCB;
311
312 DACBuildVolTables(); // necessary to build for every chip?
313
314 bAddSignal = bAdd;
315 }
316
DACSetRoute(INT32 Chip,double nVolume,INT32 nRouteDir)317 void DACSetRoute(INT32 Chip, double nVolume, INT32 nRouteDir)
318 {
319 #if defined FBA_DEBUG
320 if (!DebugSnd_DACInitted) bprintf(PRINT_ERROR, _T("DACSetRoute called without init\n"));
321 if (Chip > NumChips) bprintf(PRINT_ERROR, _T("DACSetRoute called with invalid chip %i\n"), Chip);
322 #endif
323
324 struct dac_info *ptr;
325
326 ptr = &dac_table[Chip];
327 ptr->nVolume = nVolume;
328 ptr->OutputDir = nRouteDir;
329 }
330
DACReset()331 void DACReset()
332 {
333 #if defined FBA_DEBUG
334 if (!DebugSnd_DACInitted) bprintf(PRINT_ERROR, _T("DACReset called without init\n"));
335 #endif
336
337 struct dac_info *ptr;
338
339 for (INT32 i = 0; i < NumChips; i++) {
340 ptr = &dac_table[i];
341
342 ptr->nCurrentPosition = 0;
343 ptr->Output = 0;
344 ptr->Output2 = 0;
345 }
346
347 dac_lastin_r = dac_lastout_r = 0;
348 dac_lastin_l = dac_lastout_l = 0;
349 }
350
DACExit()351 void DACExit()
352 {
353 #if defined FBA_DEBUG
354 if (!DebugSnd_DACInitted) bprintf(PRINT_ERROR, _T("DACExit called without init\n"));
355 #endif
356
357 if (!DebugSnd_DACInitted) return;
358
359 struct dac_info *ptr;
360
361 for (INT32 i = 0; i < DAC_NUM; i++) {
362 ptr = &dac_table[i];
363
364 ptr->Initialized = 0;
365 ptr->pSyncCallback = NULL;
366 }
367
368 pCPUTotalCycles = NULL;
369 nDACCPUMHZ = 0;
370
371 NumChips = 0;
372
373 dac_dcblock = 0;
374
375 DebugSnd_DACInitted = 0;
376
377 BurnFree (lBuffer);
378 BurnFree (rBuffer);
379 lBuffer = NULL;
380 rBuffer = NULL;
381 }
382
DACScan(INT32 nAction,INT32 * pnMin)383 void DACScan(INT32 nAction, INT32 *pnMin)
384 {
385 #if defined FBA_DEBUG
386 if (!DebugSnd_DACInitted) bprintf(PRINT_ERROR, _T("DACScan called without init\n"));
387 #endif
388
389 if (pnMin != NULL) {
390 *pnMin = 0x029719;
391 }
392
393 struct dac_info *ptr;
394
395 if (nAction & ACB_DRIVER_DATA) {
396 for (INT32 i = 0; i < NumChips; i++) {
397 ptr = &dac_table[i];
398
399 SCAN_VAR(ptr->Output);
400 SCAN_VAR(ptr->Output2);
401 }
402 }
403 }
404