internal protected byte[] FindStartOfSound(int sound, ChunkType ct = ChunkType.MThd | ChunkType.FORM)
{
int size, pos;
var ptr = ScummEngine.Instance.ResourceManager.GetSound(ScummEngine.Instance.Sound.MusicType, sound);
if (ptr == null)
{
Debug.WriteLine("IMuseInternal::findStartOfSound(): Sound {0} doesn't exist", sound);
return null;
}
// Check for old-style headers first, like 'RO'
const ChunkType trFlag = ChunkType.MThd | ChunkType.FORM;
if (System.Text.Encoding.UTF8.GetString(ptr, 0, 3) == "ROL")
return ct == trFlag ? ptr : null;
if (System.Text.Encoding.UTF8.GetString(ptr, 4, 2) == "SO")
{
if (ct == trFlag)
{
var tmp = new byte[ptr.Length - 4];
Array.Copy(ptr, 4, tmp, 0, tmp.Length);
return tmp;
}
return null;
}
var ids = new string[]
{
"MThd",
"FORM",
"MDhd",
"MDpg"
};
using (var ms = new MemoryStream(ptr))
{
var br = new BinaryReader(ms);
ms.Seek(4, SeekOrigin.Current);
size = (int)br.ReadUInt32BigEndian();
// Okay, we're looking for one of those things: either
// an 'MThd' tag (for SMF), or a 'FORM' tag (for XMIDI).
size = 48; // Arbitrary; we should find our tag within the first 48 bytes of the resource
pos = 0;
while (pos < size)
{
for (int i = 0; i < ids.Length; ++i)
{
var sig = System.Text.Encoding.UTF8.GetString(br.ReadBytes(4));
ms.Seek(-4, SeekOrigin.Current);
if ((((int)ct) & (1 << i)) != 0 && (sig == ids[i]))
{
var tmp = new byte[ptr.Length - ms.Position];
Array.Copy(ptr, (int)ms.Position, tmp, 0, tmp.Length);
return tmp;
}
}
++pos; // We could probably iterate more intelligently
ms.Seek(1, SeekOrigin.Current);
}
if (ct == (ChunkType.MThd | ChunkType.FORM))
Debug.WriteLine("IMuseInternal.FindStartOfSound(): Failed to align on sound {0}", sound);
}
return null;
}