Try to handle BOM for utf stream metadata (doesn't seem common, at all).

This commit is contained in:
Shyotl
2014-11-22 22:01:45 -06:00
parent 972c92a3fe
commit 6e537cd322

View File

@@ -127,6 +127,45 @@ void LLStreamingAudio_FMODEX::start(const std::string& url)
} }
} }
enum utf_endian_type_t
{
UTF16LE,
UTF16BE,
UTF16
};
std::string utf16input_to_utf8(char* input, U32 len, utf_endian_type_t type)
{
if (type == UTF16)
{
type = UTF16BE; //Default
if (len > 2)
{
//Parse and strip BOM.
if ((input[0] == 0xFE && input[1] == 0xFF) ||
(input[0] == 0xFF && input[1] == 0xFE))
{
input += 2;
len -= 2;
type = input[0] == 0xFE ? UTF16BE : UTF16LE;
}
}
}
llutf16string out_16((U16*)input, len / 2);
if (len % 2)
{
out_16.push_back((input)[len - 1] << 8);
}
if (type == UTF16BE)
{
for (llutf16string::iterator i = out_16.begin(); i < out_16.end(); ++i)
{
llutf16string::value_type v = *i;
*i = ((v & 0x00FF) << 8) | ((v & 0xFF00) >> 8);
}
}
return utf16str_to_utf8str(out_16);
}
void LLStreamingAudio_FMODEX::update() void LLStreamingAudio_FMODEX::update()
{ {
@@ -216,23 +255,27 @@ void LLStreamingAudio_FMODEX::update()
switch(tag.type) //Crappy tag translate table. switch(tag.type) //Crappy tag translate table.
{ {
case(FMOD_TAGTYPE_ID3V2): case(FMOD_TAGTYPE_ID3V2):
if(name == "TIT2") name = "TITLE"; if (!LLStringUtil::compareInsensitive(name, "TIT2")) name = "TITLE";
else if(name == "TPE1") name = "ARTIST"; else if(name == "TPE1") name = "ARTIST";
break; break;
case(FMOD_TAGTYPE_ASF): case(FMOD_TAGTYPE_ASF):
if(name == "Title") name = "TITLE"; if (!LLStringUtil::compareInsensitive(name, "Title")) name = "TITLE";
else if(name == "WM/AlbumArtist") name = "ARTIST"; else if (!LLStringUtil::compareInsensitive(name, "WM/AlbumArtist")) name = "ARTIST";
break; break;
case(FMOD_TAGTYPE_FMOD): case(FMOD_TAGTYPE_FMOD):
if (!strcmp(tag.name, "Sample Rate Change")) if (!LLStringUtil::compareInsensitive(name, "Sample Rate Change"))
{ {
llinfos << "Stream forced changing sample rate to " << *((float *)tag.data) << llendl; llinfos << "Stream forced changing sample rate to " << *((float *)tag.data) << llendl;
mFMODInternetStreamChannelp->setFrequency(*((float *)tag.data)); mFMODInternetStreamChannelp->setFrequency(*((float *)tag.data));
} }
continue; continue;
default: default:
if (!LLStringUtil::compareInsensitive(name, "TITLE") ||
!LLStringUtil::compareInsensitive(name, "ARTIST"))
LLStringUtil::toUpper(name);
break; break;
} }
switch(tag.datatype) switch(tag.datatype)
{ {
case(FMOD_TAGDATATYPE_INT): case(FMOD_TAGDATATYPE_INT):
@@ -247,24 +290,31 @@ void LLStreamingAudio_FMODEX::update()
{ {
std::string out = rawstr_to_utf8(std::string((char*)tag.data,tag.datalen)); std::string out = rawstr_to_utf8(std::string((char*)tag.data,tag.datalen));
(*mMetaData)[name]=out; (*mMetaData)[name]=out;
llinfos << tag.name << ": " << out << llendl; llinfos << tag.name << "(RAW): " << out << llendl;
}
break;
case(FMOD_TAGDATATYPE_STRING_UTF8) :
{
U8 offs = 0;
if (tag.datalen > 3 && ((char*)tag.data)[0] == 0xEF && ((char*)tag.data)[1] == 0xBB && ((char*)tag.data)[2] == 0xBF)
offs = 3;
std::string out((char*)tag.data + offs, tag.datalen - offs);
(*mMetaData)[name] = out;
llinfos << tag.name << "(UTF8): " << out << llendl;
} }
break; break;
case(FMOD_TAGDATATYPE_STRING_UTF16): case(FMOD_TAGDATATYPE_STRING_UTF16):
{ {
std::string out((char*)tag.data,tag.datalen); std::string out = utf16input_to_utf8((char*)tag.data, tag.datalen, UTF16);
(*mMetaData)[std::string(tag.name)]=out; (*mMetaData)[name] = out;
llinfos << tag.name << ": " << out << llendl; llinfos << tag.name << "(UTF16): " << out << llendl;
} }
break; break;
case(FMOD_TAGDATATYPE_STRING_UTF16BE): case(FMOD_TAGDATATYPE_STRING_UTF16BE):
{ {
std::string out((char*)tag.data,tag.datalen); std::string out = utf16input_to_utf8((char*)tag.data, tag.datalen, UTF16BE);
U16* buf = (U16*)out.c_str(); (*mMetaData)[name] = out;
for(U32 j = 0; j < out.size()/2; ++j) llinfos << tag.name << "(UTF16BE): " << out << llendl;
(((buf[j] & 0xff)<<8) | ((buf[j] & 0xff00)>>8));
(*mMetaData)[std::string(tag.name)]=out;
llinfos << tag.name << ": " << out << llendl;
} }
default: default:
break; break;