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