1 #include "burnint.h"
2 #include "burn_ym2608.h"
3
4 void (*BurnYM2608Update)(INT16* pSoundBuf, INT32 nSegmentEnd);
5
6 static INT32 (*BurnYM2608StreamCallback)(INT32 nSoundRate);
7
8 static INT32 nBurnYM2608SoundRate;
9
10 static INT16* pBuffer;
11 static INT16* pYM2608Buffer[6];
12
13 static INT32* pAYBuffer;
14
15 static INT32 nYM2608Position;
16 static INT32 nAY8910Position;
17
18 static UINT32 nSampleSize;
19 static INT32 nFractionalPosition;
20
21 static INT32 bYM2608AddSignal;
22
23 static double YM2608Volumes[3];
24 static INT32 YM2608RouteDirs[3];
25
26 // ----------------------------------------------------------------------------
27 // Dummy functions
28
YM2608UpdateDummy(INT16 *,INT32)29 static void YM2608UpdateDummy(INT16*, INT32)
30 {
31 return;
32 }
33
YM2608StreamCallbackDummy(INT32)34 static INT32 YM2608StreamCallbackDummy(INT32)
35 {
36 return 0;
37 }
38
39 // ----------------------------------------------------------------------------
40 // Execute YM2608 for part of a frame
41
AY8910Render(INT32 nSegmentLength)42 static void AY8910Render(INT32 nSegmentLength)
43 {
44 #if defined FBA_DEBUG
45 if (!DebugSnd_YM2608Initted) bprintf(PRINT_ERROR, _T("BurnYM2608 AY8910Render called without init\n"));
46 #endif
47
48 if (nAY8910Position >= nSegmentLength) {
49 return;
50 }
51
52 nSegmentLength -= nAY8910Position;
53
54 pYM2608Buffer[2] = pBuffer + 2 * 4096 + 4 + nAY8910Position;
55 pYM2608Buffer[3] = pBuffer + 3 * 4096 + 4 + nAY8910Position;
56 pYM2608Buffer[4] = pBuffer + 4 * 4096 + 4 + nAY8910Position;
57
58 AY8910Update(0, &pYM2608Buffer[2], nSegmentLength);
59
60 nAY8910Position += nSegmentLength;
61 }
62
YM2608Render(INT32 nSegmentLength)63 static void YM2608Render(INT32 nSegmentLength)
64 {
65 #if defined FBA_DEBUG
66 if (!DebugSnd_YM2608Initted) bprintf(PRINT_ERROR, _T("YM2608Render called without init\n"));
67 #endif
68
69 if (nYM2608Position >= nSegmentLength) {
70 return;
71 }
72
73 nSegmentLength -= nYM2608Position;
74
75 pYM2608Buffer[0] = pBuffer + 0 * 4096 + 4 + nYM2608Position;
76 pYM2608Buffer[1] = pBuffer + 1 * 4096 + 4 + nYM2608Position;
77
78 YM2608UpdateOne(0, &pYM2608Buffer[0], nSegmentLength);
79
80 nYM2608Position += nSegmentLength;
81 }
82
83 // ----------------------------------------------------------------------------
84 // Update the sound buffer
85
YM2608UpdateResample(INT16 * pSoundBuf,INT32 nSegmentEnd)86 static void YM2608UpdateResample(INT16* pSoundBuf, INT32 nSegmentEnd)
87 {
88 #if defined FBA_DEBUG
89 if (!DebugSnd_YM2608Initted) bprintf(PRINT_ERROR, _T("YM2608UpdateResample called without init\n"));
90 #endif
91
92 INT32 nSegmentLength = nSegmentEnd;
93 INT32 nSamplesNeeded = nSegmentEnd * nBurnYM2608SoundRate / nBurnSoundRate + 1;
94
95 if (nSamplesNeeded < nAY8910Position) {
96 nSamplesNeeded = nAY8910Position;
97 }
98 if (nSamplesNeeded < nYM2608Position) {
99 nSamplesNeeded = nYM2608Position;
100 }
101
102 if (nSegmentLength > nBurnSoundLen) {
103 nSegmentLength = nBurnSoundLen;
104 }
105 nSegmentLength <<= 1;
106
107 YM2608Render(nSamplesNeeded);
108 AY8910Render(nSamplesNeeded);
109
110 pYM2608Buffer[0] = pBuffer + 0 * 4096 + 4;
111 pYM2608Buffer[1] = pBuffer + 1 * 4096 + 4;
112 pYM2608Buffer[2] = pBuffer + 2 * 4096 + 4;
113 pYM2608Buffer[3] = pBuffer + 3 * 4096 + 4;
114 pYM2608Buffer[4] = pBuffer + 4 * 4096 + 4;
115 pYM2608Buffer[5] = pBuffer + 5 * 4096 + 4;
116
117 for (INT32 i = (nFractionalPosition >> 16) - 4; i < nSamplesNeeded; i++) {
118 pYM2608Buffer[5][i] = (INT32)((pYM2608Buffer[2][i] + pYM2608Buffer[3][i] + pYM2608Buffer[4][i]) * YM2608Volumes[BURN_SND_YM2608_AY8910_ROUTE]);
119 }
120
121 for (INT32 i = (nFractionalPosition & 0xFFFF0000) >> 15; i < nSegmentLength; i += 2, nFractionalPosition += nSampleSize) {
122 INT32 nLeftSample[4] = {0, 0, 0, 0};
123 INT32 nRightSample[4] = {0, 0, 0, 0};
124 INT32 nTotalLeftSample, nTotalRightSample;
125
126 if ((YM2608RouteDirs[BURN_SND_YM2608_AY8910_ROUTE] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
127 nLeftSample[0] += pYM2608Buffer[5][(nFractionalPosition >> 16) - 3];
128 nLeftSample[1] += pYM2608Buffer[5][(nFractionalPosition >> 16) - 2];
129 nLeftSample[2] += pYM2608Buffer[5][(nFractionalPosition >> 16) - 1];
130 nLeftSample[3] += pYM2608Buffer[5][(nFractionalPosition >> 16) - 0];
131 }
132 if ((YM2608RouteDirs[BURN_SND_YM2608_AY8910_ROUTE] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
133 nRightSample[0] += pYM2608Buffer[5][(nFractionalPosition >> 16) - 3];
134 nRightSample[1] += pYM2608Buffer[5][(nFractionalPosition >> 16) - 2];
135 nRightSample[2] += pYM2608Buffer[5][(nFractionalPosition >> 16) - 1];
136 nRightSample[3] += pYM2608Buffer[5][(nFractionalPosition >> 16) - 0];
137 }
138
139 if ((YM2608RouteDirs[BURN_SND_YM2608_YM2608_ROUTE_1] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
140 nLeftSample[0] += (INT32)(pYM2608Buffer[0][(nFractionalPosition >> 16) - 3] * YM2608Volumes[BURN_SND_YM2608_YM2608_ROUTE_1]);
141 nLeftSample[1] += (INT32)(pYM2608Buffer[0][(nFractionalPosition >> 16) - 2] * YM2608Volumes[BURN_SND_YM2608_YM2608_ROUTE_1]);
142 nLeftSample[2] += (INT32)(pYM2608Buffer[0][(nFractionalPosition >> 16) - 1] * YM2608Volumes[BURN_SND_YM2608_YM2608_ROUTE_1]);
143 nLeftSample[3] += (INT32)(pYM2608Buffer[0][(nFractionalPosition >> 16) - 0] * YM2608Volumes[BURN_SND_YM2608_YM2608_ROUTE_1]);
144 }
145 if ((YM2608RouteDirs[BURN_SND_YM2608_YM2608_ROUTE_1] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
146 nRightSample[0] += (INT32)(pYM2608Buffer[0][(nFractionalPosition >> 16) - 3] * YM2608Volumes[BURN_SND_YM2608_YM2608_ROUTE_1]);
147 nRightSample[1] += (INT32)(pYM2608Buffer[0][(nFractionalPosition >> 16) - 2] * YM2608Volumes[BURN_SND_YM2608_YM2608_ROUTE_1]);
148 nRightSample[2] += (INT32)(pYM2608Buffer[0][(nFractionalPosition >> 16) - 1] * YM2608Volumes[BURN_SND_YM2608_YM2608_ROUTE_1]);
149 nRightSample[3] += (INT32)(pYM2608Buffer[0][(nFractionalPosition >> 16) - 0] * YM2608Volumes[BURN_SND_YM2608_YM2608_ROUTE_1]);
150 }
151
152 if ((YM2608RouteDirs[BURN_SND_YM2608_YM2608_ROUTE_2] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
153 nLeftSample[0] += (INT32)(pYM2608Buffer[1][(nFractionalPosition >> 16) - 3] * YM2608Volumes[BURN_SND_YM2608_YM2608_ROUTE_2]);
154 nLeftSample[1] += (INT32)(pYM2608Buffer[1][(nFractionalPosition >> 16) - 2] * YM2608Volumes[BURN_SND_YM2608_YM2608_ROUTE_2]);
155 nLeftSample[2] += (INT32)(pYM2608Buffer[1][(nFractionalPosition >> 16) - 1] * YM2608Volumes[BURN_SND_YM2608_YM2608_ROUTE_2]);
156 nLeftSample[3] += (INT32)(pYM2608Buffer[1][(nFractionalPosition >> 16) - 0] * YM2608Volumes[BURN_SND_YM2608_YM2608_ROUTE_2]);
157 }
158 if ((YM2608RouteDirs[BURN_SND_YM2608_YM2608_ROUTE_2] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
159 nRightSample[0] += (INT32)(pYM2608Buffer[1][(nFractionalPosition >> 16) - 3] * YM2608Volumes[BURN_SND_YM2608_YM2608_ROUTE_2]);
160 nRightSample[1] += (INT32)(pYM2608Buffer[1][(nFractionalPosition >> 16) - 2] * YM2608Volumes[BURN_SND_YM2608_YM2608_ROUTE_2]);
161 nRightSample[2] += (INT32)(pYM2608Buffer[1][(nFractionalPosition >> 16) - 1] * YM2608Volumes[BURN_SND_YM2608_YM2608_ROUTE_2]);
162 nRightSample[3] += (INT32)(pYM2608Buffer[1][(nFractionalPosition >> 16) - 0] * YM2608Volumes[BURN_SND_YM2608_YM2608_ROUTE_2]);
163 }
164
165 nTotalLeftSample = INTERPOLATE4PS_16BIT((nFractionalPosition >> 4) & 0x0fff, nLeftSample[0], nLeftSample[1], nLeftSample[2], nLeftSample[3]);
166 nTotalRightSample = INTERPOLATE4PS_16BIT((nFractionalPosition >> 4) & 0x0fff, nRightSample[0], nRightSample[1], nRightSample[2], nRightSample[3]);
167
168 nTotalLeftSample = BURN_SND_CLIP(nTotalLeftSample);
169 nTotalRightSample = BURN_SND_CLIP(nTotalRightSample);
170
171 if (bYM2608AddSignal) {
172 pSoundBuf[i + 0] += nTotalLeftSample;
173 pSoundBuf[i + 1] += nTotalRightSample;
174 } else {
175 pSoundBuf[i + 0] = nTotalLeftSample;
176 pSoundBuf[i + 1] = nTotalRightSample;
177 }
178 }
179
180 if (nSegmentEnd >= nBurnSoundLen) {
181 INT32 nExtraSamples = nSamplesNeeded - (nFractionalPosition >> 16);
182
183 for (INT32 i = -4; i < nExtraSamples; i++) {
184 pYM2608Buffer[0][i] = pYM2608Buffer[0][(nFractionalPosition >> 16) + i];
185 pYM2608Buffer[1][i] = pYM2608Buffer[1][(nFractionalPosition >> 16) + i];
186 pYM2608Buffer[2][i] = pYM2608Buffer[2][(nFractionalPosition >> 16) + i];
187 pYM2608Buffer[3][i] = pYM2608Buffer[3][(nFractionalPosition >> 16) + i];
188 pYM2608Buffer[4][i] = pYM2608Buffer[4][(nFractionalPosition >> 16) + i];
189 }
190
191 nFractionalPosition &= 0xFFFF;
192
193 nYM2608Position = nExtraSamples;
194 nAY8910Position = nExtraSamples;
195
196 dTime += 100.0 / nBurnFPS;
197 }
198 }
199
YM2608UpdateNormal(INT16 * pSoundBuf,INT32 nSegmentEnd)200 static void YM2608UpdateNormal(INT16* pSoundBuf, INT32 nSegmentEnd)
201 {
202 #if defined FBA_DEBUG
203 if (!DebugSnd_YM2608Initted) bprintf(PRINT_ERROR, _T("YM2608UpdateNormal called without init\n"));
204 #endif
205
206 INT32 nSegmentLength = nSegmentEnd;
207
208 if (nSegmentEnd < nAY8910Position) {
209 nSegmentEnd = nAY8910Position;
210 }
211 if (nSegmentEnd < nYM2608Position) {
212 nSegmentEnd = nYM2608Position;
213 }
214
215 if (nSegmentLength > nBurnSoundLen) {
216 nSegmentLength = nBurnSoundLen;
217 }
218
219 YM2608Render(nSegmentEnd);
220 AY8910Render(nSegmentEnd);
221
222 pYM2608Buffer[0] = pBuffer + 4 + 0 * 4096;
223 pYM2608Buffer[1] = pBuffer + 4 + 1 * 4096;
224 pYM2608Buffer[2] = pBuffer + 4 + 2 * 4096;
225 pYM2608Buffer[3] = pBuffer + 4 + 3 * 4096;
226 pYM2608Buffer[4] = pBuffer + 4 + 4 * 4096;
227
228 for (INT32 n = nFractionalPosition; n < nSegmentLength; n++) {
229 INT32 nAYSample, nLeftSample = 0, nRightSample = 0;
230
231 nAYSample = pYM2608Buffer[2][n];
232 nAYSample += pYM2608Buffer[3][n];
233 nAYSample += pYM2608Buffer[4][n];
234
235 if ((YM2608RouteDirs[BURN_SND_YM2608_AY8910_ROUTE] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
236 nLeftSample += (INT32)(nAYSample * YM2608Volumes[BURN_SND_YM2608_AY8910_ROUTE]);
237 }
238 if ((YM2608RouteDirs[BURN_SND_YM2608_AY8910_ROUTE] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
239 nRightSample += (INT32)(nAYSample * YM2608Volumes[BURN_SND_YM2608_AY8910_ROUTE]);
240 }
241
242 if ((YM2608RouteDirs[BURN_SND_YM2608_YM2608_ROUTE_1] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
243 nLeftSample += (INT32)(pYM2608Buffer[0][n] * YM2608Volumes[BURN_SND_YM2608_YM2608_ROUTE_1]);
244 }
245 if ((YM2608RouteDirs[BURN_SND_YM2608_YM2608_ROUTE_1] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
246 nRightSample += (INT32)(pYM2608Buffer[0][n] * YM2608Volumes[BURN_SND_YM2608_YM2608_ROUTE_1]);
247 }
248
249 if ((YM2608RouteDirs[BURN_SND_YM2608_YM2608_ROUTE_2] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
250 nLeftSample += (INT32)(pYM2608Buffer[1][n] * YM2608Volumes[BURN_SND_YM2608_YM2608_ROUTE_2]);
251 }
252 if ((YM2608RouteDirs[BURN_SND_YM2608_YM2608_ROUTE_2] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
253 nRightSample += (INT32)(pYM2608Buffer[1][n] * YM2608Volumes[BURN_SND_YM2608_YM2608_ROUTE_2]);
254 }
255
256 nLeftSample = BURN_SND_CLIP(nLeftSample);
257 nRightSample = BURN_SND_CLIP(nRightSample);
258
259 if (bYM2608AddSignal) {
260 pSoundBuf[(n << 1) + 0] += nLeftSample;
261 pSoundBuf[(n << 1) + 1] += nRightSample;
262 } else {
263 pSoundBuf[(n << 1) + 0] = nLeftSample;
264 pSoundBuf[(n << 1) + 1] = nRightSample;
265 }
266 }
267
268 nFractionalPosition = nSegmentLength;
269
270 if (nSegmentEnd >= nBurnSoundLen) {
271 INT32 nExtraSamples = nSegmentEnd - nBurnSoundLen;
272
273 for (INT32 i = 0; i < nExtraSamples; i++) {
274 pYM2608Buffer[0][i] = pYM2608Buffer[0][nBurnSoundLen + i];
275 pYM2608Buffer[1][i] = pYM2608Buffer[1][nBurnSoundLen + i];
276 pYM2608Buffer[2][i] = pYM2608Buffer[2][nBurnSoundLen + i];
277 pYM2608Buffer[3][i] = pYM2608Buffer[3][nBurnSoundLen + i];
278 pYM2608Buffer[4][i] = pYM2608Buffer[4][nBurnSoundLen + i];
279 }
280
281 nFractionalPosition = 0;
282
283 nYM2608Position = nExtraSamples;
284 nAY8910Position = nExtraSamples;
285
286 dTime += 100.0 / nBurnFPS;
287 }
288 }
289
290 // ----------------------------------------------------------------------------
291 // Callbacks for YM2608 core
292
BurnYM2608UpdateRequest()293 void BurnYM2608UpdateRequest()
294 {
295 #if defined FBA_DEBUG
296 if (!DebugSnd_YM2608Initted) bprintf(PRINT_ERROR, _T("BurnYM2608UpdateRequest called without init\n"));
297 #endif
298
299 YM2608Render(BurnYM2608StreamCallback(nBurnYM2608SoundRate));
300 }
301
BurnAY8910UpdateRequest()302 static void BurnAY8910UpdateRequest()
303 {
304 #if defined FBA_DEBUG
305 if (!DebugSnd_YM2608Initted) bprintf(PRINT_ERROR, _T("BurnYM2608 BurnAY8910UpdateRequest called without init\n"));
306 #endif
307
308 AY8910Render(BurnYM2608StreamCallback(nBurnYM2608SoundRate));
309 }
310
311 // ----------------------------------------------------------------------------
312 // Initialisation, etc.
313
BurnYM2608Reset()314 void BurnYM2608Reset()
315 {
316 #if defined FBA_DEBUG
317 if (!DebugSnd_YM2608Initted) bprintf(PRINT_ERROR, _T("BurnYM2608Reset called without init\n"));
318 #endif
319
320 BurnTimerReset();
321
322 YM2608ResetChip(0);
323 }
324
BurnYM2608Exit()325 void BurnYM2608Exit()
326 {
327 #if defined FBA_DEBUG
328 if (!DebugSnd_YM2608Initted) bprintf(PRINT_ERROR, _T("BurnYM2608Exit called without init\n"));
329 #endif
330
331 if (!DebugSnd_YM2608Initted) return;
332
333 YM2608Shutdown();
334 AY8910Exit(0);
335
336 BurnTimerExit();
337
338 BurnFree(pBuffer);
339 BurnFree(pAYBuffer);
340
341 bYM2608AddSignal = 0;
342
343 DebugSnd_YM2608Initted = 0;
344 }
345
BurnYM2608Init(INT32 nClockFrequency,UINT8 * YM2608ADPCMROM,INT32 * nYM2608ADPCMSize,UINT8 * YM2608IROM,FM_IRQHANDLER IRQCallback,INT32 bAddSignal)346 INT32 BurnYM2608Init(INT32 nClockFrequency, UINT8* YM2608ADPCMROM, INT32* nYM2608ADPCMSize, UINT8* YM2608IROM, FM_IRQHANDLER IRQCallback, INT32 bAddSignal)
347 {
348 return BurnYM2608Init(nClockFrequency, YM2608ADPCMROM, nYM2608ADPCMSize, YM2608IROM, IRQCallback, BurnSynchroniseStream, BurnGetTime, bAddSignal);
349 }
350
BurnYM2608Init(INT32 nClockFrequency,UINT8 * YM2608ADPCMROM,INT32 * nYM2608ADPCMSize,UINT8 * YM2608IROM,FM_IRQHANDLER IRQCallback,INT32 (* StreamCallback)(INT32),double (* GetTimeCallback)(),INT32 bAddSignal)351 INT32 BurnYM2608Init(INT32 nClockFrequency, UINT8* YM2608ADPCMROM, INT32* nYM2608ADPCMSize, UINT8* YM2608IROM, FM_IRQHANDLER IRQCallback, INT32 (*StreamCallback)(INT32), double (*GetTimeCallback)(), INT32 bAddSignal)
352 {
353 DebugSnd_YM2608Initted = 1;
354
355 BurnTimerInit(&YM2608TimerOver, GetTimeCallback);
356
357 if (nBurnSoundRate <= 0) {
358 BurnYM2608StreamCallback = YM2608StreamCallbackDummy;
359
360 BurnYM2608Update = YM2608UpdateDummy;
361
362 AY8910InitYM(0, nClockFrequency, 11025, NULL, NULL, NULL, NULL, BurnAY8910UpdateRequest);
363 YM2608Init(1, nClockFrequency, 11025, (void**)(&YM2608ADPCMROM), nYM2608ADPCMSize, YM2608IROM, &BurnOPNTimerCallback, IRQCallback);
364 return 0;
365 }
366
367 BurnYM2608StreamCallback = StreamCallback;
368
369 if (nFMInterpolation == 3) {
370 // Set YM2608 core samplerate to match the hardware
371 nBurnYM2608SoundRate = nClockFrequency / 144;
372 // Bring YM2608 core samplerate within usable range
373 while (nBurnYM2608SoundRate > nBurnSoundRate * 3) {
374 nBurnYM2608SoundRate >>= 1;
375 }
376
377 BurnYM2608Update = YM2608UpdateResample;
378
379 nSampleSize = (UINT32)nBurnYM2608SoundRate * (1 << 16) / nBurnSoundRate;
380 nFractionalPosition = 0;
381 } else {
382 nBurnYM2608SoundRate = nBurnSoundRate;
383
384 BurnYM2608Update = YM2608UpdateNormal;
385 }
386
387 AY8910InitYM(0, nClockFrequency, nBurnYM2608SoundRate, NULL, NULL, NULL, NULL, BurnAY8910UpdateRequest);
388 YM2608Init(1, nClockFrequency, nBurnYM2608SoundRate, (void**)(&YM2608ADPCMROM), nYM2608ADPCMSize, YM2608IROM, &BurnOPNTimerCallback, IRQCallback);
389
390 pBuffer = (INT16*)BurnMalloc(4096 * 6 * sizeof(INT16));
391 memset(pBuffer, 0, 4096 * 6 * sizeof(INT16));
392
393 pAYBuffer = (INT32*)BurnMalloc(4096 * sizeof(INT32));
394 memset(pAYBuffer, 0, 4096 * sizeof(INT32));
395
396 nYM2608Position = 0;
397 nAY8910Position = 0;
398
399 bYM2608AddSignal = bAddSignal;
400
401 // default routes
402 YM2608Volumes[BURN_SND_YM2608_YM2608_ROUTE_1] = 1.00;
403 YM2608Volumes[BURN_SND_YM2608_YM2608_ROUTE_2] = 1.00;
404 YM2608Volumes[BURN_SND_YM2608_AY8910_ROUTE] = 1.00;
405 YM2608RouteDirs[BURN_SND_YM2608_YM2608_ROUTE_1] = BURN_SND_ROUTE_LEFT;
406 YM2608RouteDirs[BURN_SND_YM2608_YM2608_ROUTE_2] = BURN_SND_ROUTE_RIGHT;
407 YM2608RouteDirs[BURN_SND_YM2608_AY8910_ROUTE] = BURN_SND_ROUTE_BOTH;
408
409 return 0;
410 }
411
BurnYM2608SetRoute(INT32 nIndex,double nVolume,INT32 nRouteDir)412 void BurnYM2608SetRoute(INT32 nIndex, double nVolume, INT32 nRouteDir)
413 {
414 #if defined FBA_DEBUG
415 if (!DebugSnd_YM2608Initted) bprintf(PRINT_ERROR, _T("BurnYM2608SetRoute called without init\n"));
416 if (nIndex < 0 || nIndex > 2) bprintf(PRINT_ERROR, _T("BurnYM2608SetRoute called with invalid index %i\n"), nIndex);
417 #endif
418
419 YM2608Volumes[nIndex] = nVolume;
420 YM2608RouteDirs[nIndex] = nRouteDir;
421 }
422
BurnYM2608Scan(INT32 nAction,INT32 * pnMin)423 void BurnYM2608Scan(INT32 nAction, INT32* pnMin)
424 {
425 #if defined FBA_DEBUG
426 if (!DebugSnd_YM2608Initted) bprintf(PRINT_ERROR, _T("BurnYM2608Scan called without init\n"));
427 #endif
428
429 BurnTimerScan(nAction, pnMin);
430 AY8910Scan(nAction, pnMin);
431
432 if (nAction & ACB_DRIVER_DATA) {
433 SCAN_VAR(nYM2608Position);
434 SCAN_VAR(nAY8910Position);
435 }
436 }
437