public MThdChunkHeader(int format, int numTracks, int division) { if ((format < 0) || (format > 2)) { throw new ArgumentOutOfRangeException("format", format, "Format must be 0, 1, or 2."); } if (numTracks < 1) { throw new ArgumentOutOfRangeException("numTracks", numTracks, "There must be at least 1 track."); } if (division < 1) { throw new ArgumentOutOfRangeException("division", division, "Division must be at least 1."); } this._header = new ChunkHeader(MThdID, 6L); this._format = format; this._numTracks = numTracks; this._division = division; }
/// <summary>Initialize the MThd chunk header.</summary> /// <param name="format"> /// The format for the MIDI file (0, 1, or 2). /// 0 - a single multi-channel track /// 1 - one or more simultaneous tracks /// 2 - one or more sequentially independent single-track patterns /// </param> /// <param name="numTracks">The number of tracks in the MIDI file.</param> /// <param name="division"> /// The meaning of the delta-times in the file. /// If the number is zero or positive, then bits 14 thru 0 represent the number of delta-time /// ticks which make up a quarter-note. If number is negative, then bits 14 through 0 represent /// subdivisions of a second, in a way consistent with SMPTE and MIDI time code. /// </param> public MThdChunkHeader(int format, int numTracks, int division) { // Verify the parameters if (format < 0 || format > 2) { throw new ArgumentOutOfRangeException("format", format, "Format must be 0, 1, or 2."); } if (numTracks < 1) { throw new ArgumentOutOfRangeException("numTracks", numTracks, "There must be at least 1 track."); } if (division < 1) { throw new ArgumentOutOfRangeException("division", division, "Division must be at least 1."); } _header = new ChunkHeader( MThdID, // 0x4d546864 = "MThd" 6); // 2 bytes for each of the format, num tracks, and division == 6 _format = format; _numTracks = numTracks; _division = division; }
private static void ValidateHeader(ChunkHeader header) { byte[] mThdID = MThdID; for (int i = 0; i < 4; i++) { if (header.ID[i] != mThdID[i]) { throw new InvalidOperationException("Invalid MThd header."); } } if (header.Length != 6L) { throw new InvalidOperationException("The length of the MThd header is incorrect."); } }
/// <summary>Validates that a header is correct as an MThd header.</summary> /// <param name="header">The header to be validated.</param> private static void ValidateHeader(ChunkHeader header) { byte [] validHeader = MTrkID; for(int i=0; i<4; i++) { if (header.ID[i] != validHeader[i]) throw new InvalidOperationException("Invalid MThd header."); } if (header.Length <= 0) throw new InvalidOperationException("The length of the MThd header is incorrect."); }
/// <summary>Initialize the MTrk chunk header.</summary> /// <param name="data">The track data for which this is a header.</param> public MTrkChunkHeader(byte [] data) { _header = new ChunkHeader( MTrkID, // 0x4d54726b = "MTrk" data != null ? data.Length : 0); _data = data; }
/// <summary>Initialize the MThd chunk header.</summary> /// <param name="format"> /// The format for the MIDI file (0, 1, or 2). /// 0 - a single multi-channel track /// 1 - one or more simultaneous tracks /// 2 - one or more sequentially independent single-track patterns /// </param> /// <param name="numTracks">The number of tracks in the MIDI file.</param> /// <param name="division"> /// The meaning of the delta-times in the file. /// If the number is zero or positive, then bits 14 thru 0 represent the number of delta-time /// ticks which make up a quarter-note. If number is negative, then bits 14 through 0 represent /// subdivisions of a second, in a way consistent with SMPTE and MIDI time code. /// </param> public MThdChunkHeader(int format, int numTracks, int division) { // Verify the parameters if (format < 0 || format > 2) throw new ArgumentOutOfRangeException("format", format, "Format must be 0, 1, or 2."); if (numTracks < 1) throw new ArgumentOutOfRangeException("numTracks", numTracks, "There must be at least 1 track."); if (division < 1) throw new ArgumentOutOfRangeException("division", division, "Division must be at least 1."); _header = new ChunkHeader( MThdID, // 0x4d546864 = "MThd" 6); // 2 bytes for each of the format, num tracks, and division == 6 _format = format; _numTracks = numTracks; _division = division; }
public MTrkChunkHeader(byte[] data) { this._header = new ChunkHeader(MTrkID, (data != null) ? ((long) data.Length) : ((long) 0)); this._data = data; }
/// <summary>Read in an MThd chunk from the stream.</summary> /// <param name="inputStream">The stream from which to read the MThd chunk.</param> /// <returns>The MThd chunk read.</returns> public static MThdChunkHeader Read(Stream inputStream) { // Validate input if (inputStream == null) { throw new ArgumentNullException("inputStream"); } if (!inputStream.CanRead) { throw new ArgumentException("Stream must be readable.", "inputStream"); } // Read in a header from the stream and validate it ChunkHeader header = ChunkHeader.Read(inputStream); ValidateHeader(header); // Read in the format int format = 0; for (int i = 0; i < 2; i++) { int val = inputStream.ReadByte(); if (val < 0) { throw new InvalidOperationException("The stream is invalid."); } format <<= 8; format |= val; } // Read in the number of tracks int numTracks = 0; for (int i = 0; i < 2; i++) { int val = inputStream.ReadByte(); if (val < 0) { throw new InvalidOperationException("The stream is invalid."); } numTracks <<= 8; numTracks |= val; } // Read in the division int division = 0; for (int i = 0; i < 2; i++) { int val = inputStream.ReadByte(); if (val < 0) { throw new InvalidOperationException("The stream is invalid."); } division <<= 8; division |= val; } // Create a new MThd header and return it return(new MThdChunkHeader(format, numTracks, division)); }