Problem with MIDI-protocol

Hi everybody,
I have some troubles with the well-known MIDI-protocol. I am trying to make some kind of program that is able to generically generate .midi music. It is not that complicated yet, so do not bother with it, in fact I am just running tests right now. I have this problem when I try to play a self generated MIDI-file with only one note. I was able to copy a existing midi in code (rdbuf()), so it is not my compiler's fault (Dev-C++ 4.9.9.2). I would rather not work with MIDI-libraries so as to only use my own code.
After some hard work on the Internet i finally managed to get the information I needed about MIDI on byte level. I made the midi with fstream and afterwards I wrote a few lines C++ to test if I could correctly apply my newly aquired knowledge. This is the program:

1
2
3
4
5
6
7
8
9
10
#include <fstream>
int main()
{
  std::ifstream MIDI("MIDI.mid");      //my created sequence (does not work)
  std::ofstream test("txt.txt");       //(I like palindromes)
  test<<std::hex;
  while(!MIDI.fail())
  {
    test<<MIDI.get()<<'\n';
  }

in file txt.txt:

4d
54
68
64
0
0
0
6
0
0
0
1
0
60
4d
54\72
6b
0
0
0
b
1
91
3c
f
66
81
3c
f
ff
2f
0
ffffffff

I started with the header chunk,
then a track chunk,
a note on and
a note off event,
and a end-of-track meta-event.
I have no idea where the large number at the end comes from, is it the cause of all the trouble? When i open MIDI.mid with Notepad, the number 0xffffffff is not represented in Unicode-character, so I cannot get it out of the file. I guess it is just a glitch. The problem occurs when I try to play the file. Windows Media Player starts complaining about insufficient memory so I guess I forgot some kind of EOF event. I also tried Synthesia, becuase I know Windows long enough, but it also refuses to play my file... For the interested, my knowledge originates form this lovely tutorial:
http://www.sonicspot.com/guide/midifiles.html
if you see the error, PLEASE contact me. C++ is my hobby, I learned C++ from a book, so I do not have a teacher to answer my questions. You people are my only hope...

Atleast thanks for reading!

Kind regards,
Niels Meijer
get() returns -1 when the stream reaches the EOF. fail() doesn't check if the stream has reached the EOF. Check good(), instead.

Windows Media Player starts complaining about insufficient memory so I guess I forgot some kind of EOF event. I also tried Synthesia, becuase I know Windows long enough, but it also refuses to play my file
Well, my first question would be: when you generated the file, did you open the stream as text or as binary?
Wow, I didn't expect such a fast answer! I took your advice and to make a long story short here is the complete sourcecode of my program:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <fstream>
#include <iomanip>
//#define show
#define write
int main()
{
#ifdef show
  std::ifstream MIDI("MIDI.mid");
  std::ofstream test("txt.txt");
  test<<std::hex;
  while(MIDI.good())
  {
    test<<MIDI.get()<<'\n';
  }
  MIDI.close();
  test.close();
#endif
#ifdef write
  std::ofstream MIDI("MIDI.mid",std::ios::binary);
  MIDI.put('M');
  MIDI.put('T');
  MIDI.put('h');
  MIDI.put('d');
  MIDI.put('\x0');
  MIDI.put('\x0');
  MIDI.put('\x0');
  MIDI.put('\x6');
  MIDI.put('\x0');
  MIDI.put('\x0');
  MIDI.put('\x0');
  MIDI.put('\x1');
  MIDI.put('\x0');
  MIDI.put('\x60');
  MIDI.put('M');
  MIDI.put('T');
  MIDI.put('r');
  MIDI.put('k');
  MIDI.put('\x0');
  MIDI.put('\x0');
  MIDI.put('\x0');
  MIDI.put('\xB');
  MIDI.put('\x1');
  MIDI.put('\x91');
  MIDI.put('\x3C');
  MIDI.put('\xF');
  MIDI.put('\x66');
  MIDI.put('\x81');
  MIDI.put('\x3C');
  MIDI.put('\xF');
  MIDI.put('\xFF');
  MIDI.put('\x2F');
  MIDI.put('\x0');
  MIDI.close();
#endif
  std::cin.get();
  return 0;
}

MIDI.mid remains unplayable so I guess the fault lies in my MIDI-syntax.
After uncommenting the forth line I placed '//' before line 5. This is the content of txt.txt:

4d
54
68
64
0
0
0
6
0
0
0
1
0
60
4d
54
72
6b
0
0
0
b
1
91
3c
f
66
81
3c
f
ff
2f
0
ffffffff

Where in the world does 0xffffffff come from? Did I apply good() correctly?
Although I still can't play MIDI.mid, nevertheless thanks for your fast answer!
I guess get() only sets the EOF flag if it's called while the stream is at the EOF, and not if it returns while at the EOF. I swear, the C I/O semantics must have been designed by an inhabitant of the Backwards Dimension.
1
2
3
4
5
6
while(1){
    char c=MIDI.get();
    if (!MIDI.good())
        break;
    test<<c<<'\n';
}


Personally, unless I have reasons not to (memory constraints, for example), I just open everything as binary and load entire files to memory. Saves me the trouble of dealing with this backwards BS, and it's more efficient.

Ah! the number at the end has disappeared! I only had to use an int instead of a char, because char would put ASCII graphs instead of hexadecimal numbers in txt.txt. Thanks again! And I agree about the semantics designers.

Ok, so now my C++ code is fine, but does anyone know what is wrong with the MIDI syntax? I still can't play the file...

The MIDI protocol is so simple, and yet capable of fustrating newbies like me this much!
Topic archived. No new replies allowed.