Category : Files from Magazines
Archive   : VOL11N19.ZIP
Filename : MIDFIL.C

 
Output of file : MIDFIL.C contained in archive : VOL11N19.ZIP
/*-----------------------------------------------------
MIDFIL.C -- MIDI Recorder and Player with File Save
(c) Charles Petzold, 1992
-----------------------------------------------------*/

#include
#include
#include
#include
#include
#include
#include
#include "midbuf.h"
#include "midfil.h"

#define BUFFER_SIZE 4096 // Should be multiple of 8

long FAR PASCAL _export WndProc (HWND, UINT, UINT, LONG) ;
BOOL FAR PASCAL _export DlgProc (HWND, UINT, UINT, LONG) ;

char szAppName [] = "MidFil" ;
HANDLE hInst ;
HWND hDlg ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpszCmdParam, int nCmdShow)
{
HWND hwnd ;
int xWin, yWin ;
MSG msg ;
WNDCLASS wndclass ;

hInst = hInstance ;

if (!hPrevInstance)
{
wndclass.style = CS_HREDRAW | CS_VREDRAW ;

wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (hInstance, szAppName) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = szAppName ;
wndclass.lpszClassName = szAppName ;

RegisterClass (&wndclass) ;
}

xWin = DLG_WIDTH * LOWORD (GetDialogBaseUnits ()) / 4 +
2 * GetSystemMetrics (SM_CXBORDER) ;

yWin = DLG_HEIGHT * HIWORD (GetDialogBaseUnits ()) / 8 +
2 * GetSystemMetrics (SM_CYBORDER) +
GetSystemMetrics (SM_CYCAPTION) +
GetSystemMetrics (SM_CYMENU) ;

hwnd = CreateWindow (szAppName, "Midi File Saver",
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU |
WS_BORDER | WS_MINIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, xWin, yWin,
NULL, NULL, hInstance, lpszCmdParam) ;

ShowWindow (hwnd, nCmdShow) ;
UpdateWindow (hwnd) ;

while (GetMessage (&msg, NULL, 0, 0))
{
if (hDlg != NULL || !IsDialogMessage (hDlg, &msg))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}
return msg.wParam ;
}

// Functions to allocate and free MIDIHDR structures and buffers
// -------------------------------------------------------------

LPMIDIHDR AllocMidiHeader (HANDLE hMidi, LPMIDIHDR pmhRoot)
{
LPMIDIHDR pmhNew, pmhNext ;

// Allocate memory for the new MIDIHDR

pmhNew = (LPMIDIHDR) GlobalAllocPtr (GHND | GMEM_SHARE, sizeof (MIDIHDR));

if (pmhNew == NULL)
return NULL ;

// Allocate memory for the buffer

pmhNew->lpData = (LPSTR) GlobalAllocPtr (GHND | GMEM_SHARE, BUFFER_SIZE) ;

if (pmhNew->lpData == NULL)
{
GlobalFreePtr (pmhNew) ;
return NULL ;
}

pmhNew->dwBufferLength = BUFFER_SIZE ;

// Prepare the header

if (midiInPrepareHeader (hMidi, pmhNew, sizeof (MIDIHDR)))
{
GlobalFreePtr (pmhNew->lpData) ;
GlobalFreePtr (pmhNew) ;
return NULL ;
}

// Attach new header to end of chain

if (pmhRoot != NULL)
{
pmhNext = pmhRoot ;

while (pmhNext->dwUser != NULL)
pmhNext = (LPMIDIHDR) pmhNext->dwUser ;

pmhNext->dwUser = (DWORD) pmhNew ;
}

return pmhNew ;
}

LPMIDIHDR CleanUpMidiHeaderChain (HANDLE hMidi, LPMIDIHDR pmhRoot)
{
LPMIDIHDR pmhCurr, pmhLast, pmhNext, pmhRetn ;

pmhRetn = pmhRoot ;
pmhCurr = pmhRoot ;
pmhLast = NULL ;


while (pmhCurr != NULL)
{
pmhNext = (LPMIDIHDR) pmhCurr->dwUser ;

if (pmhCurr->dwBytesRecorded == 0)
{
midiInUnprepareHeader (hMidi, pmhCurr, sizeof (MIDIHDR)) ;

GlobalFreePtr (pmhCurr->lpData) ;
GlobalFreePtr (pmhCurr) ;

if (pmhCurr == pmhRoot)
pmhRetn = NULL ;

if (pmhLast != NULL)
pmhLast->dwUser = (DWORD) pmhNext ;

pmhCurr = pmhLast ;
}

else if (pmhCurr->dwBytesRecorded < BUFFER_SIZE)
{
midiInUnprepareHeader (hMidi, pmhCurr, sizeof (MIDIHDR)) ;

GlobalReAllocPtr (pmhCurr->lpData,
pmhCurr->dwBytesRecorded, 0) ;

midiInPrepareHeader (hMidi, pmhCurr, sizeof (MIDIHDR)) ;

pmhCurr->dwBufferLength = pmhCurr->dwBytesRecorded ;
}

pmhLast = pmhCurr ;
pmhCurr = pmhNext ;
}

return pmhRetn ;
}

VOID FreeMidiHeaderChain (HANDLE hMidi, LPMIDIHDR pmhRoot)
{
LPMIDIHDR pmhNext, pmhTemp ;

pmhNext = pmhRoot ;

while (pmhNext != NULL)
{
pmhTemp = (LPMIDIHDR) pmhNext->dwUser ;

midiInUnprepareHeader (hMidi, pmhNext, sizeof (MIDIHDR)) ;

GlobalFreePtr (pmhNext->lpData) ;
GlobalFreePtr (pmhNext) ;

pmhNext = pmhTemp ;
}
}

// Add MIDI device lists to the program's menu
// -------------------------------------------

WORD AddDevicesToMenu (HWND hwnd, int iNumInpDevs, int iNumOutDevs)
{
HMENU hMenu, hMenuInp, hMenuMon, hMenuOut ;
int i ;
MIDIINCAPS mic ;
MIDIOUTCAPS moc ;
WORD wDefaultOut ;

hMenu = GetMenu (hwnd) ;

// Create "Input" popup menu

hMenuInp = CreateMenu () ;

for (i = 0 ; i < iNumInpDevs ; i++)
{
midiInGetDevCaps (i, &mic, sizeof (MIDIINCAPS)) ;
AppendMenu (hMenuInp, MF_STRING, ID_DEV_INP + i, mic.szPname) ;
}

CheckMenuItem (hMenuInp, 0, MF_BYPOSITION | MF_CHECKED) ;
ModifyMenu (hMenu, ID_DEV_INP, MF_POPUP, hMenuInp, "&Input") ;

// Create "Monitor" and "Output" popup menus

hMenuMon = CreateMenu () ;
hMenuOut = CreateMenu () ;

AppendMenu (hMenuMon, MF_STRING, ID_DEV_MON, "&None") ;

if (!midiOutGetDevCaps (MIDIMAPPER, &moc, sizeof (moc)))
{
AppendMenu (hMenuMon, MF_STRING, ID_DEV_MON + 1, moc.szPname) ;
AppendMenu (hMenuOut, MF_STRING, ID_DEV_OUT , moc.szPname) ;

wDefaultOut = 0 ;
}
else
wDefaultOut = 1 ;

// Add the rest of the MIDI devices

for (i = 0 ; i < iNumOutDevs ; i++)
{
midiOutGetDevCaps (i, &moc, sizeof (moc)) ;
AppendMenu (hMenuMon, MF_STRING, ID_DEV_MON + i + 2, moc.szPname) ;
AppendMenu (hMenuOut, MF_STRING, ID_DEV_OUT + i + 1, moc.szPname) ;
}

CheckMenuItem (hMenuMon, 0, MF_BYPOSITION | MF_CHECKED) ;
CheckMenuItem (hMenuOut, 0, MF_BYPOSITION | MF_CHECKED) ;

ModifyMenu (hMenu, ID_DEV_MON, MF_POPUP, hMenuMon, "&Monitor") ;
ModifyMenu (hMenu, ID_DEV_OUT, MF_POPUP, hMenuOut, "&Output") ;

return wDefaultOut ;
}

// Functions to save the MIDI data buffers as a .MID file
// ------------------------------------------------------

int VarLenNumOut (BYTE * pOut, int iOut, long lAbsTime)
{
long lVarTime ;

lVarTime = lAbsTime & 0x7F ;

while ((lAbsTime >>= 7) > 0)
{
lVarTime <<= 8 ;
lVarTime |= 0x80 ;
lVarTime += lAbsTime & 0x7F ;
}

while (TRUE)
{
pOut[iOut++] = (char) lVarTime ;

if (lVarTime & 0x80)
lVarTime >>= 8 ;
else
break ;
}

return iOut ;
}

long IntelToMotorolaLong (long lIn)
{
long lOut ;

* ((char *) & lOut + 0) = * ((char *) & lIn + 3) ;
* ((char *) & lOut + 1) = * ((char *) & lIn + 2) ;
* ((char *) & lOut + 2) = * ((char *) & lIn + 1) ;
* ((char *) & lOut + 3) = * ((char *) & lIn + 0) ;

return lOut ;
}

BOOL SaveMidiFile (char * szFileName, LPMIDIHDR pMidiHdrRoot)
{
static BYTE pBufOut [2 * BUFFER_SIZE] ;
static BYTE pHeader [] = { 'M', 'T', 'h', 'd', 0, 0, 0, 6,
0, 0, 0, 1, -25, 40,
'M', 'T', 'r', 'k', 0, 0, 0, 0 } ;
static BYTE pEndTrk [] = { 0, 0xFF, 0x2F, 0x00 } ;
BYTE bStatus, bChannel, bData1, bData2 ;
DWORD dwTime, dwMidiMsg ;
int hFile, iLenIn, iIn, iOut ;
long lTotLen ;
LPMIDIHDR pMidiHdr ;
LPDWORD pdwBufIn ;

// Attempt to open the file

if (-1 == (hFile = _lcreat (szFileName, 0)))
return FALSE ;

// Write out the header chunk and some of the track chunk

_lwrite (hFile, pHeader, sizeof (pHeader)) ;

// Loop through the MIDIHDR chain

pMidiHdr = pMidiHdrRoot ;
lTotLen = 0 ;

while (pMidiHdr != NULL)
{
iLenIn = (int) pMidiHdr->dwBufferLength / 4 ;
pdwBufIn = (LPDWORD) pMidiHdr->lpData ;
iOut = 0 ;

// Loop through the DWORDs in the buffer

for (iIn = 0 ; iIn < iLenIn ; iIn += 2)
{
// Get the delta time in milliseconds

dwTime = pdwBufIn [iIn] ;

// If it's the very first, set it to zero

if (pMidiHdr == pMidiHdrRoot && iIn == 0)
dwTime = 0 ;

// Store it as a variable length number

iOut = VarLenNumOut (pBufOut, iOut, dwTime) ;

// Get the MIDI message

dwMidiMsg = pdwBufIn [iIn + 1] ;

bStatus = LOBYTE (LOWORD (dwMidiMsg)) ;
bData1 = HIBYTE (LOWORD (dwMidiMsg)) ;
bData2 = LOBYTE (HIWORD (dwMidiMsg)) ;

// Forget about system messages

if (bStatus >= 0xF0)
continue ;

// Store the status byte and first data byte

pBufOut[iOut++] = bStatus ;
pBufOut[iOut++] = bData1 ;

// For three-byte messages, store the second data byte

if (bStatus < 0xC0 || bStatus >= 0xE0)
pBufOut [iOut++] = bData2 ;

// Get the channel number

bChannel = bStatus & 0x0F ;

// If it's not mappable, continue with next loop

if ((bChannel > 2 && bChannel < 9) ||
(bChannel > 9 && bChannel < 12))
continue ;

// Map the channel and create a new status byte

if (bChannel < 3)
bChannel += 12 ;

else if (bChannel == 9)
bChannel = 15 ;

else if (bChannel == 15)
bChannel = 9 ;

else if (bChannel > 11)
bChannel -= 12 ;

bStatus = (bStatus & 0xF0) | bChannel ;

// Store a delta time of zero

pBufOut[iOut++] = 0 ;

// Store the MIDI message as above

pBufOut[iOut++] = bStatus ;
pBufOut[iOut++] = bData1 ;

if (bStatus < 0xC0 || bStatus >= 0xE0)
pBufOut [iOut++] = bData2 ;
}

// Write out the buffer

if (iOut != (int) _lwrite (hFile, pBufOut, iOut))
{
_lclose (hFile) ;
unlink (szFileName) ;
return FALSE ;
}

// Increment the total track size

lTotLen += iOut ;

// Get next MIDIHDR structure in chain

pMidiHdr = (LPMIDIHDR) pMidiHdr->dwUser ;
}

// Store an "end of track" meta-message

_lwrite (hFile, pEndTrk, sizeof (pEndTrk)) ;

lTotLen += sizeof (pEndTrk) ;

// Convert track length to Motorola format and store it
// in the size field of the track chunk

lTotLen = IntelToMotorolaLong (lTotLen) ;

_llseek (hFile, 18, 0) ;
_lwrite (hFile, &lTotLen, sizeof (long)) ;

// Close the file

_lclose (hFile) ;

return TRUE ;
}

long FAR PASCAL _export WndProc (HWND hwnd, UINT message, UINT wParam,
LONG lParam)
{
static BOOL bRecording, bPlaying, bEnding, bPaused, bTerminating ;
static char szInpError[] = { "Error opening MIDI input port!" } ;
static char szOutError[] = { "Error opening MIDI output port!" } ;
static char szMonError[] = { "Error opening MIDI output port "
"for monitoring input! Continuing." } ;
static char szMemError[] = { "Error allocating memory!" } ;
static char szFilError[] = { "Error save file!" } ;
static char szFileName [_MAX_PATH],
szFileTitle [_MAX_FNAME | _MAX_EXT] ;
static HMIDIIN hMidiIn ;
static HMIDIOUT hMidiOut ;
static int iNumInpDevs, iNumOutDevs ;
static LPMIDIHDR pMidiHdrRoot, pMidiHdrNext, pMidiHdr ;
static OPENFILENAME ofn ;
static char * szFilter[] = { "Midi Files (*.MID)", "*.mid",
"" } ;
static WORD wDeviceInp, wDeviceMon, wDeviceOut ;
FARPROC lpDlgProc ;
HMENU hMenu ;
int i ;

switch (message)
{
case WM_CREATE:
if (0 == (iNumInpDevs = midiInGetNumDevs ()))
{
MessageBox (hwnd, "No MIDI Input Devices!", szAppName,
MB_ICONEXCLAMATION | MB_OK) ;
DestroyWindow (hwnd) ;
}

if (0 == (iNumOutDevs = midiOutGetNumDevs ()))
{
MessageBox (hwnd, "No MIDI Output Devices!", szAppName,
MB_ICONEXCLAMATION | MB_OK) ;
DestroyWindow (hwnd) ;
}

wDeviceOut = AddDevicesToMenu (hwnd, iNumInpDevs, iNumOutDevs) ;

lpDlgProc = MakeProcInstance ((FARPROC) DlgProc, hInst) ;
hDlg = CreateDialog (hInst, szAppName, hwnd, lpDlgProc) ;
return 0 ;

case WM_COMMAND:

hMenu = GetMenu (hwnd) ;

switch (wParam)
{
case ID_RECORD_BEG:

// Open MIDI In port for recording

if (midiInOpen (&hMidiIn, wDeviceInp, hwnd, 0L,
CALLBACK_WINDOW))
{
MessageBox (hwnd, szInpError, szAppName,
MB_ICONEXCLAMATION | MB_OK) ;

return 0 ;
}

// Open MIDI Out port for monitoring
// (continue if unable to open it)

if (wDeviceMon > 0)
{
if (midiOutOpen (&hMidiOut, wDeviceMon - 2,
0L, 0L, 0L))
{
hMidiOut = NULL ;
MessageBox (hwnd, szMonError, szAppName,
MB_ICONEXCLAMATION | MB_OK) ;
}
}
else
hMidiOut = NULL ;

return 0 ;

case ID_RECORD_END:
// Reset and close input

bEnding = TRUE ;

midiInReset (hMidiIn) ;
midiInClose (hMidiIn) ;

return 0 ;

case ID_FILE_SAVE:
ofn.lStructSize = sizeof (OPENFILENAME) ;
ofn.hwndOwner = hwnd ;
ofn.lpstrFilter = szFilter [0] ;
ofn.lpstrFile = szFileName ;
ofn.nMaxFile = _MAX_PATH ;
ofn.lpstrFileTitle = szFileTitle ;
ofn.nMaxFileTitle = _MAX_FNAME + _MAX_EXT ;
ofn.Flags = OFN_OVERWRITEPROMPT ;
ofn.lpstrDefExt = "mid" ;

if (!GetSaveFileName (&ofn))
return 0 ;

if (!SaveMidiFile (szFileName, pMidiHdrRoot))
MessageBox (hwnd, szFilError, szAppName,
MB_ICONEXCLAMATION | MB_OK) ;

SetFocus (GetDlgItem (hDlg, ID_RECORD_BEG)) ;

return 0 ;

case ID_PLAY_BEG:
// Open MIDI Out port for playing

if (midiOutOpen (&hMidiOut, wDeviceOut - 1,
hwnd, 0L, CALLBACK_WINDOW))
{
MessageBox (hwnd, szOutError, szAppName,
MB_ICONEXCLAMATION | MB_OK) ;
}

return 0 ;

case ID_PLAY_PAUSE:
// Pause or restart output

if (!bPaused)
{
midiOutPause (hMidiOut) ;

// All Notes Off message

for (i = 0 ; i < 16 ; i++)
midiOutShortMsg (hMidiOut, 0x7BB0 + i) ;

SetDlgItemText (hwnd, ID_PLAY_PAUSE, "Resume") ;
bPaused = TRUE ;
}
else
{
midiOutRestart (hMidiOut) ;
SetDlgItemText (hwnd, ID_PLAY_PAUSE, "Pause") ;
bPaused = FALSE ;
}

return 0 ;

case ID_PLAY_END:
// Reset the port and close it

bEnding = TRUE ;
midiOutReset (hMidiOut) ;
midiOutClose (hMidiOut) ;
return 0 ;

default:
break ;
}

if (wParam >= ID_DEV_INP & wParam < ID_DEV_MON)
{
CheckMenuItem (hMenu, wDeviceInp + ID_DEV_INP,
MF_UNCHECKED) ;

wDeviceInp = wParam - ID_DEV_INP ;

CheckMenuItem (hMenu, wDeviceInp + ID_DEV_INP,
MF_CHECKED) ;
return 0 ;
}

else if (wParam >= ID_DEV_MON & wParam < ID_DEV_OUT)
{
CheckMenuItem (hMenu, wDeviceMon + ID_DEV_MON,
MF_UNCHECKED) ;

wDeviceMon = wParam - ID_DEV_MON ;

CheckMenuItem (hMenu, wDeviceMon + ID_DEV_MON,
MF_CHECKED) ;
return 0 ;
}

if (wParam >= ID_DEV_OUT)
{
CheckMenuItem (hMenu, wDeviceOut + ID_DEV_OUT,
MF_UNCHECKED) ;

wDeviceOut = wParam - ID_DEV_OUT ;

CheckMenuItem (hMenu, wDeviceOut + ID_DEV_OUT,
MF_CHECKED) ;
return 0 ;
}

break ;

case MM_MIM_OPEN:
hMidiIn = wParam ;

// Free existing headers

FreeMidiHeaderChain (hMidiIn, pMidiHdrRoot) ;

// Allocate root header

if (NULL == (pMidiHdrRoot = AllocMidiHeader (hMidiIn, NULL)))
{
midiInClose (hMidiIn) ;
MessageBox (hwnd, szMemError, szAppName,
MB_ICONEXCLAMATION | MB_OK) ;

return 0 ;
}

// Allocate next header

if (NULL == (pMidiHdrNext = AllocMidiHeader (hMidiIn,
pMidiHdrRoot)))
{
FreeMidiHeaderChain (hMidiIn, pMidiHdrRoot) ;
midiInClose (hMidiIn) ;
MessageBox (hwnd, szMemError, szAppName,
MB_ICONEXCLAMATION | MB_OK) ;

return 0 ;
}
// Enable and disable buttons

EnableWindow (GetDlgItem (hDlg, ID_RECORD_BEG), FALSE) ;
EnableWindow (GetDlgItem (hDlg, ID_RECORD_END), TRUE) ;
EnableWindow (GetDlgItem (hDlg, ID_FILE_SAVE), FALSE) ;
EnableWindow (GetDlgItem (hDlg, ID_PLAY_BEG), FALSE) ;
EnableWindow (GetDlgItem (hDlg, ID_PLAY_PAUSE), FALSE) ;
EnableWindow (GetDlgItem (hDlg, ID_PLAY_END), FALSE) ;
SetFocus (GetDlgItem (hDlg, ID_RECORD_END)) ;

// Submit the buffers for receiving data

midiInShortBuffer (hMidiIn, pMidiHdrRoot, sizeof (MIDIHDR)) ;
midiInShortBuffer (hMidiIn, pMidiHdrNext, sizeof (MIDIHDR)) ;

// Begin recording

midiInStart (hMidiIn) ;
bRecording = TRUE ;
bEnding = FALSE ;
return 0 ;

case MM_MIM_DATA:
if (hMidiOut)
{
midiOutShortMsg (hMidiOut, lParam) ;
}

return 0 ;

case MM_MIM_LONGDATA:

if (bEnding)
return 0 ;

pMidiHdrNext = AllocMidiHeader (hMidiIn, pMidiHdrRoot) ;

if (pMidiHdrNext == NULL)
{
midiInReset (hMidiIn) ;
midiInClose (hMidiIn) ;
MessageBox (hwnd, szMemError, szAppName,
MB_ICONEXCLAMATION | MB_OK) ;

return 0 ;
}

midiInShortBuffer (hMidiIn, pMidiHdrNext, sizeof (MIDIHDR));

return 0 ;

case MM_MIM_CLOSE:
// Close the monitoring output port

if (hMidiOut)
{
midiOutReset (hMidiOut) ;
midiOutClose (hMidiOut) ;
}

// Enable and Disable Buttons

EnableWindow (GetDlgItem (hDlg, ID_RECORD_BEG), TRUE) ;
EnableWindow (GetDlgItem (hDlg, ID_RECORD_END), FALSE) ;
SetFocus (GetDlgItem (hDlg, ID_RECORD_BEG)) ;

pMidiHdrRoot = CleanUpMidiHeaderChain (hMidiIn, pMidiHdrRoot) ;

if (pMidiHdrRoot != NULL)
{
EnableWindow (GetDlgItem (hDlg, ID_FILE_SAVE), TRUE) ;
EnableWindow (GetDlgItem (hDlg, ID_PLAY_BEG), TRUE) ;
EnableWindow (GetDlgItem (hDlg, ID_PLAY_PAUSE), FALSE) ;
EnableWindow (GetDlgItem (hDlg, ID_PLAY_END), FALSE) ;
SetFocus (GetDlgItem (hDlg, ID_PLAY_BEG)) ;
}

bRecording = FALSE ;

if (bTerminating)
{
FreeMidiHeaderChain (hMidiIn, pMidiHdrRoot) ;
SendMessage (hwnd, WM_SYSCOMMAND, SC_CLOSE, 0L) ;
}

return 0 ;

case MM_MOM_OPEN:
hMidiOut = wParam ;

// Enable and Disable Buttons

EnableWindow (GetDlgItem (hDlg, ID_RECORD_BEG), FALSE) ;
EnableWindow (GetDlgItem (hDlg, ID_RECORD_END), FALSE) ;
EnableWindow (GetDlgItem (hDlg, ID_PLAY_BEG), FALSE) ;
EnableWindow (GetDlgItem (hDlg, ID_PLAY_PAUSE), TRUE) ;
EnableWindow (GetDlgItem (hDlg, ID_PLAY_END), TRUE) ;
SetFocus (GetDlgItem (hDlg, ID_PLAY_END)) ;

// Submit the root buffer to begin playing

midiOutShortBuffer (hMidiOut, pMidiHdrRoot, sizeof (MIDIHDR)) ;

// If there's a second buffer, submit that also

if (NULL != (pMidiHdr = (LPMIDIHDR) pMidiHdrRoot->dwUser))
midiOutShortBuffer (hMidiOut, pMidiHdr, sizeof (MIDIHDR)) ;

bEnding = FALSE ;
bPlaying = TRUE ;

return 0 ;

case MM_MOM_DONE:

// If stopping playback, just return

if (bEnding)
return 0 ;

// Get header of buffer just finished playing

pMidiHdr = (LPMIDIHDR) lParam ;

// Get header of next buffer (already submitted)

pMidiHdr = (LPMIDIHDR) pMidiHdr->dwUser ;

// Get header of next buffer to submit now

if (pMidiHdr != NULL)
pMidiHdr = (LPMIDIHDR) pMidiHdr->dwUser ;

if (pMidiHdr != NULL)
midiOutShortBuffer (hMidiOut, pMidiHdr, sizeof (MIDIHDR)) ;
else
{
midiOutReset (hMidiOut) ;
midiOutClose (hMidiOut) ;
}

return 0 ;

case MM_MOM_CLOSE:

// Enable and Disable Buttons

EnableWindow (GetDlgItem (hDlg, ID_RECORD_BEG), TRUE) ;
EnableWindow (GetDlgItem (hDlg, ID_RECORD_END), TRUE) ;
EnableWindow (GetDlgItem (hDlg, ID_PLAY_BEG), TRUE) ;
EnableWindow (GetDlgItem (hDlg, ID_PLAY_PAUSE), FALSE) ;
EnableWindow (GetDlgItem (hDlg, ID_PLAY_END), FALSE) ;
SetFocus (GetDlgItem (hDlg, ID_PLAY_BEG)) ;

SetDlgItemText (hwnd, ID_PLAY_PAUSE, "Pause") ;
bPaused = FALSE ;
bPlaying = FALSE ;

if (bTerminating)
{
FreeMidiHeaderChain (hMidiIn, pMidiHdrRoot) ;
SendMessage (hwnd, WM_SYSCOMMAND, SC_CLOSE, 0L) ;
}

return 0 ;

case WM_CLOSE:
if (bRecording)
{
bTerminating = TRUE ;
bEnding = TRUE ;
midiInReset (hMidiIn) ;
midiInClose (hMidiIn) ;
}

if (bPlaying)
{
bTerminating = TRUE ;
bEnding = TRUE ;
midiOutReset (hMidiOut) ;
midiOutClose (hMidiOut) ;
}

break ;

case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}

return DefWindowProc (hwnd, message, wParam, lParam) ;
}

BOOL FAR PASCAL _export DlgProc (HWND hwnd, UINT message, UINT wParam,
LONG lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE ;

case WM_COMMAND:
SendMessage (GetParent (hwnd), WM_COMMAND, wParam, lParam) ;
return TRUE ;
}
return FALSE ;
}


  3 Responses to “Category : Files from Magazines
Archive   : VOL11N19.ZIP
Filename : MIDFIL.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/