yeah, they're not very clear on that nowhere, that's why I wrote that MIDI
series. It's long to explain because what you do in it depends on other
factors, but here's a function (hopefully it will work in RB)....that should
help clarify what to do with it when you need to. it's commented so
hopefully it will be clear in code, and what it's trying to do :-).
This function would display information about what it's reading from the
header...so the print statements should help you see what's being read from
the header.
' =======================================================
' NAME: ReadMIDIFileFormatProperties()
' PARAMETERS: MidiHandle AS INTEGER
' Position AS INTEGER
' EndOfTrack AS INTEGER
' ASSUMES: MidiHandle links to already Opened File
' RETURNS: A String containing MIDI File Properties
' CALLED FROM: The ReadMIDIFile() Function
' -------------------------------------------------------
' DESCRIPTION: This function takes the pass MIDI file
' handle and current position in the file
' and gets information from the file that
' it adds to a string. When it is done,
' it will return that string to the
' calling function (ReadMIDIFile in this
' case).
' =======================================================
FUNCTION MIDIFileFormatProperties( BYREF MidiHandle AS INTEGER, _
BYVAL Position AS INTEGER, _
BYREF EndOfTrack AS INTEGER ) AS STRING
' ----------------
' Work Variables
' ----------------
DIM Counter AS LONG
DIM Bytes AS LONG
DIM DataByte AS BYTE
DIM DataByte2 AS BYTE
DIM DataByte3 AS BYTE
DIM DataByte4 AS BYTE
DIM DataByte5 AS BYTE
DIM WorkString AS STRING
DIM WorkItem AS STRING * 13
' -----------------------------------------
' We Get the next byte from the MIDI file
' -----------------------------------------
GET #MidiHandle, Position, DataByte2
Position = Position + 1
' ------------------------------------------------------
' IF the byte read is 0 we can get the sequence number
' ------------------------------------------------------
IF DataByte2 = 0 THEN
GET #MidiHandle, Position, DataByte3
Position = Position + 1
IF DataByte3 = 0 Then
WorkString = WorkString + "seqnr/posfile"
ELSE
GET #MidiHandle, Position, DataByte4
Position = Position + 1
GET #MidiHandle, Position, DataByte5
Position = Position + 1
WorkString = WorkString + "Sequence Number " + _
CStr(B5 * 256 + B4)
END IF
' -----------------------------------------------------
' If the byte read is between 1 and 7 inclusively, we
' can get some more specific information.
' -----------------------------------------------------
ELSEIF DataByte2 >= 1 AND DataByte2 <= 7 THEN
SELECT CASE DataByte2
CASE 1
WorkItem = "text" + " - "
CASE 2
WorkItem = "copyright" + " - "
CASE 3
WorkItem = "seq/tr. name" + " - "
CASE 4
WorkItem = "instrument" + " - "
CASE 5
WorkItem = "lyric" + " - "
CASE 6
WorkItem = "marker" + " - "
CASE 7
WorkItem = "cue point" + " - "
END SELECT
WorkString = WorkString & WorkItem
Bytes = GetVariableLength(MidiHandle, Position)
FOR Counter = 1 To Bytes
Get #MidiHandle, Position, DataByte
Position = Position + 1
WorkString = Workstring + CHR$(DataByte)
NEXT Counter
' ------------------------------------------------------
' IF the byte read is &H20 we can get the MIDI Channel
' ------------------------------------------------------
ELSEIF DataByte2 = &H20 Then
WorkString = WorkString + "midi channel "
Get #MidiHandle, Position, DataByte3
Position = Position + 1
Get #MidiHandle, Position, DataByte4
Position = Position + 1
If DataByte3 <> 0 Then WorkString = WorkString + "Length Error"
WorkString = WorkString + HexByte(DataByte4)
' ----------------------------------------------------------
' IF the byte read is &H21 we can get the MIDI Port Number
' ----------------------------------------------------------
ELSEIF DataByte2 = &H21 Then
WorkString = WorkString + "midi port "
Get #MidiHandle, Position, DataByte3
Position = Position + 1
Get #MidiHandle, Position, DataByte4
Position = Position + 1
If DataByte3 <> 0 THEN WorkString = WorkString + "Length Error"
WorkString = WorkString + HexByte(DataByte4)
' -------------------------------------------------------------
' A byte value of &H21 indicates the End of the current track
' -------------------------------------------------------------
ElseIf DataByte2 = &H2F Then
WorkString = WorkString + "end of track "
Get #MidiHandle, Position, DataByte3
Position = Position + 1
EndOfTrack = True
' -----------------------------------------------------------
' A byte value of &H51 Means we're reading the song's tempo
' -----------------------------------------------------------
ELSEIF DataByte2 = &H51 THEN
WorkString = WorkString + "tempo "
GET #MidiHandle, Position, DataByte3
Position = Position + 1
Bytes = DataByte3
If Bytes <> 3 Then WorkString = WorkString + "Length Error"
GET #MidiHandle, Position, DataByte3
Position = Position + 1
GET #MidiHandle, Position, DataByte4
Position = Position + 1
GET #MidiHandle, Position, DataByte5
Position = Position + 1
WorkString = WorkString + _
CStr(CLng(60000000 / CLng(CLng(DataByte3) * _
256 * 256 + CLng(DataByte4) * 256 + _
CLng(DataByte5)))) + " BPM"
' -----------------------------------------------------
' A byte value of &H54 Gets SMPTE Offsets Information
' -----------------------------------------------------
ELSEIF DataByte2 = &H54 THEN
WorkString = WorkString + "SMPTE Offs "
GET #MidiHandle, Position, DataByte3
Position = Position + 1
Bytes = DataByte3
IF Bytes <> 5 THEN WorkString = WorkString + "Length Error"
FOR Counter = 1 TO Bytes
Get #MidiHandle, Position, DataByte
Position = Position + 1
WorkString = WorkString + HexByte(DataByte)
NEXT Counter
' ----------------------------------------------------------
' A byte value of &H58 Indicates the song's time signature
' ----------------------------------------------------------
ELSEIF DataByte2 = &H58 THEN
WorkString = WorkString + "time sign "
GET #MidiHandle, Position, DataByte3
Position = Position + 1
Bytes = DataByte3
IF Bytes <> 4 THEN WorkString = WorkString + "Length Error"
GET #MidiHandle, Position, DataByte4
Position = Position + 1
GEt #MidiHandle, Position, DataByte5
Position = Position + 1
WorkString = WorkString + CStr(DataByte4) + "/" + _
CStr(2 ^ DataByte5) + " - "
GET #MidiHandle, Position, DataByte4
Position = Position + 1
WorkString = WorkString + DataByte4 + " clocks/metr.click - "
GET #MidiHandle, Position, DataByte5
Position = Position + 1
WorkString = WorkString + DataByte5 + " 32nd/quarter "
' ---------------------------------------------------------
' A byte value of &H59 Indicates the song's key signature
' ---------------------------------------------------------
ELSEIF DataByte2 = &H59 THEN
WorkString = WorkString + "key sign "
GET #MidiHandle, Position, DataByte3
Position = Position + 1
Bytes = DataByte3
IF Bytes <> 2 THEN WorkString = WorkString + "Length Error"
FOR Counter = 1 TO Bytes
GET #MidiHandle, Position, DataByte
Pos = Pos + 1
WorkString = WorkString + HexByte(DataByte) & " "
NEXT Counter
' -----------------------------------------------------------
' A byte value of &H7F Indicates a variable length property
' -----------------------------------------------------------
ELSEIF DataByte2 = &H7F Then
Bytes = GetVariableLength(MidiHandle, Position)
WorkString = WorkString + "propr.- len " + CStr(Bytes)
Position = Position + Bytes
END IFEMD SUB----- Original Message -----
From: "Maarten de Vries" <[EMAIL PROTECTED]>
To: "REALbasic NUG" <[email protected]>
Sent: Friday, August 11, 2006 1:24 PM
Subject: Re: MIDI type 1
But, what if it's in the header? Two bytes for the division. If the first
one is negative (last bit set) it's using frames and subframes, else just
the regular PPQN. I can't just ignore that can I? I must say I haven't
seen
a MIDI file using that, but it's in the header description... They just
don't explain it to well...
Maarten
On 11/08/06, stephane richard <[EMAIL PROTECTED]> wrote:
This is for SMPTE synchonisation.
Frames are 1 second...subframes are the number of events per
second. Mostly
used to control video instrumentation (subframes 24 subframes per second
for
example).
as far as MIDI is concerned you don't need to be concerned with these
values.
----- Original Message -----
From: "Maarten de Vries" <[EMAIL PROTECTED]>
To: "REALbasic NUG" <[email protected]>
Sent: Friday, August 11, 2006 12:55 PM
Subject: Re: MIDI type 1
> Ok, I understand, but what are the frames? and subframes? Is it just
> the
> amount of delta time per second (opposed to delta time per quarter
notes)?
> And if so, what are the subframes for, why isn't it enough to just have
> frames?
>
> Thanks,
> Maarten
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>
Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>
--
No virus found in this incoming message.
Checked by AVG Free Edition.
Version: 7.1.405 / Virus Database: 268.10.9/416 - Release Date: 8/10/2006
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>
Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>