mirror of
https://github.com/claunia/cuetools.net.git
synced 2025-12-16 18:14:25 +00:00
basic tags support for ALAC
This commit is contained in:
@@ -33,6 +33,7 @@ namespace ALACDotNet
|
||||
_path = path;
|
||||
m_spIO = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
_buff = new byte[4];
|
||||
_tags = new NameValueCollection();
|
||||
qtmovie_read();
|
||||
if (!_formatRead || _bitsPerSample != 16 || _channelCount != 2 || _sampleRate != 44100)
|
||||
throw new Exception("Invalid ALAC file.");
|
||||
@@ -788,13 +789,6 @@ namespace ALACDotNet
|
||||
}
|
||||
}
|
||||
|
||||
/* 'udta' user data.. contains tag info */
|
||||
private void read_chunk_udta(UInt32 chunk_len)
|
||||
{
|
||||
/* don't need anything from here atm, skip */
|
||||
skip_chunk(chunk_len);
|
||||
}
|
||||
|
||||
private void read_chunk_tkhd(UInt32 chunk_len)
|
||||
{
|
||||
/* don't need anything from here atm, skip */
|
||||
@@ -826,6 +820,178 @@ namespace ALACDotNet
|
||||
skip_chunk(chunk_len);
|
||||
}
|
||||
|
||||
private void mov_parse_udta_string(string name, UInt32 chunk_len)
|
||||
{
|
||||
ushort str_size = stream_read_uint16();
|
||||
ushort language = stream_read_uint16();
|
||||
byte[] value = new byte[str_size];
|
||||
if (m_spIO.Read(value, 0, str_size) != str_size)
|
||||
throw new Exception("Decoding failed.");
|
||||
_tags.Add (name, Encoding.Default.GetString(value));
|
||||
}
|
||||
|
||||
/* 'ilst' tag info */
|
||||
private void read_chunk_ilst_tag(UInt32 chunk_len, string name)
|
||||
{
|
||||
UInt32 size_remaining = chunk_len - 8; /* FIXME WRONG */
|
||||
while (size_remaining > 0)
|
||||
{
|
||||
UInt32 sub_chunk_len = stream_read_uint32();
|
||||
if (sub_chunk_len <= 1 || sub_chunk_len > size_remaining)
|
||||
throw new Exception("strange size for chunk inside stbl.");
|
||||
|
||||
UInt32 sub_chunk_id = stream_read_uint32();
|
||||
switch (sub_chunk_id)
|
||||
{
|
||||
case FCC_DATA:
|
||||
UInt32 unknown01 = stream_read_uint32();
|
||||
UInt32 unknown00 = stream_read_uint32(); // language?
|
||||
int str_size = (int) sub_chunk_len - 16;
|
||||
if (str_size <= 0)
|
||||
break;
|
||||
|
||||
if (name == "TRACKNUMBER")
|
||||
{
|
||||
byte[] value = new byte[str_size];
|
||||
if (m_spIO.Read(value, 0, str_size) != str_size)
|
||||
throw new Exception("Decoding failed.");
|
||||
if (str_size >= 4)
|
||||
_tags.Add("TRACKNUMBER", value[3].ToString());
|
||||
if (str_size >= 6)
|
||||
_tags.Add("TOTALTRACKS", value[5].ToString());
|
||||
}
|
||||
else if (name == "DISCNUMBER")
|
||||
{
|
||||
byte[] value = new byte[str_size];
|
||||
if (m_spIO.Read(value, 0, str_size) != str_size)
|
||||
throw new Exception("Decoding failed.");
|
||||
if (str_size >= 4)
|
||||
_tags.Add("DISCNUMBER", value[3].ToString());
|
||||
if (str_size >= 6)
|
||||
_tags.Add("TOTALDISCS", value[5].ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] value = new byte[str_size];
|
||||
if (m_spIO.Read(value, 0, str_size) != str_size)
|
||||
throw new Exception("Decoding failed.");
|
||||
_tags.Add(name, new UTF8Encoding().GetString(value));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
stream_skip(sub_chunk_len - 8);
|
||||
break;
|
||||
}
|
||||
size_remaining -= sub_chunk_len;
|
||||
}
|
||||
}
|
||||
|
||||
/* 'ilst' tag info */
|
||||
private void read_chunk_ilst(UInt32 chunk_len)
|
||||
{
|
||||
UInt32 size_remaining = chunk_len - 8; /* FIXME WRONG */
|
||||
while (size_remaining > 0)
|
||||
{
|
||||
UInt32 sub_chunk_len = stream_read_uint32();
|
||||
if (sub_chunk_len <= 1 || sub_chunk_len > size_remaining)
|
||||
throw new Exception("strange size for chunk inside stbl.");
|
||||
|
||||
UInt32 sub_chunk_id = stream_read_uint32();
|
||||
switch (sub_chunk_id)
|
||||
{
|
||||
case FCC_UDTA_NAM:
|
||||
read_chunk_ilst_tag(sub_chunk_len, "TITLE");
|
||||
break;
|
||||
case FCC_UDTA_ART:
|
||||
read_chunk_ilst_tag(sub_chunk_len, "ARTIST");
|
||||
break;
|
||||
case FCC_UDTA_ALB:
|
||||
read_chunk_ilst_tag(sub_chunk_len, "ALBUM");
|
||||
break;
|
||||
case FCC_UDTA_DAY:
|
||||
read_chunk_ilst_tag(sub_chunk_len, "DATE");
|
||||
break;
|
||||
case FCC_UDTA_GEN:
|
||||
read_chunk_ilst_tag(sub_chunk_len, "GENRE");
|
||||
break;
|
||||
case FCC_TRKN:
|
||||
read_chunk_ilst_tag(sub_chunk_len, "TRACKNUMBER");
|
||||
break;
|
||||
case FCC_DISK:
|
||||
read_chunk_ilst_tag(sub_chunk_len, "DISCNUMBER");
|
||||
break;
|
||||
//case MKTAG(0xa9,'w','r','t'):
|
||||
// mov_parse_udta_string(pb, c->fc->author, sizeof(c->fc->author));
|
||||
// break;
|
||||
//case MKTAG(0xa9,'c','p','y'):
|
||||
// mov_parse_udta_string(pb, c->fc->copyright, sizeof(c->fc->copyright));
|
||||
// break;
|
||||
//case MKTAG(0xa9,'i','n','f'):
|
||||
// mov_parse_udta_string(pb, c->fc->comment, sizeof(c->fc->comment));
|
||||
// break;
|
||||
default:
|
||||
stream_skip(sub_chunk_len - 8);
|
||||
break;
|
||||
}
|
||||
size_remaining -= sub_chunk_len;
|
||||
}
|
||||
}
|
||||
|
||||
/* 'meta' tag info */
|
||||
private void read_chunk_meta(UInt32 chunk_len)
|
||||
{
|
||||
UInt32 size_remaining = chunk_len - 8; /* FIXME WRONG */
|
||||
stream_read_uint32();
|
||||
size_remaining -= 4;
|
||||
//stream_skip(size_remaining);
|
||||
// hdlr
|
||||
while (size_remaining > 0)
|
||||
{
|
||||
UInt32 sub_chunk_len = stream_read_uint32();
|
||||
if (sub_chunk_len <= 1 || sub_chunk_len > size_remaining)
|
||||
throw new Exception("strange size for chunk inside stbl.");
|
||||
|
||||
UInt32 sub_chunk_id = stream_read_uint32();
|
||||
switch (sub_chunk_id)
|
||||
{
|
||||
case FCC_ILST:
|
||||
read_chunk_ilst(sub_chunk_len);
|
||||
break;
|
||||
default:
|
||||
stream_skip(sub_chunk_len - 8);
|
||||
break;
|
||||
}
|
||||
size_remaining -= sub_chunk_len;
|
||||
}
|
||||
}
|
||||
|
||||
/* 'udta' user data.. contains tag info */
|
||||
private void read_chunk_udta(UInt32 chunk_len)
|
||||
{
|
||||
UInt32 size_remaining = chunk_len - 8; /* FIXME WRONG */
|
||||
while (size_remaining > 0)
|
||||
{
|
||||
UInt32 sub_chunk_len = stream_read_uint32();
|
||||
if (sub_chunk_len <= 1 || sub_chunk_len > size_remaining)
|
||||
throw new Exception("strange size for chunk inside stbl.");
|
||||
|
||||
UInt32 sub_chunk_id = stream_read_uint32();
|
||||
switch (sub_chunk_id)
|
||||
{
|
||||
case FCC_META:
|
||||
read_chunk_meta(sub_chunk_len);
|
||||
break;
|
||||
//case FCC_UDTA_NAM:
|
||||
// mov_parse_udta_string("TITLE", sub_chunk_id);
|
||||
// break;
|
||||
default:
|
||||
stream_skip(sub_chunk_len - 8);
|
||||
break;
|
||||
}
|
||||
size_remaining -= sub_chunk_len;
|
||||
}
|
||||
}
|
||||
|
||||
private void read_chunk_stsd(UInt32 chunk_len)
|
||||
{
|
||||
uint i;
|
||||
@@ -1366,5 +1532,16 @@ namespace ALACDotNet
|
||||
const UInt32 FCC_STSC = ('s' << 24) + ('t' << 16) + ('s' << 8) + ('c' << 0);
|
||||
const UInt32 FCC_STCO = ('s' << 24) + ('t' << 16) + ('c' << 8) + ('o' << 0);
|
||||
const UInt32 FCC_ALAC = ('a' << 24) + ('l' << 16) + ('a' << 8) + ('c' << 0);
|
||||
const UInt32 FCC_META = ('m' << 24) + ('e' << 16) + ('t' << 8) + ('a' << 0);
|
||||
const UInt32 FCC_ILST = ('i' << 24) + ('l' << 16) + ('s' << 8) + ('t' << 0);
|
||||
const UInt32 FCC_DATA = ('d' << 24) + ('a' << 16) + ('t' << 8) + ('a' << 0);
|
||||
const UInt32 FCC_TRKN = ('t' << 24) + ('r' << 16) + ('k' << 8) + ('n' << 0);
|
||||
const UInt32 FCC_DISK = ('d' << 24) + ('i' << 16) + ('s' << 8) + ('k' << 0);
|
||||
const UInt32 FCC_UDTA_NAM = (0xa9000000) + ('n' << 16) + ('a' << 8) + ('m' << 0);
|
||||
const UInt32 FCC_UDTA_ART = (0xa9000000) + ('A' << 16) + ('R' << 8) + ('T' << 0);
|
||||
const UInt32 FCC_UDTA_ALB = (0xa9000000) + ('a' << 16) + ('l' << 8) + ('b' << 0);
|
||||
const UInt32 FCC_UDTA_DAY = (0xa9000000) + ('d' << 16) + ('a' << 8) + ('y' << 0);
|
||||
const UInt32 FCC_UDTA_GEN = (0xa9000000) + ('g' << 16) + ('e' << 8) + ('n' << 0);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user