bool SoundSource::processXiphComment(TagLib::Ogg::XiphComment* xiph) { if (s_bDebugMetadata) { for (TagLib::Ogg::FieldListMap::ConstIterator it = xiph->fieldListMap().begin(); it != xiph->fieldListMap().end(); ++it) { qDebug() << "XIPH" << TStringToQString((*it).first) << "-" << TStringToQString((*it).second.toString()); } } // Some tags use "BPM" so check for that. if (xiph->fieldListMap().contains("BPM")) { TagLib::StringList bpmString = xiph->fieldListMap()["BPM"]; QString sBpm = TStringToQString(bpmString.toString()); processBpmString("XIPH-BPM", sBpm); } // Give preference to the "TEMPO" tag which seems to be more standard if (xiph->fieldListMap().contains("TEMPO")) { TagLib::StringList bpmString = xiph->fieldListMap()["TEMPO"]; QString sBpm = TStringToQString(bpmString.toString()); processBpmString("XIPH-TEMPO", sBpm); } if (xiph->fieldListMap().contains("REPLAYGAIN_ALBUM_GAIN")) { TagLib::StringList rgainString = xiph->fieldListMap()["REPLAYGAIN_ALBUM_GAIN"]; QString sReplayGain = TStringToQString(rgainString.toString()); parseReplayGainString(sReplayGain); } if (xiph->fieldListMap().contains("REPLAYGAIN_TRACK_GAIN")) { TagLib::StringList rgainString = xiph->fieldListMap()["REPLAYGAIN_TRACK_GAIN"]; QString sReplayGain = TStringToQString(rgainString.toString()); parseReplayGainString(sReplayGain); } /* * Reading key code information * Unlike, ID3 tags, there's no standard or recommendation on how to store 'key' code * * Luckily, there are only a few tools for that, e.g., Rapid Evolution (RE). * Assuming no distinction between start and end key, RE uses a "INITIALKEY" * or a "KEY" vorbis comment. */ if (xiph->fieldListMap().contains("KEY")) { TagLib::StringList keyStr = xiph->fieldListMap()["KEY"]; QString key = TStringToQString(keyStr.toString()); setKey(key); } if (getKey() == "" && xiph->fieldListMap().contains("INITIALKEY")) { TagLib::StringList keyStr = xiph->fieldListMap()["INITIALKEY"]; QString key = TStringToQString(keyStr.toString()); setKey(key); } return true; }
// Utility function to format tags so that they can be correctly parsed back string formatString(const TagLib::StringList& strList) { TagLib::String str = strList.toString(";"); if (str.isEmpty()) return ""; string result = str.to8Bit(true); // heuristic to detect wrongly encoded tags (ie: twice latin-1 to utf-8, mostly) // we should encode everything ourselves to utf-8, but sometimes it might happen // that someone already did that, but told us the string was in latin-1. // A way to detect that is if the string contains only latin-1 chars, when // converting it to latin-1 it contains code chars, this probably means it was // previously encoded in utf-8 if (isLatin1(str) && containsControlChars(str.to8Bit(false))) { result = str.to8Bit(false); } // fix invalid utf-8 characters result = fixInvalidUTF8(result); return result; }