Try to handle BOM for utf stream metadata (doesn't seem common, at all).
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user