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 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); }
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); }