1 #include "burnint.h"
2 #include "burn_ym2203.h"
3
4 #define MAX_YM2203 3
5
6 void (*BurnYM2203Update)(INT16* pSoundBuf, INT32 nSegmentEnd);
7
8 static INT32 (*BurnYM2203StreamCallback)(INT32 nSoundRate);
9
10 static INT32 nBurnYM2203SoundRate;
11
12 static INT16* pBuffer;
13 static INT16* pYM2203Buffer[4 * MAX_YM2203];
14
15 static INT32 nYM2203Position;
16 static INT32 nAY8910Position;
17
18 static UINT32 nSampleSize;
19 static INT32 nFractionalPosition;
20
21 static INT32 nNumChips = 0;
22
23 static INT32 bYM2203AddSignal;
24
25 static double YM2203Volumes[4 * MAX_YM2203];
26 static INT32 YM2203RouteDirs[4 * MAX_YM2203];
27
28 static double YM2203LeftVolumes[4 * MAX_YM2203];
29 static double YM2203RightVolumes[4 * MAX_YM2203];
30
31 INT32 bYM2203UseSeperateVolumes; // support custom Taito panning hardware
32
33 // ----------------------------------------------------------------------------
34 // Dummy functions
35
YM2203UpdateDummy(INT16 *,INT32)36 static void YM2203UpdateDummy(INT16*, INT32)
37 {
38 return;
39 }
40
YM2203StreamCallbackDummy(INT32)41 static INT32 YM2203StreamCallbackDummy(INT32)
42 {
43 return 0;
44 }
45
46 // ----------------------------------------------------------------------------
47 // Execute YM2203 for part of a frame
48
AY8910Render(INT32 nSegmentLength)49 static void AY8910Render(INT32 nSegmentLength)
50 {
51 #if defined FBA_DEBUG
52 if (!DebugSnd_YM2203Initted) bprintf(PRINT_ERROR, _T("BurnYM2203 AY8910Render called without init\n"));
53 #endif
54
55 if (nAY8910Position >= nSegmentLength) {
56 return;
57 }
58
59 nSegmentLength -= nAY8910Position;
60
61 pYM2203Buffer[1] = pBuffer + 1 * 4096 + 4 + nAY8910Position;
62 pYM2203Buffer[2] = pBuffer + 2 * 4096 + 4 + nAY8910Position;
63 pYM2203Buffer[3] = pBuffer + 3 * 4096 + 4 + nAY8910Position;
64
65 AY8910Update(0, &pYM2203Buffer[1], nSegmentLength);
66
67 if (nNumChips > 1) {
68 pYM2203Buffer[5] = pBuffer + 5 * 4096 + 4 + nAY8910Position;
69 pYM2203Buffer[6] = pBuffer + 6 * 4096 + 4 + nAY8910Position;
70 pYM2203Buffer[7] = pBuffer + 7 * 4096 + 4 + nAY8910Position;
71
72 AY8910Update(1, &pYM2203Buffer[5], nSegmentLength);
73 }
74
75 if (nNumChips > 2) {
76 pYM2203Buffer[9] = pBuffer + 9 * 4096 + 4 + nAY8910Position;
77 pYM2203Buffer[10] = pBuffer + 10 * 4096 + 4 + nAY8910Position;
78 pYM2203Buffer[11] = pBuffer + 11 * 4096 + 4 + nAY8910Position;
79
80 AY8910Update(2, &pYM2203Buffer[9], nSegmentLength);
81 }
82
83 nAY8910Position += nSegmentLength;
84 }
85
YM2203Render(INT32 nSegmentLength)86 static void YM2203Render(INT32 nSegmentLength)
87 {
88 #if defined FBA_DEBUG
89 if (!DebugSnd_YM2203Initted) bprintf(PRINT_ERROR, _T("YM2203Render called without init\n"));
90 #endif
91
92 if (nYM2203Position >= nSegmentLength) {
93 return;
94 }
95
96 nSegmentLength -= nYM2203Position;
97
98 pYM2203Buffer[0] = pBuffer + 0 * 4096 + 4 + nYM2203Position;
99
100 YM2203UpdateOne(0, pYM2203Buffer[0], nSegmentLength);
101
102 if (nNumChips > 1) {
103 pYM2203Buffer[4] = pBuffer + 4 * 4096 + 4 + nYM2203Position;
104
105 YM2203UpdateOne(1, pYM2203Buffer[4], nSegmentLength);
106 }
107
108 if (nNumChips > 2) {
109 pYM2203Buffer[8] = pBuffer + 8 * 4096 + 4 + nYM2203Position;
110
111 YM2203UpdateOne(2, pYM2203Buffer[8], nSegmentLength);
112 }
113
114 nYM2203Position += nSegmentLength;
115 }
116
117 // ----------------------------------------------------------------------------
118 // Update the sound buffer
119
120 #define INTERPOLATE_ADD_SOUND_LEFT(route, buffer) \
121 if ((YM2203RouteDirs[route] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) { \
122 nLeftSample[0] += (INT32)(pYM2203Buffer[buffer][(nFractionalPosition >> 16) - 3] * YM2203Volumes[route]); \
123 nLeftSample[1] += (INT32)(pYM2203Buffer[buffer][(nFractionalPosition >> 16) - 2] * YM2203Volumes[route]); \
124 nLeftSample[2] += (INT32)(pYM2203Buffer[buffer][(nFractionalPosition >> 16) - 1] * YM2203Volumes[route]); \
125 nLeftSample[3] += (INT32)(pYM2203Buffer[buffer][(nFractionalPosition >> 16) - 0] * YM2203Volumes[route]); \
126 }
127
128 #define INTERPOLATE_ADD_SOUND_RIGHT(route, buffer) \
129 if ((YM2203RouteDirs[route] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) { \
130 nRightSample[0] += (INT32)(pYM2203Buffer[buffer][(nFractionalPosition >> 16) - 3] * YM2203Volumes[route]); \
131 nRightSample[1] += (INT32)(pYM2203Buffer[buffer][(nFractionalPosition >> 16) - 2] * YM2203Volumes[route]); \
132 nRightSample[2] += (INT32)(pYM2203Buffer[buffer][(nFractionalPosition >> 16) - 1] * YM2203Volumes[route]); \
133 nRightSample[3] += (INT32)(pYM2203Buffer[buffer][(nFractionalPosition >> 16) - 0] * YM2203Volumes[route]); \
134 }
135
136 #define SPLIT_INTERPOLATE_ADD_SOUND_LEFT(route, buffer) \
137 nLeftSample[0] += (INT32)(pYM2203Buffer[buffer][(nFractionalPosition >> 16) - 3] * YM2203LeftVolumes[route]); \
138 nLeftSample[1] += (INT32)(pYM2203Buffer[buffer][(nFractionalPosition >> 16) - 2] * YM2203LeftVolumes[route]); \
139 nLeftSample[2] += (INT32)(pYM2203Buffer[buffer][(nFractionalPosition >> 16) - 1] * YM2203LeftVolumes[route]); \
140 nLeftSample[3] += (INT32)(pYM2203Buffer[buffer][(nFractionalPosition >> 16) - 0] * YM2203LeftVolumes[route]);
141
142 #define SPLIT_INTERPOLATE_ADD_SOUND_RIGHT(route, buffer) \
143 nRightSample[0] += (INT32)(pYM2203Buffer[buffer][(nFractionalPosition >> 16) - 3] * YM2203RightVolumes[route]); \
144 nRightSample[1] += (INT32)(pYM2203Buffer[buffer][(nFractionalPosition >> 16) - 2] * YM2203RightVolumes[route]); \
145 nRightSample[2] += (INT32)(pYM2203Buffer[buffer][(nFractionalPosition >> 16) - 1] * YM2203RightVolumes[route]); \
146 nRightSample[3] += (INT32)(pYM2203Buffer[buffer][(nFractionalPosition >> 16) - 0] * YM2203RightVolumes[route]);
147
YM2203UpdateResample(INT16 * pSoundBuf,INT32 nSegmentEnd)148 static void YM2203UpdateResample(INT16* pSoundBuf, INT32 nSegmentEnd)
149 {
150 #if defined FBA_DEBUG
151 if (!DebugSnd_YM2203Initted) bprintf(PRINT_ERROR, _T("YM2203UpdateResample called without init\n"));
152 #endif
153
154 INT32 nSegmentLength = nSegmentEnd;
155 INT32 nSamplesNeeded = nSegmentEnd * nBurnYM2203SoundRate / nBurnSoundRate + 1;
156
157 if (nSamplesNeeded < nAY8910Position) {
158 nSamplesNeeded = nAY8910Position;
159 }
160 if (nSamplesNeeded < nYM2203Position) {
161 nSamplesNeeded = nYM2203Position;
162 }
163
164 if (nSegmentLength > nBurnSoundLen) {
165 nSegmentLength = nBurnSoundLen;
166 }
167 nSegmentLength <<= 1;
168
169 YM2203Render(nSamplesNeeded);
170 AY8910Render(nSamplesNeeded);
171
172 pYM2203Buffer[0] = pBuffer + 0 * 4096 + 4;
173 pYM2203Buffer[1] = pBuffer + 1 * 4096 + 4;
174 pYM2203Buffer[2] = pBuffer + 2 * 4096 + 4;
175 pYM2203Buffer[3] = pBuffer + 3 * 4096 + 4;
176
177 if (nNumChips > 1) {
178 pYM2203Buffer[4] = pBuffer + 4 * 4096 + 4;
179 pYM2203Buffer[5] = pBuffer + 5 * 4096 + 4;
180 pYM2203Buffer[6] = pBuffer + 6 * 4096 + 4;
181 pYM2203Buffer[7] = pBuffer + 7 * 4096 + 4;
182 }
183
184 if (nNumChips > 2) {
185 pYM2203Buffer[8] = pBuffer + 8 * 4096 + 4;
186 pYM2203Buffer[9] = pBuffer + 9 * 4096 + 4;
187 pYM2203Buffer[10] = pBuffer + 10 * 4096 + 4;
188 pYM2203Buffer[11] = pBuffer + 11 * 4096 + 4;
189 }
190
191 for (INT32 i = (nFractionalPosition & 0xFFFF0000) >> 15; i < nSegmentLength; i += 2, nFractionalPosition += nSampleSize) {
192 INT32 nLeftSample[4] = {0, 0, 0, 0};
193 INT32 nRightSample[4] = {0, 0, 0, 0};
194 INT32 nTotalLeftSample, nTotalRightSample;
195
196 if (bYM2203UseSeperateVolumes) {
197 SPLIT_INTERPOLATE_ADD_SOUND_LEFT (BURN_SND_YM2203_AY8910_ROUTE_1, 1)
198 SPLIT_INTERPOLATE_ADD_SOUND_LEFT (BURN_SND_YM2203_AY8910_ROUTE_2, 2)
199 SPLIT_INTERPOLATE_ADD_SOUND_LEFT (BURN_SND_YM2203_AY8910_ROUTE_3, 3)
200 SPLIT_INTERPOLATE_ADD_SOUND_LEFT (BURN_SND_YM2203_YM2203_ROUTE , 0)
201
202 SPLIT_INTERPOLATE_ADD_SOUND_RIGHT (BURN_SND_YM2203_AY8910_ROUTE_1, 1)
203 SPLIT_INTERPOLATE_ADD_SOUND_RIGHT (BURN_SND_YM2203_AY8910_ROUTE_2, 2)
204 SPLIT_INTERPOLATE_ADD_SOUND_RIGHT (BURN_SND_YM2203_AY8910_ROUTE_3, 3)
205 SPLIT_INTERPOLATE_ADD_SOUND_RIGHT (BURN_SND_YM2203_YM2203_ROUTE , 0)
206
207 if (nNumChips > 1) {
208 SPLIT_INTERPOLATE_ADD_SOUND_LEFT (4 + BURN_SND_YM2203_AY8910_ROUTE_1, 5)
209 SPLIT_INTERPOLATE_ADD_SOUND_LEFT (4 + BURN_SND_YM2203_AY8910_ROUTE_2, 6)
210 SPLIT_INTERPOLATE_ADD_SOUND_LEFT (4 + BURN_SND_YM2203_AY8910_ROUTE_3, 7)
211 SPLIT_INTERPOLATE_ADD_SOUND_LEFT (4 + BURN_SND_YM2203_YM2203_ROUTE , 4)
212
213 SPLIT_INTERPOLATE_ADD_SOUND_RIGHT (4 + BURN_SND_YM2203_AY8910_ROUTE_1, 5)
214 SPLIT_INTERPOLATE_ADD_SOUND_RIGHT (4 + BURN_SND_YM2203_AY8910_ROUTE_2, 6)
215 SPLIT_INTERPOLATE_ADD_SOUND_RIGHT (4 + BURN_SND_YM2203_AY8910_ROUTE_3, 7)
216 SPLIT_INTERPOLATE_ADD_SOUND_RIGHT (4 + BURN_SND_YM2203_YM2203_ROUTE , 4)
217 }
218
219 if (nNumChips > 2) {
220 SPLIT_INTERPOLATE_ADD_SOUND_LEFT (8 + BURN_SND_YM2203_AY8910_ROUTE_1, 9)
221 SPLIT_INTERPOLATE_ADD_SOUND_LEFT (8 + BURN_SND_YM2203_AY8910_ROUTE_2, 10)
222 SPLIT_INTERPOLATE_ADD_SOUND_LEFT (8 + BURN_SND_YM2203_AY8910_ROUTE_3, 11)
223 SPLIT_INTERPOLATE_ADD_SOUND_LEFT (8 + BURN_SND_YM2203_YM2203_ROUTE , 8)
224
225 SPLIT_INTERPOLATE_ADD_SOUND_RIGHT (8 + BURN_SND_YM2203_AY8910_ROUTE_1, 9)
226 SPLIT_INTERPOLATE_ADD_SOUND_RIGHT (8 + BURN_SND_YM2203_AY8910_ROUTE_2, 10)
227 SPLIT_INTERPOLATE_ADD_SOUND_RIGHT (8 + BURN_SND_YM2203_AY8910_ROUTE_3, 11)
228 SPLIT_INTERPOLATE_ADD_SOUND_RIGHT (8 + BURN_SND_YM2203_YM2203_ROUTE , 8)
229 }
230 } else {
231 INTERPOLATE_ADD_SOUND_LEFT (BURN_SND_YM2203_AY8910_ROUTE_1, 1)
232 INTERPOLATE_ADD_SOUND_RIGHT (BURN_SND_YM2203_AY8910_ROUTE_1, 1)
233 INTERPOLATE_ADD_SOUND_LEFT (BURN_SND_YM2203_AY8910_ROUTE_2, 2)
234 INTERPOLATE_ADD_SOUND_RIGHT (BURN_SND_YM2203_AY8910_ROUTE_2, 2)
235 INTERPOLATE_ADD_SOUND_LEFT (BURN_SND_YM2203_AY8910_ROUTE_3, 3)
236 INTERPOLATE_ADD_SOUND_RIGHT (BURN_SND_YM2203_AY8910_ROUTE_3, 3)
237 INTERPOLATE_ADD_SOUND_LEFT (BURN_SND_YM2203_YM2203_ROUTE , 0)
238 INTERPOLATE_ADD_SOUND_RIGHT (BURN_SND_YM2203_YM2203_ROUTE , 0)
239
240 if (nNumChips > 1) {
241 INTERPOLATE_ADD_SOUND_LEFT (4 + BURN_SND_YM2203_AY8910_ROUTE_1, 5)
242 INTERPOLATE_ADD_SOUND_RIGHT (4 + BURN_SND_YM2203_AY8910_ROUTE_1, 5)
243 INTERPOLATE_ADD_SOUND_LEFT (4 + BURN_SND_YM2203_AY8910_ROUTE_2, 6)
244 INTERPOLATE_ADD_SOUND_RIGHT (4 + BURN_SND_YM2203_AY8910_ROUTE_2, 6)
245 INTERPOLATE_ADD_SOUND_LEFT (4 + BURN_SND_YM2203_AY8910_ROUTE_3, 7)
246 INTERPOLATE_ADD_SOUND_RIGHT (4 + BURN_SND_YM2203_AY8910_ROUTE_3, 7)
247 INTERPOLATE_ADD_SOUND_LEFT (4 + BURN_SND_YM2203_YM2203_ROUTE , 4)
248 INTERPOLATE_ADD_SOUND_RIGHT (4 + BURN_SND_YM2203_YM2203_ROUTE , 4)
249 }
250
251 if (nNumChips > 2) {
252 INTERPOLATE_ADD_SOUND_LEFT (8 + BURN_SND_YM2203_AY8910_ROUTE_1, 9)
253 INTERPOLATE_ADD_SOUND_RIGHT (8 + BURN_SND_YM2203_AY8910_ROUTE_1, 9)
254 INTERPOLATE_ADD_SOUND_LEFT (8 + BURN_SND_YM2203_AY8910_ROUTE_2, 10)
255 INTERPOLATE_ADD_SOUND_RIGHT (8 + BURN_SND_YM2203_AY8910_ROUTE_2, 10)
256 INTERPOLATE_ADD_SOUND_LEFT (8 + BURN_SND_YM2203_AY8910_ROUTE_3, 11)
257 INTERPOLATE_ADD_SOUND_RIGHT (8 + BURN_SND_YM2203_AY8910_ROUTE_3, 11)
258 INTERPOLATE_ADD_SOUND_LEFT (8 + BURN_SND_YM2203_YM2203_ROUTE , 8)
259 INTERPOLATE_ADD_SOUND_RIGHT (8 + BURN_SND_YM2203_YM2203_ROUTE , 8)
260 }
261 }
262
263 nTotalLeftSample = INTERPOLATE4PS_CUSTOM((nFractionalPosition >> 4) & 0x0fff, nLeftSample[0], nLeftSample[1], nLeftSample[2], nLeftSample[3], 16384.0);
264 nTotalRightSample = INTERPOLATE4PS_CUSTOM((nFractionalPosition >> 4) & 0x0fff, nRightSample[0], nRightSample[1], nRightSample[2], nRightSample[3], 16384.0);
265
266 nTotalLeftSample = BURN_SND_CLIP(nTotalLeftSample);
267 nTotalRightSample = BURN_SND_CLIP(nTotalRightSample);
268
269 if (bYM2203AddSignal) {
270 //pSoundBuf[i + 0] += nTotalLeftSample;
271 //pSoundBuf[i + 1] += nTotalRightSample;
272 pSoundBuf[i + 0] = BURN_SND_CLIP(pSoundBuf[i + 0] + nTotalLeftSample);
273 pSoundBuf[i + 1] = BURN_SND_CLIP(pSoundBuf[i + 1] + nTotalRightSample);
274 } else {
275 pSoundBuf[i + 0] = nTotalLeftSample;
276 pSoundBuf[i + 1] = nTotalRightSample;
277 }
278
279 }
280
281 if (nSegmentEnd >= nBurnSoundLen) {
282 INT32 nExtraSamples = nSamplesNeeded - (nFractionalPosition >> 16);
283
284 for (INT32 i = -4; i < nExtraSamples; i++) {
285 pYM2203Buffer[0][i] = pYM2203Buffer[0][(nFractionalPosition >> 16) + i];
286 pYM2203Buffer[1][i] = pYM2203Buffer[1][(nFractionalPosition >> 16) + i];
287 pYM2203Buffer[2][i] = pYM2203Buffer[2][(nFractionalPosition >> 16) + i];
288 pYM2203Buffer[3][i] = pYM2203Buffer[3][(nFractionalPosition >> 16) + i];
289
290 if (nNumChips > 1) {
291 pYM2203Buffer[4][i] = pYM2203Buffer[4][(nFractionalPosition >> 16) + i];
292 pYM2203Buffer[5][i] = pYM2203Buffer[5][(nFractionalPosition >> 16) + i];
293 pYM2203Buffer[6][i] = pYM2203Buffer[6][(nFractionalPosition >> 16) + i];
294 pYM2203Buffer[7][i] = pYM2203Buffer[7][(nFractionalPosition >> 16) + i];
295 }
296
297 if (nNumChips > 2) {
298 pYM2203Buffer[8][i] = pYM2203Buffer[8][(nFractionalPosition >> 16) + i];
299 pYM2203Buffer[9][i] = pYM2203Buffer[9][(nFractionalPosition >> 16) + i];
300 pYM2203Buffer[10][i] = pYM2203Buffer[10][(nFractionalPosition >> 16) + i];
301 pYM2203Buffer[11][i] = pYM2203Buffer[11][(nFractionalPosition >> 16) + i];
302 }
303 }
304
305 nFractionalPosition &= 0xFFFF;
306
307 nYM2203Position = nExtraSamples;
308 nAY8910Position = nExtraSamples;
309
310 dTime += 100.0 / nBurnFPS;
311 }
312 }
313
YM2203UpdateNormal(INT16 * pSoundBuf,INT32 nSegmentEnd)314 static void YM2203UpdateNormal(INT16* pSoundBuf, INT32 nSegmentEnd)
315 {
316 #if defined FBA_DEBUG
317 if (!DebugSnd_YM2203Initted) bprintf(PRINT_ERROR, _T("YM2203UpdateNormal called without init\n"));
318 #endif
319
320 INT32 nSegmentLength = nSegmentEnd;
321 INT32 i;
322
323 if (nSegmentEnd < nAY8910Position) {
324 nSegmentEnd = nAY8910Position;
325 }
326 if (nSegmentEnd < nYM2203Position) {
327 nSegmentEnd = nYM2203Position;
328 }
329
330 if (nSegmentLength > nBurnSoundLen) {
331 nSegmentLength = nBurnSoundLen;
332 }
333
334 YM2203Render(nSegmentEnd);
335 AY8910Render(nSegmentEnd);
336
337 pYM2203Buffer[0] = pBuffer + 4 + 0 * 4096;
338 pYM2203Buffer[1] = pBuffer + 4 + 1 * 4096;
339 pYM2203Buffer[2] = pBuffer + 4 + 2 * 4096;
340 pYM2203Buffer[3] = pBuffer + 4 + 3 * 4096;
341 if (nNumChips > 1) {
342 pYM2203Buffer[4] = pBuffer + 4 + 4 * 4096;
343 pYM2203Buffer[5] = pBuffer + 4 + 5 * 4096;
344 pYM2203Buffer[6] = pBuffer + 4 + 6 * 4096;
345 pYM2203Buffer[7] = pBuffer + 4 + 7 * 4096;
346 }
347 if (nNumChips > 2) {
348 pYM2203Buffer[8] = pBuffer + 4 + 8 * 4096;
349 pYM2203Buffer[9] = pBuffer + 4 + 9 * 4096;
350 pYM2203Buffer[10] = pBuffer + 4 + 10 * 4096;
351 pYM2203Buffer[11] = pBuffer + 4 + 11 * 4096;
352 }
353
354 for (INT32 n = nFractionalPosition; n < nSegmentLength; n++) {
355 INT32 nLeftSample = 0, nRightSample = 0;
356
357 if (bYM2203UseSeperateVolumes) {
358 nLeftSample += (INT32)(pYM2203Buffer[1][n] * YM2203LeftVolumes[BURN_SND_YM2203_AY8910_ROUTE_1]);
359 nLeftSample += (INT32)(pYM2203Buffer[2][n] * YM2203LeftVolumes[BURN_SND_YM2203_AY8910_ROUTE_2]);
360 nLeftSample += (INT32)(pYM2203Buffer[3][n] * YM2203LeftVolumes[BURN_SND_YM2203_AY8910_ROUTE_3]);
361 nLeftSample += (INT32)(pYM2203Buffer[0][n] * YM2203LeftVolumes[BURN_SND_YM2203_YM2203_ROUTE]);
362
363 nRightSample += (INT32)(pYM2203Buffer[1][n] * YM2203RightVolumes[BURN_SND_YM2203_AY8910_ROUTE_1]);
364 nRightSample += (INT32)(pYM2203Buffer[2][n] * YM2203RightVolumes[BURN_SND_YM2203_AY8910_ROUTE_2]);
365 nRightSample += (INT32)(pYM2203Buffer[3][n] * YM2203RightVolumes[BURN_SND_YM2203_AY8910_ROUTE_3]);
366 nRightSample += (INT32)(pYM2203Buffer[0][n] * YM2203RightVolumes[BURN_SND_YM2203_YM2203_ROUTE]);
367
368 if (nNumChips > 1) {
369 nLeftSample += (INT32)(pYM2203Buffer[5][n] * YM2203LeftVolumes[4 + BURN_SND_YM2203_AY8910_ROUTE_1]);
370 nLeftSample += (INT32)(pYM2203Buffer[6][n] * YM2203LeftVolumes[4 + BURN_SND_YM2203_AY8910_ROUTE_2]);
371 nLeftSample += (INT32)(pYM2203Buffer[7][n] * YM2203LeftVolumes[4 + BURN_SND_YM2203_AY8910_ROUTE_3]);
372 nLeftSample += (INT32)(pYM2203Buffer[4][n] * YM2203LeftVolumes[4 + BURN_SND_YM2203_YM2203_ROUTE]);
373
374 nRightSample += (INT32)(pYM2203Buffer[5][n] * YM2203RightVolumes[4 + BURN_SND_YM2203_AY8910_ROUTE_1]);
375 nRightSample += (INT32)(pYM2203Buffer[6][n] * YM2203RightVolumes[4 + BURN_SND_YM2203_AY8910_ROUTE_2]);
376 nRightSample += (INT32)(pYM2203Buffer[7][n] * YM2203RightVolumes[4 + BURN_SND_YM2203_AY8910_ROUTE_3]);
377 nRightSample += (INT32)(pYM2203Buffer[4][n] * YM2203RightVolumes[4 + BURN_SND_YM2203_YM2203_ROUTE]);
378 }
379
380 if (nNumChips > 2) {
381 nLeftSample += (INT32)(pYM2203Buffer[9][n] * YM2203LeftVolumes[8 + BURN_SND_YM2203_AY8910_ROUTE_1]);
382 nLeftSample += (INT32)(pYM2203Buffer[10][n] * YM2203LeftVolumes[8 + BURN_SND_YM2203_AY8910_ROUTE_2]);
383 nLeftSample += (INT32)(pYM2203Buffer[11][n] * YM2203LeftVolumes[8 + BURN_SND_YM2203_AY8910_ROUTE_3]);
384 nLeftSample += (INT32)(pYM2203Buffer[8][n] * YM2203LeftVolumes[8 + BURN_SND_YM2203_YM2203_ROUTE]);
385
386 nRightSample += (INT32)(pYM2203Buffer[9][n] * YM2203RightVolumes[8 + BURN_SND_YM2203_AY8910_ROUTE_1]);
387 nRightSample += (INT32)(pYM2203Buffer[10][n] * YM2203RightVolumes[8 + BURN_SND_YM2203_AY8910_ROUTE_2]);
388 nRightSample += (INT32)(pYM2203Buffer[11][n] * YM2203RightVolumes[8 + BURN_SND_YM2203_AY8910_ROUTE_3]);
389 nRightSample += (INT32)(pYM2203Buffer[8][n] * YM2203RightVolumes[8 + BURN_SND_YM2203_YM2203_ROUTE]);
390 }
391 } else {
392 if ((YM2203RouteDirs[BURN_SND_YM2203_AY8910_ROUTE_1] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
393 nLeftSample += (INT32)(pYM2203Buffer[1][n] * YM2203Volumes[BURN_SND_YM2203_AY8910_ROUTE_1]);
394 }
395 if ((YM2203RouteDirs[BURN_SND_YM2203_AY8910_ROUTE_1] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
396 nRightSample += (INT32)(pYM2203Buffer[1][n] * YM2203Volumes[BURN_SND_YM2203_AY8910_ROUTE_1]);
397 }
398
399 if ((YM2203RouteDirs[BURN_SND_YM2203_AY8910_ROUTE_2] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
400 nLeftSample += (INT32)(pYM2203Buffer[2][n] * YM2203Volumes[BURN_SND_YM2203_AY8910_ROUTE_2]);
401 }
402 if ((YM2203RouteDirs[BURN_SND_YM2203_AY8910_ROUTE_2] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
403 nRightSample += (INT32)(pYM2203Buffer[2][n] * YM2203Volumes[BURN_SND_YM2203_AY8910_ROUTE_2]);
404 }
405
406 if ((YM2203RouteDirs[BURN_SND_YM2203_AY8910_ROUTE_3] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
407 nLeftSample += (INT32)(pYM2203Buffer[3][n] * YM2203Volumes[BURN_SND_YM2203_AY8910_ROUTE_3]);
408 }
409 if ((YM2203RouteDirs[BURN_SND_YM2203_AY8910_ROUTE_3] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
410 nRightSample += (INT32)(pYM2203Buffer[3][n] * YM2203Volumes[BURN_SND_YM2203_AY8910_ROUTE_3]);
411 }
412
413 if ((YM2203RouteDirs[BURN_SND_YM2203_YM2203_ROUTE] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
414 nLeftSample += (INT32)(pYM2203Buffer[0][n] * YM2203Volumes[BURN_SND_YM2203_YM2203_ROUTE]);
415 }
416 if ((YM2203RouteDirs[BURN_SND_YM2203_YM2203_ROUTE] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
417 nRightSample += (INT32)(pYM2203Buffer[0][n] * YM2203Volumes[BURN_SND_YM2203_YM2203_ROUTE]);
418 }
419
420 if (nNumChips > 1) {
421 if ((YM2203RouteDirs[4 + BURN_SND_YM2203_AY8910_ROUTE_1] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
422 nLeftSample += (INT32)(pYM2203Buffer[5][n] * YM2203Volumes[4 + BURN_SND_YM2203_AY8910_ROUTE_1]);
423 }
424 if ((YM2203RouteDirs[4 + BURN_SND_YM2203_AY8910_ROUTE_1] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
425 nRightSample += (INT32)(pYM2203Buffer[5][n] * YM2203Volumes[4 + BURN_SND_YM2203_AY8910_ROUTE_1]);
426 }
427
428 if ((YM2203RouteDirs[4 + BURN_SND_YM2203_AY8910_ROUTE_2] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
429 nLeftSample += (INT32)(pYM2203Buffer[6][n] * YM2203Volumes[4 + BURN_SND_YM2203_AY8910_ROUTE_2]);
430 }
431 if ((YM2203RouteDirs[4 + BURN_SND_YM2203_AY8910_ROUTE_2] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
432 nRightSample += (INT32)(pYM2203Buffer[6][n] * YM2203Volumes[4 + BURN_SND_YM2203_AY8910_ROUTE_2]);
433 }
434
435 if ((YM2203RouteDirs[4 + BURN_SND_YM2203_AY8910_ROUTE_3] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
436 nLeftSample += (INT32)(pYM2203Buffer[7][n] * YM2203Volumes[4 + BURN_SND_YM2203_AY8910_ROUTE_3]);
437 }
438 if ((YM2203RouteDirs[4 + BURN_SND_YM2203_AY8910_ROUTE_3] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
439 nRightSample += (INT32)(pYM2203Buffer[7][n] * YM2203Volumes[4 + BURN_SND_YM2203_AY8910_ROUTE_3]);
440 }
441
442 if ((YM2203RouteDirs[4 + BURN_SND_YM2203_YM2203_ROUTE] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
443 nLeftSample += (INT32)(pYM2203Buffer[4][n] * YM2203Volumes[4 + BURN_SND_YM2203_YM2203_ROUTE]);
444 }
445 if ((YM2203RouteDirs[4 + BURN_SND_YM2203_YM2203_ROUTE] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
446 nRightSample += (INT32)(pYM2203Buffer[4][n] * YM2203Volumes[4 + BURN_SND_YM2203_YM2203_ROUTE]);
447 }
448 }
449
450 if (nNumChips > 2) {
451 if ((YM2203RouteDirs[8 + BURN_SND_YM2203_AY8910_ROUTE_1] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
452 nLeftSample += (INT32)(pYM2203Buffer[9][n] * YM2203Volumes[8 + BURN_SND_YM2203_AY8910_ROUTE_1]);
453 }
454 if ((YM2203RouteDirs[8 + BURN_SND_YM2203_AY8910_ROUTE_1] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
455 nRightSample += (INT32)(pYM2203Buffer[9][n] * YM2203Volumes[8 + BURN_SND_YM2203_AY8910_ROUTE_1]);
456 }
457
458 if ((YM2203RouteDirs[8 + BURN_SND_YM2203_AY8910_ROUTE_2] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
459 nLeftSample += (INT32)(pYM2203Buffer[10][n] * YM2203Volumes[8 + BURN_SND_YM2203_AY8910_ROUTE_2]);
460 }
461 if ((YM2203RouteDirs[8 + BURN_SND_YM2203_AY8910_ROUTE_2] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
462 nRightSample += (INT32)(pYM2203Buffer[10][n] * YM2203Volumes[8 + BURN_SND_YM2203_AY8910_ROUTE_2]);
463 }
464
465 if ((YM2203RouteDirs[8 + BURN_SND_YM2203_AY8910_ROUTE_3] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
466 nLeftSample += (INT32)(pYM2203Buffer[11][n] * YM2203Volumes[8 + BURN_SND_YM2203_AY8910_ROUTE_3]);
467 }
468 if ((YM2203RouteDirs[8 + BURN_SND_YM2203_AY8910_ROUTE_3] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
469 nRightSample += (INT32)(pYM2203Buffer[11][n] * YM2203Volumes[8 + BURN_SND_YM2203_AY8910_ROUTE_3]);
470 }
471
472 if ((YM2203RouteDirs[8 + BURN_SND_YM2203_YM2203_ROUTE] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
473 nLeftSample += (INT32)(pYM2203Buffer[8][n] * YM2203Volumes[8 + BURN_SND_YM2203_YM2203_ROUTE]);
474 }
475 if ((YM2203RouteDirs[8 + BURN_SND_YM2203_YM2203_ROUTE] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
476 nRightSample += (INT32)(pYM2203Buffer[8][n] * YM2203Volumes[8 + BURN_SND_YM2203_YM2203_ROUTE]);
477 }
478 }
479 }
480
481 nLeftSample = BURN_SND_CLIP(nLeftSample);
482 nRightSample = BURN_SND_CLIP(nRightSample);
483
484 if (bYM2203AddSignal) {
485 //pSoundBuf[(n << 1) + 0] += nLeftSample;
486 //pSoundBuf[(n << 1) + 1] += nRightSample;
487 pSoundBuf[(n << 1) + 0] = BURN_SND_CLIP(pSoundBuf[(n << 1) + 0] + nLeftSample);
488 pSoundBuf[(n << 1) + 1] = BURN_SND_CLIP(pSoundBuf[(n << 1) + 1] + nRightSample);
489 } else {
490 pSoundBuf[(n << 1) + 0] = nLeftSample;
491 pSoundBuf[(n << 1) + 1] = nRightSample;
492 }
493 }
494
495 nFractionalPosition = nSegmentLength;
496
497 if (nSegmentEnd >= nBurnSoundLen) {
498 INT32 nExtraSamples = nSegmentEnd - nBurnSoundLen;
499
500 for (i = 0; i < nExtraSamples; i++) {
501 pYM2203Buffer[0][i] = pYM2203Buffer[0][nBurnSoundLen + i];
502 pYM2203Buffer[1][i] = pYM2203Buffer[1][nBurnSoundLen + i];
503 pYM2203Buffer[2][i] = pYM2203Buffer[2][nBurnSoundLen + i];
504 pYM2203Buffer[3][i] = pYM2203Buffer[3][nBurnSoundLen + i];
505 if (nNumChips > 1) {
506 pYM2203Buffer[4][i] = pYM2203Buffer[4][nBurnSoundLen + i];
507 pYM2203Buffer[5][i] = pYM2203Buffer[5][nBurnSoundLen + i];
508 pYM2203Buffer[6][i] = pYM2203Buffer[6][nBurnSoundLen + i];
509 pYM2203Buffer[7][i] = pYM2203Buffer[7][nBurnSoundLen + i];
510 }
511 if (nNumChips > 2) {
512 pYM2203Buffer[8][i] = pYM2203Buffer[8][nBurnSoundLen + i];
513 pYM2203Buffer[9][i] = pYM2203Buffer[9][nBurnSoundLen + i];
514 pYM2203Buffer[10][i] = pYM2203Buffer[10][nBurnSoundLen + i];
515 pYM2203Buffer[11][i] = pYM2203Buffer[11][nBurnSoundLen + i];
516 }
517 }
518
519 nFractionalPosition = 0;
520
521 nYM2203Position = nExtraSamples;
522 nAY8910Position = nExtraSamples;
523
524 dTime += 100.0 / nBurnFPS;
525 }
526 }
527
528 // ----------------------------------------------------------------------------
529 // Callbacks for YM2203 core
530
BurnYM2203UpdateRequest()531 void BurnYM2203UpdateRequest()
532 {
533 #if defined FBA_DEBUG
534 if (!DebugSnd_YM2203Initted) bprintf(PRINT_ERROR, _T("BurnYM2203UpdateRequest called without init\n"));
535 #endif
536
537 YM2203Render(BurnYM2203StreamCallback(nBurnYM2203SoundRate));
538 }
539
BurnAY8910UpdateRequest()540 static void BurnAY8910UpdateRequest()
541 {
542 #if defined FBA_DEBUG
543 if (!DebugSnd_YM2203Initted) bprintf(PRINT_ERROR, _T("BurnYM2203 BurnAY8910UpdateRequest called without init\n"));
544 #endif
545
546 AY8910Render(BurnYM2203StreamCallback(nBurnYM2203SoundRate));
547 }
548
549 // ----------------------------------------------------------------------------
550 // Initialisation, etc.
551
BurnYM2203Reset()552 void BurnYM2203Reset()
553 {
554 #if defined FBA_DEBUG
555 if (!DebugSnd_YM2203Initted) bprintf(PRINT_ERROR, _T("BurnYM2203Reset called without init\n"));
556 #endif
557
558 BurnTimerReset();
559
560 for (INT32 i = 0; i < nNumChips; i++) {
561 YM2203ResetChip(i);
562 AY8910Reset(i);
563 }
564 }
565
BurnYM2203Exit()566 void BurnYM2203Exit()
567 {
568 #if defined FBA_DEBUG
569 if (!DebugSnd_YM2203Initted) bprintf(PRINT_ERROR, _T("BurnYM2203Exit called without init\n"));
570 #endif
571
572 if (!DebugSnd_YM2203Initted) return;
573
574 YM2203Shutdown();
575
576 for (INT32 i = 0; i < nNumChips; i++) {
577 AY8910Exit(i);
578 }
579
580 BurnTimerExit();
581
582 BurnFree(pBuffer);
583
584 nNumChips = 0;
585 bYM2203AddSignal = 0;
586 bYM2203UseSeperateVolumes = 0;
587
588 DebugSnd_YM2203Initted = 0;
589 }
590
BurnYM2203Init(INT32 num,INT32 nClockFrequency,FM_IRQHANDLER IRQCallback,INT32 bAddSignal)591 INT32 BurnYM2203Init(INT32 num, INT32 nClockFrequency, FM_IRQHANDLER IRQCallback, INT32 bAddSignal)
592 {
593 return BurnYM2203Init(num, nClockFrequency, IRQCallback, BurnSynchroniseStream, BurnGetTime, bAddSignal);
594 }
595
BurnYM2203Init(INT32 num,INT32 nClockFrequency,FM_IRQHANDLER IRQCallback,INT32 (* StreamCallback)(INT32),double (* GetTimeCallback)(),INT32 bAddSignal)596 INT32 BurnYM2203Init(INT32 num, INT32 nClockFrequency, FM_IRQHANDLER IRQCallback, INT32 (*StreamCallback)(INT32), double (*GetTimeCallback)(), INT32 bAddSignal)
597 {
598 DebugSnd_YM2203Initted = 1;
599
600 if (num > MAX_YM2203) num = MAX_YM2203;
601
602 BurnTimerInit(&YM2203TimerOver, GetTimeCallback);
603 if (nBurnSoundRate <= 0) {
604 BurnYM2203StreamCallback = YM2203StreamCallbackDummy;
605
606 BurnYM2203Update = YM2203UpdateDummy;
607
608 for (INT32 i = 0; i < num; i++) {
609 AY8910InitYM(i, nClockFrequency, 11025, NULL, NULL, NULL, NULL, BurnAY8910UpdateRequest);
610 }
611 YM2203Init(num, nClockFrequency, 11025, &BurnOPNTimerCallback, IRQCallback);
612 return 0;
613 }
614
615 BurnYM2203StreamCallback = StreamCallback;
616
617 if (nFMInterpolation == 3) {
618 // Set YM2203 core samplerate to match the hardware
619 nBurnYM2203SoundRate = nClockFrequency >> 6;
620 // Bring YM2203 core samplerate within usable range
621 while (nBurnYM2203SoundRate > nBurnSoundRate * 3) {
622 nBurnYM2203SoundRate >>= 1;
623 }
624
625 if (nBurnYM2203SoundRate < nBurnSoundRate)
626 nBurnYM2203SoundRate = nBurnSoundRate;
627
628 BurnYM2203Update = YM2203UpdateResample;
629 nSampleSize = (UINT32)nBurnYM2203SoundRate * (1 << 16) / nBurnSoundRate;
630
631 } else {
632 nBurnYM2203SoundRate = nBurnSoundRate;
633 BurnYM2203Update = YM2203UpdateNormal;
634 }
635
636 for (INT32 i = 0; i < num; i++) {
637 AY8910InitYM(i, nClockFrequency, nBurnYM2203SoundRate, NULL, NULL, NULL, NULL, BurnAY8910UpdateRequest);
638 }
639
640 YM2203Init(num, nClockFrequency, nBurnYM2203SoundRate, &BurnOPNTimerCallback, IRQCallback);
641
642 pBuffer = (INT16*)BurnMalloc(4096 * 4 * num * sizeof(INT16));
643 memset(pBuffer, 0, 4096 * 4 * num * sizeof(INT16));
644
645 nYM2203Position = 0;
646 nAY8910Position = 0;
647 nFractionalPosition = 0;
648
649 nNumChips = num;
650 bYM2203AddSignal = bAddSignal;
651
652 // default routes
653 YM2203Volumes[BURN_SND_YM2203_YM2203_ROUTE] = 1.00;
654 YM2203Volumes[BURN_SND_YM2203_AY8910_ROUTE_1] = 1.00;
655 YM2203Volumes[BURN_SND_YM2203_AY8910_ROUTE_2] = 1.00;
656 YM2203Volumes[BURN_SND_YM2203_AY8910_ROUTE_3] = 1.00;
657 YM2203RouteDirs[BURN_SND_YM2203_YM2203_ROUTE] = BURN_SND_ROUTE_BOTH;
658 YM2203RouteDirs[BURN_SND_YM2203_AY8910_ROUTE_1] = BURN_SND_ROUTE_BOTH;
659 YM2203RouteDirs[BURN_SND_YM2203_AY8910_ROUTE_2] = BURN_SND_ROUTE_BOTH;
660 YM2203RouteDirs[BURN_SND_YM2203_AY8910_ROUTE_3] = BURN_SND_ROUTE_BOTH;
661
662 bYM2203UseSeperateVolumes = 0;
663 YM2203LeftVolumes[BURN_SND_YM2203_YM2203_ROUTE] = 1.00;
664 YM2203LeftVolumes[BURN_SND_YM2203_AY8910_ROUTE_1] = 1.00;
665 YM2203LeftVolumes[BURN_SND_YM2203_AY8910_ROUTE_2] = 1.00;
666 YM2203LeftVolumes[BURN_SND_YM2203_AY8910_ROUTE_3] = 1.00;
667 YM2203RightVolumes[BURN_SND_YM2203_YM2203_ROUTE] = 1.00;
668 YM2203RightVolumes[BURN_SND_YM2203_AY8910_ROUTE_1] = 1.00;
669 YM2203RightVolumes[BURN_SND_YM2203_AY8910_ROUTE_2] = 1.00;
670 YM2203RightVolumes[BURN_SND_YM2203_AY8910_ROUTE_3] = 1.00;
671
672 if (nNumChips > 1) {
673 YM2203Volumes[4 + BURN_SND_YM2203_YM2203_ROUTE] = 1.00;
674 YM2203Volumes[4 + BURN_SND_YM2203_AY8910_ROUTE_1] = 1.00;
675 YM2203Volumes[4 + BURN_SND_YM2203_AY8910_ROUTE_2] = 1.00;
676 YM2203Volumes[4 + BURN_SND_YM2203_AY8910_ROUTE_3] = 1.00;
677 YM2203RouteDirs[4 + BURN_SND_YM2203_YM2203_ROUTE] = BURN_SND_ROUTE_BOTH;
678 YM2203RouteDirs[4 + BURN_SND_YM2203_AY8910_ROUTE_1] = BURN_SND_ROUTE_BOTH;
679 YM2203RouteDirs[4 + BURN_SND_YM2203_AY8910_ROUTE_2] = BURN_SND_ROUTE_BOTH;
680 YM2203RouteDirs[4 + BURN_SND_YM2203_AY8910_ROUTE_3] = BURN_SND_ROUTE_BOTH;
681
682 YM2203LeftVolumes[4 + BURN_SND_YM2203_YM2203_ROUTE] = 1.00;
683 YM2203LeftVolumes[4 + BURN_SND_YM2203_AY8910_ROUTE_1] = 1.00;
684 YM2203LeftVolumes[4 + BURN_SND_YM2203_AY8910_ROUTE_2] = 1.00;
685 YM2203LeftVolumes[4 + BURN_SND_YM2203_AY8910_ROUTE_3] = 1.00;
686 YM2203RightVolumes[4 + BURN_SND_YM2203_YM2203_ROUTE] = 1.00;
687 YM2203RightVolumes[4 + BURN_SND_YM2203_AY8910_ROUTE_1] = 1.00;
688 YM2203RightVolumes[4 + BURN_SND_YM2203_AY8910_ROUTE_2] = 1.00;
689 YM2203RightVolumes[4 + BURN_SND_YM2203_AY8910_ROUTE_3] = 1.00;
690 }
691
692 if (nNumChips > 2) {
693 YM2203Volumes[8 + BURN_SND_YM2203_YM2203_ROUTE] = 1.00;
694 YM2203Volumes[8 + BURN_SND_YM2203_AY8910_ROUTE_1] = 1.00;
695 YM2203Volumes[8 + BURN_SND_YM2203_AY8910_ROUTE_2] = 1.00;
696 YM2203Volumes[8 + BURN_SND_YM2203_AY8910_ROUTE_3] = 1.00;
697 YM2203RouteDirs[8 + BURN_SND_YM2203_YM2203_ROUTE] = BURN_SND_ROUTE_BOTH;
698 YM2203RouteDirs[8 + BURN_SND_YM2203_AY8910_ROUTE_1] = BURN_SND_ROUTE_BOTH;
699 YM2203RouteDirs[8 + BURN_SND_YM2203_AY8910_ROUTE_2] = BURN_SND_ROUTE_BOTH;
700 YM2203RouteDirs[8 + BURN_SND_YM2203_AY8910_ROUTE_3] = BURN_SND_ROUTE_BOTH;
701
702 YM2203LeftVolumes[8 + BURN_SND_YM2203_YM2203_ROUTE] = 1.00;
703 YM2203LeftVolumes[8 + BURN_SND_YM2203_AY8910_ROUTE_1] = 1.00;
704 YM2203LeftVolumes[8 + BURN_SND_YM2203_AY8910_ROUTE_2] = 1.00;
705 YM2203LeftVolumes[8 + BURN_SND_YM2203_AY8910_ROUTE_3] = 1.00;
706 YM2203RightVolumes[8 + BURN_SND_YM2203_YM2203_ROUTE] = 1.00;
707 YM2203RightVolumes[8 + BURN_SND_YM2203_AY8910_ROUTE_1] = 1.00;
708 YM2203RightVolumes[8 + BURN_SND_YM2203_AY8910_ROUTE_2] = 1.00;
709 YM2203RightVolumes[8 + BURN_SND_YM2203_AY8910_ROUTE_3] = 1.00;
710 }
711
712 return 0;
713 }
714
BurnYM2203SetRoute(INT32 nChip,INT32 nIndex,double nVolume,INT32 nRouteDir)715 void BurnYM2203SetRoute(INT32 nChip, INT32 nIndex, double nVolume, INT32 nRouteDir)
716 {
717 #if defined FBA_DEBUG
718 if (!DebugSnd_YM2203Initted) bprintf(PRINT_ERROR, _T("BurnYM2203SetRoute called without init\n"));
719 if (nIndex < 0 || nIndex > 3) bprintf(PRINT_ERROR, _T("BurnYM2203SetRoute called with invalid index %i\n"), nIndex);
720 if (nChip >= nNumChips) bprintf(PRINT_ERROR, _T("BurnYM2203SetRoute called with invalid chip %i\n"), nChip);
721 #endif
722
723 if (nChip == 0) {
724 YM2203Volumes[nIndex] = nVolume;
725 YM2203RouteDirs[nIndex] = nRouteDir;
726 }
727
728 if (nChip == 1) {
729 YM2203Volumes[4 + nIndex] = nVolume;
730 YM2203RouteDirs[4 + nIndex] = nRouteDir;
731 }
732
733 if (nChip == 2) {
734 YM2203Volumes[8 + nIndex] = nVolume;
735 YM2203RouteDirs[8 + nIndex] = nRouteDir;
736 }
737 }
738
BurnYM2203SetLeftVolume(INT32 nChip,INT32 nIndex,double nLeftVolume)739 void BurnYM2203SetLeftVolume(INT32 nChip, INT32 nIndex, double nLeftVolume)
740 {
741 #if defined FBA_DEBUG
742 if (!DebugSnd_YM2203Initted) bprintf(PRINT_ERROR, _T("BurnYM2203SetLeftVolume called without init\n"));
743 if (nIndex < 0 || nIndex > 3) bprintf(PRINT_ERROR, _T("BurnYM2203SetLeftVolume called with invalid index %i\n"), nIndex);
744 if (nChip >= nNumChips) bprintf(PRINT_ERROR, _T("BurnYM2203SetLeftVolume called with invalid chip %i\n"), nChip);
745 #endif
746
747 if (nChip == 0) YM2203LeftVolumes[nIndex] = nLeftVolume;
748 if (nChip == 1) YM2203LeftVolumes[4 + nIndex] = nLeftVolume;
749 if (nChip == 2) YM2203LeftVolumes[8 + nIndex] = nLeftVolume;
750 }
751
BurnYM2203SetRightVolume(INT32 nChip,INT32 nIndex,double nRightVolume)752 void BurnYM2203SetRightVolume(INT32 nChip, INT32 nIndex, double nRightVolume)
753 {
754 #if defined FBA_DEBUG
755 if (!DebugSnd_YM2203Initted) bprintf(PRINT_ERROR, _T("BurnYM2203SetRightVolume called without init\n"));
756 if (nIndex < 0 || nIndex > 3) bprintf(PRINT_ERROR, _T("BurnYM2203SetRightVolume called with invalid index %i\n"), nIndex);
757 if (nChip >= nNumChips) bprintf(PRINT_ERROR, _T("BurnYM2203SetRightVolume called with invalid chip %i\n"), nChip);
758 #endif
759
760 if (nChip == 0) YM2203RightVolumes[nIndex] = nRightVolume;
761 if (nChip == 1) YM2203RightVolumes[4 + nIndex] = nRightVolume;
762 if (nChip == 2) YM2203RightVolumes[8 + nIndex] = nRightVolume;
763 }
764
BurnYM2203Scan(INT32 nAction,INT32 * pnMin)765 void BurnYM2203Scan(INT32 nAction, INT32* pnMin)
766 {
767 #if defined FBA_DEBUG
768 if (!DebugSnd_YM2203Initted) bprintf(PRINT_ERROR, _T("BurnYM2203Scan called without init\n"));
769 #endif
770
771 BurnTimerScan(nAction, pnMin);
772 AY8910Scan(nAction, pnMin);
773
774 if (nAction & ACB_DRIVER_DATA) {
775 SCAN_VAR(nYM2203Position);
776 SCAN_VAR(nAY8910Position);
777 }
778 }
779
780 #undef MAX_YM2203
781