2009-02-20 13:29:39 +00:00
|
|
|
/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
|
2009-06-21 11:00:53 +00:00
|
|
|
* Developed and maintained by the Pcsx2 Development Team.
|
|
|
|
*
|
|
|
|
* Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz]
|
|
|
|
*
|
|
|
|
* SPU2-X is free software: you can redistribute it and/or modify it under the terms
|
|
|
|
* of the GNU Lesser General Public License as published by the Free Software Found-
|
|
|
|
* ation, either version 3 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
|
|
* PURPOSE. See the GNU Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
|
|
* along with SPU2-X. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
2009-02-20 13:29:39 +00:00
|
|
|
|
2009-09-29 19:18:50 +00:00
|
|
|
#include "Global.h"
|
2010-02-05 03:59:19 +00:00
|
|
|
#include "Dma.h"
|
2009-09-29 19:18:50 +00:00
|
|
|
|
2010-02-03 03:37:55 +00:00
|
|
|
#include "PS2E-spu2.h" // required for ENABLE_NEW_IOPDMA_SPU2 define
|
|
|
|
|
2009-10-04 08:47:43 +00:00
|
|
|
// Core 0 Input is "SPDIF mode" - Source audio is AC3 compressed.
|
2009-10-03 13:32:23 +00:00
|
|
|
|
2009-10-04 08:47:43 +00:00
|
|
|
// Core 1 Input is "CDDA mode" - Source audio data is 32 bits.
|
2009-09-29 19:18:50 +00:00
|
|
|
// PS2 note: Very! few PS2 games use this mode. Some PSX games used it, however no
|
|
|
|
// *known* PS2 game does since it was likely only available if the game was recorded to CD
|
|
|
|
// media (ie, not available in DVD mode, which almost all PS2 games use). Plus PS2 games
|
|
|
|
// generally prefer to use ADPCM streaming audio since they need as much storage space as
|
|
|
|
// possible for FMVs and high-def textures.
|
|
|
|
//
|
2009-10-04 08:47:43 +00:00
|
|
|
StereoOut32 V_Core::ReadInput_HiFi()
|
2009-02-20 13:29:39 +00:00
|
|
|
{
|
2010-02-03 03:37:55 +00:00
|
|
|
InputPosRead &= ~1;
|
2009-02-20 13:29:39 +00:00
|
|
|
|
|
|
|
#ifdef PCM24_S1_INTERLEAVE
|
2009-09-29 19:18:50 +00:00
|
|
|
StereoOut32 retval(
|
2010-02-03 03:37:55 +00:00
|
|
|
*((s32*)(ADMATempBuffer+(InputPosRead<<1))),
|
|
|
|
*((s32*)(ADMATempBuffer+(InputPosRead<<1)+2))
|
2009-09-29 19:18:50 +00:00
|
|
|
);
|
2009-02-20 13:29:39 +00:00
|
|
|
#else
|
2009-09-29 19:18:50 +00:00
|
|
|
StereoOut32 retval(
|
2010-02-03 03:37:55 +00:00
|
|
|
(s32&)(ADMATempBuffer[InputPosRead]),
|
|
|
|
(s32&)(ADMATempBuffer[InputPosRead+0x200])
|
2009-09-29 19:18:50 +00:00
|
|
|
);
|
2009-02-20 13:29:39 +00:00
|
|
|
#endif
|
|
|
|
|
2009-10-04 08:47:43 +00:00
|
|
|
if( Index == 1 )
|
2009-09-29 19:18:50 +00:00
|
|
|
{
|
2009-10-04 08:47:43 +00:00
|
|
|
// CDDA Mode:
|
|
|
|
// give 30 bit data (SndOut downsamples the rest of the way)
|
|
|
|
// HACKFIX: 28 bits seems better according to rama. I should take some time and do some
|
|
|
|
// bitcounting on this one. --air
|
|
|
|
retval.Left >>= 4;
|
|
|
|
retval.Right >>= 4;
|
2009-09-29 19:18:50 +00:00
|
|
|
}
|
2009-10-04 08:47:43 +00:00
|
|
|
|
2010-02-03 03:37:55 +00:00
|
|
|
InputPosRead += 2;
|
2009-10-04 08:47:43 +00:00
|
|
|
|
|
|
|
// Why does CDDA mode check for InputPos == 0x100? In the old code, SPDIF mode did not but CDDA did.
|
|
|
|
// One of these seems wrong, they should be the same. Since standard ADMA checks too I'm assuming that as default. -- air
|
|
|
|
|
2010-02-03 03:37:55 +00:00
|
|
|
if( (InputPosRead==0x100) || (InputPosRead>=0x200) )
|
2009-09-29 19:18:50 +00:00
|
|
|
{
|
2010-02-03 03:37:55 +00:00
|
|
|
#ifdef ENABLE_NEW_IOPDMA_SPU2
|
|
|
|
// WARNING: Assumes this to be in the same thread as the dmas
|
|
|
|
AutoDmaFree += 0x200;
|
|
|
|
#else
|
2009-09-29 19:18:50 +00:00
|
|
|
AdmaInProgress = 0;
|
|
|
|
if(InputDataLeft >= 0x200)
|
|
|
|
{
|
2009-02-20 13:29:39 +00:00
|
|
|
#ifdef PCM24_S1_INTERLEAVE
|
2009-09-29 19:18:50 +00:00
|
|
|
AutoDMAReadBuffer(1);
|
2009-02-20 13:29:39 +00:00
|
|
|
#else
|
2009-09-29 19:18:50 +00:00
|
|
|
AutoDMAReadBuffer(0);
|
2009-02-20 13:29:39 +00:00
|
|
|
#endif
|
2009-09-29 19:18:50 +00:00
|
|
|
AdmaInProgress = 1;
|
2009-02-20 13:29:39 +00:00
|
|
|
|
2010-02-03 03:37:55 +00:00
|
|
|
TSA = (Index<<10) + InputPosRead;
|
2009-02-20 13:29:39 +00:00
|
|
|
|
2009-09-29 19:18:50 +00:00
|
|
|
if (InputDataLeft < 0x200)
|
|
|
|
{
|
2009-10-04 08:47:43 +00:00
|
|
|
FileLog("[%10d] %s AutoDMA%c block end.\n", (Index==1) ? "CDDA" : "SPDIF", Cycles, GetDmaIndexChar());
|
2009-02-20 13:29:39 +00:00
|
|
|
|
2009-09-29 19:18:50 +00:00
|
|
|
if( IsDevBuild )
|
2009-02-20 13:29:39 +00:00
|
|
|
{
|
2009-09-29 19:18:50 +00:00
|
|
|
if(InputDataLeft > 0)
|
2009-02-20 13:29:39 +00:00
|
|
|
{
|
2009-09-29 19:18:50 +00:00
|
|
|
if(MsgAutoDMA()) ConLog("WARNING: adma buffer didn't finish with a whole block!!\n");
|
2009-02-20 13:29:39 +00:00
|
|
|
}
|
|
|
|
}
|
2009-09-29 19:18:50 +00:00
|
|
|
InputDataLeft = 0;
|
|
|
|
DMAICounter = 1;
|
2009-02-20 13:29:39 +00:00
|
|
|
}
|
2009-09-29 19:18:50 +00:00
|
|
|
}
|
2010-02-03 03:37:55 +00:00
|
|
|
#endif
|
|
|
|
InputPosRead &= 0x1ff;
|
2009-09-29 19:18:50 +00:00
|
|
|
}
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
StereoOut32 V_Core::ReadInput()
|
|
|
|
{
|
|
|
|
if((AutoDMACtrl&(Index+1)) != (Index+1))
|
|
|
|
return StereoOut32();
|
2009-02-20 13:29:39 +00:00
|
|
|
|
2009-10-04 08:47:43 +00:00
|
|
|
StereoOut32 retval;
|
|
|
|
|
|
|
|
if( (Index!=1) || ((PlayMode&2)==0) )
|
2009-09-29 19:18:50 +00:00
|
|
|
{
|
2009-10-04 08:47:43 +00:00
|
|
|
// Using the temporary buffer because this area gets overwritten by some other code.
|
|
|
|
//*PData.Left = (s32)*(s16*)(spu2mem+0x2000+(core<<10)+InputPos);
|
|
|
|
//*PData.Right = (s32)*(s16*)(spu2mem+0x2200+(core<<10)+InputPos);
|
|
|
|
|
|
|
|
retval = StereoOut32(
|
2010-02-03 03:37:55 +00:00
|
|
|
(s32)ADMATempBuffer[InputPosRead],
|
|
|
|
(s32)ADMATempBuffer[InputPosRead+0x200]
|
2009-10-04 08:47:43 +00:00
|
|
|
);
|
2009-09-29 19:18:50 +00:00
|
|
|
}
|
2009-10-04 08:47:43 +00:00
|
|
|
|
2010-02-03 03:37:55 +00:00
|
|
|
InputPosRead++;
|
|
|
|
if( (InputPosRead==0x100) || (InputPosRead>=0x200) )
|
2009-09-29 19:18:50 +00:00
|
|
|
{
|
2010-02-03 03:37:55 +00:00
|
|
|
#ifdef ENABLE_NEW_IOPDMA_SPU2
|
|
|
|
// WARNING: Assumes this to be in the same thread as the dmas
|
|
|
|
AutoDmaFree += 0x200;
|
|
|
|
#else
|
2009-10-04 08:47:43 +00:00
|
|
|
AdmaInProgress = 0;
|
|
|
|
if(InputDataLeft >= 0x200)
|
2009-09-29 19:18:50 +00:00
|
|
|
{
|
2009-10-04 08:47:43 +00:00
|
|
|
u8 k=InputDataLeft>=InputDataProgress;
|
2009-09-29 19:18:50 +00:00
|
|
|
|
2009-10-04 08:47:43 +00:00
|
|
|
AutoDMAReadBuffer(0);
|
2009-02-20 13:29:39 +00:00
|
|
|
|
2009-10-04 08:47:43 +00:00
|
|
|
AdmaInProgress = 1;
|
2010-02-03 03:37:55 +00:00
|
|
|
TSA = (Index<<10) + InputPosRead;
|
2009-02-20 13:29:39 +00:00
|
|
|
|
2009-10-04 08:47:43 +00:00
|
|
|
if (InputDataLeft < 0x200)
|
|
|
|
{
|
|
|
|
AutoDMACtrl |= ~3;
|
2009-02-20 13:29:39 +00:00
|
|
|
|
2009-10-04 08:47:43 +00:00
|
|
|
if( IsDevBuild )
|
2009-02-20 13:29:39 +00:00
|
|
|
{
|
2009-10-04 08:47:43 +00:00
|
|
|
FileLog("[%10d] AutoDMA%c block end.\n",Cycles, GetDmaIndexChar());
|
|
|
|
if(InputDataLeft>0)
|
2009-02-20 13:29:39 +00:00
|
|
|
{
|
2009-10-04 08:47:43 +00:00
|
|
|
if(MsgAutoDMA()) ConLog("WARNING: adma buffer didn't finish with a whole block!!\n");
|
2009-02-20 13:29:39 +00:00
|
|
|
}
|
|
|
|
}
|
2009-10-04 08:47:43 +00:00
|
|
|
|
|
|
|
InputDataLeft = 0;
|
|
|
|
DMAICounter = 1;
|
2009-02-20 13:29:39 +00:00
|
|
|
}
|
|
|
|
}
|
2010-02-03 03:37:55 +00:00
|
|
|
#endif
|
|
|
|
InputPosRead&=0x1ff;
|
2009-02-20 13:29:39 +00:00
|
|
|
}
|
2009-10-04 08:47:43 +00:00
|
|
|
return retval;
|
2009-02-20 13:29:39 +00:00
|
|
|
}
|