private void button1_Click(object sender, EventArgs e) { richTextBox1.Clear(); if (openFileDialogMIDI.ShowDialog() == DialogResult.OK) // . { openMIDIFile(openFileDialogMIDI.FileName); // . } }
// MIDI. public class MIDIReaderFile { public BinaryReader BinaryReaderMIDIFile; // . MIDI . public MIDIReaderFile(Stream input) // . { BinaryReaderMIDIFile = new BinaryReader(input); // . } public UInt32 ReadUInt32BigEndian() // 4 " " . { UInt32 bufferData = 0; // = 0. for (int IndexByte = 3; IndexByte >= 0; IndexByte--) // . bufferData |= (UInt32)((UInt32)BinaryReaderMIDIFile.ReadByte()) << 8 * IndexByte; // . return bufferData; } public UInt16 ReadUInt16BigEndian() // 2 " " . { UInt16 bufferData = 0; // = 0. for (int IndexByte = 1; IndexByte >= 0; IndexByte--) // . bufferData |= (UInt16)((UInt16)BinaryReaderMIDIFile.ReadByte() << 8 * IndexByte); // . return bufferData; } public string ReadStringOf4byte() // 4 . { return Encoding.Default.GetString(BinaryReaderMIDIFile.ReadBytes(4)); // 4 4- . } public byte ReadByte() // 1 . { return BinaryReaderMIDIFile.ReadByte(); } public byte[] ReadBytes(int count) // count . { return BinaryReaderMIDIFile.ReadBytes(count); } }
// : MIDI . // : MIDI . public struct MIDIheaderStruct { public string nameSection; // . "MThd". public UInt32 lengthSection; // , 4 . 0x6; public UInt16 mode; // MIDI : 0, 1 2. public UInt16 channels; // . public UInt16 settingTime; // . }
// : MIDI . // : FileStream . // - MIDIheaderStruct. public MIDIheaderStruct CopyHeaderOfMIDIFile(MIDIReaderFile MIDIFile) { MIDIheaderStruct ST = new MIDIheaderStruct(); // . ST.nameSection = MIDIFile.ReadStringOf4byte(); // . ST.lengthSection = MIDIFile.ReadUInt32BigEndian(); // 4 . 0x6 ST.mode = MIDIFile.ReadUInt16BigEndian(); // 2 MIDI. 0, 1 2. ST.channels = MIDIFile.ReadUInt16BigEndian(); // 2 MIDI . ST.settingTime = MIDIFile.ReadUInt16BigEndian(); // 2 . return ST; // . }
// : . // : . // : . true - , false - . public bool openMIDIFile(string pathToFile) { FileStream fileStream = new FileStream(pathToFile, FileMode.Open, FileAccess.Read); // . MIDIReaderFile MIDIFile = new MIDIReaderFile(fileStream); // MIDI . . . MIDIheaderStruct HeaderMIDIStruct = CopyHeaderOfMIDIFile(MIDIFile); // . MIDIMTrkStruct[] MTrkStruct = new MIDIMTrkStruct[HeaderMIDIStruct.channels]; // MTrkStruct. richTextBox1.Text += " : " + HeaderMIDIStruct.channels.ToString() + "\n"; // . richTextBox1.Text += " : " + HeaderMIDIStruct.settingTime.ToString() + "\n"; richTextBox1.Text += " MIDI: " + HeaderMIDIStruct.mode.ToString() + "\n"; return true; }
// : MIDI . // : MIDI . public struct MIDIMTrkStruct { public string nameSection; // . "MTrk". public UInt32 lengthSection; // , 4 . public ArrayList arrayNoteStruct; // . }
// : / . public struct noteStruct { public byte roomNotes; // . public UInt32 noteTime; // . public byte dynamicsNote; // / . public byte channelNote; // . public bool flagNote; // (true) (false). }
// : MTrk ( ) MIDI . // : MIDI . // : . public MIDIMTrkStruct CopyMIDIMTrkSection(MIDIReaderFile MIDIFile) { MIDIMTrkStruct ST = new MIDIMTrkStruct(); // MIDI . ST.arrayNoteStruct = new ArrayList(); // . noteStruct bufferSTNote = new noteStruct(); // ( , arrayNoteStruct). ST.nameSection = MIDIFile.ReadStringOf4byte(); // . ST.lengthSection = MIDIFile.ReadUInt32BigEndian(); // 4 . UInt32 LoopIndex = ST.lengthSection; // . , = 0. UInt32 realTime = 0; // . while (LoopIndex != 0) // . { // . 8- ( ). byte loopount = 0; // . byte buffer; // . UInt32 bufferTime = 0; // . do { buffer = MIDIFile.ReadByte(); // . loopount++; // , . bufferTime <<= 7; // 7 (.. 1 ). bufferTime |= (byte)(buffer & (0x7F)); // . } while ((buffer & (1<<7)) != 0); // , ( = 0). realTime += bufferTime; // . buffer = MIDIFile.ReadByte(); loopount++; // -, , . // -, ... if (buffer == 0xFF) { buffer = MIDIFile.ReadByte(); // -. buffer = MIDIFile.ReadByte(); // . loopount+=2; for (int loop = 0; loop < buffer; loop++) MIDIFile.ReadByte(); LoopIndex = LoopIndex - loopount - buffer; // . } // -, , . else switch ((byte)buffer & 0xF0) // 4- . { // . case 0x80: // . bufferSTNote.channelNote = (byte)(buffer & 0x0F); // . bufferSTNote.flagNote = false; // . bufferSTNote.roomNotes = MIDIFile.ReadByte(); // . bufferSTNote.dynamicsNote = MIDIFile.ReadByte(); // . bufferSTNote.noteTime = realTime; // . ST.arrayNoteStruct.Add(bufferSTNote); // . LoopIndex = LoopIndex - loopount - 2; // . break; case 0x90: // . bufferSTNote.channelNote = (byte)(buffer & 0x0F); // . bufferSTNote.flagNote = true; // . bufferSTNote.roomNotes = MIDIFile.ReadByte(); // . bufferSTNote.dynamicsNote = MIDIFile.ReadByte(); // . bufferSTNote.noteTime = realTime; // . ST.arrayNoteStruct.Add(bufferSTNote); // . LoopIndex = LoopIndex - loopount - 2; // . break; case 0xA0: // . bufferSTNote.channelNote = (byte)(buffer & 0x0F); // . bufferSTNote.flagNote = true; // . bufferSTNote.roomNotes = MIDIFile.ReadByte(); // . bufferSTNote.dynamicsNote = MIDIFile.ReadByte(); // . bufferSTNote.noteTime = realTime; // . ST.arrayNoteStruct.Add(bufferSTNote); // . LoopIndex = LoopIndex - loopount - 2; // . break; // 2- . case 0xB0: byte buffer2level = MIDIFile.ReadByte(); // . switch (buffer2level) // . { default: // ( ). MIDIFile.ReadByte(); // - . LoopIndex = LoopIndex - loopount - 2; // . break; } break; // . case 0xC0: // . MIDIFile.ReadByte(); // . LoopIndex = LoopIndex - loopount - 1; // . break; case 0xD0: // . MIDIFile.ReadByte(); // . LoopIndex = LoopIndex - loopount - 1; // . break; case 0xE0: // . MIDIFile.ReadBytes(2); // . LoopIndex = LoopIndex - loopount - 2; // . break; } } return ST; // . }
// : : /. // : , ; . public ArrayList reateNotesArray(MIDIMTrkStruct[] arrayST, int arrayCount) { ArrayList arrayChannelNote = new ArrayList(); // . for (int indexBlock = 0; indexBlock < arrayCount; indexBlock++) // MIDI. { for (int eventArray = 0; eventArray < arrayST[indexBlock].arrayNoteStruct.Count; eventArray++) // . { noteStruct bufferNoteST = (noteStruct)arrayST[indexBlock].arrayNoteStruct[eventArray]; // . if (bufferNoteST.flagNote == true) // . { byte indexChennelNoteWrite = 0; while (true) // . { if (indexChennelNoteWrite<arrayChannelNote.Count) // . { channelNote bufferChannel = (channelNote)arrayChannelNote[indexChennelNoteWrite]; // . if (bufferChannel.ToWriteaNewNote(bufferNoteST.roomNotes, bufferNoteST.noteTime) == true) break; // - . } else // - . { channelNote noteNambeChannelBuffer = new channelNote(); // . noteNambeChannelBuffer.ToWriteaNewNote(bufferNoteST.roomNotes, bufferNoteST.noteTime);// - . arrayChannelNote.Add(noteNambeChannelBuffer); // . break; // . } indexChennelNoteWrite++; // - . } } else // . { byte indexChennelNoteWrite = 0; while (true) // . { channelNote bufferChannel = (channelNote)arrayChannelNote[indexChennelNoteWrite]; // . if (bufferChannel.EntryEndNotes(bufferNoteST.roomNotes, bufferNoteST.noteTime) == true) break;// - . indexChennelNoteWrite++; // - . } } } } return arrayChannelNote; }
// richTextBox1. public void outData(ArrayList Data) { for (int loop = 0; loop<Data.Count; loop++) // . { channelNote buffer = (channelNote)Data[loop]; // . // . richTextBox1.Text += "uint16_t channel" + loop.ToString() + "[" + buffer.arrayNoteChannel.Count.ToString() + "][2] = {"; for (int loop1 = 0; loop1 < buffer.arrayNoteChannel.Count; loop1++) { channelNote.noteInChannelNote DataD = (channelNote.noteInChannelNote)buffer.arrayNoteChannel[loop1]; richTextBox1.Text += DataD.roomNotes.ToString() + "," + DataD.noteTime.ToString(); if (loop1 != (buffer.arrayNoteChannel.Count - 1)) richTextBox1.Text += ", \t"; } richTextBox1.Text += "};\n\n"; } }
// : . // : . // : . true - , false - . public bool openMIDIFile(string pathToFile) { FileStream fileStream = new FileStream(pathToFile, FileMode.Open, FileAccess.Read); // . MIDIReaderFile MIDIFile = new MIDIReaderFile(fileStream); // MIDI . . . MIDIheaderStruct HeaderMIDIStruct = CopyHeaderOfMIDIFile(MIDIFile); // . MIDIMTrkStruct[] MTrkStruct = new MIDIMTrkStruct[HeaderMIDIStruct.channels]; // MTrkStruct. richTextBox1.Text += " : " + HeaderMIDIStruct.channels.ToString() + "\n"; // . richTextBox1.Text += " : " + HeaderMIDIStruct.settingTime.ToString() + "\n"; richTextBox1.Text += " MIDI: " + HeaderMIDIStruct.mode.ToString() + "\n"; for (int loop = 0; loop<HeaderMIDIStruct.channels; loop++) MTrkStruct[loop] = CopyMIDIMTrkSection(MIDIFile); // MIDI . outData(reateNotesArray(MTrkStruct, HeaderMIDIStruct.channels)); // /. return true; }
Source: https://habr.com/ru/post/271693/
All Articles