SPU2-X: Experimental PortAudio module. No config dialogs. Will use the system default output device & whatever the default "api" is in portaudio. Requires user-compiled portaudio lib, might commit later.

Widnows users probably don't have any interest in this unless you want to play the audio through portaudio's ASIO driver. Arcum was interested so I commited.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2439 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gigaherz 2010-01-16 17:59:00 +00:00
parent 03e29f3f71
commit ce396272d1
9 changed files with 225 additions and 15 deletions

View File

@ -205,7 +205,7 @@ public:
return 0;
}
int GetEmptySampleCount() const
int GetEmptySampleCount()
{
if(handle == NULL) return 0;
@ -234,4 +234,4 @@ public:
}
} static Alsa;
SndOutModule *AlsaOut = &Alsa;
SndOutModule *AlsaOut = &Alsa;

View File

@ -67,6 +67,13 @@ struct StereoOut32
{
return StereoOut32( Left / src, Right / src );
}
void ResampleFrom( const StereoOut32& src )
{
this->Left = src.Left << 2;
this->Right = src.Right << 2;
}
};

View File

@ -58,7 +58,7 @@ public:
s32 Test() const { return 0; }
void Configure(uptr parent) { }
bool Is51Out() const { return false; }
int GetEmptySampleCount() const { return 0; }
int GetEmptySampleCount() { return 0; }
const wchar_t* GetIdent() const
{
@ -88,6 +88,7 @@ SndOutModule* mods[]=
DSoundOut,
WaveOut,
#endif
PortaudioOut,
NULL // signals the end of our list
};

View File

@ -476,7 +476,7 @@ public:
// Returns the number of empty samples in the output buffer.
// (which is effectively the amount of data played since the last update)
virtual int GetEmptySampleCount() const=0;
virtual int GetEmptySampleCount() =0;
};
@ -486,6 +486,7 @@ extern SndOutModule* WaveOut;
extern SndOutModule* DSoundOut;
extern SndOutModule* XAudio2Out;
#endif
extern SndOutModule* PortaudioOut;
extern SndOutModule* mods[];

View File

@ -0,0 +1,187 @@
/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
* 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/>.
*/
#include "Global.h"
#define _WIN32_DCOM
#include "Dialogs.h"
#include "portaudio/include/portaudio.h"
class Portaudio : public SndOutModule
{
private:
static const uint MAX_BUFFER_COUNT = 8;
static const int PacketsPerBuffer = 1;
static const int BufferSize = SndOutPacketSize * PacketsPerBuffer;
//////////////////////////////////////////////////////////////////////////////////////////
// Configuration Vars (unused still)
wstring m_Api;
wstring m_Device;
bool m_UseHardware;
//////////////////////////////////////////////////////////////////////////////////////////
// Instance vars
int writtenSoFar;
int writtenLastTime;
int availableLastTime;
bool started;
PaStream* stream;
static int PaCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
return PA.ActualPaCallback(inputBuffer,outputBuffer,framesPerBuffer,timeInfo,statusFlags,userData);
}
int ActualPaCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
StereoOut32* p1 = (StereoOut32*)outputBuffer;
int packets = framesPerBuffer / SndOutPacketSize;
for(int p=0; p<packets; p++, p1+=SndOutPacketSize )
SndBuffer::ReadSamples( p1 );
writtenSoFar += packets * SndOutPacketSize;
return 0;
}
public:
s32 Init()
{
started=false;
stream=NULL;
PaError err = Pa_Initialize();
if( err != paNoError )
{
fprintf(stderr," * SPU2: PortAudio error: %s\n", Pa_GetErrorText( err ) );
return -1;
}
started=true;
err = Pa_OpenDefaultStream( &stream,
0, 2, paInt32, 48000,
SndOutPacketSize,
PaCallback, NULL );
if( err != paNoError )
{
fprintf(stderr," * SPU2: PortAudio error: %s\n", Pa_GetErrorText( err ) );
Pa_Terminate();
return -1;
}
err = Pa_StartStream( stream );
if( err != paNoError )
{
fprintf(stderr," * SPU2: PortAudio error: %s\n", Pa_GetErrorText( err ) );
Pa_CloseStream(stream);
stream=NULL;
Pa_Terminate();
return -1;
}
return 0;
}
void Close()
{
PaError err;
if(started)
{
if(stream)
{
if(Pa_IsStreamActive(stream))
{
err = Pa_StopStream(stream);
if( err != paNoError )
fprintf(stderr," * SPU2: PortAudio error: %s\n", Pa_GetErrorText( err ) );
}
err = Pa_CloseStream(stream);
if( err != paNoError )
fprintf(stderr," * SPU2: PortAudio error: %s\n", Pa_GetErrorText( err ) );
stream=NULL;
}
PaError err = Pa_Terminate();
if( err != paNoError )
fprintf(stderr," * SPU2: PortAudio error: %s\n", Pa_GetErrorText( err ) );
started=false;
}
}
virtual void Configure(uptr parent)
{
}
virtual bool Is51Out() const { return false; }
s32 Test() const
{
return 0;
}
int GetEmptySampleCount()
{
long availableNow = Pa_GetStreamWriteAvailable(stream);
int playedSinceLastTime = (writtenSoFar - writtenLastTime) + (availableNow - availableLastTime);
writtenLastTime = writtenSoFar;
availableLastTime = availableNow;
return playedSinceLastTime;
}
const wchar_t* GetIdent() const
{
return L"portaudio";
}
const wchar_t* GetLongName() const
{
return L"Portaudio (crossplatform)";
}
void ReadSettings()
{
}
void WriteSettings() const
{
}
} static PA;
SndOutModule *PortaudioOut = &PA;

View File

@ -429,7 +429,7 @@ public:
return 0;
}
int GetEmptySampleCount() const
int GetEmptySampleCount()
{
DWORD play, write;
buffer->GetCurrentPosition( &play, &write );

View File

@ -85,7 +85,7 @@ private:
CRITICAL_SECTION cs;
public:
int GetEmptySampleCount() const
int GetEmptySampleCount()
{
XAUDIO2_VOICE_STATE state;
pSourceVoice->GetState( &state );
@ -364,7 +364,7 @@ public:
return 0;
}
int GetEmptySampleCount() const
int GetEmptySampleCount()
{
if( voiceContext == NULL ) return 0;
return voiceContext->GetEmptySampleCount();

View File

@ -292,7 +292,7 @@ public:
return 0;
}
int GetEmptySampleCount() const
int GetEmptySampleCount()
{
int result = 0;
for(int i=0;i<MAX_BUFFER_COUNT;i++)

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Version="9,00"
Name="SPU2-X"
ProjectGUID="{5307BBB7-EBB9-4AA4-8CB6-A94EC473C8C4}"
RootNamespace="spu2x"
@ -48,7 +48,7 @@
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
AdditionalIncludeDirectories="$(SolutionDir)\3rdparty\portaudio\include\portaudio\include\"
PreprocessorDefinitions="FLOAT_SAMPLES;NDEBUG;_USRDLL"
ExceptionHandling="2"
EnableEnhancedInstructionSet="2"
@ -70,8 +70,9 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="rpcrt4.lib winmm.lib dsound.lib comctl32.lib soundtouch.lib x86emitter.lib utilities.lib"
AdditionalDependencies="rpcrt4.lib winmm.lib dsound.lib comctl32.lib soundtouch.lib x86emitter.lib utilities.lib portaudio_x86.lib"
OutputFile="$(OutDir)\$(ProjectName)-dev.dll"
AdditionalLibraryDirectories="$(SolutionDir)\3rdparty\portaudio"
ModuleDefinitionFile=".\Spu2-X.def"
RandomizedBaseAddress="1"
TargetMachine="1"
@ -132,6 +133,7 @@
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="$(SolutionDir)\3rdparty\portaudio\include\portaudio\include\"
PreprocessorDefinitions="FLOAT_SAMPLES;_USRDLL"
ExceptionHandling="2"
UsePrecompiledHeader="2"
@ -150,8 +152,9 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="rpcrt4.lib winmm.lib dsound.lib comctl32.lib soundtouch.lib x86emitter.lib utilities.lib"
AdditionalDependencies="rpcrt4.lib winmm.lib dsound.lib comctl32.lib soundtouch.lib x86emitter.lib utilities.lib portaudio_x86.lib"
OutputFile="$(OutDir)\$(ProjectName)-dbg.dll"
AdditionalLibraryDirectories="$(SolutionDir)\3rdparty\portaudio"
ModuleDefinitionFile=".\Spu2-X.def"
RandomizedBaseAddress="1"
SupportUnloadOfDelayLoadedDLL="false"
@ -212,6 +215,7 @@
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="$(SolutionDir)\3rdparty\portaudio\include\portaudio\include\"
PreprocessorDefinitions="FLOAT_SAMPLES;NDEBUG;_USRDLL"
ExceptionHandling="2"
EnableEnhancedInstructionSet="2"
@ -233,9 +237,10 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="rpcrt4.lib winmm.lib dsound.lib comctl32.lib soundtouch.lib x86emitter.lib utilities.lib"
AdditionalDependencies="rpcrt4.lib winmm.lib dsound.lib comctl32.lib soundtouch.lib x86emitter.lib utilities.lib portaudio_x86.lib"
OutputFile="$(OutDir)\$(ProjectName).dll"
LinkIncremental="1"
AdditionalLibraryDirectories="$(SolutionDir)\3rdparty\portaudio"
ModuleDefinitionFile=".\Spu2-X.def"
ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb"
StripPrivateSymbols=""
@ -298,7 +303,7 @@
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
AdditionalIncludeDirectories="$(SolutionDir)\3rdparty\portaudio\include\portaudio\include\"
PreprocessorDefinitions="wxUSE_GUI=0;FLOAT_SAMPLES;DEBUG_FAST;_USRDLL"
ExceptionHandling="2"
UsePrecompiledHeader="2"
@ -318,9 +323,10 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="rpcrt4.lib winmm.lib dsound.lib comctl32.lib soundtouch.lib x86emitter.lib utilities.lib"
AdditionalDependencies="rpcrt4.lib winmm.lib dsound.lib comctl32.lib soundtouch.lib x86emitter.lib utilities.lib portaudio_x86.lib"
OutputFile="$(OutDir)\$(ProjectName)-dbg.dll"
LinkIncremental="2"
AdditionalLibraryDirectories="$(SolutionDir)\3rdparty\portaudio"
ModuleDefinitionFile=".\Spu2-X.def"
RandomizedBaseAddress="1"
SupportUnloadOfDelayLoadedDLL="false"
@ -702,6 +708,14 @@
>
</File>
</Filter>
<Filter
Name="Crossplatform"
>
<File
RelativePath="..\SndOut_Portaudio.cpp"
>
</File>
</Filter>
</Filter>
<Filter
Name="decoder"