diff --git a/src/burn/drv/dataeast/d_dec8.cpp b/src/burn/drv/dataeast/d_dec8.cpp index 270fc037e..b2cd7de00 100644 --- a/src/burn/drv/dataeast/d_dec8.cpp +++ b/src/burn/drv/dataeast/d_dec8.cpp @@ -3423,6 +3423,7 @@ static INT32 GondoInit() BurnYM3526Init(3000000, &DrvYM3812FMIRQHandler, &DrvYM3812SynchroniseStream, 0); BurnTimerAttachM6502YM3526(1500000); + BurnYM3526SetRoute(BURN_SND_YM3526_ROUTE, 0.70, BURN_SND_ROUTE_BOTH); BurnYM2203Init(1, 1500000, NULL, DrvYM2203SynchroniseStream, DrvYM2203GetTime, 1); BurnTimerAttachHD6309(1200000); @@ -4031,6 +4032,7 @@ static INT32 OscarInit() BurnYM3526Init(3000000, &DrvYM3812FMIRQHandler, &DrvYM3812SynchroniseStream, 0); BurnTimerAttachM6502YM3526(1500000); + BurnYM3526SetRoute(BURN_SND_YM3526_ROUTE, 0.70, BURN_SND_ROUTE_BOTH); BurnYM2203Init(1, 1500000, NULL, DrvYM2203SynchroniseStream6000000, DrvYM2203GetTime6000000, 1); BurnTimerAttachHD6309(6000000); @@ -4683,6 +4685,7 @@ static INT32 LastmissInit() BurnYM3526Init(3000000, &DrvYM3812FMIRQHandler, &DrvYM3812SynchroniseStream, 0); BurnTimerAttachM6502YM3526(1500000); + BurnYM3526SetRoute(BURN_SND_YM3526_ROUTE, 0.70, BURN_SND_ROUTE_BOTH); BurnYM2203Init(1, 1500000, NULL, DrvYM2203M6809SynchroniseStream, DrvYM2203M6809GetTime, 1); BurnTimerAttachM6809(2000000); @@ -5392,6 +5395,7 @@ static INT32 CsilverInit() BurnYM3526Init(3000000, &DrvYM3812FMIRQHandler, &DrvYM3812SynchroniseStream, 0); BurnTimerAttachM6502YM3526(1500000); + BurnYM3526SetRoute(BURN_SND_YM3526_ROUTE, 0.70, BURN_SND_ROUTE_BOTH); BurnYM2203Init(1, 1500000, NULL, DrvYM2203M6809SynchroniseStream1500000, DrvYM2203M6809GetTime1500000, 1); BurnTimerAttachM6809(1500000); diff --git a/src/burn/drv/dataeast/d_karnov.cpp b/src/burn/drv/dataeast/d_karnov.cpp index ad1925c30..467882771 100644 --- a/src/burn/drv/dataeast/d_karnov.cpp +++ b/src/burn/drv/dataeast/d_karnov.cpp @@ -903,6 +903,7 @@ static INT32 DrvInit() BurnYM3526Init(3000000, &DrvYM3526FMIRQHandler, &DrvYM3526SynchroniseStream, 0); BurnTimerAttachM6502YM3526(1500000); + BurnYM3526SetRoute(BURN_SND_YM3526_ROUTE, 1.00, BURN_SND_ROUTE_BOTH); BurnYM2203Init(1, 1500000, NULL, DrvYM2203SynchroniseStream, DrvYM2203GetTime, 1); BurnTimerAttachSek(10000000); diff --git a/src/burn/drv/dataeast/d_sidepckt.cpp b/src/burn/drv/dataeast/d_sidepckt.cpp index a4ede04ae..53179f363 100644 --- a/src/burn/drv/dataeast/d_sidepckt.cpp +++ b/src/burn/drv/dataeast/d_sidepckt.cpp @@ -689,6 +689,7 @@ static INT32 DrvInit() BurnYM3526Init(3000000, &DrvFMIRQHandler, &DrvYM3526SynchroniseStream, 1); BurnTimerAttachM6502YM3526(1500000); + BurnYM3526SetRoute(BURN_SND_YM3526_ROUTE, 1.00, BURN_SND_ROUTE_BOTH); GenericTilesInit(); diff --git a/src/burn/drv/pre90s/d_renegade.cpp b/src/burn/drv/pre90s/d_renegade.cpp index e11ec8710..abd24856a 100644 --- a/src/burn/drv/pre90s/d_renegade.cpp +++ b/src/burn/drv/pre90s/d_renegade.cpp @@ -1030,6 +1030,7 @@ static INT32 DrvInit(INT32 nMcuType) BurnYM3526Init(3000000, &DrvFMIRQHandler, &DrvSynchroniseStream, 0); BurnTimerAttachM6809YM3526(1500000); + BurnYM3526SetRoute(BURN_SND_YM3526_ROUTE, 1.00, BURN_SND_ROUTE_BOTH); RenegadeADPCMInit(8000); diff --git a/src/burn/drv/pre90s/d_terracre.cpp b/src/burn/drv/pre90s/d_terracre.cpp index 0970c3d3d..4331e2870 100644 --- a/src/burn/drv/pre90s/d_terracre.cpp +++ b/src/burn/drv/pre90s/d_terracre.cpp @@ -1076,6 +1076,7 @@ static INT32 DrvInit() } else { BurnYM3526Init(4000000, NULL, &DrvSynchroniseStream, 0); BurnTimerAttachZetYM3526(4000000); + BurnYM3526SetRoute(BURN_SND_YM3526_ROUTE, 1.00, BURN_SND_ROUTE_BOTH); } DACInit(0, 0, 1, TerracreSyncDAC); @@ -1131,6 +1132,7 @@ static INT32 DrvAmazonInit() BurnYM3526Init(4000000, NULL, &DrvSynchroniseStream, 0); BurnTimerAttachZetYM3526(4000000); + BurnYM3526SetRoute(BURN_SND_YM3526_ROUTE, 1.00, BURN_SND_ROUTE_BOTH); DACInit(0, 0, 1, TerracreSyncDAC); DACInit(1, 0, 1, TerracreSyncDAC); diff --git a/src/burn/drv/pst90s/d_suna16.cpp b/src/burn/drv/pst90s/d_suna16.cpp index ab5cb1105..54f240235 100644 --- a/src/burn/drv/pst90s/d_suna16.cpp +++ b/src/burn/drv/pst90s/d_suna16.cpp @@ -1459,6 +1459,7 @@ static INT32 BestbestInit() BurnYM3526Init(3000000, &bestbestFMIRQHandler, &bestbestSynchroniseStream, 0); BurnTimerAttachZetYM3526(6000000); + BurnYM3526SetRoute(BURN_SND_YM3526_ROUTE, 1.00, BURN_SND_ROUTE_BOTH); AY8910Init(0, 1500000, nBurnSoundRate, NULL, NULL, bestbest_ay8910_write_a, NULL); diff --git a/src/burn/drv/taito/d_bublbobl.cpp b/src/burn/drv/taito/d_bublbobl.cpp index ea3e3e7c0..65d4e1347 100644 --- a/src/burn/drv/taito/d_bublbobl.cpp +++ b/src/burn/drv/taito/d_bublbobl.cpp @@ -1760,6 +1760,7 @@ static INT32 MachineInit() BurnYM3526Init(3000000, NULL, &DrvYM3526SynchroniseStream, 1); BurnTimerAttachZetYM3526(6000000); + BurnYM3526SetRoute(BURN_SND_YM3526_ROUTE, 0.50, BURN_SND_ROUTE_BOTH); if (BublboblCallbackFunction()) return 1; diff --git a/src/burn/snd/burn_ym3526.cpp b/src/burn/snd/burn_ym3526.cpp index fcc06fede..835afb3e1 100644 --- a/src/burn/snd/burn_ym3526.cpp +++ b/src/burn/snd/burn_ym3526.cpp @@ -49,8 +49,6 @@ INT32 BurnTimerUpdateYM3526(INT32 nCycles) nTicksTotal = MAKE_TIMER_TICKS(nCycles, nCPUClockspeed); -// bprintf(PRINT_NORMAL, _T(" -- Ticks: %08X, cycles %i\n"), nTicksTotal, nCycles); - while (nTicksDone < nTicksTotal) { INT32 nTimer, nCyclesSegment, nTicksSegment; @@ -65,12 +63,10 @@ INT32 BurnTimerUpdateYM3526(INT32 nCycles) } nCyclesSegment = MAKE_CPU_CYLES(nTicksSegment + nTicksExtra, nCPUClockspeed); -// bprintf(PRINT_NORMAL, _T(" - Timer: %08X, %08X, %08X, cycles %i, %i\n"), nTicksDone, nTicksSegment, nTicksTotal, nCyclesSegment, pCPUTotalCycles()); pCPURun(nCyclesSegment - pCPUTotalCycles()); nTicksDone = MAKE_TIMER_TICKS(pCPUTotalCycles() + 1, nCPUClockspeed) - 1; -// bprintf(PRINT_NORMAL, _T(" - ticks done -> %08X cycles -> %i\n"), nTicksDone, pCPUTotalCycles()); nTimer = 0; if (nTicksDone >= nTimerCount[0]) { @@ -79,7 +75,6 @@ INT32 BurnTimerUpdateYM3526(INT32 nCycles) } else { nTimerCount[0] += nTimerStart[0]; } -// bprintf(PRINT_NORMAL, _T(" - timer 0 fired\n")); nTimer |= 1; } if (nTicksDone >= nTimerCount[1]) { @@ -88,7 +83,6 @@ INT32 BurnTimerUpdateYM3526(INT32 nCycles) } else { nTimerCount[1] += nTimerStart[1]; } -// bprintf(PRINT_NORMAL, _T(" - timer 1 fired\n")); nTimer |= 2; } if (nTimer & 1) { @@ -117,15 +111,12 @@ void BurnTimerEndFrameYM3526(INT32 nCycles) nTicksDone -= nTicks; if (nTicksDone < 0) { -// bprintf(PRINT_ERROR, _T(" -- ticks done -> %08X\n"), nTicksDone); nTicksDone = 0; } } void BurnTimerUpdateEndYM3526() { -// bprintf(PRINT_NORMAL, _T(" - end %i\n"), pCPUTotalCycles()); - pCPURunEnd(); nTicksTotal = 0; @@ -137,14 +128,11 @@ void BurnOPLTimerCallbackYM3526(INT32 c, double period) if (period == 0.0) { nTimerCount[c] = MAX_TIMER_VALUE; -// bprintf(PRINT_NORMAL, _T(" - timer %i stopped\n"), c); return; } nTimerCount[c] = (INT32)(period * (double)TIMER_TICKS_PER_SECOND); nTimerCount[c] += MAKE_TIMER_TICKS(pCPUTotalCycles(), nCPUClockspeed); - -// bprintf(PRINT_NORMAL, _T(" - timer %i started, %08X ticks (fires in %lf seconds)\n"), c, nTimerCount[c], period); } void BurnTimerScanYM3526(INT32 nAction, INT32* pnMin) @@ -203,8 +191,6 @@ INT32 BurnTimerAttachSekYM3526(INT32 nClockspeed) nTicksExtra = MAKE_TIMER_TICKS(1, nCPUClockspeed) - 1; -// bprintf(PRINT_NORMAL, _T("--- timer cpu speed %iHz, one cycle = %i ticks.\n"), nClockspeed, MAKE_TIMER_TICKS(1, nCPUClockspeed)); - return 0; } @@ -217,8 +203,6 @@ INT32 BurnTimerAttachZetYM3526(INT32 nClockspeed) nTicksExtra = MAKE_TIMER_TICKS(1, nCPUClockspeed) - 1; -// bprintf(PRINT_NORMAL, _T("--- timer cpu speed %iHz, one cycle = %i ticks.\n"), nClockspeed, MAKE_TIMER_TICKS(1, nCPUClockspeed)); - return 0; } @@ -231,8 +215,6 @@ INT32 BurnTimerAttachM6809YM3526(INT32 nClockspeed) nTicksExtra = MAKE_TIMER_TICKS(1, nCPUClockspeed) - 1; -// bprintf(PRINT_NORMAL, _T("--- timer cpu speed %iHz, one cycle = %i ticks.\n"), nClockspeed, MAKE_TIMER_TICKS(1, nCPUClockspeed)); - return 0; } @@ -245,8 +227,6 @@ INT32 BurnTimerAttachHD6309YM3526(INT32 nClockspeed) nTicksExtra = MAKE_TIMER_TICKS(1, nCPUClockspeed) - 1; -// bprintf(PRINT_NORMAL, _T("--- timer cpu speed %iHz, one cycle = %i ticks.\n"), nClockspeed, MAKE_TIMER_TICKS(1, nCPUClockspeed)); - return 0; } @@ -259,8 +239,6 @@ INT32 BurnTimerAttachM6800YM3526(INT32 nClockspeed) nTicksExtra = MAKE_TIMER_TICKS(1, nCPUClockspeed) - 1; -// bprintf(PRINT_NORMAL, _T("--- timer cpu speed %iHz, one cycle = %i ticks.\n"), nClockspeed, MAKE_TIMER_TICKS(1, nCPUClockspeed)); - return 0; } @@ -273,8 +251,6 @@ INT32 BurnTimerAttachHD63701YM3526(INT32 nClockspeed) nTicksExtra = MAKE_TIMER_TICKS(1, nCPUClockspeed) - 1; -// bprintf(PRINT_NORMAL, _T("--- timer cpu speed %iHz, one cycle = %i ticks.\n"), nClockspeed, MAKE_TIMER_TICKS(1, nCPUClockspeed)); - return 0; } @@ -287,8 +263,6 @@ INT32 BurnTimerAttachM6803YM3526(INT32 nClockspeed) nTicksExtra = MAKE_TIMER_TICKS(1, nCPUClockspeed) - 1; -// bprintf(PRINT_NORMAL, _T("--- timer cpu speed %iHz, one cycle = %i ticks.\n"), nClockspeed, MAKE_TIMER_TICKS(1, nCPUClockspeed)); - return 0; } @@ -301,8 +275,6 @@ INT32 BurnTimerAttachM6502YM3526(INT32 nClockspeed) nTicksExtra = MAKE_TIMER_TICKS(1, nCPUClockspeed) - 1; -// bprintf(PRINT_NORMAL, _T("--- timer cpu speed %iHz, one cycle = %i ticks.\n"), nClockspeed, MAKE_TIMER_TICKS(1, nCPUClockspeed)); - return 0; } @@ -324,15 +296,18 @@ static INT32 nFractionalPosition; static INT32 bYM3526AddSignal; +static double YM3526Volumes[1]; +static INT32 YM3526RouteDirs[1]; + // ---------------------------------------------------------------------------- // Dummy functions -static void YM3526UpdateDummy(INT16* , INT32 /* nSegmentEnd */) +static void YM3526UpdateDummy(INT16* , INT32) { return; } -static INT32 YM3526StreamCallbackDummy(INT32 /* nSoundRate */) +static INT32 YM3526StreamCallbackDummy(INT32) { return 0; } @@ -350,8 +325,6 @@ static void YM3526Render(INT32 nSegmentLength) return; } -// bprintf(PRINT_NORMAL, _T(" YM3526 render %6i -> %6i\n", nYM3526Position, nSegmentLength)); - nSegmentLength -= nYM3526Position; YM3526UpdateOne(0, pBuffer + 0 * 4096 + 4 + nYM3526Position, nSegmentLength); @@ -371,8 +344,6 @@ static void YM3526UpdateResample(INT16* pSoundBuf, INT32 nSegmentEnd) INT32 nSegmentLength = nSegmentEnd; INT32 nSamplesNeeded = nSegmentEnd * nBurnYM3526SoundRate / nBurnSoundRate + 1; -// bprintf(PRINT_NORMAL, _T(" YM3526 update -> %6i\n", nSegmentLength)); - if (nSamplesNeeded < nYM3526Position) { nSamplesNeeded = nYM3526Position; } @@ -387,25 +358,41 @@ static void YM3526UpdateResample(INT16* pSoundBuf, INT32 nSegmentEnd) pYM3526Buffer = pBuffer + 0 * 4096 + 4; for (INT32 i = (nFractionalPosition & 0xFFFF0000) >> 15; i < nSegmentLength; i += 2, nFractionalPosition += nSampleSize) { - INT16 nSample = INTERPOLATE4PS_16BIT((nFractionalPosition >> 4) & 0x0FFF, - pYM3526Buffer[(nFractionalPosition >> 16) - 3], - pYM3526Buffer[(nFractionalPosition >> 16) - 2], - pYM3526Buffer[(nFractionalPosition >> 16) - 1], - pYM3526Buffer[(nFractionalPosition >> 16) - 0]); + INT32 nLeftSample[4] = {0, 0, 0, 0}; + INT32 nRightSample[4] = {0, 0, 0, 0}; + INT32 nTotalLeftSample, nTotalRightSample; + + if ((YM3526RouteDirs[BURN_SND_YM3526_ROUTE] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) { + nLeftSample[0] += (INT32)(pYM3526Buffer[(nFractionalPosition >> 16) - 3] * YM3526Volumes[BURN_SND_YM3526_ROUTE]); + nLeftSample[1] += (INT32)(pYM3526Buffer[(nFractionalPosition >> 16) - 2] * YM3526Volumes[BURN_SND_YM3526_ROUTE]); + nLeftSample[2] += (INT32)(pYM3526Buffer[(nFractionalPosition >> 16) - 1] * YM3526Volumes[BURN_SND_YM3526_ROUTE]); + nLeftSample[3] += (INT32)(pYM3526Buffer[(nFractionalPosition >> 16) - 0] * YM3526Volumes[BURN_SND_YM3526_ROUTE]); + } + if ((YM3526RouteDirs[BURN_SND_YM3526_ROUTE] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) { + nRightSample[0] += (INT32)(pYM3526Buffer[(nFractionalPosition >> 16) - 3] * YM3526Volumes[BURN_SND_YM3526_ROUTE]); + nRightSample[1] += (INT32)(pYM3526Buffer[(nFractionalPosition >> 16) - 2] * YM3526Volumes[BURN_SND_YM3526_ROUTE]); + nRightSample[2] += (INT32)(pYM3526Buffer[(nFractionalPosition >> 16) - 1] * YM3526Volumes[BURN_SND_YM3526_ROUTE]); + nRightSample[3] += (INT32)(pYM3526Buffer[(nFractionalPosition >> 16) - 0] * YM3526Volumes[BURN_SND_YM3526_ROUTE]); + } + + nTotalLeftSample = INTERPOLATE4PS_16BIT((nFractionalPosition >> 4) & 0x0fff, nLeftSample[0], nLeftSample[1], nLeftSample[2], nLeftSample[3]); + nTotalRightSample = INTERPOLATE4PS_16BIT((nFractionalPosition >> 4) & 0x0fff, nRightSample[0], nRightSample[1], nRightSample[2], nRightSample[3]); + + nTotalLeftSample = BURN_SND_CLIP(nTotalLeftSample); + nTotalRightSample = BURN_SND_CLIP(nTotalRightSample); + if (bYM3526AddSignal) { - pSoundBuf[i + 0] += nSample; - pSoundBuf[i + 1] += nSample; + pSoundBuf[i + 0] += nTotalLeftSample; + pSoundBuf[i + 1] += nTotalRightSample; } else { - pSoundBuf[i + 0] = nSample; - pSoundBuf[i + 1] = nSample; + pSoundBuf[i + 0] = nTotalLeftSample; + pSoundBuf[i + 1] = nTotalRightSample; } } if (nSegmentEnd >= nBurnSoundLen) { INT32 nExtraSamples = nSamplesNeeded - (nFractionalPosition >> 16); -// bprintf(PRINT_NORMAL, _T(" %6i rendered, %i extra, %i <- %i\n"), nSamplesNeeded, nExtraSamples, nExtraSamples, (nFractionalPosition >> 16) + nExtraSamples - 1); - for (INT32 i = -4; i < nExtraSamples; i++) { pYM3526Buffer[i] = pYM3526Buffer[(nFractionalPosition >> 16) + i]; } @@ -424,8 +411,6 @@ static void YM3526UpdateNormal(INT16* pSoundBuf, INT32 nSegmentEnd) INT32 nSegmentLength = nSegmentEnd; -// bprintf(PRINT_NORMAL, _T(" YM3526 render %6i -> %6i\n"), nYM3526Position, nSegmentEnd); - if (nSegmentEnd < nYM3526Position) { nSegmentEnd = nYM3526Position; } @@ -438,13 +423,25 @@ static void YM3526UpdateNormal(INT16* pSoundBuf, INT32 nSegmentEnd) pYM3526Buffer = pBuffer + 4 + 0 * 4096; - for (INT32 i = nFractionalPosition; i < nSegmentLength; i++) { + for (INT32 n = nFractionalPosition; n < nSegmentLength; n++) { + INT32 nLeftSample = 0, nRightSample = 0; + + if ((YM3526RouteDirs[BURN_SND_YM3526_ROUTE] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) { + nLeftSample += (INT32)(pYM3526Buffer[n] * YM3526Volumes[BURN_SND_YM3526_ROUTE]); + } + if ((YM3526RouteDirs[BURN_SND_YM3526_ROUTE] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) { + nRightSample += (INT32)(pYM3526Buffer[n] * YM3526Volumes[BURN_SND_YM3526_ROUTE]); + } + + nLeftSample = BURN_SND_CLIP(nLeftSample); + nRightSample = BURN_SND_CLIP(nRightSample); + if (bYM3526AddSignal) { - pSoundBuf[(i << 1) + 0] += pYM3526Buffer[i]; - pSoundBuf[(i << 1) + 1] += pYM3526Buffer[i]; + pSoundBuf[(n << 1) + 0] += nLeftSample; + pSoundBuf[(n << 1) + 1] += nRightSample; } else { - pSoundBuf[(i << 1) + 0] = pYM3526Buffer[i]; - pSoundBuf[(i << 1) + 1] = pYM3526Buffer[i]; + pSoundBuf[(n << 1) + 0] = nLeftSample; + pSoundBuf[(n << 1) + 1] = nRightSample; } } @@ -558,10 +555,25 @@ INT32 BurnYM3526Init(INT32 nClockFrequency, OPL_IRQHANDLER IRQCallback, INT32 (* nFractionalPosition = 0; bYM3526AddSignal = bAddSignal; + + // default routes + YM3526Volumes[BURN_SND_YM3526_ROUTE] = 1.00; + YM3526RouteDirs[BURN_SND_YM3526_ROUTE] = BURN_SND_ROUTE_BOTH; return 0; } +void BurnYM3526SetRoute(INT32 nIndex, double nVolume, INT32 nRouteDir) +{ +#if defined FBA_DEBUG + if (!DebugSnd_YM3526Initted) bprintf(PRINT_ERROR, _T("BurnYM3526SetRoute called without init\n")); + if (nIndex < 0 || nIndex > 1) bprintf(PRINT_ERROR, _T("BurnYM3526SetRoute called with invalid index %i\n"), nIndex); +#endif + + YM3526Volumes[nIndex] = nVolume; + YM3526RouteDirs[nIndex] = nRouteDir; +} + void BurnYM3526Scan(INT32 nAction, INT32* pnMin) { #if defined FBA_DEBUG diff --git a/src/burn/snd/burn_ym3526.h b/src/burn/snd/burn_ym3526.h index 9ffe51ddd..d7df9bd30 100644 --- a/src/burn/snd/burn_ym3526.h +++ b/src/burn/snd/burn_ym3526.h @@ -18,11 +18,14 @@ INT32 BurnTimerAttachM6502YM3526(INT32 nClockspeed); extern "C" void BurnYM3526UpdateRequest(); INT32 BurnYM3526Init(INT32 nClockFrequency, OPL_IRQHANDLER IRQCallback, INT32 (*StreamCallback)(INT32), INT32 bAddSignal); +void BurnYM3526SetRoute(INT32 nIndex, double nVolume, INT32 nRouteDir); void BurnYM3526Reset(); void BurnYM3526Exit(); extern void (*BurnYM3526Update)(INT16* pSoundBuf, INT32 nSegmentEnd); void BurnYM3526Scan(INT32 nAction, INT32* pnMin); +#define BURN_SND_YM3526_ROUTE 0 + #define BurnYM3526Read(a) YM3526Read(0, a) #if defined FBA_DEBUG