Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Code Snippets / Read MIDI data in DarkBasic

Author
Message
ironhoof
21
Years of Service
User Offline
Joined: 3rd Sep 2002
Location:
Posted: 14th Nov 2002 07:06
This is obviously not finished but it will return some of the events so far, use this on DB's LESSONS.MID since i started decoding in the order i recieved the commands in that Midi, now thesecond snippet under that is the midi decoding documentation I used.

open to read 1,"lessons.mid"
Header$=ByteChunk$(1,3)
print Header$
HeaderSize$=ByteHex$(1,3)
print HeaderSize$
MidiFormat$=ByteHex$(1,1)
print MidiFormat$
MidiTracks$=ByteHex$(1,1)
print MidiTracks$
DeltaTime$=ByteHex$(1,1)
print DeltaTime$
tracknex:
print
TrackHeader$=ByteChunk$(1,3)
print TrackHeader$
MidiData$=ByteHex$(1,3)
print MidiData$
TrkDeltaTime$=ByteHex$(1,0)
print TrkDeltaTime$

recall:
wait key:cls
Command$=ByteHex$(1,0)
if command$="FF " then Dose$="- Midi Meta Event / ":print command$+Dose$;:goto recall:
if command$="51 " then Dose$="- Set Tempo"arms=2:Typ=0
if command$="00 " then Dose$="- Set Track Sequencer Number"arms=1:Typ=0
if command$="58 " then Dose$="- Time Signature"arms=3:Typ=0
if command$="59 " then Dose$="- Key Signature"arms=3:typ=0
if command$="2F " then Dose$="- End Of Track":Leng$=ByteHex$(1,0):fin=1
if command$="03 " then Dose$="- Sequence Or TrackName":goto txtdat:

print command$+Dose$:if fin=1 then fin=0:goto tracknex:

Leng$=ByteHex$(1,0)
if typ=0 then Para$=ByteHex$(1,Parms) else Para$=ByteChunk$(1,Parms)
print "Parameters - "+leng$+" - "+Para$
something$=ByteHex$(1,0)
print "Data - "+something$
goto recall:

txtdat:
print command$+Dose$
Leng$=ByteHex$(1,0):GLong=HexVal(Leng$)
Txt$=ByteChunk$(1,GLong-1)
print "TEXT - "+Leng$+"- "+Txt$
something$=ByteHex$(1,0)
print "Data - "+something$
goto recall:
end


function ByteChunk$(Filenumber,Chunklength)
tmp$=""
for i=0 to Chunklength
read byte Filenumber,N
tmp$=tmp$+chr$(N)
next i
endfunction tmp$

function ByteHex$(Filenumber,Chunklength)
tmp$=""
for i=0 to Chunklength
read byte Filenumber,N
if len(Hex$(N))=1 then fore$="0"+Hex$(N) else fore$=Hex$(N)
tmp$=tmp$+fore$+" "
next i
endfunction tmp$

function HexVal(hexnum$)
if len(hexnum$)=1 then h$="0"+hexnum$:hexnum$=h$
NYBBLE$=mid$(hexnum$,1):V=0
if val(NYBBLE$)>0 then V=Val(NYBBLE$)
if NYBBLE$="A" then V=10
if NYBBLE$="B" then V=11
if NYBBLE$="C" then V=12
if NYBBLE$="D" then V=13
if NYBBLE$="E" then V=14
if NYBBLE$="F" then V=15
NYBBLE$=mid$(hexnum$,2):V2=V*16:V=0
if val(NYBBLE$)>0 then V=Val(NYBBLE$)
if NYBBLE$="A" then V=10
if NYBBLE$="B" then V=11
if NYBBLE$="C" then V=12
if NYBBLE$="D" then V=13
if NYBBLE$="E" then V=14
if NYBBLE$="F" then V=15
endfunction V2+V


MIDI DATA READ BY - DUSTON CALDWELL (Free to distribute)
Standard MIDI File Format
Dustin Caldwell

The standard MIDI file format is a very strange beast. When viewed as a
whole, it can be quite overwhelming. Of course, no matter how you look at it,
describing a piece of music in enough detail to be able to reproduce it
accurately is no small task. So, while complicated, the structure of the midi
file format is fairly intuitive when understood.
I must insert a disclaimer here that I am by no means an expert with
midi nor midi files. I recently obtained a Gravis UltraSound board for my PC,
and upon hearing a few midi files (.MID) thought, "Gee, I'd like to be able to
make my own .MID files." Well, many aggravating hours later, I discovered that
this was no trivial task. But, I couldn't let a stupid file format stop me.
(besides, I once told my wife that computers aren't really that hard to use,
and I'd hate to be a hypocrite) So if any errors are found in this
information, please let me know and I will fix it. Also, this document's scope
does not extend to EVERY type of midi command and EVERY possible file
configuration. It is a basic guide that should enable the reader (with a
moderate investment in time) to generate a quality midi file.

1. Overview

A midi (.MID) file contains basically 2 things, Header chunks and Track
chunks. Section 2 explains the header chunks, and Section 3 explains the track
chunks. A midi file contains ONE header chunk describing the file format,
etc., and any number of track chunks. A track may be thought of in the same
way as a track on a multi-track tape deck. You may assign one track to each
voice, each staff, each instrument or whatever you want.

2. Header Chunk

The header chunk appears at the beginning of the file, and describes the
file in three ways. The header chunk always looks like:

4D 54 68 64 00 00 00 06 ff ff nn nn dd dd

The ascii equivalent of the first 4 bytes is MThd. After MThd comes the 4-byte
size of the header. This will always be 00 00 00 06, because the actual header
information will always be 6 bytes.

ff ff is the file format. There are 3 formats:

0 - single-track
1 - multiple tracks, synchronous
2 - multiple tracks, asynchronous

Single track is fairly self-explanatory - one track only. Synchronous multiple
tracks means that the tracks will all be vertically synchronous, or in other
words, they all start at the same time, and so can represent different parts
in one song. Asynchronous multiple tracks do not necessarily start at the same
time, and can be completely asynchronous.

nn nn is the number of tracks in the midi file.

dd dd is the number of delta-time ticks per quarter note. (More about this
later)


3. Track Chunks

The remainder of the file after the header chunk consists of track chunks.
Each track has one header and may contain as many midi commands as you like.
The header for a track is very similar to the one for the file:

4D 54 72 6B xx xx xx xx

As with the header, the first 4 bytes has an ascii equivalent. This one is
MTrk. The 4 bytes after MTrk give the length of the track (not including the
track header) in bytes.
Following the header are midi events. These events are identical to the
actual data sent and received by MIDI ports on a synth with one addition. A
midi event is preceded by a delta-time. A delta time is the number of ticks
after which the midi event is to be executed. The number of ticks per quarter
note was defined previously in the file header chunk. This delta-time is a
variable-length encoded value. This format, while confusing, allows large
numbers to use as many bytes as they need, without requiring small numbers to
waste bytes by filling with zeros. The number is converted into 7-bit bytes,
and the most-significant bit of each byte is 1 except for the last byte of the
number, which has a msb of 0. This allows the number to be read one byte at a
time, and when you see a msb of 0, you know that it was the last (least
significant) byte of the number. According to the MIDI spec, the entire delta-
time should be at most 4 bytes long.
Following the delta-time is a midi event. Each midi event (except a
running midi event) has a command byte which will always have a msb of 1 (the
value will be >= 128). A list of most of these commands is in appendix A. Each
command has different parameters and lengths, but the data that follows the
command will have a msb of 0 (less than 128). The exception to this is a meta-
event, which may contain data with a msb of 1. However, meta-events require a
length parameter which alleviates confusion.
One subtlety which can cause confusion is running mode. This is where
the actual midi command is omitted, and the last midi command issued is
assumed. This means that the midi event will consist of a delta-time and the
parameters that would go to the command if it were included.

4. Conclusion

If this explanation has only served to confuse the issue more, the
appendices contain examples which may help clarify the issue. Also, 2
utilities and a graphic file should have been included with this document:

DEC.EXE - This utility converts a binary file (like .MID) to a tab-delimited
text file containing the decimal equivalents of each byte.

REC.EXE - This utility converts a tab-delimited text file of decimal values
into a binary file in which each byte corresponds to one of the decimal
values.

Appendix A

1. MIDI Event Commands

Each command byte has 2 parts. The left nybble (4 bits) contains the actual
command, and the right nybble contains the midi channel number on which the
command will be executed. There are 16 midi channels, and 8 midi commands (the
command nybble must have a msb of 1).
In the following table, x indicates the midi channel number. Note that all
data bytes will be
-----\
There was a man on the stairs that wasn't there.
He wasn't there agian today I think he's from the CIA.
Mirthin
21
Years of Service
User Offline
Joined: 13th Oct 2002
Location: Land of the Rising Haggis
Posted: 14th Nov 2002 16:28
Hold the phone. You do seem to know a fair bit about MIDI, so I was wondering if you could help me out. I was wondering: can DarkBASIC read MIDI cues from the file? A cue is an event that marks a place, If I could use such markers, I could give the illusion of a repeating song with a start and end. It's hard to explain, but here's what the event looks like:

Min:Sec:Frames=0:00:00, Marker: Start

This means at 0 seconds into the file, there's a marker called "Start."

With MIDI events, traditionally the file was started, and a user played the level. Since some players were slower than others, the MIDI is looped around. When the level ends, the MIDI is allowed to go beyond the turnaround point and finish. Without cues, as in earlier games (Like Kyrandia 2 and Lands of Lore) they were separate files. The single file system is just more convenient. TIA, Mirthin.

This has "Fiasco" written all over it.
The Darthster
21
Years of Service
User Offline
Joined: 25th Sep 2002
Location: United Kingdom
Posted: 15th Nov 2002 00:14
There is an easier way to make midi's, using Noteworthy Composer, although this requires you know enough music theory to write music (you don't have to, but if you can't read music then you are not likely to be able to write good music). Have a look at http://www.noteworthysoftware.com/

This could be quite useful for me, I'm interested in music and would like to make a midi editor in DB. Appendix A doesn't look finished, however.
empty
21
Years of Service
User Offline
Joined: 26th Aug 2002
Location: 3 boats down from the candy
Posted: 15th Nov 2002 02:18
Mirthin:
AFAIK DB can't read cues or markers in MidiFiles.
I hoped that DBPro would fully support DirectMusic8 including DLS and scripts. This would make seamless transitions very easy.

ironHoof:
Very nice snippet. (Maybe a tad too many gotos in it )

Ogres have layers.
ironhoof
21
Years of Service
User Offline
Joined: 3rd Sep 2002
Location:
Posted: 16th Nov 2002 11:05
Ah but its not abou an easier way to makemidi's the midi editor is a project I woul like to do for many reasons not because its practicle. Sometimes I feel the ned to do it because I never done it before. =) and to simply point out it would definately make a showcase to have a nice gui darkbasic made media editor, "not that im trying to get another showcase..." Im just saying its something that hasnt been done in DB yet far as I am aware of.

-----\
There was a man on the stairs that wasn't there.
He wasn't there agian today I think he's from the CIA.
David T
Retired Moderator
21
Years of Service
User Offline
Joined: 27th Aug 2002
Location: England
Posted: 30th Nov 2002 16:20
Very impressive, not that I'd understand it!

I love Star Trek.
Especially the Episodes with Starships in.
Dark Gamez
21
Years of Service
User Offline
Joined: 4th Dec 2002
Location:
Posted: 5th Dec 2002 21:56
I can do that to!

load music "lesson.mid",1
play music 1

Login to post a reply

Server time is: 2024-04-17 00:04:40
Your offset time is: 2024-04-17 00:04:40