365 lines
7.5 KiB
C++
365 lines
7.5 KiB
C++
/*************************************************************************/
|
|
/* File : MidiManager.cpp
|
|
/*
|
|
/*************************************************************************/
|
|
|
|
#include "CKAll.h"
|
|
#include "MidiManager.h"
|
|
|
|
#include "MidiSound/MidiSound.h"
|
|
|
|
// Constructor
|
|
MidiManager::MidiManager(CKContext *ctx):CKMidiManager(ctx,"Midi Manager")
|
|
{
|
|
memset(noteState,0,sizeof(noteState));
|
|
ctx->RegisterNewManager(this);
|
|
}
|
|
|
|
// Destructor
|
|
MidiManager::~MidiManager()
|
|
{
|
|
}
|
|
|
|
|
|
//-----------------------------
|
|
// Midi Callback Function
|
|
//-----------------------------
|
|
void CALLBACK MidiInProc( HMIDIIN hMidiIn, UINT wMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 ){
|
|
|
|
MidiManager *mm = (MidiManager *) dwInstance;
|
|
|
|
if (!mm->midiDeviceIsOpen)
|
|
return;
|
|
|
|
|
|
midiMessage tmp;
|
|
tmp.channel = (BYTE)((dwParam1 & 0x0F));
|
|
tmp.command = (BYTE)((dwParam1 & 0xF0) >> 4);
|
|
tmp.note = (BYTE)((dwParam1 & 0xFF00) >> 8);
|
|
tmp.attack = (BYTE)((dwParam1 & 0xFF0000) >> 16);
|
|
tmp.time = dwParam2;
|
|
|
|
mm->listFromCallBack.PushBack(tmp);
|
|
|
|
|
|
if( tmp.command==9 && tmp.attack!=0 ){ // note activated
|
|
mm->ActivateNote(tmp.note, tmp.channel, TRUE);
|
|
return;
|
|
}
|
|
if( tmp.command==9 || tmp.command==8 ){ // note deactivated
|
|
mm->ActivateNote(tmp.note, tmp.channel, FALSE);
|
|
return;
|
|
}
|
|
}
|
|
|
|
//-------------------
|
|
// Midi Note State
|
|
//-------------------
|
|
void MidiManager::ActivateNote( int note, int channel, CKBOOL state){
|
|
int notedec = note>>3;
|
|
int dec = abs( (channel<<4) + notedec );
|
|
|
|
if( dec>=MIDI_MAXNOTES ) dec = MIDI_MAXNOTES-1;
|
|
|
|
if( state ){
|
|
noteState[dec] |= 1 << (note-(notedec<<3));
|
|
} else {
|
|
noteState[dec] &= ~(1 << (note-(notedec<<3)));
|
|
}
|
|
}
|
|
|
|
CKBOOL MidiManager::IsNoteActive(int note, int channel){
|
|
int notedec = note>>3;
|
|
int dec = abs( (channel<<4) + notedec );
|
|
|
|
if( dec>=MIDI_MAXNOTES ) dec = MIDI_MAXNOTES-1;
|
|
|
|
if( noteState[dec] & (1 << (note-(notedec<<3))) ) return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//------------------
|
|
//------------------
|
|
// Manager Events
|
|
//------------------
|
|
//------------------
|
|
CKERROR MidiManager::OnCKPlay()
|
|
{
|
|
if( m_Context->IsReseted() ){ // to be sure it's not a un-resume PLAY
|
|
if (midiDeviceBBrefcount) {
|
|
if (OpenMidiIn(DesiredmidiDevice)!=CK_OK) {
|
|
//console output disabled for now : these messages must be displayed only when Midi
|
|
//interface is requested
|
|
//m_Context->OutputToConsole("Trying to open default port (0)");
|
|
if( DesiredmidiDevice!=0 ){
|
|
if( OpenMidiIn(0)!=CK_OK) {
|
|
//m_Context->OutputToConsole("Unable to open Default port (0)");
|
|
return CKERR_INVALIDOPERATION;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return CK_OK;
|
|
}
|
|
|
|
CKERROR MidiManager::OnCKInit()
|
|
{
|
|
|
|
midiDeviceHandle = 0;
|
|
midiDeviceIsOpen = FALSE;
|
|
midiCurrentDevice = 0;
|
|
DesiredmidiDevice = 0;
|
|
midiDeviceBBrefcount = 0;
|
|
|
|
int midiDeviceCount = midiInGetNumDevs();
|
|
if( !midiDeviceCount ){
|
|
m_Context->OutputToConsole("No Midi Device !");
|
|
return CK_OK;
|
|
}
|
|
|
|
MIDIINCAPS tmp; // get midi devices infos
|
|
for( int a=0 ; a< midiDeviceCount ; a++ ){
|
|
midiInGetDevCaps(a, &tmp,sizeof(tmp) );
|
|
}
|
|
|
|
return CK_OK;
|
|
}
|
|
|
|
CKERROR MidiManager::OnCKEnd()
|
|
{
|
|
return CK_OK;
|
|
}
|
|
|
|
CKERROR MidiManager::OnCKReset()
|
|
{
|
|
if (midiDeviceIsOpen )
|
|
return CloseMidiIn();
|
|
return CK_OK;
|
|
}
|
|
|
|
CKERROR MidiManager::CloseMidiIn() {
|
|
|
|
if( midiDeviceHandle && midiDeviceIsOpen ){
|
|
if (midiInStop( midiDeviceHandle )== MMSYSERR_NOERROR) {
|
|
|
|
if (midiInClose(midiDeviceHandle) == MMSYSERR_NOERROR) {
|
|
|
|
midiDeviceIsOpen = FALSE;
|
|
return CK_OK;
|
|
}
|
|
}
|
|
}
|
|
|
|
return CKERR_INVALIDOPERATION;
|
|
}
|
|
|
|
CKERROR MidiManager::OpenMidiIn(int DesiredmidiDevice) {
|
|
|
|
if(midiDeviceIsOpen) {
|
|
m_Context->OutputToConsole("Midi Device Already open");
|
|
return CKERR_INVALIDOPERATION;
|
|
}
|
|
|
|
|
|
MMRESULT mr;
|
|
//midiDeviceHandle = NULL;
|
|
mr = midiInOpen( &midiDeviceHandle, DesiredmidiDevice, (DWORD)MidiInProc, (unsigned long)this, CALLBACK_FUNCTION|MIDI_IO_STATUS );
|
|
|
|
|
|
if(!midiDeviceHandle || (mr!=MMSYSERR_NOERROR) ) {
|
|
m_Context->OutputToConsole("Failed to open Desired Midi Device");
|
|
return CKERR_INVALIDOPERATION;
|
|
}
|
|
|
|
midiDeviceIsOpen = TRUE;
|
|
midiCurrentDevice = DesiredmidiDevice;
|
|
ZeroMemory(¬eState, MIDI_MAXNOTES);
|
|
mr = midiInStart( midiDeviceHandle );
|
|
if (mr!=MMSYSERR_NOERROR){
|
|
m_Context->OutputToConsole("Failed to Start Desired Midi Device");
|
|
return CKERR_INVALIDOPERATION;
|
|
}
|
|
|
|
return CK_OK;
|
|
|
|
}
|
|
|
|
CKERROR MidiManager::PostClearAll()
|
|
{
|
|
midiDeviceBBrefcount = 0;
|
|
return CK_OK;
|
|
}
|
|
|
|
CKERROR MidiManager::PreProcess()
|
|
{
|
|
listFromCallBack.Swap(listForBehaviors);
|
|
|
|
|
|
return CK_OK;
|
|
}
|
|
|
|
CKERROR MidiManager::PostProcess()
|
|
{
|
|
listForBehaviors.Clear();
|
|
if (midiDeviceIsOpen && (midiCurrentDevice!=DesiredmidiDevice)) {
|
|
MMRESULT mreset;
|
|
mreset = midiInReset(midiDeviceHandle);
|
|
if (mreset != MMSYSERR_NOERROR) {
|
|
m_Context->OutputToConsole("Unable to Reset the current Midi Device, before opening a new Midi device");
|
|
return CKERR_INVALIDOPERATION;
|
|
}
|
|
if (CloseMidiIn()!= CK_OK)
|
|
return CKERR_INVALIDOPERATION;
|
|
|
|
midiDeviceIsOpen = FALSE;
|
|
|
|
if (OpenMidiIn(DesiredmidiDevice)!=CK_OK)
|
|
return CKERR_INVALIDOPERATION;
|
|
}
|
|
return CK_OK;
|
|
}
|
|
|
|
// Midi Sound Functions
|
|
CKERROR
|
|
MidiManager::SetSoundFileName(void* source,CKSTRING filename)
|
|
{
|
|
MidiSound* ms = (MidiSound*)source;
|
|
if (!ms) return CKERR_INVALIDPARAMETER;
|
|
|
|
return ms->SetSoundFileName(filename);
|
|
}
|
|
|
|
CKSTRING
|
|
MidiManager::GetSoundFileName(void* source)
|
|
{
|
|
MidiSound* ms = (MidiSound*)source;
|
|
if (!ms) return NULL;
|
|
|
|
return (CKSTRING)ms->GetSoundFileName();
|
|
}
|
|
|
|
CKERROR
|
|
MidiManager::Play(void* source)
|
|
{
|
|
MidiSound* ms = (MidiSound*)source;
|
|
if (!ms) return CKERR_INVALIDPARAMETER;
|
|
|
|
return ms->Start();
|
|
}
|
|
|
|
CKERROR
|
|
MidiManager::Restart(void* source)
|
|
{
|
|
MidiSound* ms = (MidiSound*)source;
|
|
if (!ms) return CKERR_INVALIDPARAMETER;
|
|
|
|
return ms->Restart();
|
|
}
|
|
|
|
CKERROR
|
|
MidiManager::Stop(void* source)
|
|
{
|
|
MidiSound* ms = (MidiSound*)source;
|
|
if (!ms) return CKERR_INVALIDPARAMETER;
|
|
|
|
return ms->Stop();
|
|
}
|
|
|
|
CKERROR
|
|
MidiManager::Pause(void* source,CKBOOL pause)
|
|
{
|
|
MidiSound* ms = (MidiSound*)source;
|
|
if (!ms) return CKERR_INVALIDPARAMETER;
|
|
|
|
return ms->Pause();
|
|
}
|
|
|
|
CKBOOL
|
|
MidiManager::IsPlaying(void* source)
|
|
{
|
|
MidiSound* ms = (MidiSound*)source;
|
|
if (!ms) return CKERR_INVALIDPARAMETER;
|
|
|
|
return ms->IsPlaying();
|
|
}
|
|
|
|
CKBOOL
|
|
MidiManager::IsPaused(void* source)
|
|
{
|
|
MidiSound* ms = (MidiSound*)source;
|
|
if (!ms) return CKERR_INVALIDPARAMETER;
|
|
|
|
return ms->IsPaused();
|
|
}
|
|
|
|
void*
|
|
MidiManager::Create(void* hwnd)
|
|
{
|
|
return new MidiSound(hwnd);
|
|
}
|
|
|
|
void
|
|
MidiManager::Release(void* source)
|
|
{
|
|
CloseFile(source);
|
|
delete ((MidiSound*)(source));
|
|
}
|
|
|
|
CKERROR
|
|
MidiManager::OpenFile(void* source)
|
|
{
|
|
MidiSound* ms = (MidiSound*)source;
|
|
if (!ms) return CKERR_INVALIDPARAMETER;
|
|
|
|
return ms->OpenFile();
|
|
}
|
|
|
|
CKERROR
|
|
MidiManager::CloseFile(void* source)
|
|
{
|
|
MidiSound* ms = (MidiSound*)source;
|
|
if (!ms) return CKERR_INVALIDPARAMETER;
|
|
|
|
return ms->CloseFile();
|
|
}
|
|
|
|
CKERROR
|
|
MidiManager::Preroll(void* source)
|
|
{
|
|
MidiSound* ms = (MidiSound*)source;
|
|
if (!ms) return CKERR_INVALIDPARAMETER;
|
|
|
|
return ms->Preroll();
|
|
}
|
|
|
|
CKERROR
|
|
MidiManager::Time(void* source,CKDWORD* pTicks)
|
|
{
|
|
MidiSound* ms = (MidiSound*)source;
|
|
if (!ms) return CKERR_INVALIDPARAMETER;
|
|
|
|
return ms->Time((DWORD*)pTicks);
|
|
}
|
|
|
|
CKDWORD
|
|
MidiManager::MillisecsToTicks(void* source,CKDWORD msOffset)
|
|
{
|
|
MidiSound* ms = (MidiSound*)source;
|
|
if (!ms) return CKERR_INVALIDPARAMETER;
|
|
|
|
return ms->MillisecsToTicks(msOffset);
|
|
}
|
|
|
|
CKDWORD
|
|
MidiManager::TicksToMillisecs(void* source,CKDWORD tkOffset)
|
|
{
|
|
MidiSound* ms = (MidiSound*)source;
|
|
if (!ms) return CKERR_INVALIDPARAMETER;
|
|
|
|
return ms->TicksToMillisecs(tkOffset);
|
|
}
|