Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgraded to .NET 6 #102

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions DLS2/Chunks/Chunk.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
using Kermalis.EndianBinaryIO;
using System.Collections.Generic;
using System.IO;

namespace Kermalis.DLS2
{
public abstract class DLSChunk
{
/// <summary>Length 4</summary>
public string ChunkName { get; }
/// <summary>Size in bytes</summary>
protected internal uint Size { get; protected set; }

protected DLSChunk(string name)
{
ChunkName = name;
}
protected DLSChunk(string name, EndianBinaryReader reader)
{
ChunkName = name;
Size = reader.ReadUInt32();
}

protected long GetEndOffset(EndianBinaryReader reader)
{
return reader.BaseStream.Position + Size;
}
protected void EatRemainingBytes(EndianBinaryReader reader, long endOffset)
{
if (reader.BaseStream.Position > endOffset)
{
throw new InvalidDataException();
}
reader.BaseStream.Position = endOffset;
}

internal abstract void UpdateSize();

internal virtual void Write(EndianBinaryWriter writer)
{
UpdateSize();
writer.Write(ChunkName, 4);
writer.Write(Size);
}

internal static List<DLSChunk> GetAllChunks(EndianBinaryReader reader, long endOffset)
{
var chunks = new List<DLSChunk>();
while (reader.BaseStream.Position < endOffset)
{
chunks.Add(SwitchNextChunk(reader));
}
if (reader.BaseStream.Position > endOffset)
{
throw new InvalidDataException();
}
return chunks;
}
private static DLSChunk SwitchNextChunk(EndianBinaryReader reader)
{
string str = reader.ReadString(4, false);
switch (str)
{
case "art1": return new Level1ArticulatorChunk(reader);
case "art2": return new Level2ArticulatorChunk(reader);
case "colh": return new CollectionHeaderChunk(reader);
case "data": return new DataChunk(reader);
case "dlid": return new DLSIDChunk(reader);
case "fmt ": return new FormatChunk(reader);
case "insh": return new InstrumentHeaderChunk(reader);
case "LIST": return new ListChunk(reader);
case "ptbl": return new PoolTableChunk(reader);
case "rgnh": return new RegionHeaderChunk(reader);
case "wlnk": return new WaveLinkChunk(reader);
case "wsmp": return new WaveSampleChunk(reader);
// InfoSubChunks
case "IARL":
case "IART":
case "ICMS":
case "ICMD":
case "ICOP":
case "ICRD":
case "IENG":
case "IGNR":
case "IKEY":
case "IMED":
case "INAM":
case "IPRD":
case "ISBJ":
case "ISFT":
case "ISRC":
case "ISRF":
case "ITCH": return new InfoSubChunk(str, reader);
default: return new UnsupportedChunk(str, reader);
}
}
}
}
29 changes: 29 additions & 0 deletions DLS2/Chunks/CollectionHeaderChunk.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Kermalis.EndianBinaryIO;

namespace Kermalis.DLS2
{
// Collection Header Chunk - Page 40 of spec
public sealed class CollectionHeaderChunk : DLSChunk
{
public uint NumInstruments { get; internal set; }

internal CollectionHeaderChunk() : base("colh") { }
public CollectionHeaderChunk(EndianBinaryReader reader) : base("colh", reader)
{
long endOffset = GetEndOffset(reader);
NumInstruments = reader.ReadUInt32();
EatRemainingBytes(reader, endOffset);
}

internal override void UpdateSize()
{
Size = 4; // NumInstruments
}

internal override void Write(EndianBinaryWriter writer)
{
base.Write(writer);
writer.Write(NumInstruments);
}
}
}
36 changes: 36 additions & 0 deletions DLS2/Chunks/ConditionalChunk.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
namespace Kermalis.DLS2
{
// ALL TODO:

/*public enum DLSConditional : ushort
{
And = 1,
Or = 2,
Xor = 3,
Add = 4,
Subtract = 5,
Multiply = 6,
Divide = 7,
LogicalAnd = 8,
LogicalOr = 9,
Lt = 10,
Le = 11,
Gt = 12,
Ge = 13,
Eq = 14,
Not = 15,
Const = 16,
Query = 17,
QuerySupported = 18
}

// Conditional Chunk - Page 42 of spec
internal sealed class ConditionalChunk : DLSChunk
{
public ConditionalChunk(EndianBinaryReader reader) : base("cdl ", reader)
{
DLSConditional cond = reader.ReadEnum<DLSConditional>();

}
}*/
}
45 changes: 45 additions & 0 deletions DLS2/Chunks/DLSIDChunk.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using Kermalis.EndianBinaryIO;
using System;

namespace Kermalis.DLS2
{
// DLSID Chunk - Page 40 of spec
public sealed class DLSIDChunk : DLSChunk
{
private DLSID _dlsid;
public DLSID DLSID
{
get => _dlsid;
set
{
if (value is null)
{
throw new ArgumentNullException(nameof(value));
}
_dlsid = value;
}
}

public DLSIDChunk(DLSID id) : base("dlid")
{
DLSID = id;
}
public DLSIDChunk(EndianBinaryReader reader) : base("dlid", reader)
{
long endOffset = GetEndOffset(reader);
DLSID = new DLSID(reader);
EatRemainingBytes(reader, endOffset);
}

internal override void UpdateSize()
{
Size = 16; // DLSID
}

internal override void Write(EndianBinaryWriter writer)
{
base.Write(writer);
DLSID.Write(writer);
}
}
}
10 changes: 10 additions & 0 deletions DLS2/Chunks/DataChunk.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Kermalis.EndianBinaryIO;

namespace Kermalis.DLS2
{
public sealed class DataChunk : RawDataChunk
{
public DataChunk(byte[] data) : base("data", data) { }
internal DataChunk(EndianBinaryReader reader) : base("data", reader) { }
}
}
105 changes: 105 additions & 0 deletions DLS2/Chunks/FormatChunk.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using Kermalis.EndianBinaryIO;
using System.IO;

namespace Kermalis.DLS2
{
public abstract class FormatInfo
{
public ushort BitsPerSample { get; set; }

internal abstract void Write(EndianBinaryWriter writer);
}
public sealed class PCMInfo : FormatInfo
{
internal PCMInfo() { }
internal PCMInfo(EndianBinaryReader reader)
{
BitsPerSample = reader.ReadUInt16();
}

internal override void Write(EndianBinaryWriter writer)
{
writer.Write(BitsPerSample);
}
}
// Untested!
public sealed class ExtensibleInfo : FormatInfo
{
public ushort ExtraInfo { get; set; }
public uint ChannelMask { get; set; }
public DLSID SubFormat { get; set; }

internal ExtensibleInfo()
{
SubFormat = new DLSID();
}
internal ExtensibleInfo(EndianBinaryReader reader)
{
BitsPerSample = reader.ReadUInt16();
ushort byteSize = reader.ReadUInt16();
if (byteSize != 22)
{
throw new InvalidDataException();
}
ExtraInfo = reader.ReadUInt16();
ChannelMask = reader.ReadUInt32();
SubFormat = new DLSID(reader);
}

internal override void Write(EndianBinaryWriter writer)
{
writer.Write(BitsPerSample);
writer.Write(22u);
writer.Write(ExtraInfo);
writer.Write(ChannelMask);
SubFormat.Write(writer);
}
}

// Format Chunk - Page 57 of spec
public sealed class FormatChunk : DLSChunk
{
public WaveInfo WaveInfo { get; }
public FormatInfo FormatInfo { get; }

public FormatChunk(WaveFormat format) : base("fmt ")
{
WaveInfo = new WaveInfo() { FormatTag = format };
if (format == WaveFormat.Extensible)
{
FormatInfo = new ExtensibleInfo();
}
else
{
FormatInfo = new PCMInfo();
}
}
internal FormatChunk(EndianBinaryReader reader) : base("fmt ", reader)
{
long endOffset = GetEndOffset(reader);
WaveInfo = new WaveInfo(reader);
if (WaveInfo.FormatTag == WaveFormat.Extensible)
{
FormatInfo = new ExtensibleInfo(reader);
}
else
{
FormatInfo = new PCMInfo(reader);
}
EatRemainingBytes(reader, endOffset);
}

internal override void UpdateSize()
{
Size = 14 // WaveFormat
+ (WaveInfo.FormatTag == DLS2.WaveFormat.Extensible ? 26u : 2u); // FormatInfo
}

internal override void Write(EndianBinaryWriter writer)
{
base.Write(writer);
WaveInfo.Write(writer);
FormatInfo.Write(writer);
}
}
}
53 changes: 53 additions & 0 deletions DLS2/Chunks/InfoSubChunk.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using Kermalis.EndianBinaryIO;
using System;
using System.Linq;

namespace Kermalis.DLS2
{
public sealed class InfoSubChunk : DLSChunk
{
private string _text;
public string Text
{
get => _text;
set
{
if (value is null)
{
throw new ArgumentNullException(nameof(value));
}
if (value.Any(c => c > sbyte.MaxValue))
{
throw new ArgumentException("Text must be ASCII");
}
_text = value;
}
}

public InfoSubChunk(string name, string text) : base(name)
{
Text = text;
}
internal InfoSubChunk(string name, EndianBinaryReader reader) : base(name, reader)
{
long endOffset = GetEndOffset(reader);
_text = reader.ReadStringNullTerminated();
EatRemainingBytes(reader, endOffset);
}

internal override void UpdateSize()
{
Size = (uint)_text.Length + 1; // +1 for \0
if (Size % 2 != 0) // Align by 2 bytes
{
Size++;
}
}

internal override void Write(EndianBinaryWriter writer)
{
base.Write(writer);
writer.Write(_text, (int)Size);
}
}
}
Loading