Audio-Scan
view release on metacpan or search on metacpan
_id3_get_v1_utf8_string(id3info *id3, SV **string, uint32_t len)
{
uint32_t read = 0;
char *ptr;
char *str;
read = _id3_get_utf8_string(id3, string, len, ISO_8859_1);
if (read) {
// Trim spaces from end
if (*string != NULL) {
str = SvPVX(*string);
ptr = str + sv_len(*string);
while (ptr > str && ptr[-1] == ' ')
--ptr;
*ptr = 0;
SvCUR_set(*string, ptr - str);
}
}
return read;
}
uint32_t
_id3_get_utf8_string(id3info *id3, SV **string, uint32_t len, uint8_t encoding)
{
uint8_t byteorder = UTF16_BYTEORDER_ANY;
uint32_t read = 0;
unsigned char *bptr;
// Init scratch buffer if necessary
if ( !id3->utf8->alloc ) {
// Use a larger initial buffer if reading ISO-8859-1 to avoid
// always having to allocate a second time
buffer_init( id3->utf8, encoding == ISO_8859_1 ? len * 2 : len );
}
else {
// Reset scratch buffer
buffer_clear(id3->utf8);
}
if ( *string != NULL ) {
warn(" !!! string SV is not null: %s\n", SvPVX(*string));
}
switch (encoding) {
case ISO_8859_1:
read += buffer_get_latin1_as_utf8(id3->buf, id3->utf8, len);
break;
case UTF_16BE:
byteorder = UTF16_BYTEORDER_BE;
case UTF_16:
bptr = buffer_ptr(id3->buf);
switch ( (bptr[0] << 8) | bptr[1] ) {
case 0xfeff:
DEBUG_TRACE(" UTF-16 BOM is big-endian\n");
byteorder = UTF16_BYTEORDER_BE;
buffer_consume(id3->buf, 2);
read += 2;
break;
case 0xfffe:
DEBUG_TRACE(" UTF-16 BOM is little-endian\n");
byteorder = UTF16_BYTEORDER_LE;
buffer_consume(id3->buf, 2);
read += 2;
break;
}
/* Bug 14728
If there is no BOM, assume LE, this is what appears in the wild -andy
*/
if (byteorder == UTF16_BYTEORDER_ANY) {
DEBUG_TRACE(" UTF-16 byte order defaulting to little-endian, no BOM\n");
byteorder = UTF16_BYTEORDER_LE;
}
read += buffer_get_utf16_as_utf8(id3->buf, id3->utf8, len - read, byteorder);
break;
case UTF_8:
read += buffer_get_utf8(id3->buf, id3->utf8, len);
break;
default:
break;
}
if (read) {
if ( buffer_len(id3->utf8) ) {
*string = newSVpv( buffer_ptr(id3->utf8), 0 );
sv_utf8_decode(*string);
DEBUG_TRACE(" read utf8 string of %d bytes: %s\n", buffer_len(id3->utf8), SvPVX(*string));
}
else {
DEBUG_TRACE(" empty string\n");
}
}
return read;
}
uint32_t
_id3_parse_rvad(id3info *id3, char const *id, uint32_t size)
{
unsigned char *rva = buffer_ptr(id3->buf);
int sign_r = rva[0] & 0x01 ? 1 : -1;
int sign_l = rva[0] & 0x02 ? 1 : -1;
int bytes = rva[1] / 8;
float vol[2];
float peak[2];
int i;
AV *framedata = newAV();
// Sanity check, first byte must be either 0 or 1, second byte > 0
if (rva[0] & 0xFE || rva[1] == 0) {
return 0;
}
// Calculated size must match the actual size
if (size != 2 + (bytes * 4)) {
return 0;
}
rva += 2;
vol[0] = _varint( rva, bytes ) * sign_r / 256.;
vol[1] = _varint( rva + bytes, bytes ) * sign_l / 256.;
peak[0] = _varint( rva + (bytes * 2), bytes );
peak[1] = _varint( rva + (bytes * 3), bytes );
// iTunes uses a range of -255 to 255
// to be -100% (silent) to 100% (+6dB)
( run in 1.627 second using v1.01-cache-2.11-cpan-39bf76dae61 )