public static short ReadInt16LE(this IReadable input) { var ch1 = input.ReadByte(); var ch2 = input.ReadByte(); return(Platform.ToInt16((ch2 << 8) | ch1)); }
public static ushort ReadUInt16BE(this IReadable input) { var ch1 = input.ReadByte(); var ch2 = input.ReadByte(); return(Platform.Platform.ToUInt16((ch1 << 8) | (ch2 << 0))); }
private static MidiEvent ReadVoiceMessage(IReadable input, int delta, byte status, byte data1) { switch ((MidiEventTypeEnum)(status & 0xF0)) { case MidiEventTypeEnum.NoteOff: return(new MidiEvent(delta, status, data1, (byte)input.ReadByte())); case MidiEventTypeEnum.NoteOn: var velocity = input.ReadByte(); if (velocity == 0) { status = (byte)((status & 0x0F) | 0x80); } return(new MidiEvent(delta, status, data1, (byte)velocity)); case MidiEventTypeEnum.NoteAftertouch: return(new MidiEvent(delta, status, data1, (byte)input.ReadByte())); case MidiEventTypeEnum.Controller: return(new MidiEvent(delta, status, data1, (byte)input.ReadByte())); case MidiEventTypeEnum.ProgramChange: return(new MidiEvent(delta, status, data1, 0)); case MidiEventTypeEnum.ChannelAftertouch: return(new MidiEvent(delta, status, data1, 0)); case MidiEventTypeEnum.PitchBend: return(new MidiEvent(delta, status, data1, (byte)input.ReadByte())); default: throw new Exception("The status provided was not that of a voice message."); } }
public static short ReadInt16BE(this IReadable input) { var ch1 = input.ReadByte(); var ch2 = input.ReadByte(); return(TypeUtils.ToInt16((ch1 << 8) | (ch2 << 0))); }
public SoundFontSampleData(IReadable input) { var id = input.Read8BitChars(4); var size = input.ReadInt32LE(); if (id.ToLower() != "list") throw new Exception("Invalid soundfont. Could not find sdta LIST chunk."); var readTo = input.Position + size; id = input.Read8BitChars(4); if (id.ToLower() != "sdta") throw new Exception("Invalid soundfont. The LIST chunk is not of type sdta."); BitsPerSample = 0; byte[] rawSampleData = null; while (input.Position < readTo) { var subID = input.Read8BitChars(4); size = input.ReadInt32LE(); switch (subID.ToLower()) { case "smpl": BitsPerSample = 16; rawSampleData = input.ReadByteArray(size); break; case "sm24": if (rawSampleData == null || size != Math.Ceiling(SampleData.Length / 2.0)) {//ignore this chunk if wrong size or if it comes first input.Skip(size); } else { BitsPerSample = 24; for (var x = 0; x < SampleData.Length; x++) { var b = new byte[3]; b[0] = (byte)input.ReadByte(); b[1] = rawSampleData[2 * x]; b[2] = rawSampleData[2 * x + 1]; } } if (size % 2 == 1) { if (input.ReadByte() != 0) { input.Position--; } } break; default: throw new Exception("Invalid soundfont. Unknown chunk id: " + subID + "."); } } if (BitsPerSample == 16) { SampleData = rawSampleData; } else if (BitsPerSample != 24) throw new Exception("Only 16 and 24 bit samples are supported."); }
public static uint ReadUInt32(this IReadable input) { var ch1 = input.ReadByte(); var ch2 = input.ReadByte(); var ch3 = input.ReadByte(); var ch4 = input.ReadByte(); return(TypeUtils.ToUInt32((ch1 << 24) | (ch2 << 16) | (ch3 << 8) | (ch4 << 0))); }
public static int ReadInt32LE(this IReadable input) { var ch1 = input.ReadByte(); var ch2 = input.ReadByte(); var ch3 = input.ReadByte(); var ch4 = input.ReadByte(); return((ch4 << 24) | (ch3 << 16) | (ch2 << 8) | (ch1 << 0)); }
public static uint ReadUInt32LE(this IReadable input) { var ch1 = input.ReadByte(); var ch2 = input.ReadByte(); var ch3 = input.ReadByte(); var ch4 = input.ReadByte(); return(Platform.ToUInt32((ch4 << 24) | (ch3 << 16) | (ch2 << 8) | ch1)); }
public static float GpReadFloat(this IReadable data) { var bytes = new byte[4]; bytes[3] = (byte)data.ReadByte(); bytes[2] = (byte)data.ReadByte(); bytes[2] = (byte)data.ReadByte(); bytes[1] = (byte)data.ReadByte(); return(Platform.Platform.ToFloat(bytes)); }
public static string Read8BitString(this IReadable input) { var s = new StringBuilder(); var c = input.ReadByte(); while (c != 0) { s.AppendChar(c); c = input.ReadByte(); } return(s.ToString()); }
public SampleHeader(IReadable input) { Name = input.Read8BitStringLength(20); Start = input.ReadInt32LE(); End = input.ReadInt32LE(); StartLoop = input.ReadInt32LE(); EndLoop = input.ReadInt32LE(); SampleRate = input.ReadInt32LE(); RootKey = (byte)input.ReadByte(); Tune = Platform.Platform.ToInt16(input.ReadByte()); SampleLink = input.ReadUInt16LE(); SoundFontSampleLink = (SFSampleLink)input.ReadUInt16LE(); }
public SampleHeader(IReadable input) { Name = input.Read8BitStringLength(20); Start = input.ReadInt32LE(); End = input.ReadInt32LE(); StartLoop = input.ReadInt32LE(); EndLoop = input.ReadInt32LE(); SampleRate = input.ReadInt32LE(); RootKey = (byte) input.ReadByte(); Tune = TypeUtils.ToInt16(input.ReadByte()); SampleLink = input.ReadUInt16LE(); SoundFontSampleLink = (SFSampleLink) input.ReadUInt16LE(); }
public static string Read8BitStringLength(this IReadable input, int length) { var s = new StringBuilder(); var z = -1; for (var i = 0; i < length; i++) { var c = input.ReadByte(); if (c == 0 && z == -1) { z = i; } s.AppendChar(c); } var t = s.ToString(); if (z >= 0) { return(t.Substring(0, z)); } return(t); }
/// <summary> /// Reads an integer as size, skips a byte and reads the string itself /// </summary> /// <returns></returns> public static string GpReadStringIntByte(this IReadable data) { var length = data.ReadInt32LE() - 1; data.ReadByte(); return(data.GpReadString(length)); }
private bool FindHead(IReadable input, int attempts) { var match = 0; while (attempts > 0) { switch (input.ReadByte()) { case (int)'M': match = 1; break; case (int)'T': match = match == 1 ? 2 : 0; break; case (int)'h': match = match == 2 ? 3 : 0; break; case (int)'d': if (match == 3) { return(true); } match = 0; break; } attempts--; } return(false); }
public static Color GpReadColor(this IReadable data, bool readAlpha = false) { byte r = (byte)data.ReadByte(); byte g = (byte)data.ReadByte(); byte b = (byte)data.ReadByte(); byte a = 255; if (readAlpha) { a = (byte)data.ReadByte(); } else { data.Skip(1); } return(new Color(r, g, b, a)); }
public static string Read8BitChars(this IReadable input, int length) { var s = new StringBuilder(); for (int i = 0; i < length; i++) { s.AppendChar(input.ReadByte()); } return(s.ToString()); }
public static sbyte ReadSignedByte(this IReadable readable) { var n = readable.ReadByte(); if (n >= 128) { return((sbyte)(n - 256)); } return((sbyte)n); }
private static MidiEvent ReadSystemCommonMessage(IReadable input, int delta, byte status) { switch ((SystemCommonTypeEnum)status) { case SystemCommonTypeEnum.SystemExclusive2: case SystemCommonTypeEnum.SystemExclusive: { var maker = input.ReadInt16BE(); if (maker == 0x0) { maker = input.ReadInt16BE(); } else if (maker == 0xF7) { return(null); } var data = new FastList <byte>(); var b = input.ReadByte(); while (b != 0xF7) { data.Add((byte)b); b = input.ReadByte(); } return(new SystemExclusiveEvent(delta, status, maker, data.ToArray())); } case SystemCommonTypeEnum.MtcQuarterFrame: return(new SystemCommonEvent(delta, status, (byte)input.ReadByte(), 0)); case SystemCommonTypeEnum.SongPosition: return(new SystemCommonEvent(delta, status, (byte)input.ReadByte(), (byte)input.ReadByte())); case SystemCommonTypeEnum.SongSelect: return(new SystemCommonEvent(delta, status, (byte)input.ReadByte(), 0)); case SystemCommonTypeEnum.TuneRequest: return(new SystemCommonEvent(delta, status, 0, 0)); default: throw new Exception("The system common message was invalid or unsupported : " + status); } }
/// <summary> /// Reads a byte as size and the string itself. /// Additionally it is ensured the specified amount of bytes is read. /// </summary> /// <param name="data">the data to read from.</param> /// <param name="length">the amount of bytes to read</param> /// <returns></returns> public static string GpReadStringByteLength(this IReadable data, int length) { var stringLength = data.ReadByte(); var s = data.GpReadString(stringLength); if (stringLength < length) { data.Skip(length - stringLength); } return(s); }
private static int ReadVariableLength(IReadable input) { var value = 0; int next; do { next = input.ReadByte(); value = value << 7; value = value | (next & 0x7F); } while ((next & 0x80) == 0x80); return(value); }
public static HydraShdr Load(IReadable reader) { var shdr = new HydraShdr(); shdr.SampleName = reader.Read8BitStringLength(20); shdr.Start = reader.ReadUInt32LE(); shdr.End = reader.ReadUInt32LE(); shdr.StartLoop = reader.ReadUInt32LE(); shdr.EndLoop = reader.ReadUInt32LE(); shdr.SampleRate = reader.ReadUInt32LE(); shdr.OriginalPitch = (byte)reader.ReadByte(); shdr.PitchCorrection = reader.ReadSignedByte(); shdr.SampleLink = reader.ReadUInt16LE(); shdr.SampleType = reader.ReadUInt16LE(); return(shdr); }
public int ReadBit() { // need a new byte? if (_position >= ByteSize) { _currentByte = _source.ReadByte(); if (_currentByte == -1) { throw new EndOfReaderException(); } _position = 0; } // shift the desired byte to the least significant bit and // get the value using masking var value = (_currentByte >> (ByteSize - _position - 1)) & 0x01; _position++; return(value); }
private static MidiEvent ReadSystemCommonMessage(IReadable input, int delta, byte status) { switch ((SystemCommonTypeEnum)status) { case SystemCommonTypeEnum.SystemExclusive2: case SystemCommonTypeEnum.SystemExclusive: { var maker = input.ReadInt16BE(); if (maker == 0x0) { maker = input.ReadInt16BE(); } else if (maker == 0xF7) return null; var data = new FastList<byte>(); var b = input.ReadByte(); while (b != 0xF7) { data.Add((byte)b); b = input.ReadByte(); } return new SystemExclusiveEvent(delta, status, maker, data.ToArray()); } case SystemCommonTypeEnum.MtcQuarterFrame: return new SystemCommonEvent(delta, status, (byte)input.ReadByte(), 0); case SystemCommonTypeEnum.SongPosition: return new SystemCommonEvent(delta, status, (byte)input.ReadByte(), (byte)input.ReadByte()); case SystemCommonTypeEnum.SongSelect: return new SystemCommonEvent(delta, status, (byte)input.ReadByte(), 0); case SystemCommonTypeEnum.TuneRequest: return new SystemCommonEvent(delta, status, 0, 0); default: throw new Exception("The system common message was invalid or unsupported : " + status); } }
private static MidiEvent ReadMetaMessage(IReadable input, int delta, byte status) { var metaStatus = input.ReadByte(); switch ((MetaEventTypeEnum)metaStatus) { case MetaEventTypeEnum.SequenceNumber: { var count = input.ReadByte(); if (count == 0) { return(new MetaNumberEvent(delta, status, (byte)metaStatus, -1)); } else if (count == 2) { return(new MetaNumberEvent(delta, status, (byte)metaStatus, input.ReadInt16BE())); } else { throw new Exception("Invalid sequence number event."); } } case MetaEventTypeEnum.TextEvent: return(new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input))); case MetaEventTypeEnum.CopyrightNotice: return(new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input))); case MetaEventTypeEnum.SequenceOrTrackName: return(new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input))); case MetaEventTypeEnum.InstrumentName: return(new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input))); case MetaEventTypeEnum.LyricText: return(new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input))); case MetaEventTypeEnum.MarkerText: return(new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input))); case MetaEventTypeEnum.CuePoint: return(new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input))); case MetaEventTypeEnum.PatchName: return(new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input))); case MetaEventTypeEnum.PortName: return(new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input))); case MetaEventTypeEnum.MidiChannel: if (input.ReadByte() != 1) { throw new Exception("Invalid midi channel event. Expected size of 1."); } return(new MetaEvent(delta, status, (byte)metaStatus, (byte)input.ReadByte())); case MetaEventTypeEnum.MidiPort: if (input.ReadByte() != 1) { throw new Exception("Invalid midi port event. Expected size of 1."); } return(new MetaEvent(delta, status, (byte)metaStatus, (byte)input.ReadByte())); case MetaEventTypeEnum.EndOfTrack: return(new MetaEvent(delta, status, (byte)metaStatus, (byte)input.ReadByte())); case MetaEventTypeEnum.Tempo: if (input.ReadByte() != 3) { throw new Exception("Invalid tempo event. Expected size of 3."); } return(new MetaNumberEvent(delta, status, (byte)metaStatus, (input.ReadByte() << 16) | (input.ReadByte() << 8) | input.ReadByte())); case MetaEventTypeEnum.SmpteOffset: if (input.ReadByte() != 5) { throw new Exception("Invalid smpte event. Expected size of 5."); } return(new MetaTextEvent(delta, status, (byte)metaStatus, input.ReadByte() + ":" + input.ReadByte() + ":" + input.ReadByte() + ":" + input.ReadByte() + ":" + input.ReadByte())); case MetaEventTypeEnum.TimeSignature: if (input.ReadByte() != 4) { throw new Exception("Invalid time signature event. Expected size of 4."); } return(new MetaTextEvent(delta, status, (byte)metaStatus, input.ReadByte() + ":" + input.ReadByte() + ":" + input.ReadByte() + ":" + input.ReadByte())); case MetaEventTypeEnum.KeySignature: if (input.ReadByte() != 2) { throw new Exception("Invalid key signature event. Expected size of 2."); } return(new MetaTextEvent(delta, status, (byte)metaStatus, input.ReadByte() + ":" + input.ReadByte())); case MetaEventTypeEnum.SequencerSpecific: var length = ReadVariableLength(input); var data = input.ReadByteArray(length); return(new MetaDataEvent(delta, status, (byte)metaStatus, data)); } throw new Exception("Not a valid meta message Status: " + status + " Meta: " + metaStatus); }
private MidiTrack ReadTrack(IReadable input) { var instList = new FastList <Byte>(); var drumList = new FastList <Byte>(); var channelList = new FastList <Byte>(); var eventList = new FastList <MidiEvent>(); var noteOnCount = 0; var totalTime = 0; while (input.Read8BitChars(4) != "MTrk") { var length = input.ReadInt32BE(); while (length > 0) { length--; input.ReadByte(); } } var endPosition = input.ReadInt32BE() + input.Position; var prevStatus = 0; while (input.Position < endPosition) { var delta = ReadVariableLength(input); totalTime += delta; var status = input.ReadByte(); if (status >= 0x80 && status <= 0xEF) {//voice message prevStatus = status; eventList.Add(ReadVoiceMessage(input, delta, (byte)status, (byte)input.ReadByte())); noteOnCount = TrackVoiceStats(eventList[eventList.Count - 1], instList, drumList, channelList, noteOnCount); } else if (status >= 0xF0 && status <= 0xF7) {//system common message prevStatus = 0; eventList.Add(ReadSystemCommonMessage(input, delta, (byte)status)); } else if (status >= 0xF8 && status <= 0xFF) {//realtime message eventList.Add(ReadRealTimeMessage(input, delta, (byte)status)); } else { //data bytes if (prevStatus == 0) { //if no running status continue to next status byte while ((status & 0x80) != 0x80) { status = input.ReadByte(); } if (status >= 0x80 && status <= 0xEF) {//voice message prevStatus = status; eventList.Add(ReadVoiceMessage(input, delta, (byte)status, (byte)input.ReadByte())); noteOnCount = TrackVoiceStats(eventList[eventList.Count - 1], instList, drumList, channelList, noteOnCount); } else if (status >= 0xF0 && status <= 0xF7) {//system common message eventList.Add(ReadSystemCommonMessage(input, delta, (byte)status)); } else if (status >= 0xF8 && status <= 0xFF) {//realtime message eventList.Add(ReadRealTimeMessage(input, delta, (byte)status)); } } else {//otherwise apply running status eventList.Add(ReadVoiceMessage(input, delta, (byte)prevStatus, (byte)status)); noteOnCount = TrackVoiceStats(eventList[eventList.Count - 1], instList, drumList, channelList, noteOnCount); } } } if (input.Position != endPosition) { throw new Exception("The track length was invalid for the current MTrk chunk."); } if (channelList.IndexOf(MidiHelper.DrumChannel) != -1) { if (drumList.IndexOf(0) == -1) { drumList.Add(0); } } else { if (instList.IndexOf(0) == -1) { instList.Add(0); } } var track = new MidiTrack(instList.ToArray(), drumList.ToArray(), channelList.ToArray(), eventList.ToArray()); track.NoteOnCount = noteOnCount; track.EndTime = totalTime; return(track); }
/// <summary> /// Skips an integer (4byte) and reads a string using /// a bytesize /// </summary> /// <returns></returns> public static string GpReadStringIntUnused(this IReadable data) { data.Skip(4); return(data.GpReadString(data.ReadByte())); }
private bool FindHead(IReadable input, int attempts) { var match = 0; while (attempts > 0) { switch (input.ReadByte()) { case (int)'M': match = 1; break; case (int)'T': match = match == 1 ? 2 : 0; break; case (int)'h': match = match == 2 ? 3 : 0; break; case (int)'d': if (match == 3) return true; match = 0; break; } attempts--; } return false; }
public static bool GpReadBool(this IReadable data) { return(data.ReadByte() != 0); }
public static int ReadSInt8(this IReadable input) { var v = input.ReadByte(); return((((v & 255) >> 7) * (-256)) + (v & 255)); }
private static MidiEvent ReadVoiceMessage(IReadable input, int delta, byte status, byte data1) { switch ((MidiEventTypeEnum)(status & 0xF0)) { case MidiEventTypeEnum.NoteOff: return new MidiEvent(delta, status, data1, (byte)input.ReadByte()); case MidiEventTypeEnum.NoteOn: var velocity = input.ReadByte(); if (velocity == 0) status = (byte)((status & 0x0F) | 0x80); return new MidiEvent(delta, status, data1, (byte)velocity); case MidiEventTypeEnum.NoteAftertouch: return new MidiEvent(delta, status, data1, (byte)input.ReadByte()); case MidiEventTypeEnum.Controller: return new MidiEvent(delta, status, data1, (byte)input.ReadByte()); case MidiEventTypeEnum.ProgramChange: return new MidiEvent(delta, status, data1, 0); case MidiEventTypeEnum.ChannelAftertouch: return new MidiEvent(delta, status, data1, 0); case MidiEventTypeEnum.PitchBend: return new MidiEvent(delta, status, data1, (byte)input.ReadByte()); default: throw new Exception("The status provided was not that of a voice message."); } }
private static int ReadVariableLength(IReadable input) { var value = 0; int next; do { next = input.ReadByte(); value = value << 7; value = value | (next & 0x7F); } while ((next & 0x80) == 0x80); return value; }
public override HaxeInt ReadByte() { return(_readable.ReadByte()); }
public SoundFontSampleData(IReadable input) { var id = input.Read8BitChars(4); var size = input.ReadInt32LE(); if (id.ToLower() != "list") { throw new Exception("Invalid soundfont. Could not find sdta LIST chunk."); } var readTo = input.Position + size; id = input.Read8BitChars(4); if (id.ToLower() != "sdta") { throw new Exception("Invalid soundfont. The LIST chunk is not of type sdta."); } BitsPerSample = 0; byte[] rawSampleData = null; while (input.Position < readTo) { var subID = input.Read8BitChars(4); size = input.ReadInt32LE(); switch (subID.ToLower()) { case "smpl": BitsPerSample = 16; rawSampleData = input.ReadByteArray(size); break; case "sm24": if (rawSampleData == null || size != Math.Ceiling(SampleData.Length / 2.0)) { //ignore this chunk if wrong size or if it comes first input.Skip(size); } else { BitsPerSample = 24; for (var x = 0; x < SampleData.Length; x++) { var b = new byte[3]; b[0] = (byte)input.ReadByte(); b[1] = rawSampleData[2 * x]; b[2] = rawSampleData[2 * x + 1]; } } if (size % 2 == 1) { if (input.ReadByte() != 0) { input.Position--; } } break; default: throw new Exception("Invalid soundfont. Unknown chunk id: " + subID + "."); } } if (BitsPerSample == 16) { SampleData = rawSampleData; } else if (BitsPerSample != 24) { throw new Exception("Only 16 and 24 bit samples are supported."); } }
private static MidiEvent ReadMetaMessage(IReadable input, int delta, byte status) { var metaStatus = input.ReadByte(); switch ((MetaEventTypeEnum)metaStatus) { case MetaEventTypeEnum.SequenceNumber: { var count = input.ReadByte(); if (count == 0) return new MetaNumberEvent(delta, status, (byte)metaStatus, -1); else if (count == 2) { return new MetaNumberEvent(delta, status, (byte)metaStatus, input.ReadInt16BE()); } else throw new Exception("Invalid sequence number event."); } case MetaEventTypeEnum.TextEvent: return new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input)); case MetaEventTypeEnum.CopyrightNotice: return new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input)); case MetaEventTypeEnum.SequenceOrTrackName: return new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input)); case MetaEventTypeEnum.InstrumentName: return new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input)); case MetaEventTypeEnum.LyricText: return new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input)); case MetaEventTypeEnum.MarkerText: return new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input)); case MetaEventTypeEnum.CuePoint: return new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input)); case MetaEventTypeEnum.PatchName: return new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input)); case MetaEventTypeEnum.PortName: return new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input)); case MetaEventTypeEnum.MidiChannel: if (input.ReadByte() != 1) throw new Exception("Invalid midi channel event. Expected size of 1."); return new MetaEvent(delta, status, (byte)metaStatus, (byte)input.ReadByte()); case MetaEventTypeEnum.MidiPort: if (input.ReadByte() != 1) throw new Exception("Invalid midi port event. Expected size of 1."); return new MetaEvent(delta, status, (byte)metaStatus, (byte)input.ReadByte()); case MetaEventTypeEnum.EndOfTrack: return new MetaEvent(delta, status, (byte)metaStatus, (byte)input.ReadByte()); case MetaEventTypeEnum.Tempo: if (input.ReadByte() != 3) throw new Exception("Invalid tempo event. Expected size of 3."); return new MetaNumberEvent(delta, status, (byte)metaStatus, (input.ReadByte() << 16) | (input.ReadByte() << 8) | input.ReadByte()); case MetaEventTypeEnum.SmpteOffset: if (input.ReadByte() != 5) throw new Exception("Invalid smpte event. Expected size of 5."); return new MetaTextEvent(delta, status, (byte)metaStatus, input.ReadByte() + ":" + input.ReadByte() + ":" + input.ReadByte() + ":" + input.ReadByte() + ":" + input.ReadByte()); case MetaEventTypeEnum.TimeSignature: if (input.ReadByte() != 4) throw new Exception("Invalid time signature event. Expected size of 4."); return new MetaTextEvent(delta, status, (byte)metaStatus, input.ReadByte() + ":" + input.ReadByte() + ":" + input.ReadByte() + ":" + input.ReadByte()); case MetaEventTypeEnum.KeySignature: if (input.ReadByte() != 2) throw new Exception("Invalid key signature event. Expected size of 2."); return new MetaTextEvent(delta, status, (byte)metaStatus, input.ReadByte() + ":" + input.ReadByte()); case MetaEventTypeEnum.SequencerSpecific: var length = ReadVariableLength(input); var data = input.ReadByteArray(length); return new MetaDataEvent(delta, status, (byte)metaStatus, data); } throw new Exception("Not a valid meta message Status: " + status + " Meta: " + metaStatus); }
public static sbyte ReadSignedByte(this IReadable readable) { return(unchecked ((sbyte)(byte)readable.ReadByte())); }
private MidiTrack ReadTrack(IReadable input) { var instList = new FastList<Byte>(); var drumList = new FastList<Byte>(); var channelList = new FastList<Byte>(); var eventList = new FastList<MidiEvent>(); var noteOnCount = 0; var totalTime = 0; while (input.Read8BitChars(4) != "MTrk") { var length = input.ReadInt32BE(); while (length > 0) { length--; input.ReadByte(); } } var endPosition = input.ReadInt32BE() + input.Position; var prevStatus = 0; while (input.Position < endPosition) { var delta = ReadVariableLength(input); totalTime += delta; var status = input.ReadByte(); if (status >= 0x80 && status <= 0xEF) {//voice message prevStatus = status; eventList.Add(ReadVoiceMessage(input, delta, (byte)status, (byte)input.ReadByte())); noteOnCount = TrackVoiceStats(eventList[eventList.Count - 1], instList, drumList, channelList, noteOnCount); } else if (status >= 0xF0 && status <= 0xF7) {//system common message prevStatus = 0; eventList.Add(ReadSystemCommonMessage(input, delta, (byte)status)); } else if (status >= 0xF8 && status <= 0xFF) {//realtime message eventList.Add(ReadRealTimeMessage(input, delta, (byte)status)); } else {//data bytes if (prevStatus == 0) {//if no running status continue to next status byte while ((status & 0x80) != 0x80) { status = input.ReadByte(); } if (status >= 0x80 && status <= 0xEF) {//voice message prevStatus = status; eventList.Add(ReadVoiceMessage(input, delta, (byte)status, (byte)input.ReadByte())); noteOnCount = TrackVoiceStats(eventList[eventList.Count - 1], instList, drumList, channelList, noteOnCount); } else if (status >= 0xF0 && status <= 0xF7) {//system common message eventList.Add(ReadSystemCommonMessage(input, delta, (byte)status)); } else if (status >= 0xF8 && status <= 0xFF) {//realtime message eventList.Add(ReadRealTimeMessage(input, delta, (byte)status)); } } else {//otherwise apply running status eventList.Add(ReadVoiceMessage(input, delta, (byte)prevStatus, (byte)status)); noteOnCount = TrackVoiceStats(eventList[eventList.Count - 1], instList, drumList, channelList, noteOnCount); } } } if (input.Position != endPosition) throw new Exception("The track length was invalid for the current MTrk chunk."); if (channelList.IndexOf(MidiHelper.DrumChannel) != -1) { if (drumList.IndexOf(0) == -1) drumList.Add(0); } else { if (instList.IndexOf(0) == -1) instList.Add(0); } var track = new MidiTrack(instList.ToArray(), drumList.ToArray(), channelList.ToArray(), eventList.ToArray()); track.NoteOnCount = noteOnCount; track.EndTime = totalTime; return track; }