Map<const String, String> items;
Map<const String, ByteVector> unknowns;
-
};
+
/*
struct APE::Tag::Item
{
ByteVector bin;
}
bool readOnly;
-}*/
+}
+*/
////////////////////////////////////////////////////////////////////////////////
delete d;
}
-using TagLib::uint;
-
-static ByteVector APEItem(String key, String value) {
+static ByteVector APEItem(String key, String value)
+{
ByteVector data;
- uint flags = 0;
+ TagLib::uint flags = 0;
- data.append(ByteVector::fromUInt(value.size(),false));
- data.append(ByteVector::fromUInt(flags,false));
+ data.append(ByteVector::fromUInt(value.size(), false));
+ data.append(ByteVector::fromUInt(flags, false));
data.append(key.data(String::UTF8));
data.append(char(0));
data.append(value.data(String::UTF8));
return data;
}
-static ByteVector APEFrame(bool isHeader, uint dataSize, uint itemCount) {
+static ByteVector APEFrame(bool isHeader, TagLib::uint dataSize, TagLib::uint itemCount)
+{
ByteVector header;
- uint tagSize = 32 + dataSize;
+ TagLib::uint tagSize = 32 + dataSize;
// bit 31: Has a header
// bit 29: Is the header
- uint flags = (1U<<31) | ((isHeader) ? (1U<<29) : 0);
+ TagLib::uint flags = (1U << 31) | ((isHeader) ? (1U << 29) : 0);
header.append(APE::Tag::fileIdentifier());
- header.append(ByteVector::fromUInt(2,false));
- header.append(ByteVector::fromUInt(tagSize,false));
- header.append(ByteVector::fromUInt(itemCount,false));
- header.append(ByteVector::fromUInt(flags,false));
- header.append(ByteVector::fromLongLong(0,false));
+ header.append(ByteVector::fromUInt(2, false));
+ header.append(ByteVector::fromUInt(tagSize, false));
+ header.append(ByteVector::fromUInt(itemCount, false));
+ header.append(ByteVector::fromUInt(flags, false));
+ header.append(ByteVector::fromLongLong(0, false));
return header;
}
ByteVector data;
uint itemCount = 0;
- { Map<String,String>::Iterator i = d->items.begin();
- while (i != d->items.end()) {
- if (!i->second.isEmpty()) {
+ {
+ Map<String,String>::Iterator i = d->items.begin();
+ while(i != d->items.end()) {
+ if(!i->second.isEmpty()) {
data.append(APEItem(i->first, i->second));
itemCount++;
}
}
}
- { Map<String,ByteVector>::Iterator i = d->unknowns.begin();
- while (i != d->unknowns.end()) {
- if (!i->second.isEmpty()) {
- data.append(i->second);
- itemCount++;
+ {
+ Map<String,ByteVector>::Iterator i = d->unknowns.begin();
+ while(i != d->unknowns.end()) {
+ if(!i->second.isEmpty()) {
+ data.append(i->second);
+ itemCount++;
}
i++;
}
String APE::Tag::title() const
{
- if (d->items.contains("Title"))
+ if(d->items.contains("Title"))
return d->items["Title"];
else
return String::null;
String APE::Tag::artist() const
{
- if (d->items.contains("Artist"))
+ if(d->items.contains("Artist"))
return d->items["Artist"];
else
return String::null;
String APE::Tag::album() const
{
- if (d->items.contains("Album"))
+ if(d->items.contains("Album"))
return d->items["Album"];
else
return String::null;
String APE::Tag::comment() const
{
- if (d->items.contains("Comment"))
+ if(d->items.contains("Comment"))
return d->items["Comment"];
else
return String::null;
String APE::Tag::genre() const
{
- if (d->items.contains("Genre"))
+ if(d->items.contains("Genre"))
return d->items["Genre"];
else
return String::null;
TagLib::uint APE::Tag::year() const
{
- if (d->items.contains("Year"))
+ if(d->items.contains("Year"))
return (d->items["Year"]).toInt();
return 0;
}
TagLib::uint APE::Tag::track() const
{
- if (d->items.contains("Track"))
+ if(d->items.contains("Track"))
return (d->items["Track"]).toInt();
return 0;
}
void APE::Tag::setComment(const String &s)
{
- if(s.isEmpty() )
+ if(s.isEmpty())
removeComment("Comment");
else
d->items["Comment"] = s;
void APE::Tag::setYear(uint i)
{
- if(i <=0 )
+ if(i <= 0)
removeComment("Year");
else
d->items["Year"] = String::number(i);
d->items.erase(it);
}
-void APE::Tag::addComment(const String &key, const String &value) {
- if (value.isEmpty())
+void APE::Tag::addComment(const String &key, const String &value)
+{
+ if(value.isEmpty())
removeComment(key);
else
d->items[key] = value;
}
-uint APE::Tag::tagSize(ByteVector footer) {
-
- // The reported length (excl. header)
-
- uint length = footer.mid(12,4).toUInt(false);
+TagLib::uint APE::Tag::tagSize(ByteVector footer)
+{
+ // The reported length (excl. header)
- // Flags (bit 31: tag contains a header)
+ uint length = footer.mid(12, 4).toUInt(false);
- uint flags = footer.mid(20,4).toUInt(false);
+ // Flags (bit 31: tag contains a header)
- return length + (flags & (1U<<31) ? 32 : 0);
+ uint flags = footer.mid(20, 4).toUInt(false);
+ return length + (flags & (1U << 31) ? 32 : 0);
}
////////////////////////////////////////////////////////////////////////////////
d->tagLength = length;
d->file->seek(d->tagOffset + 32 -length);
ByteVector data = d->file->readBlock(length-32);
- parse(data,count);
+ parse(data, count);
}
else
debug("APE tag is not valid or could not be read at the specified offset.");
void APE::Tag::parse(const ByteVector &data, uint count)
{
- uint pos = 0;
- uint vallen, flags;
- String key, value;
- while(count > 0) {
- vallen = data.mid(pos+0,4).toUInt(false);
- flags = data.mid(pos+4,4).toUInt(false);
- key = String(data.mid(pos+8), String::UTF8);
-
- if (flags == 0) {
- value = String(data.mid(pos+8+key.size()+1, vallen), String::UTF8);
- d->items.insert(key,value);
- } else {
- d->unknowns.insert(key,data.mid(pos, 8+key.size()+1+vallen));
- }
-
- pos += 8+key.size()+1+vallen;
- count--;
+ uint pos = 0;
+ uint vallen, flags;
+ String key, value;
+ while(count > 0) {
+ vallen = data.mid(pos + 0, 4).toUInt(false);
+ flags = data.mid(pos + 4, 4).toUInt(false);
+ key = String(data.mid(pos + 8), String::UTF8);
+
+ if(flags == 0) {
+ value = String(data.mid(pos + 8 + key.size() + 1, vallen), String::UTF8);
+ d->items.insert(key, value);
+ }
+ else {
+ d->unknowns.insert(key, data.mid(pos, 8 + key.size() + 1 + vallen));
}
+
+ pos += 8 + key.size() + 1 + vallen;
+ count--;
+ }
}
+
/*
void APE::Tag::parse(const ByteVector &data, uint count)
{
- uint pos = 0;
- uint vallen, flags;
- String key;
- while(count > 0) {
- vallen = data.mid(pos+0,4).toUInt(false);
- flags = data.mid(pos+4,4).toUInt(false);
- key = String(data.mid(pos+8), String::UTF8);
- Item item(key);
-
- ByteVector value = data.mid(pos+8+key.size()+1, vallen);
-
- switch ((flags >> 1) & 3) {
- case 0:
- item.value.str = String(value, String::UTF8);
- item.type = Item::STRING;
- break;
- case 1:
- item.value.bin = value;
- item.type = Item::BINARY;
- break;
- case 2:
- item.value.str = String(value, String::UTF8);
- item.type = Item::URL;
- break;
- case 3:
- item.value.bin = value;
- item.type = Item::RESERVED;
- break;
- }
- item.readOnly = (flags & 1);
+ uint pos = 0;
+ uint vallen, flags;
+ String key;
+ while(count > 0) {
+ vallen = data.mid(pos + 0, 4).toUInt(false);
+ flags = data.mid(pos + 4, 4).toUInt(false);
+ key = String(data.mid(pos + 8), String::UTF8);
+ Item item(key);
+
+ ByteVector value = data.mid(pos+8+key.size()+1, vallen);
+
+ switch ((flags >> 1) & 3) {
+ case 0:
+ item.value.str = String(value, String::UTF8);
+ item.type = Item::STRING;
+ break;
+ case 1:
+ item.value.bin = value;
+ item.type = Item::BINARY;
+ break;
+ case 2:
+ item.value.str = String(value, String::UTF8);
+ item.type = Item::URL;
+ break;
+ case 3:
+ item.value.bin = value;
+ item.type = Item::RESERVED;
+ break;
+ }
+ item.readOnly = (flags & 1);
- d->items.insert(key,item);
+ d->items.insert(key,item);
- pos += 8+key.size()+1+vallen;
- count--;
- }
-}*/
+ pos += 8 + key.size() + 1 + vallen;
+ count--;
+ }
+}
+*/
// public members
////////////////////////////////////////////////////////////////////////////////
-MPC::Properties::Properties(ByteVector data, long streamLength, ReadStyle style) : AudioProperties(style)
+MPC::Properties::Properties(const ByteVector &data, long streamLength, ReadStyle style) : AudioProperties(style)
{
d = new PropertiesPrivate(data, streamLength, style);
read();
{
return d->sampleRate;
}
+
/*
int MPC::Properties::sampleWidth() const
{
return d->sampleWidth;
-}*/
+}
+*/
int MPC::Properties::channels() const
{
void MPC::Properties::read()
{
- if (d->data.mid(0,3) != "MP+") return;
+ if(d->data.mid(0,3) != "MP+")
+ return;
d->version = d->data[3] & 15;
unsigned int frames;
- if (d->version >= 7) {
+
+ if(d->version >= 7) {
frames = d->data.mid(4,4).toUInt(false);
- std::bitset<32> flags = d->data.mid(8,4).toUInt(true);
- d->sampleRate = sftable[flags[17]*2+flags[16]];
+ std::bitset<32> flags = d->data.mid(8, 4).toUInt(true);
+ d->sampleRate = sftable[flags[17] * 2 + flags[16]];
d->channels = 2;
-
- } else {
- unsigned int headerData = d->data.mid(0,4).toUInt(false);
+ }
+ else {
+ unsigned int headerData = d->data.mid(0, 4).toUInt(false);
d->bitrate = (headerData >> 23) & 0x01ff;
d->version = (headerData >> 11) & 0x03ff;
d->sampleRate = 44100;
d->channels = 2;
- if (d->version >= 5)
- frames = d->data.mid(4,4).toUInt(false);
+ if(d->version >= 5)
+ frames = d->data.mid(4, 4).toUInt(false);
else
- frames = d->data.mid(4,2).toUInt(false);
+ frames = d->data.mid(4, 2).toUInt(false);
}
unsigned int samples = frames * 1152 - 576;
- d->length = (samples+(d->sampleRate/2)) / d->sampleRate;
+ d->length = (samples + (d->sampleRate / 2)) / d->sampleRate;
- if (!d->bitrate)
- d->bitrate = ((d->streamLength*8L) / d->length)/1000;
+ if(!d->bitrate)
+ d->bitrate = ((d->streamLength * 8L) / d->length) / 1000;
}