diff --git a/Source/Core/Core/Src/HW/EXI_DeviceMic.cpp b/Source/Core/Core/Src/HW/EXI_DeviceMic.cpp index f0f8e18a57..6fc3674da2 100644 --- a/Source/Core/Core/Src/HW/EXI_DeviceMic.cpp +++ b/Source/Core/Core/Src/HW/EXI_DeviceMic.cpp @@ -23,17 +23,15 @@ #include "EXI_Device.h" #include "EXI_DeviceMic.h" - - bool MicButton; - bool IsOpen; -// Doing it this way since it's Linux only atm due to portaudio, even though the lib is crossplatform -// I had to include libs in the DolphinWX Sconscript file which I thought was BS. -// So I'm committing with all the code ifdeff'ed out -#if 1 -void SetMic(bool Value) -{} -bool GetMic() -{return false;} + +bool MicButton = false; +bool IsOpen; + +//#define USE_PORTAUDIO +#ifndef USE_PORTAUDIO + +void SetMic(bool Value){} + CEXIMic::CEXIMic(int _Index){} CEXIMic::~CEXIMic(){} bool CEXIMic::IsPresent() {return false;} @@ -41,79 +39,86 @@ void CEXIMic::SetCS(int cs){} void CEXIMic::Update(){} void CEXIMic::TransferByte(u8 &byte){} bool CEXIMic::IsInterruptSet(){return false;} + #else - +////////////////////////////////////////////////////////////////////////// +// We use PortAudio for cross-platform audio input. +// It needs the headers and a lib file for the dll #include -#include - unsigned char InputData[128*44100]; // Max Data is 128 samples at 44100 - PaStream *stream; - PaError err; - unsigned short SFreq; - unsigned short SNum; - unsigned int Sample; - bool m_bInterruptSet; - bool Sampling; +#ifdef _WIN32 +#pragma comment(lib, "C:/Users/Shawn/Desktop/portaudio/portaudio-v19/portaudio_x64.lib") +#endif + +unsigned char InputData[128*44100]; // Max Data is 128 samples at 44100 +PaStream *stream; +PaError err; +unsigned short SFreq; +unsigned short SNum; +unsigned int Sample; +bool m_bInterruptSet; +bool Sampling; void SetMic(bool Value) { - if(Value != MicButton) + MicButton = Value; + if(Sampling) { - MicButton = Value; - printf("Mic is set to %s\n", MicButton ? "true" : "false"); - if(Sampling) - { - if(MicButton) - Pa_StartStream( stream ); - else - Pa_StopStream( stream ); - } + if(MicButton) + Pa_StartStream( stream ); + else + Pa_StopStream( stream ); } } -bool GetMic() -{ - return MicButton; -} + static unsigned int k = 0; int patestCallback( const void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - const PaStreamCallbackTimeInfo* timeInfo, - PaStreamCallbackFlags statusFlags, - void *userData ) + unsigned long framesPerBuffer, + const PaStreamCallbackTimeInfo* timeInfo, + PaStreamCallbackFlags statusFlags, + void *userData ) { - unsigned char *data = (unsigned char*)inputBuffer; - unsigned int i; - - for( i=0; i %02x", byte); if (m_uPosition == 0) { - command = byte; // first byte is command - byte = 0xFF; // would be tristate, but we don't care. - - if(command == cmdClearStatus) - { - byte = 0xFF; - m_uPosition = 0; - m_bInterruptSet = false; - } + command = byte; // first byte is command + byte = 0xFF; // would be tristate, but we don't care. } else { @@ -176,111 +182,118 @@ void CEXIMic::TransferByte(u8 &byte) { case cmdID: if (m_uPosition == 1) - ;//byte = 0x80; // dummy cycle + ;//byte = 0x80; // dummy cycle - taken from memcard, it doesn't seem to need it here else - byte = (u8)(ID >> (24-(((m_uPosition-2) & 3) * 8))); - break; - // Setting Bits: REMEMBER THIS! D:< - // var |= (1 << bitnum_from_0) - // var &= ~(1 << bitnum_from_0) clears - case cmdStatus: - { - if(GetMic()) + byte = (u8)(EXI_DEVTYPE_MIC >> (24-(((m_uPosition-2) & 3) * 8))); + break; + case cmdGetStatus: { - Status.U16 |= (1 << 7); + if (m_uPosition != 1 && m_uPosition != 2) + LOGV(EXPANSIONINTERFACE, 0, "EXI MIC: WARNING GetStatus @ pos: %d should never happen", m_uPosition); + if((!Status.button && MicButton)||(Status.button && !MicButton)) + LOGV(EXPANSIONINTERFACE, 0, "EXI MIC: Mic button %s", MicButton ? "pressed" : "released"); + + Status.button = MicButton ? 1 : 0; + byte = Status.U8[ (m_uPosition - 1) ? 0 : 1]; } - else - { - Status.U16 &= ~(1 << 7); - } - byte = (u8)(Status.U16 >> (24-(((m_uPosition-2) & 3) * 8))); - - } - break; + break; case cmdSetStatus: - { - Status.U8[ (m_uPosition - 1) ? 0 : 1] = byte; - if(m_uPosition == 2) { - printf("Status is 0x%04x ", Status.U16); - //Status is 0x7273 1 1 0 0 1 1 1 0\ 0 1 0 0 1 1 1 0 - //Status is 0x4b00 - // 0 0 0 0 0 0 0 0 : Bit 0-7: Unknown - // 1 : Bit 8 : 1 : Button Pressed - // 1 : Bit 9 : 1 ? Overflow? - // 0 : Bit 10 : Unknown related to 0 and 15 values It seems - // 1 0 : Bit 11-12 : Sample Rate, 00-11025, 01-22050, 10-44100, 11-?? - // 0 1 : Bit 13-14 : Period Length, 00-32, 01-64, 10-128, 11-??? - // 0 : Bit 15 : If We Are Sampling or Not - - if((Status.U16 >> 15) & 1) // We ARE Sampling + // 0x80 0xXX 0xYY + // cmd pos1 pos2 + + // Here we assign the byte to the proper place in Status and update portaudio settings + Status.U8[ (m_uPosition - 1) ? 0 : 1] = byte; + + if(m_uPosition == 2) { - printf("We are now Sampling"); - Sampling = true; - } - else - { - Sampling = false; - // Only set to false once we have run out of Data? - //m_bInterruptSet = false; - } - if(!(Status.U16 >> 11) & 1) - if((Status.U16 >> 12) & 1 ) - SFreq = 22050; - else + Sampling = (Status.sampling == 1) ? true : false; + + switch (Status.sRate) + { + case 0: SFreq = 11025; - else - SFreq = 44100; - - if(!(Status.U16 >> 13) & 1) - if((Status.U16 >> 14) & 1) - SNum = 64; - else + break; + case 1: + SFreq = 22050; + break; + case 2: + SFreq = 44100; + break; + default: + LOGV(EXPANSIONINTERFACE, 0, "EXI MIC: Trying to set unknown sampling rate"); + SFreq = 44100; + break; + } + + switch (Status.pLength) + { + case 0: SNum = 32; - else - SNum = 128; - - for(int a = 0;a < 16;a++) - printf("%d ", (Status.U16 >> a) & 1); - printf("\n"); - if(!IsOpen) - { - // Open Our PortAudio Stream - err = Pa_OpenDefaultStream( &stream, - 1, - 0, - paUInt8 , - SFreq, - SNum, - patestCallback, - NULL); - if( err != paNoError ) - printf("error %s\n", Pa_GetErrorText (err)); - IsOpen = true; + break; + case 1: + SNum = 64; + break; + case 2: + SNum = 128; + break; + default: + LOGV(EXPANSIONINTERFACE, 0, "EXI MIC: Trying to set unknown period length"); + SNum = 128; + break; + } + + LOGV(EXPANSIONINTERFACE, 0, "//////////////////////////////////////////////////////////////////////////"); + LOGV(EXPANSIONINTERFACE, 0, "EXI MIC: Status is now 0x%04x", Status.U16); + LOGV(EXPANSIONINTERFACE, 0, "\tbutton %i\tsRate %i\tpLength %i\tsampling %i\n", + Status.button, Status.sRate, Status.pLength, Status.sampling); + + if(!IsOpen) + { + // Open Our PortAudio Stream + // (shuffle2) This (and the callback) are probably wrong, I can't test + err = Pa_OpenDefaultStream( &stream, + 1, // Input Channels + 0, // Output Channels + paInt16, // Output format - GC wants PCM samples in signed 16-bit format + SFreq, // Sample Rate + SNum, // Period Length (frames per buffer) + patestCallback,// Our callback! + NULL); // Pointer passed to our callback + if (err != paNoError) + { + LOGV(EXPANSIONINTERFACE, 0, "EXI MIC: PortAudio error %s", Pa_GetErrorText(err)); + } + else + IsOpen = true; + } } } - } - break; + break; case cmdGetBuffer: - static unsigned long At = 0; - printf("POS %d\n", m_uPosition); - // 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. - // Set to False here? Prevents lock ups maybe? - if(At >= SNum){ - At = 0; - k = 0; - m_bInterruptSet = false; + { + static unsigned long At = 0; + LOGV(EXPANSIONINTERFACE, 0, "EXI MIC: POS %d\n", m_uPosition); + // 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. + // (sonicadvance1) Set to False here? Prevents lock ups maybe? + // (shuffle2) It seems to play nice with interrupts for the most part. + if(At >= SNum){ + At = 0; + k = 0; + m_bInterruptSet = true; + } + byte = 0xAB;//InputData[At]; (shuffle2) just sending constant dummy data for now + At++; } - byte = InputData[At]; - At++; - break; + break; default: - printf("Don't know command %x in Byte transfer\n", command); - break; + LOGV(EXPANSIONINTERFACE, 0, "EXI MIC: unknown command byte %02x\n", command); + break; } } m_uPosition++; + LOGV(EXPANSIONINTERFACE, 1, "EXI MIC: < %02x", byte); } #endif diff --git a/Source/Core/Core/Src/HW/EXI_DeviceMic.h b/Source/Core/Core/Src/HW/EXI_DeviceMic.h index d35c43c63c..8996c86a6e 100644 --- a/Source/Core/Core/Src/HW/EXI_DeviceMic.h +++ b/Source/Core/Core/Src/HW/EXI_DeviceMic.h @@ -30,23 +30,18 @@ public: private: + enum + { + EXI_DEVTYPE_MIC = 0x0A000000 + }; + enum { - cmdID = 0x00, - cmdStatus = 0x40, - cmdSetStatus = 0x80, - cmdGetBuffer = 0x20, - cmdWriteBuffer = 0x82, - cmdReadStatus = 0x83, - cmdReadID = 0x85, - cmdReadErrorBuffer = 0x86, - cmdWakeUp = 0x87, - cmdSleep = 0x88, - cmdClearStatus = 0x89, - cmdSectorErase = 0xF1, - cmdPageProgram = 0xF2, - cmdExtraByteProgram = 0xF3, - cmdChipErase = 0xF4, + cmdID = 0x00, + cmdGetStatus = 0x40, + cmdSetStatus = 0x80, + cmdGetBuffer = 0x20, + cmdWakeUp = 0xFF, }; // STATE_TO_SAVE @@ -56,22 +51,25 @@ private: { u16 U16; u8 U8[2]; + struct + { + unsigned :8; // Unknown + unsigned button :1; // 1: Button Pressed + unsigned unk1 :1; // 1 ? Overflow? + unsigned unk2 :1; // Unknown related to 0 and 15 values It seems + unsigned sRate :2; // Sample Rate, 00-11025, 01-22050, 10-44100, 11-?? + unsigned pLength :2; // Period Length, 00-32, 01-64, 10-128, 11-??? + unsigned sampling :1; // If We Are Sampling or Not + }; }; int Index; u32 m_uPosition; - u32 formatDelay; - uStatus Status; - - //! memory card parameters - unsigned int ID; - unsigned int address; + uStatus Status; protected: virtual void TransferByte(u8 &byte); }; void SetMic(bool Value); -bool GetMic(); #endif - diff --git a/Source/Plugins/Plugin_PadSimple/Plugin_PadSimple.vcproj b/Source/Plugins/Plugin_PadSimple/Plugin_PadSimple.vcproj index 8e3e8453ef..3bf74a252b 100644 --- a/Source/Plugins/Plugin_PadSimple/Plugin_PadSimple.vcproj +++ b/Source/Plugins/Plugin_PadSimple/Plugin_PadSimple.vcproj @@ -590,6 +590,7 @@ LinkIncremental="1" SuppressStartupBanner="true" GenerateManifest="false" + GenerateDebugInformation="true" ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb" RandomizedBaseAddress="1" DataExecutionPrevention="0" diff --git a/Source/Plugins/Plugin_PadSimple/Src/PadSimple.cpp b/Source/Plugins/Plugin_PadSimple/Src/PadSimple.cpp index ffdbb23ad3..c54c62260b 100644 --- a/Source/Plugins/Plugin_PadSimple/Src/PadSimple.cpp +++ b/Source/Plugins/Plugin_PadSimple/Src/PadSimple.cpp @@ -334,6 +334,8 @@ void DInput_Read(int _numPAD, SPADStatus* _pPADStatus) if (dinput.diks[pad[_numPAD].keyForControl[CTL_DPADLEFT]] & 0xFF){_pPADStatus->button |= PAD_BUTTON_LEFT;} if (dinput.diks[pad[_numPAD].keyForControl[CTL_DPADRIGHT]]& 0xFF){_pPADStatus->button |= PAD_BUTTON_RIGHT;} if (dinput.diks[pad[_numPAD].keyForControl[CTL_START]] & 0xFF){_pPADStatus->button |= PAD_BUTTON_START;} + + _pPADStatus->MicButton = (dinput.diks[pad[_numPAD].keyForControl[CTL_MIC]] & 0xFF) ? true : false; } bool XInput_Read(int XPadPlayer, SPADStatus* _pPADStatus) @@ -381,6 +383,8 @@ bool XInput_Read(int XPadPlayer, SPADStatus* _pPADStatus) if (xpad.wButtons & XINPUT_GAMEPAD_DPAD_UP) {_pPADStatus->button |= PAD_BUTTON_UP;} if (xpad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) {_pPADStatus->button |= PAD_BUTTON_DOWN;} + //_pPADStatus->MicButton = (xpad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) ? true : false; + return true; } else @@ -742,7 +746,8 @@ void LoadConfig() DIK_G, DIK_F, DIK_H, - DIK_LSHIFT + DIK_LSHIFT, //halfpress + DIK_M //Mic }; #elif defined(HAVE_X11) && HAVE_X11 const int defaultKeyForControl[NUMCONTROLS] = @@ -768,7 +773,7 @@ void LoadConfig() XK_f, XK_h, XK_Shift_L, //halfpress - XK_p + XK_p //Mic }; #elif defined(HAVE_COCOA) && HAVE_COCOA const int defaultKeyForControl[NUMCONTROLS] = @@ -794,7 +799,7 @@ void LoadConfig() 3, 4, 56, //halfpress - 35 + 35 //Mic }; #endif IniFile file;