Re: Looking for Visual Basic Source Code
Posted by: moydog (IP Logged)
Date: April 19, 2006 10:45PM
Go here for the .frm
[www.blackbeltvb.com]
Option Explicit
' Midinote sample from BlackBeltVB.com
' [blackbeltvb.com]
'
' Written by Matt Hart
' Copyright 1999 by Matt Hart
'
' This software is FREEWARE. You may use it as you see fit for
' your own projects but you may not re-sell the original or the
' source code. Do not copy this sample to a collection, such as
' a CD-ROM archive. You may link directly to the original sample
' using "http://blackbeltvb.com/midinote.htm"
'
' No warranty express or implied, is given as to the use of this
' program. Use at your own risk.
'
' This one plays a few MIDI notes to the default MIDI
' device, showing you the basics of streaming MIDI output.
'
' It is a translation of a C program sent to me by
' Pier Calderan in the ' form of a question ...
' "How do I get this to work in VB?".
Private Type midiHdr
lpData As Long ' As String
dwBufferLength As Long
dwBytesRecorded As Long
dwUser As Long
dwFlags As Long
lpNext As Long
Reserved As Long
dwOffset As Long
dwReserved(0 To 3) As Long
End Type
Private Type MIDIPROPTIMEDIV
cbStruct As Long
dwTimeDiv As Long
End Type
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)
Private Declare Function midiOutPrepareHeader Lib "winmm.dll" (ByVal hMidiOut As Long, lpMidiOutHdr As Any, ByVal uSize As Long) As Long
Private Declare Function midiOutUnprepareHeader Lib "winmm.dll" (ByVal hMidiOut As Long, lpMidiOutHdr As Any, ByVal uSize As Long) As Long
Private Declare Function midiStreamClose Lib "winmm.dll" (ByVal hms As Long) As Long
Private Declare Function midiStreamOpen Lib "winmm.dll" (phms As Long, puDeviceID As Long, ByVal cMidi As Long, ByVal dwCallback As Long, ByVal dwInstance As Long, ByVal fdwOpen As Long) As Long
Private Declare Function midiStreamOut Lib "winmm.dll" (ByVal hms As Long, pmh As Any, ByVal cbmh As Long) As Long
Private Declare Function midiStreamProperty Lib "winmm.dll" (ByVal hms As Long, lppropdata As Any, ByVal dwProperty As Long) As Long
Private Declare Function midiStreamRestart Lib "winmm.dll" (ByVal hms As Long) As Long
Private Const GMEM_FIXED = &H0
Private Const GMEM_ZEROINIT = &H40
Private Const GPTR = (GMEM_FIXED Or GMEM_ZEROINIT)
Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long
mHdr.lpData = hMem ' or VarPtr(Phrase(0)) without the global memory junk, but Phrase(0) might moved by VB unexpectedly
mHdr.dwBufferLength = lSize
mHdr.dwBytesRecorded = lSize - 4
If midiOutPrepareHeader(Handle, mHdr, Len(mHdr)) = MMSYSERR_NOERROR Then
midiStreamOut Handle, mHdr, Len(mHdr)
End If
midiStreamRestart Handle
Do While midiOutUnprepareHeader(Handle, mHdr, Len(mHdr)) = MIDIERR_STILLPLAYING: DoEvents: Loop
midiStreamClose Handle
GlobalFree hMem
End If
End Sub
/*
native_midi: Hardware Midi support for the SDL_mixer library
Copyright (C) 2000,2001 Florian 'Proff' Schulze
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
song->CurrentPos=0;
laststatus=0;
lastchan=0;
atime=0;
for (;;)
{
if (song->CurrentPos>=song->mididata.track[song->CurrentTrack].len)
return;
atime+=getvl(song);
event=song->mididata.track[song->CurrentTrack].data[song->CurrentPos];
song->CurrentPos++;
if(event==0xF0 || event == 0xF7) // SysEx event
{
len=getvl(song);
song->CurrentPos+=len;
}
else if(event==0xFF) // Meta event
{
type=song->mididata.track[song->CurrentTrack].data[song->CurrentPos];
song->CurrentPos++;
len=getvl(song);
switch(type)
{
case 0x2f:
return;
case 0x51: // Tempo
a=song->mididata.track[song->CurrentTrack].data[song->CurrentPos];
song->CurrentPos++;
b=song->mididata.track[song->CurrentTrack].data[song->CurrentPos];
song->CurrentPos++;
c=song->mididata.track[song->CurrentTrack].data[song->CurrentPos];
song->CurrentPos++;
AddEvent(song, atime, MEVT_TEMPO, c, b, a);
break;
default:
song->CurrentPos+=len;
break;
}
}
else
{
a=event;
if (a & 0x80) // status byte
{
lastchan=a & 0x0F;
laststatus=(a>>4) & 0x07;
a=song->mididata.track[song->CurrentTrack].data[song->CurrentPos];
song->CurrentPos++;
a &= 0x7F;
}
switch(laststatus)
{
case 0: // Note off
b=song->mididata.track[song->CurrentTrack].data[song->CurrentPos];
song->CurrentPos++;
b &= 0x7F;
AddEvent(song, atime, MEVT_SHORTMSG, (byte)((laststatus<<4)+lastchan+0x80), a, b);
break;
case 1: // Note on
b=song->mididata.track[song->CurrentTrack].data[song->CurrentPos];
song->CurrentPos++;
b &= 0x7F;
AddEvent(song, atime, MEVT_SHORTMSG, (byte)((laststatus<<4)+lastchan+0x80), a, b);
break;
case 2: // Key Pressure
b=song->mididata.track[song->CurrentTrack].data[song->CurrentPos];
song->CurrentPos++;
b &= 0x7F;
AddEvent(song, atime, MEVT_SHORTMSG, (byte)((laststatus<<4)+lastchan+0x80), a, b);
break;
case 3: // Control change
b=song->mididata.track[song->CurrentTrack].data[song->CurrentPos];
song->CurrentPos++;
b &= 0x7F;
AddEvent(song, atime, MEVT_SHORTMSG, (byte)((laststatus<<4)+lastchan+0x80), a, b);
break;
case 4: // Program change
a &= 0x7f;
AddEvent(song, atime, MEVT_SHORTMSG, (byte)((laststatus<<4)+lastchan+0x80), a, 0);
break;
case 5: // Channel pressure
a &= 0x7f;
AddEvent(song, atime, MEVT_SHORTMSG, (byte)((laststatus<<4)+lastchan+0x80), a, 0);
break;
case 6: // Pitch wheel
b=song->mididata.track[song->CurrentTrack].data[song->CurrentPos];
song->CurrentPos++;
b &= 0x7F;
AddEvent(song, atime, MEVT_SHORTMSG, (byte)((laststatus<<4)+lastchan+0x80), a, b);
break;
default:
break;
}
}
}
}
static int BlockOut(NativeMidiSong *song)
{
MMRESULT err;
int BlockSize;
if ((song->MusicLoaded) && (song->NewEvents))
{
// proff 12/8/98: Added for savety
midiOutUnprepareHeader((struct HMIDIOUT__ *)hMidiStream,&song->MidiStreamHdr,sizeof(MIDIHDR));
if (song->NewPos>=song->NewSize)
return 0;
BlockSize=(song->NewSize-song->NewPos);
if (BlockSize<=0)
return 0;
if (BlockSize>36000)
BlockSize=36000;
song->MidiStreamHdr.lpData=(void *)((byte *)song->NewEvents+song->NewPos);
song->NewPos+=BlockSize;
song->MidiStreamHdr.dwBufferLength=BlockSize;
song->MidiStreamHdr.dwBytesRecorded=BlockSize;
song->MidiStreamHdr.dwFlags=0;
// lprintf(LO_DEBUG,"Data: %p, Size: %i\n",MidiStreamHdr.lpData,BlockSize);
err=midiOutPrepareHeader((struct HMIDIOUT__ *)hMidiStream,&song->MidiStreamHdr,sizeof(MIDIHDR));
if (err!=MMSYSERR_NOERROR)
return 0;
err=midiStreamOut(hMidiStream,&song->MidiStreamHdr,sizeof(MIDIHDR));
return 0;
}
return 1;
}
static void MIDItoStream(NativeMidiSong *song)
{
int BufferPos[MIDI_TRACKS];
MIDIEVENT *CurEvent;
MIDIEVENT *NewEvent;
int lTime;
int Dummy;
int Track;
//if (!hMidiStream)
//return;
song->NewSize=0;
for (song->CurrentTrack=0;song->CurrentTrack<MIDI_TRACKS;song->CurrentTrack++)
{
song->MidiEvents[song->CurrentTrack]=NULL;
song->BytesRecorded[song->CurrentTrack]=0;
song->BufferSize[song->CurrentTrack]=0;
MidiTracktoStream(song);
song->NewSize+=song->BytesRecorded[song->CurrentTrack];
BufferPos[song->CurrentTrack]=0;
}
song->NewEvents=realloc(song->NewEvents,song->NewSize);
if (song->NewEvents)
{
song->NewPos=0;
while (1)
{
lTime=INT_MAX;
Track=-1;
for (song->CurrentTrack=MIDI_TRACKS-1;song->CurrentTrack>=0;song->CurrentTrack--)
{
if ((song->BytesRecorded[song->CurrentTrack]>0) && (BufferPos[song->CurrentTrack]<song->BytesRecorded[song->CurrentTrack]))
CurEvent=(MIDIEVENT *)((byte *)song->MidiEvents[song->CurrentTrack]+BufferPos[song->CurrentTrack]);
else
continue;
if ((int)CurEvent->dwDeltaTime<=lTime)
{
lTime=CurEvent->dwDeltaTime;
Track=song->CurrentTrack;
}
}
if (Track==-1)
break;
else
{
CurEvent=(MIDIEVENT *)((byte *)song->MidiEvents[Track]+BufferPos[Track]);
BufferPos[Track]+=12;
NewEvent=(MIDIEVENT *)((byte *)song->NewEvents+song->NewPos);
memcpy(NewEvent,CurEvent,12);
song->NewPos+=12;
}
}
song->NewPos=0;
lTime=0;
while (song->NewPos<song->NewSize)
{
NewEvent=(MIDIEVENT *)((byte *)song->NewEvents+song->NewPos);
Dummy=NewEvent->dwDeltaTime;
NewEvent->dwDeltaTime-=lTime;
lTime=Dummy;
if ((song->NewPos+12)>=song->NewSize)
NewEvent->dwEvent |= MEVT_F_CALLBACK;
song->NewPos+=12;
}
song->NewPos=0;
song->MusicLoaded=1;
//BlockOut(song);
}
for (song->CurrentTrack=0;song->CurrentTrack<MIDI_TRACKS;song->CurrentTrack++)
{
if (song->MidiEvents[song->CurrentTrack])
free(song->MidiEvents[song->CurrentTrack]);
}
}
if (!mididata)
return;
if (!fp)
return;
fread(&midihdr,1,14,fp);
mididata->divisions=BE_SHORT(midihdr.deltatime);
for (i=0;i<BE_SHORT(midihdr.tracks);i++)
{
fread(&trackhdr,1,8,fp);
mididata->track[i].len=BE_LONG(trackhdr.size);
mididata->track[i].data=malloc(mididata->track[i].len);
if (mididata->track[i].data)
fread(mididata->track[i].data,1,mididata->track[i].len,fp);
}
mididata->loaded=1;
}