MajicDesigns/MD_MIDIFile

No Midi output use!

derGraph opened this issue · 10 comments

Hello,
How is it possible to just use the Serial output without the midi stream?
How would the sketch look like?
What are the needed Commands?
For me its not clear out of the examples.

Thanks, Paul

I am really not sure what you are asking. Perhaps if you describe what you are trying to do rather than the problem you think you have it may be clearer.

If you are sending the MIDI data out of the serial port, then that serial stream is the MIDI stream and you can't be sending other data in the stream or you will confuse the MIDI device at the other end. If you have more than one hardware serial ouput (eg a MEGA processor board) or use the SoftwareSerial library, then you split the streams and write appropriate data to each stream (eg, MIDI out one and other data through the other).

Most of the examples have a #define that allows to switch the serial output to a formatted print for debugging purposes. This choice is made in the MD_MIDIFile callback function, so you should look there.

I want a midi stream over the serial monitor with delays. I dont need anything else. I would like a basic sketch whats really needed for the lib.

By "with delays" I assume you mean with the correct timing for the music playback.

The simplest example is MIDIFile_Loop, which plays the same file over the serial port, over and over again. You need to change the name of the file to your own in the code.

image
Now I at the end of the line, there is a Question Mark and then 2 random chars.
I edited the code a bit but before it did it too

`// Play a file from the SD card in looping mode, from the SD card.
// Example program to demonstrate the use of the MIDFile library
//
// Hardware required:
// SD card interface - change SD_SELECT for SPI comms

#include <SdFat.h>
#include <MD_MIDIFile.h>

#define USE_MIDI 0 // set to 1 for MIDI output, 0 for debug output

#define DEBUGS(s) Serial.print(s)
#define DEBUG(s, x) { Serial.print(F(s)); Serial.print(x); }
#define DEBUGX(s, x) { Serial.print(F(s)); Serial.print(x, HEX); }
#define SERIAL_RATE 57600

const uint8_t SD_SELECT = 53;

#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))

// The files in the tune list should be located on the SD card
// or an error will occur opening the file and the next in the
// list will be opened (skips errors).
const char *loopfile = "bh.mid"; // simple and short file

SdFat SD;
MD_MIDIFile SMF;

void midiCallback(midi_event *pev)
// Called by the MIDIFile library when a file event needs to be processed
// thru the midi communications interface.
// This callback is set up in the setup() function.
{
Serial.write(pev->data, pev->size);
DEBUG("\nM T", pev->track);
DEBUG(": Ch ", pev->channel+1);
DEBUGS(" Data");
for (uint8_t i=0; isize; i++)
{
DEBUGX(" ", pev->data[i]);
}
}

void setup(void)
{
int err;
Serial.begin(SERIAL_RATE);
DEBUGS("\n[MidiFile Looper]");
// Initialize SD
if (!SD.begin(SD_SELECT, SPI_FULL_SPEED))
{
DEBUGS("\nSD init fail!");
while (true) ;
}

// Initialize MIDIFile
SMF.begin(&SD);
SMF.setMidiHandler(midiCallback);
SMF.looping(true);

// use the next file name and play it
DEBUG("\nFile: ", loopfile);
err = SMF.load(loopfile);
if (err != MD_MIDIFile::E_OK)
{
DEBUG("\nSMF load Error ", err);
while (true);
}
}

void loop(void)
{
// play the file
if (!SMF.isEOF())
{
SMF.getNextEvent();
}
}`

Ok, found the error, it was the Serial.write(pev->data, pev->size);
Can I use the code without the DEBUG();
What is it for.

DEBUG is for debugging. Just turn it off at the top of the file (#define USE_MIDI).

Yes but how can I replace it with a Serial.println();

Serial.write() writes the data to the serial output. That is already there. Serial.println() would be incorrect as it adds in an end of line to the stream.

It looks like you have edited the example file. I would recommend that you go back to the original version and try just changing the USE_MIDI and the file name, nothing else.

So, I got this
How can I test if its the end of the song?

The isEOF() method tells you when you have reached the end of the file.

From the library documentation:

Check if SMF is and end of file

An SMF is at EOF when there is nothing left to play (ie, all tracks have finished). The method will return EOF true when this condition is reached.

Returns
true if the SMF is at EOF, false otherwise.

The use is illustrated in ALL the examples, as they all need to know when the file is finished.

Please take some time to at least scan the documentation to understand what each function does. The doc is in the library folder under docs - open the index.html file.