static bool displayNotesPlayed = false; //Stores whether the notes that the user played should be displayed or not #region Form Triggered Methods public frmTest(midiFile _inputMidi, databaseInterface _databaseInterface) { InitializeComponent(); currentMidiFile = _inputMidi; //new midiFile(_inputMidi.devision, _inputMidi.tempo, _inputMidi.timeSig, _inputMidi.keySig, _inputMidi.listOfNotes, _inputMidi.Instrument, _databaseInterface, out bool error, out string errorString); databaseInterface = _databaseInterface; currentMidiFile.GenerateMusicPage(picDisplay.Width, picDisplay.Height, 0, ckbFingering.Checked, false, out Bitmap pageToDisplay, out nextFirstStaff, out string errorString); picDisplay.Image = pageToDisplay; }
public frmViewMusic(midiFile inputFile) { string errorString; loadedMidiFile = inputFile; InitializeComponent(); //Load bitmaps loadedMidiFile.GenerateMusicPage(picDisplay.Width, picDisplay.Height, 0, false, false, out Bitmap pageToDisplay, out int nextLine, out errorString); picDisplay.Image = pageToDisplay; }
/// <summary> /// Parses the MIDI file into the midiFile class /// </summary> /// <param name="midiStream">The Stream that should be parsed</param> /// <param name="outputMidiFile">The MIDI File class that will be outputted filled with data</param> /// <param name="errorString">In case the file could not be parsed, then this will contain the error</param> /// <returns>Returns whether the parse was sucsessful</returns> private bool ParseMidiFile(Stream midiStream, string instrument, out midiFile outputMidiFile, out string errorString) { #region Variables byte currentbyte; //Stores the current byte being processed byte statusCarry; //Stores the last status byte for use by status carry bool end = false; //Has the end of the file been reached? uint chunkType; uint currentChunkLength; //Stores the length of the current chunk outputMidiFile = null; //Stores the parsed midiFile errorString = null; //Stores any error messages that are generated List <Note> listOfNotes; //List to store the parsed notes ushort format; //Stores the Midi file's format. (The program can only deal with format 0 MIDI files) ushort numOfTracks; //Store the number of track chuhnks to be found in the file. Should be 1 for Format 0 files ushort division; //Store the pace of the MIDI file #endregion #region Parse Head Chunk #region Get data from stream //Chunk Type (4 bytes) - Will be either "MThd" for the head chunk or "MTrk" for track chunk in ASCII. chunkType = (uint)((midiStream.ReadByte() << 24) | (midiStream.ReadByte() << 16) | (midiStream.ReadByte() << 8) | (midiStream.ReadByte())); //Gets the chunk type //Length (4 bytes) - In Head chunk, should always be 6 currentChunkLength = (uint)((midiStream.ReadByte() << 24) | (midiStream.ReadByte() << 16) | (midiStream.ReadByte() << 8) | (midiStream.ReadByte())); //Convert the 4 bytes into 1 integer. First byte times by 16^6 plus the second byte times 16^4 and so on //Format (2 byte) - Should be either 0, 1 or 2. This program can only deal with format 0 MIDI Files format = (ushort)((midiStream.ReadByte() << 8) | (midiStream.ReadByte())); //Number of Tracks (2 bytes) - Should be 1 for format 0 MIDI files numOfTracks = (ushort)((midiStream.ReadByte() << 8) | (midiStream.ReadByte())); //Division (2 bytes) - Stores the speed and the tempo of the MIDI File. Can either store the Number of delta time units in a crochet, or the number of frames per second and the number of ticks per frame. Outlined below. division = (ushort)((midiStream.ReadByte() << 8) | (midiStream.ReadByte())); /* Bit: | 15 | 14 - 8 | 7 - 0 | * | 0 | Ticks per crochet | * | 1 |-frames/second|ticks/frame| */ #endregion #region Validate data //Make sure all aspects of the head chunks are valid, if they are not, then output an error and return that the parse failed if (chunkType != 0x4d546864) { errorString = "Head Chunk title not found"; return(false); } else if (currentChunkLength != 6) { errorString = "Head Chunk invalid length"; return(false); } else if (format != 0) { errorString = "Format not valid"; return(false); } else if (numOfTracks != 1) { errorString = "Invalid number of Track Chunks"; return(false); } else if (division > 0x8000) { errorString = "Invalid division format"; return(false); } #endregion #endregion #region Parse Track Chunk //Chunk Type (4 bytes) - Will be either "MThd" for the head chunk or "MTrk" for track chunk in ASCII. chunkType = (uint)((midiStream.ReadByte() << 24) | (midiStream.ReadByte() << 16) | (midiStream.ReadByte() << 8) | (midiStream.ReadByte())); //Gets the chunk type //Length (4 bytes) currentChunkLength = (uint)((midiStream.ReadByte() << 24) | (midiStream.ReadByte() << 16) | (midiStream.ReadByte() << 8) | (midiStream.ReadByte())); //Convert the 4 bytes into 1 integer. First byte times by 16^6 plus the second byte times 16^4 and so on //If the chunk type is not the track chunk, then display the error and exit the function if (chunkType != 0x4d54726b) { errorString = "Could not find Track Chunk"; return(false); } //Read MIDI Track Data. If the track data could not be read properly, end the function if (!ReadTrackData(midiStream, currentChunkLength, out listOfNotes, out errorString)) { return(false); } #endregion //Create the new midiFile and assign it the values that have been read from the stream outputMidiFile = new midiFile(division, null, null, null, listOfNotes, instrument, new databaseInterface(dbConnectionString), out bool error, out errorString); //Un-grey out the buttons to allow the people to choose other forms btnLookAtMusic.Enabled = true; btnTest.Enabled = true; return(true); }