more mic WIP. Seems to at least give correct volume levels to odama, it might even work.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2178 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
0868770d24
commit
c4c8bde34d
|
@ -50,12 +50,17 @@ bool CEXIMic::IsInterruptSet(){return false;}
|
||||||
#pragma comment(lib, "C:/Users/Shawn/Desktop/portaudio/portaudio-v19/portaudio_x64.lib")
|
#pragma comment(lib, "C:/Users/Shawn/Desktop/portaudio/portaudio-v19/portaudio_x64.lib")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
unsigned char InputData[128*44100]; // Max Data is 128 samples at 44100
|
union InputData
|
||||||
|
{
|
||||||
|
s16 word;
|
||||||
|
u8 byte[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
InputData inputData[64]; // 64 words = Max 128 bytes returned????
|
||||||
PaStream *stream;
|
PaStream *stream;
|
||||||
PaError err;
|
PaError err;
|
||||||
unsigned short SFreq;
|
unsigned short SFreq;
|
||||||
unsigned short SNum;
|
unsigned short SNum;
|
||||||
unsigned int Sample;
|
|
||||||
bool m_bInterruptSet;
|
bool m_bInterruptSet;
|
||||||
bool Sampling;
|
bool Sampling;
|
||||||
|
|
||||||
|
@ -64,30 +69,30 @@ void SetMic(bool Value)
|
||||||
{
|
{
|
||||||
MicButton = Value;
|
MicButton = Value;
|
||||||
if(Sampling)
|
if(Sampling)
|
||||||
{
|
Pa_StartStream( stream );
|
||||||
if(MicButton)
|
else
|
||||||
Pa_StartStream( stream );
|
Pa_StopStream( stream );
|
||||||
else
|
|
||||||
Pa_StopStream( stream );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int k = 0;
|
|
||||||
int patestCallback( const void *inputBuffer, void *outputBuffer,
|
int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||||
unsigned long framesPerBuffer,
|
unsigned long frameCount,
|
||||||
const PaStreamCallbackTimeInfo* timeInfo,
|
const PaStreamCallbackTimeInfo* timeInfo,
|
||||||
PaStreamCallbackFlags statusFlags,
|
PaStreamCallbackFlags statusFlags,
|
||||||
void *userData )
|
void *userData )
|
||||||
{
|
{
|
||||||
unsigned char *data = (unsigned char*)inputBuffer;
|
s16 *data = (s16*)inputBuffer;
|
||||||
unsigned int i;
|
//s16 *out = (s16*)outputBuffer;
|
||||||
|
|
||||||
for( i=0; i<framesPerBuffer && k < (SFreq*SNum); i++, k++ )
|
if (!m_bInterruptSet && Sampling)
|
||||||
{
|
{
|
||||||
InputData[k] = data[i];
|
for(unsigned int i = 0; i < SNum; ++i)
|
||||||
|
{
|
||||||
|
inputData[i].word = data[i];
|
||||||
|
//out[i] = inputData[i].word;
|
||||||
|
}
|
||||||
|
m_bInterruptSet = true;
|
||||||
}
|
}
|
||||||
m_bInterruptSet = true;
|
return paContinue;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -97,9 +102,9 @@ CEXIMic::CEXIMic(int _Index)
|
||||||
{
|
{
|
||||||
Index = _Index;
|
Index = _Index;
|
||||||
|
|
||||||
|
memset(&inputData, 0 , sizeof(inputData));
|
||||||
memset(&Status.U16, 0 , sizeof(u16));
|
memset(&Status.U16, 0 , sizeof(u16));
|
||||||
command = 0;
|
command = 0;
|
||||||
Sample = 0;
|
|
||||||
m_uPosition = 0;
|
m_uPosition = 0;
|
||||||
m_bInterruptSet = false;
|
m_bInterruptSet = false;
|
||||||
MicButton = false;
|
MicButton = false;
|
||||||
|
@ -107,10 +112,8 @@ CEXIMic::CEXIMic(int _Index)
|
||||||
err = Pa_Initialize();
|
err = Pa_Initialize();
|
||||||
if (err != paNoError)
|
if (err != paNoError)
|
||||||
LOGV(EXPANSIONINTERFACE, 0, "EXI MIC: PortAudio Initialize error %s", Pa_GetErrorText(err));
|
LOGV(EXPANSIONINTERFACE, 0, "EXI MIC: PortAudio Initialize error %s", Pa_GetErrorText(err));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CEXIMic::~CEXIMic()
|
CEXIMic::~CEXIMic()
|
||||||
{
|
{
|
||||||
err = Pa_CloseStream( stream );
|
err = Pa_CloseStream( stream );
|
||||||
|
@ -128,20 +131,21 @@ bool CEXIMic::IsPresent()
|
||||||
|
|
||||||
void CEXIMic::SetCS(int cs)
|
void CEXIMic::SetCS(int cs)
|
||||||
{
|
{
|
||||||
if (cs) // not-selected to selected
|
if (cs) // not-selected to selected
|
||||||
{
|
|
||||||
m_uPosition = 0;
|
m_uPosition = 0;
|
||||||
m_bInterruptSet = false;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (command)
|
switch (command)
|
||||||
{
|
{
|
||||||
|
case cmdID:
|
||||||
|
case cmdGetStatus:
|
||||||
|
case cmdSetStatus:
|
||||||
|
case cmdGetBuffer:
|
||||||
|
break;
|
||||||
case cmdWakeUp:
|
case cmdWakeUp:
|
||||||
// This is probably not a command, but anyway...
|
// This is probably not a command, but anyway...
|
||||||
// The command 0xff seems to be used to get in sync with the microphone or to wake it up.
|
// The command 0xff seems to be used to get in sync with the microphone or to wake it up.
|
||||||
// Normally, it is issued before any other command, or to recover from errors.
|
// Normally, it is issued before any other command, or to recover from errors.
|
||||||
// (shuffle2) Perhaps we should just clear the buffer and effectively "reset" here?
|
|
||||||
LOGV(EXPANSIONINTERFACE, 1, "EXI MIC: WakeUp cmd");
|
LOGV(EXPANSIONINTERFACE, 1, "EXI MIC: WakeUp cmd");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -170,7 +174,6 @@ bool CEXIMic::IsInterruptSet()
|
||||||
|
|
||||||
void CEXIMic::TransferByte(u8 &byte)
|
void CEXIMic::TransferByte(u8 &byte)
|
||||||
{
|
{
|
||||||
LOGV(EXPANSIONINTERFACE, 1, "EXI MIC: > %02x", byte);
|
|
||||||
if (m_uPosition == 0)
|
if (m_uPosition == 0)
|
||||||
{
|
{
|
||||||
command = byte; // first byte is command
|
command = byte; // first byte is command
|
||||||
|
@ -195,6 +198,7 @@ void CEXIMic::TransferByte(u8 &byte)
|
||||||
|
|
||||||
Status.button = MicButton ? 1 : 0;
|
Status.button = MicButton ? 1 : 0;
|
||||||
byte = Status.U8[ (m_uPosition - 1) ? 0 : 1];
|
byte = Status.U8[ (m_uPosition - 1) ? 0 : 1];
|
||||||
|
LOGV(EXPANSIONINTERFACE, 1, "EXI MIC: Status is 0x%04x", Status.U16);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case cmdSetStatus:
|
case cmdSetStatus:
|
||||||
|
@ -246,13 +250,14 @@ void CEXIMic::TransferByte(u8 &byte)
|
||||||
LOGV(EXPANSIONINTERFACE, 0, "//////////////////////////////////////////////////////////////////////////");
|
LOGV(EXPANSIONINTERFACE, 0, "//////////////////////////////////////////////////////////////////////////");
|
||||||
LOGV(EXPANSIONINTERFACE, 0, "EXI MIC: Status is now 0x%04x", Status.U16);
|
LOGV(EXPANSIONINTERFACE, 0, "EXI MIC: Status is now 0x%04x", Status.U16);
|
||||||
LOGV(EXPANSIONINTERFACE, 0, "\tbutton %i\tsRate %i\tpLength %i\tsampling %i\n",
|
LOGV(EXPANSIONINTERFACE, 0, "\tbutton %i\tsRate %i\tpLength %i\tsampling %i\n",
|
||||||
Status.button, Status.sRate, Status.pLength, Status.sampling);
|
Status.button, SFreq, SNum, Status.sampling);
|
||||||
|
|
||||||
if(!IsOpen)
|
if(!IsOpen)
|
||||||
{
|
{
|
||||||
// Open Our PortAudio Stream
|
// Open Our PortAudio Stream
|
||||||
// (shuffle2) This (and the callback) are probably wrong, I can't test
|
// (shuffle2) This (and the callback) could still be wrong
|
||||||
err = Pa_OpenDefaultStream( &stream,
|
err = Pa_OpenDefaultStream(
|
||||||
|
&stream, // Our PaStream
|
||||||
1, // Input Channels
|
1, // Input Channels
|
||||||
0, // Output Channels
|
0, // Output Channels
|
||||||
paInt16, // Output format - GC wants PCM samples in signed 16-bit format
|
paInt16, // Output format - GC wants PCM samples in signed 16-bit format
|
||||||
|
@ -272,20 +277,14 @@ void CEXIMic::TransferByte(u8 &byte)
|
||||||
break;
|
break;
|
||||||
case cmdGetBuffer:
|
case cmdGetBuffer:
|
||||||
{
|
{
|
||||||
static unsigned long At = 0;
|
int pos = m_uPosition - 1;
|
||||||
LOGV(EXPANSIONINTERFACE, 0, "EXI MIC: POS %d\n", m_uPosition);
|
// (sonicadvance1)I think if we set the Interrupt to false, it reads another 64
|
||||||
// Are we not able to return all the data then?
|
|
||||||
// I think if we set the Interrupt to false, it reads another 64
|
|
||||||
// Will Look in to it.
|
// Will Look in to it.
|
||||||
// (sonicadvance1) Set to False here? Prevents lock ups maybe?
|
// (shuffle2)Seems like games just continuously get the buffer as long as
|
||||||
// (shuffle2) It seems to play nice with interrupts for the most part.
|
// they're sampling and the mic is generating interrupts
|
||||||
if(At >= SNum){
|
byte = inputData[pos].byte[ (pos & 1) ? 0 : 1 ];
|
||||||
At = 0;
|
LOGV(EXPANSIONINTERFACE, 1, "EXI MIC: GetBuffer%s%d/%d byte: 0x%02x",
|
||||||
k = 0;
|
(pos > 9) ? " " : " ", pos, SNum, byte);
|
||||||
m_bInterruptSet = true;
|
|
||||||
}
|
|
||||||
byte = 0xAB;//InputData[At]; (shuffle2) just sending constant dummy data for now
|
|
||||||
At++;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -294,6 +293,5 @@ void CEXIMic::TransferByte(u8 &byte)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_uPosition++;
|
m_uPosition++;
|
||||||
LOGV(EXPANSIONINTERFACE, 1, "EXI MIC: < %02x", byte);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -38,7 +38,7 @@ private:
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
cmdID = 0x00,
|
cmdID = 0x00,
|
||||||
cmdGetStatus = 0x40,
|
cmdGetStatus = 0x40,
|
||||||
cmdSetStatus = 0x80,
|
cmdSetStatus = 0x80,
|
||||||
cmdGetBuffer = 0x20,
|
cmdGetBuffer = 0x20,
|
||||||
cmdWakeUp = 0xFF,
|
cmdWakeUp = 0xFF,
|
||||||
|
|
Loading…
Reference in New Issue