C Programming Column
by Al Stevens


Listing One
// ----- midiin.h
#ifndef MIDIIN_H
#define MIDIIN_H

#include <mmsystem.h>

class MidiIn    {
    void* m_pFunc;
    HMIDIIN hMidiIn;
    short int numDevices;
    short int currDevice;
public:
    MidiIn();
    ~MidiIn();
    void RegisterMIDIFunction(void* pFunc)
        { m_pFunc = pFunc; }
    void DeviceList(CListBox* dlist);
    BOOL ChangeDevice(short int device);
};
#endif


Listing Two
// ---- midiin.cpp

#include "stdafx.h"
#include "midiin.h"

MidiIn::MidiIn()
{
    m_pFunc = 0;
    hMidiIn = 0;
    currDevice = -1;
    numDevices = midiInGetNumDevs();
}
MidiIn::~MidiIn()
{
    if (hMidiIn != 0)   {
        midiInStop(hMidiIn);
        midiInClose(hMidiIn);
    }
}
void MidiIn::DeviceList(CListBox* dlist)
{
    ASSERT(dlist != 0);
    MIDIINCAPS icaps;
    for (short int i = 0; i < numDevices; i++)  {
        midiInGetDevCaps(i, &icaps, sizeof(icaps));
        dlist->AddString(icaps.szPname);
    }
}
BOOL MidiIn::ChangeDevice(short int device)
{
    ASSERT(device < numDevices);
    ASSERT(m_pFunc != 0);
    if (device != currDevice)   {
       if (hMidiIn)    {
            midiInStop(hMidiIn);
            midiInClose(hMidiIn);
            hMidiIn = 0;
        }
        HMIDIIN hIn;
        if (midiInOpen(&hIn,device,(DWORD) m_pFunc,0,CALLBACK_FUNCTION) != 0) {
            currDevice = -1;
            return FALSE;
        }
        hMidiIn = hIn;
        midiInStart(hMidiIn);
        currDevice = device;
    }
    return TRUE;
}


Listing Three
// ----- midiout.h
#ifndef MIDIOUT_H
#define MIDIOUT_H

#include <mmsystem.h>

class MidiOut   {
    HMIDIOUT hMidiOut;
    short int numDevices;
    short int currDevice;
public:
    MidiOut();
    ~MidiOut();
    void DeviceList(CListBox* dlist);
    void SendEvent(DWORD dwEvent);
    void StartMessage();
    void TimingMessage();
    void StopMessage();
    BOOL ChangeDevice(short int device);
    void CloseDevice();
};
inline void MidiOut::SendEvent(DWORD dwEvent)
{
    if (hMidiOut != 0)
        midiOutShortMsg(hMidiOut, dwEvent);
}
#endif

Listing Four
// ---- midiout.cpp

#include "stdafx.h"
#include "midiout.h"

MidiOut::MidiOut()
{
    hMidiOut = 0;
    // ---- test for MIDI output devices
    numDevices = midiOutGetNumDevs();
    currDevice = -1;
}
MidiOut::~MidiOut()
{
    CloseDevice();
}
void MidiOut::CloseDevice()
{
    if (hMidiOut != 0)  {
        // --- close the device
        midiOutClose(hMidiOut);
        hMidiOut = 0;
    }
}
BOOL MidiOut::ChangeDevice(short int device)
{
    ASSERT(device < numDevices + 1);
    if (device != currDevice)   {
        CloseDevice();
        // --- open the new device
        HMIDIOUT hOut;
        if (midiOutOpen(&hOut, device, 0, 0L, 0L) != 0) {
            currDevice = -1;
            return FALSE;
        }
        currDevice = device;
        hMidiOut = hOut;

    }
    return TRUE;
}
void MidiOut::StartMessage()
{
    if (hMidiOut != 0)  {
        DWORD mmsg  = 0xfa;
        midiOutShortMsg(hMidiOut, mmsg);
    }
}
void MidiOut::TimingMessage()
{
    if (hMidiOut != 0)  {
        DWORD mmsg  = 0xf8;
        midiOutShortMsg(hMidiOut, mmsg);
    }
}
void MidiOut::StopMessage()
{
    if (hMidiOut != 0)  {
        DWORD mmsg  = 0xfc;
        midiOutShortMsg(hMidiOut, mmsg);
    }
}
void MidiOut::DeviceList(CListBox* dlist)
{
    ASSERT(dlist != 0);
    MIDIOUTCAPS ocaps;
    for (short int i = 0; i < numDevices; i++)  {
        midiOutGetDevCaps(i, &ocaps, sizeof(ocaps));
        dlist->AddString(ocaps.szPname);
    }
}



