mirror of https://github.com/probonopd/MiniDexed
Move RPi code from Synth_Dexed to MiniDexed, thanks @rsta2
Move the Raspberry Pi specific code from the classes AudioSynthDexed* from the Synth_Dexed project to the MiniDexed project https://github.com/probonopd/MiniDexed/issues/8#issuecomment-1048590076pull/29/head
parent
1648a06612
commit
08be352d24
@ -1 +1 @@ |
|||||||
Subproject commit cdaf1f6cdeb38e9f5cfb6f2d8bb93d7933153ab6 |
Subproject commit 86dba9826c21295e72a8a38b17e1f2c001579310 |
@ -0,0 +1,232 @@ |
|||||||
|
//
|
||||||
|
// minidexed.cpp
|
||||||
|
//
|
||||||
|
#include "minidexed.h" |
||||||
|
#include <circle/devicenameservice.h> |
||||||
|
|
||||||
|
#define MIDI_NOTE_OFF 0b1000 |
||||||
|
#define MIDI_NOTE_ON 0b1001 |
||||||
|
|
||||||
|
CMiniDexed *CMiniDexed::s_pThis = 0; |
||||||
|
|
||||||
|
bool CMiniDexed::Initialize (void) |
||||||
|
{ |
||||||
|
if (!m_Serial.Initialize(31250)) |
||||||
|
{ |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
m_bUseSerial = true; |
||||||
|
|
||||||
|
activate(); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
void CMiniDexed::Process(boolean bPlugAndPlayUpdated) |
||||||
|
{ |
||||||
|
if (m_pMIDIDevice != 0) |
||||||
|
{ |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (bPlugAndPlayUpdated) |
||||||
|
{ |
||||||
|
m_pMIDIDevice = |
||||||
|
(CUSBMIDIDevice *) CDeviceNameService::Get ()->GetDevice ("umidi1", FALSE); |
||||||
|
if (m_pMIDIDevice != 0) |
||||||
|
{ |
||||||
|
m_pMIDIDevice->RegisterRemovedHandler (USBDeviceRemovedHandler); |
||||||
|
m_pMIDIDevice->RegisterPacketHandler (MIDIPacketHandler); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
m_PCKeyboard.Process (bPlugAndPlayUpdated); |
||||||
|
|
||||||
|
if (!m_bUseSerial) |
||||||
|
{ |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
// Read serial MIDI data
|
||||||
|
u8 Buffer[20]; |
||||||
|
int nResult = m_Serial.Read (Buffer, sizeof Buffer); |
||||||
|
if (nResult <= 0) |
||||||
|
{ |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
// Process MIDI messages
|
||||||
|
// See: https://www.midi.org/specifications/item/table-1-summary-of-midi-message
|
||||||
|
for (int i = 0; i < nResult; i++) |
||||||
|
{ |
||||||
|
u8 uchData = Buffer[i]; |
||||||
|
|
||||||
|
switch (m_nSerialState) |
||||||
|
{ |
||||||
|
case 0: |
||||||
|
MIDIRestart: |
||||||
|
if ((uchData & 0xE0) == 0x80) // Note on or off, all channels
|
||||||
|
{ |
||||||
|
m_SerialMessage[m_nSerialState++] = uchData; |
||||||
|
} |
||||||
|
break; |
||||||
|
|
||||||
|
case 1: |
||||||
|
case 2: |
||||||
|
if (uchData & 0x80) // got status when parameter expected
|
||||||
|
{ |
||||||
|
m_nSerialState = 0; |
||||||
|
|
||||||
|
goto MIDIRestart; |
||||||
|
} |
||||||
|
|
||||||
|
m_SerialMessage[m_nSerialState++] = uchData; |
||||||
|
|
||||||
|
if (m_nSerialState == 3) // message is complete
|
||||||
|
{ |
||||||
|
MIDIPacketHandler (0, m_SerialMessage, sizeof m_SerialMessage); |
||||||
|
|
||||||
|
m_nSerialState = 0; |
||||||
|
} |
||||||
|
break; |
||||||
|
|
||||||
|
default: |
||||||
|
assert (0); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void CMiniDexed::MIDIPacketHandler (unsigned nCable, u8 *pPacket, unsigned nLength) |
||||||
|
{ |
||||||
|
assert (s_pThis != 0); |
||||||
|
|
||||||
|
// The packet contents are just normal MIDI data - see
|
||||||
|
// https://www.midi.org/specifications/item/table-1-summary-of-midi-message
|
||||||
|
|
||||||
|
if (nLength < 3) |
||||||
|
{ |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
u8 ucStatus = pPacket[0]; |
||||||
|
//u8 ucChannel = ucStatus & 0x0F;
|
||||||
|
u8 ucType = ucStatus >> 4; |
||||||
|
u8 ucKeyNumber = pPacket[1]; |
||||||
|
u8 ucVelocity = pPacket[2]; |
||||||
|
|
||||||
|
if (ucType == MIDI_NOTE_ON) |
||||||
|
{ |
||||||
|
s_pThis->keydown(ucKeyNumber,ucVelocity); |
||||||
|
} |
||||||
|
else if (ucType == MIDI_NOTE_OFF) |
||||||
|
{ |
||||||
|
s_pThis->keyup(ucKeyNumber); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void CMiniDexed::USBDeviceRemovedHandler (CDevice *pDevice, void *pContext) |
||||||
|
{ |
||||||
|
if (s_pThis->m_pMIDIDevice == (CUSBMIDIDevice *) pDevice) |
||||||
|
{ |
||||||
|
s_pThis->m_pMIDIDevice = 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
bool CMiniDexedPWM::Initialize (void) |
||||||
|
{ |
||||||
|
if (!CMiniDexed::Initialize()) |
||||||
|
{ |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
return Start (); |
||||||
|
} |
||||||
|
|
||||||
|
unsigned CMiniDexedPWM::GetChunk(u32 *pBuffer, unsigned nChunkSize) |
||||||
|
{ |
||||||
|
unsigned nResult = nChunkSize; |
||||||
|
|
||||||
|
int16_t int16_buf[nChunkSize/2]; |
||||||
|
|
||||||
|
getSamples(nChunkSize/2, int16_buf); |
||||||
|
|
||||||
|
for (unsigned i = 0; nChunkSize > 0; nChunkSize -= 2) // fill the whole buffer
|
||||||
|
{ |
||||||
|
s32 nSample = int16_buf[i++]; |
||||||
|
nSample += 32768; |
||||||
|
nSample *= GetRangeMax()/2; |
||||||
|
nSample /= 32768; |
||||||
|
|
||||||
|
*pBuffer++ = nSample; // 2 stereo channels
|
||||||
|
*pBuffer++ = nSample; |
||||||
|
} |
||||||
|
return(nResult); |
||||||
|
}; |
||||||
|
|
||||||
|
bool CMiniDexedI2S::Initialize (void) |
||||||
|
{ |
||||||
|
if (!CMiniDexed::Initialize()) |
||||||
|
{ |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
return Start (); |
||||||
|
} |
||||||
|
|
||||||
|
unsigned CMiniDexedI2S::GetChunk(u32 *pBuffer, unsigned nChunkSize) |
||||||
|
{ |
||||||
|
unsigned nResult = nChunkSize; |
||||||
|
|
||||||
|
int16_t int16_buf[nChunkSize/2]; |
||||||
|
|
||||||
|
getSamples(nChunkSize/2, int16_buf); |
||||||
|
|
||||||
|
for (unsigned i = 0; nChunkSize > 0; nChunkSize -= 2) // fill the whole buffer
|
||||||
|
{ |
||||||
|
s32 nSample = int16_buf[i++]; |
||||||
|
nSample <<= 8; |
||||||
|
|
||||||
|
*pBuffer++ = nSample; // 2 stereo channels
|
||||||
|
*pBuffer++ = nSample; |
||||||
|
} |
||||||
|
return(nResult); |
||||||
|
}; |
||||||
|
|
||||||
|
bool CMiniDexedHDMI::Initialize (void) |
||||||
|
{ |
||||||
|
if (!CMiniDexed::Initialize()) |
||||||
|
{ |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
return Start (); |
||||||
|
} |
||||||
|
|
||||||
|
unsigned CMiniDexedHDMI::GetChunk(u32 *pBuffer, unsigned nChunkSize) |
||||||
|
{ |
||||||
|
unsigned nResult = nChunkSize; |
||||||
|
|
||||||
|
int16_t int16_buf[nChunkSize/2]; |
||||||
|
unsigned nFrame = 0; |
||||||
|
|
||||||
|
getSamples(nChunkSize/2, int16_buf); |
||||||
|
|
||||||
|
for (unsigned i = 0; nChunkSize > 0; nChunkSize -= 2) // fill the whole buffer
|
||||||
|
{ |
||||||
|
s32 nSample = int16_buf[i++]; |
||||||
|
nSample <<= 8; |
||||||
|
|
||||||
|
nSample = ConvertIEC958Sample (nSample, nFrame); |
||||||
|
|
||||||
|
if (++nFrame == IEC958_FRAMES_PER_BLOCK) |
||||||
|
nFrame = 0; |
||||||
|
|
||||||
|
*pBuffer++ = nSample; // 2 stereo channels
|
||||||
|
*pBuffer++ = nSample; |
||||||
|
} |
||||||
|
return(nResult); |
||||||
|
}; |
@ -0,0 +1,97 @@ |
|||||||
|
//
|
||||||
|
// minidexed.h
|
||||||
|
//
|
||||||
|
#ifndef _minidexed_h |
||||||
|
#define _minidexed_h |
||||||
|
|
||||||
|
#include <synth_dexed.h> |
||||||
|
#include <stdint.h> |
||||||
|
#include <math.h> |
||||||
|
#include <circle/interrupt.h> |
||||||
|
#include <circle/i2cmaster.h> |
||||||
|
#include <circle/usb/usbmidi.h> |
||||||
|
#include <circle/serial.h> |
||||||
|
#include <circle/types.h> |
||||||
|
#include <circle/pwmsoundbasedevice.h> |
||||||
|
#include <circle/i2ssoundbasedevice.h> |
||||||
|
#include <circle/hdmisoundbasedevice.h> |
||||||
|
#include "pckeyboard.h" |
||||||
|
|
||||||
|
#define SAMPLE_RATE 48000 |
||||||
|
|
||||||
|
#define CHUNK_SIZE 2048 |
||||||
|
#define CHUNK_SIZE_HDMI (384 * 10) |
||||||
|
|
||||||
|
#define DAC_I2C_ADDRESS 0 // I2C slave address of the DAC (0 for auto probing)
|
||||||
|
|
||||||
|
class CMiniDexed : public Dexed |
||||||
|
{ |
||||||
|
public: |
||||||
|
CMiniDexed(uint8_t max_notes, uint16_t sample_rate, CInterruptSystem *pInterrupt) |
||||||
|
: Dexed(max_notes,(int)sample_rate), |
||||||
|
m_pMIDIDevice (0), |
||||||
|
m_PCKeyboard (this), |
||||||
|
m_Serial (pInterrupt, TRUE), |
||||||
|
m_bUseSerial (FALSE), |
||||||
|
m_nSerialState (0) |
||||||
|
{ |
||||||
|
s_pThis = this; |
||||||
|
}; |
||||||
|
|
||||||
|
virtual bool Initialize (void); |
||||||
|
void Process(boolean bPlugAndPlayUpdated); |
||||||
|
|
||||||
|
protected: |
||||||
|
static void MIDIPacketHandler (unsigned nCable, u8 *pPacket, unsigned nLength); |
||||||
|
static void KeyStatusHandlerRaw (unsigned char ucModifiers, const unsigned char RawKeys[6]); |
||||||
|
static void USBDeviceRemovedHandler (CDevice *pDevice, void *pContext); |
||||||
|
CUSBMIDIDevice * volatile m_pMIDIDevice; |
||||||
|
CPCKeyboard m_PCKeyboard; |
||||||
|
CSerialDevice m_Serial; |
||||||
|
boolean m_bUseSerial; |
||||||
|
unsigned m_nSerialState; |
||||||
|
u8 m_SerialMessage[3]; |
||||||
|
|
||||||
|
static CMiniDexed *s_pThis; |
||||||
|
}; |
||||||
|
|
||||||
|
class CMiniDexedPWM : public CMiniDexed, public CPWMSoundBaseDevice |
||||||
|
{ |
||||||
|
public: |
||||||
|
CMiniDexedPWM(uint8_t max_notes, uint16_t sample_rate, CInterruptSystem *pInterrupt) |
||||||
|
: CMiniDexed(max_notes,(int)sample_rate, pInterrupt), |
||||||
|
CPWMSoundBaseDevice (pInterrupt, sample_rate, CHUNK_SIZE) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
bool Initialize (void); |
||||||
|
unsigned GetChunk (u32 *pBuffer, unsigned nChunkSize); |
||||||
|
}; |
||||||
|
|
||||||
|
class CMiniDexedI2S : public CMiniDexed, public CI2SSoundBaseDevice |
||||||
|
{ |
||||||
|
public: |
||||||
|
CMiniDexedI2S(uint8_t max_notes, uint16_t sample_rate, CInterruptSystem *pInterrupt, CI2CMaster *pI2CMaster) |
||||||
|
: CMiniDexed(max_notes,(int)sample_rate, pInterrupt), |
||||||
|
CI2SSoundBaseDevice (pInterrupt, sample_rate, CHUNK_SIZE, FALSE, pI2CMaster, DAC_I2C_ADDRESS) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
bool Initialize (void); |
||||||
|
unsigned GetChunk (u32 *pBuffer, unsigned nChunkSize); |
||||||
|
}; |
||||||
|
|
||||||
|
class CMiniDexedHDMI : public CMiniDexed, public CHDMISoundBaseDevice |
||||||
|
{ |
||||||
|
public: |
||||||
|
CMiniDexedHDMI(uint8_t max_notes, uint16_t sample_rate, CInterruptSystem *pInterrupt) |
||||||
|
: CMiniDexed(max_notes,(int)sample_rate, pInterrupt), |
||||||
|
CHDMISoundBaseDevice (pInterrupt, sample_rate, CHUNK_SIZE_HDMI) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
bool Initialize (void); |
||||||
|
unsigned GetChunk (u32 *pBuffer, unsigned nChunkSize); |
||||||
|
}; |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,186 @@ |
|||||||
|
//
|
||||||
|
// pckeyboard.cpp
|
||||||
|
//
|
||||||
|
// MiniSynth Pi - A virtual analogue synthesizer for Raspberry Pi
|
||||||
|
// Copyright (C) 2017-2020 R. Stange <rsta2@o2online.de>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program 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 General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
#include "pckeyboard.h" |
||||||
|
#include "minidexed.h" |
||||||
|
#include <circle/devicenameservice.h> |
||||||
|
#include <circle/util.h> |
||||||
|
#include <assert.h> |
||||||
|
|
||||||
|
struct TKeyInfo |
||||||
|
{ |
||||||
|
char KeyCode; // upper case letter or digit
|
||||||
|
u8 KeyNumber; // MIDI number
|
||||||
|
}; |
||||||
|
|
||||||
|
// KeyCode is valid for standard QWERTY keyboard
|
||||||
|
static TKeyInfo KeyTable[] = |
||||||
|
{ |
||||||
|
{',', 72}, // C4
|
||||||
|
{'M', 71}, // B4
|
||||||
|
{'J', 70}, // A#4
|
||||||
|
{'N', 69}, // A4
|
||||||
|
{'H', 68}, // G#3
|
||||||
|
{'B', 67}, // G3
|
||||||
|
{'G', 66}, // F#3
|
||||||
|
{'V', 65}, // F3
|
||||||
|
{'C', 64}, // E3
|
||||||
|
{'D', 63}, // D#3
|
||||||
|
{'X', 62}, // D3
|
||||||
|
{'S', 61}, // C#3
|
||||||
|
{'Z', 60}, // C3
|
||||||
|
{'U', 59}, // B3
|
||||||
|
{'7', 58}, // A#3
|
||||||
|
{'Y', 57}, // A3
|
||||||
|
{'6', 56}, // G#2
|
||||||
|
{'T', 55}, // G2
|
||||||
|
{'5', 54}, // F#2
|
||||||
|
{'R', 53}, // F2
|
||||||
|
{'E', 52}, // E2
|
||||||
|
{'3', 51}, // D#2
|
||||||
|
{'W', 50}, // D2
|
||||||
|
{'2', 49}, // C#2
|
||||||
|
{'Q', 48} // C2
|
||||||
|
}; |
||||||
|
|
||||||
|
CPCKeyboard *CPCKeyboard::s_pThis = 0; |
||||||
|
|
||||||
|
CPCKeyboard::CPCKeyboard (CMiniDexed *pSynthesizer) |
||||||
|
: m_pSynthesizer (pSynthesizer), |
||||||
|
m_pKeyboard (0) |
||||||
|
{ |
||||||
|
s_pThis = this; |
||||||
|
|
||||||
|
memset (m_LastKeys, 0, sizeof m_LastKeys); |
||||||
|
} |
||||||
|
|
||||||
|
CPCKeyboard::~CPCKeyboard (void) |
||||||
|
{ |
||||||
|
m_pSynthesizer = 0; |
||||||
|
|
||||||
|
s_pThis = 0; |
||||||
|
} |
||||||
|
|
||||||
|
void CPCKeyboard::Process (boolean bPlugAndPlayUpdated) |
||||||
|
{ |
||||||
|
if (!bPlugAndPlayUpdated) |
||||||
|
{ |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (m_pKeyboard == 0) |
||||||
|
{ |
||||||
|
m_pKeyboard = |
||||||
|
(CUSBKeyboardDevice *) CDeviceNameService::Get ()->GetDevice ("ukbd1", FALSE); |
||||||
|
if (m_pKeyboard != 0) |
||||||
|
{ |
||||||
|
m_pKeyboard->RegisterKeyStatusHandlerRaw (KeyStatusHandlerRaw); |
||||||
|
|
||||||
|
m_pKeyboard->RegisterRemovedHandler (DeviceRemovedHandler); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void CPCKeyboard::KeyStatusHandlerRaw (unsigned char ucModifiers, const unsigned char RawKeys[6]) |
||||||
|
{ |
||||||
|
assert (s_pThis != 0); |
||||||
|
assert (s_pThis->m_pSynthesizer != 0); |
||||||
|
|
||||||
|
// report released keys
|
||||||
|
for (unsigned i = 0; i < 6; i++) |
||||||
|
{ |
||||||
|
u8 ucKeyCode = s_pThis->m_LastKeys[i]; |
||||||
|
if ( ucKeyCode != 0 |
||||||
|
&& !FindByte (RawKeys, ucKeyCode, 6)) |
||||||
|
{ |
||||||
|
u8 ucKeyNumber = GetKeyNumber (ucKeyCode); |
||||||
|
if (ucKeyNumber != 0) |
||||||
|
{ |
||||||
|
s_pThis->m_pSynthesizer->keyup (ucKeyNumber); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// report pressed keys
|
||||||
|
for (unsigned i = 0; i < 6; i++) |
||||||
|
{ |
||||||
|
u8 ucKeyCode = RawKeys[i]; |
||||||
|
if ( ucKeyCode != 0 |
||||||
|
&& !FindByte (s_pThis->m_LastKeys, ucKeyCode, 6)) |
||||||
|
{ |
||||||
|
u8 ucKeyNumber = GetKeyNumber (ucKeyCode); |
||||||
|
if (ucKeyNumber != 0) |
||||||
|
{ |
||||||
|
s_pThis->m_pSynthesizer->keydown (ucKeyNumber, 100); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
memcpy (s_pThis->m_LastKeys, RawKeys, sizeof s_pThis->m_LastKeys); |
||||||
|
} |
||||||
|
|
||||||
|
u8 CPCKeyboard::GetKeyNumber (u8 ucKeyCode) |
||||||
|
{ |
||||||
|
char chKey; |
||||||
|
if (0x04 <= ucKeyCode && ucKeyCode <= 0x1D) |
||||||
|
{ |
||||||
|
chKey = ucKeyCode-'\x04'+'A'; // key code of 'A' is 0x04
|
||||||
|
} |
||||||
|
else if (0x1E <= ucKeyCode && ucKeyCode <= 0x26) |
||||||
|
{ |
||||||
|
chKey = ucKeyCode-'\x1E'+'1'; // key code of '1' is 0x1E
|
||||||
|
} |
||||||
|
else if (ucKeyCode == 0x36) |
||||||
|
{ |
||||||
|
chKey = ','; // key code of ',' is 0x36
|
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
for (unsigned i = 0; i < sizeof KeyTable / sizeof KeyTable[0]; i++) |
||||||
|
{ |
||||||
|
if (KeyTable[i].KeyCode == chKey) |
||||||
|
{ |
||||||
|
return KeyTable[i].KeyNumber; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
boolean CPCKeyboard::FindByte (const u8 *pBuffer, u8 ucByte, unsigned nLength) |
||||||
|
{ |
||||||
|
while (nLength-- > 0) |
||||||
|
{ |
||||||
|
if (*pBuffer++ == ucByte) |
||||||
|
{ |
||||||
|
return TRUE; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return FALSE; |
||||||
|
} |
||||||
|
|
||||||
|
void CPCKeyboard::DeviceRemovedHandler (CDevice *pDevice, void *pContext) |
||||||
|
{ |
||||||
|
assert (s_pThis != 0); |
||||||
|
s_pThis->m_pKeyboard = 0; |
||||||
|
} |
@ -0,0 +1,56 @@ |
|||||||
|
//
|
||||||
|
// pckeyboard.h
|
||||||
|
//
|
||||||
|
// MiniSynth Pi - A virtual analogue synthesizer for Raspberry Pi
|
||||||
|
// Copyright (C) 2017-2020 R. Stange <rsta2@o2online.de>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program 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 General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
#ifndef _pckeyboard_h |
||||||
|
#define _pckeyboard_h |
||||||
|
|
||||||
|
#include <circle/usb/usbkeyboard.h> |
||||||
|
#include <circle/device.h> |
||||||
|
#include <circle/types.h> |
||||||
|
|
||||||
|
class CMiniDexed; |
||||||
|
|
||||||
|
class CPCKeyboard |
||||||
|
{ |
||||||
|
public: |
||||||
|
CPCKeyboard (CMiniDexed *pSynthesizer); |
||||||
|
~CPCKeyboard (void); |
||||||
|
|
||||||
|
void Process (boolean bPlugAndPlayUpdated); |
||||||
|
|
||||||
|
private: |
||||||
|
static void KeyStatusHandlerRaw (unsigned char ucModifiers, const unsigned char RawKeys[6]); |
||||||
|
|
||||||
|
static u8 GetKeyNumber (u8 ucKeyCode); |
||||||
|
|
||||||
|
static boolean FindByte (const u8 *pBuffer, u8 ucByte, unsigned nLength); |
||||||
|
|
||||||
|
static void DeviceRemovedHandler (CDevice *pDevice, void *pContext); |
||||||
|
|
||||||
|
private: |
||||||
|
CMiniDexed *m_pSynthesizer; |
||||||
|
|
||||||
|
CUSBKeyboardDevice * volatile m_pKeyboard; |
||||||
|
|
||||||
|
u8 m_LastKeys[6]; |
||||||
|
|
||||||
|
static CPCKeyboard *s_pThis; |
||||||
|
}; |
||||||
|
|
||||||
|
#endif |
Loading…
Reference in new issue