4 #define strcat_s strcat 20 return meta_find_ex(p_name,p_name_length) != pfc_infinite;
48 if (index == pfc_infinite)
return 0;
63 return info_find_ex(p_name,p_name_length) != pfc_infinite;
79 if (index != pfc_infinite)
89 for(
t_size walk = 0; walk < total; ++walk) {
103 t_size new_index = pfc_infinite;
148 if (&p_source !=
this) {
158 if (&p_source !=
this) {
168 if (&p_source !=
this) {
180 if (index == pfc_infinite)
return 0;
182 if (p_index >= max)
return 0;
189 if (index == pfc_infinite)
return 0;
197 if (val==0)
return 0;
207 if (srate>0 && len>0)
209 ret = audio_math::time_to_samples(len,(
unsigned)srate);
230 PFC_ASSERT(unit==0 || strlen(unit) <= 64);
274 return val>0 && val<=256;
305 t_size new_index = pfc_infinite;
309 if (n == 0) new_index =
meta_set_ex(p_new_name,p_new_name_length,value,pfc_infinite);
317 if (index == pfc_infinite)
return meta_set_nocheck_ex(p_name,p_name_length,p_value,p_value_length);
352 info_set_ex(p_name,p_name_len,p_value,p_value_len);
379 PFC_ASSERT( count > 0);
380 for(val=0;val<count;val++)
382 if (val > 0) out += separator;
390 if (index == pfc_infinite)
return false;
397 if (p_filesize > 0 && p_length > 0)
info_set_bitrate((
unsigned)floor((
double)p_filesize * 8 / (p_length * 1000) + 0.5));
401 const char * encoding =
info_get(
"encoding");
402 if (encoding != NULL) {
419 for(
t_size n=0; n<count; n++) {
422 for(
t_size n1=0; n1<count; n1++) {
433 for(
t_size v = 0; v < value_count; v++) {
446 FB2K_DebugLog() <<
"meta count mismatch";
450 for(
t_size n=0; n<count; n++) {
453 for(
t_size n1=0; n1<count; n1++) {
456 FB2K_DebugLog() <<
"item2 doesn't have " << p_item1.
meta_enum_name(n1);
464 for(
t_size v = 0; v < value_count; v++) {
480 for(
t_size n1=0; n1<count; n1++) {
482 if (n2 == pfc_infinite) {
495 return p_char >= 32 && p_char < 127 && p_char != '=' && p_char != '%' && p_char != '<' && p_char != '>
'; 498 bool file_info::g_is_valid_field_name(const char * p_name,t_size p_length) { 500 for(walk = 0; walk < p_length && p_name[walk] != 0; walk++) { 501 if (!is_valid_field_name_char(p_name[walk])) return false; 506 void file_info::to_formatter(pfc::string_formatter& out) const { 507 out << "File info dump:\n"; 508 if (get_length() > 0) out<< "Duration: " << pfc::format_time_ex(get_length(), 6) << "\n"; 509 pfc::string_formatter temp; 510 for(t_size metaWalk = 0; metaWalk < meta_get_count(); ++metaWalk) { 511 meta_format_entry(metaWalk, temp); 512 out << "Meta: " << meta_enum_name(metaWalk) << " = " << temp << "\n"; 514 for(t_size infoWalk = 0; infoWalk < info_get_count(); ++infoWalk) { 515 out << "Info: " << info_enum_name(infoWalk) << " = " << info_enum_value(infoWalk) << "\n"; 519 void file_info::to_console() const { 520 FB2K_console_formatter() << "File info dump:"; 521 if (get_length() > 0) FB2K_console_formatter() << "Duration: " << pfc::format_time_ex(get_length(), 6); 522 pfc::string_formatter temp; 523 for(t_size metaWalk = 0; metaWalk < meta_get_count(); ++metaWalk) { 524 meta_format_entry(metaWalk, temp); 525 FB2K_console_formatter() << "Meta: " << meta_enum_name(metaWalk) << " = " << temp; 527 for(t_size infoWalk = 0; infoWalk < info_get_count(); ++infoWalk) { 528 FB2K_console_formatter() << "Info: " << info_enum_name(infoWalk) << " = " << info_enum_value(infoWalk); 532 void file_info::info_set_wfx_chanMask(uint32_t val) { 539 info_set ("WAVEFORMATEXTENSIBLE_CHANNEL_MASK", PFC_string_formatter() << "0x" << pfc::format_hex(val) ); 544 uint32_t file_info::info_get_wfx_chanMask() const { 545 const char * str = this->info_get("WAVEFORMATEXTENSIBLE_CHANNEL_MASK"); 546 if (str == NULL) return 0; 547 if (pfc::strcmp_partial( str, "0x") != 0) return 0; 549 return pfc::atohex<uint32_t>( str + 2, strlen(str+2) ); 550 } catch(...) { return 0;} 553 bool file_info::field_is_person(const char * fieldName) { 554 return field_name_equals(fieldName, "artist") || 555 field_name_equals(fieldName, "album artist") || 556 field_name_equals(fieldName, "composer") || 557 field_name_equals(fieldName, "performer") || 558 field_name_equals(fieldName, "conductor") || 559 field_name_equals(fieldName, "orchestra") || 560 field_name_equals(fieldName, "ensemble") || 561 field_name_equals(fieldName, "engineer"); 564 bool file_info::field_is_title(const char * fieldName) { 565 return field_name_equals(fieldName, "title") || field_name_equals(fieldName, "album"); 569 void file_info::to_stream( stream_writer * stream, abort_callback & abort ) const { 570 stream_writer_formatter<> out(* stream, abort ); 572 out << this->get_length(); 575 const auto rg = this->get_replaygain(); 576 out << rg.m_track_gain << rg.m_album_gain << rg.m_track_peak << rg.m_album_peak; 581 const uint32_t metaCount = pfc::downcast_guarded<uint32_t>( this->meta_get_count() ); 582 for(uint32_t metaWalk = 0; metaWalk < metaCount; ++metaWalk) { 583 const char * name = this->meta_enum_name( metaWalk ); 585 out.write_string_nullterm( this->meta_enum_name( metaWalk ) ); 586 const size_t valCount = this->meta_enum_value_count( metaWalk ); 587 for(size_t valWalk = 0; valWalk < valCount; ++valWalk) { 588 const char * value = this->meta_enum_value( metaWalk, valWalk ); 590 out.write_string_nullterm( value ); 593 out.write_int<char>(0); 596 out.write_int<char>(0); 600 const uint32_t infoCount = pfc::downcast_guarded<uint32_t>( this->info_get_count() ); 601 for(uint32_t infoWalk = 0; infoWalk < infoCount; ++infoWalk) { 602 const char * name = this->info_enum_name( infoWalk ); 603 const char * value = this->info_enum_value( infoWalk ); 604 if (*name && *value) { 605 out.write_string_nullterm(name); out.write_string_nullterm(value); 608 out.write_int<char>(0); 612 void file_info::from_stream( stream_reader * stream, abort_callback & abort ) { 613 stream_reader_formatter<> in( *stream, abort ); 614 pfc::string_formatter tempName, tempValue; 616 double len; in >> len; this->set_length( len ); 620 in >> rg.m_track_gain >> rg.m_album_gain >> rg.m_track_peak >> rg.m_album_peak; 624 this->meta_remove_all(); 626 in.read_string_nullterm( tempName ); 627 if (tempName.length() == 0) break; 628 size_t metaIndex = pfc_infinite; 630 in.read_string_nullterm( tempValue ); 631 if (tempValue.length() == 0) break; 632 if (metaIndex == pfc_infinite) metaIndex = this->meta_add( tempName, tempValue ); 633 else this->meta_add_value( metaIndex, tempValue ); 638 this->info_remove_all(); 640 in.read_string_nullterm( tempName ); 641 if (tempName.length() == 0) break; 642 in.read_string_nullterm( tempValue ); 643 this->info_set( tempName, tempValue ); 648 static const char * _readString( const uint8_t * & ptr, size_t & remaining ) { 649 const char * rv = (const char*)ptr; 651 if (remaining == 0) throw exception_io_data(); 652 uint8_t byte = *ptr++; --remaining; 653 if (byte == 0) break; 658 template<typename int_t> void _readInt( int_t & out, const uint8_t * &ptr, size_t & remaining) { 659 if (remaining < sizeof(out)) throw exception_io_data(); 660 pfc::decode_little_endian( out, ptr ); ptr += sizeof(out); remaining -= sizeof(out); 663 template<typename float_t> static void _readFloat(float_t & out, const uint8_t * &ptr, size_t & remaining) { 665 typename pfc::sized_int_t<sizeof(float_t)>::t_unsigned i; 668 _readInt(u.i, ptr, remaining); 672 void file_info::from_mem( const void * memPtr, size_t memSize ) { 673 size_t remaining = memSize; 674 const uint8_t * walk = (const uint8_t*) memPtr; 677 double len; _readFloat(len, walk, remaining); 678 this->set_length( len ); 683 _readFloat(rg.m_track_gain, walk, remaining ); 684 _readFloat(rg.m_album_gain, walk, remaining ); 685 _readFloat(rg.m_track_peak, walk, remaining ); 686 _readFloat(rg.m_album_peak, walk, remaining ); 687 this->set_replaygain( rg ); 691 this->meta_remove_all(); 693 const char * metaName = _readString( walk, remaining ); 694 if (*metaName == 0) break; 695 size_t metaIndex = pfc_infinite; 697 const char * metaValue = _readString( walk, remaining ); 698 if (*metaValue == 0) break; 699 if (metaIndex == pfc_infinite) metaIndex = this->meta_add( metaName, metaValue ); 700 else this->meta_add_value( metaIndex, metaName ); 705 this->info_remove_all(); 707 const char * infoName = _readString( walk, remaining ); 708 if (*infoName == 0) break; 709 const char * infoValue = _readString( walk, remaining ); 710 this->info_set( infoName, infoValue ); 715 audio_chunk::spec_t file_info::audio_chunk_spec() const 717 audio_chunk::spec_t rv = {}; 718 rv.sampleRate = (uint32_t)this->info_get_int("samplerate"); 719 rv.chanCount = (uint32_t)this->info_get_int("channels"); 720 rv.chanMask = (uint32_t)this->info_get_wfx_chanMask(); 721 if (audio_chunk::g_count_channels( rv.chanMask ) != rv.chanCount ) { 722 rv.chanMask = audio_chunk::g_guess_channel_config( rv.chanCount ); void info_set_bitrate(t_int64 val)
virtual t_size meta_set_nocheck_ex(const char *p_name, t_size p_name_length, const char *p_value, t_size p_value_length)=0
unsigned info_get_decoded_bps() const
void copy_meta_single_rename(const file_info &p_source, t_size p_index, const char *p_new_name)
virtual double get_length() const =0
Retrieves audio duration, in seconds. Note that the reported duration should not be assumed to be th...
double info_get_float(const char *name) const
t_size meta_get_count_by_name_ex(const char *p_name, t_size p_name_length) const
void copy_info_single_by_name_ex(const file_info &p_source, const char *p_name, t_size p_name_length)
virtual t_size meta_set_ex(const char *p_name, t_size p_name_length, const char *p_value, t_size p_value_length)=0
Creates a new metadata entry of specified name with specified value. If an entry of same name already...
static bool g_is_info_equal(const file_info &p_item1, const file_info &p_item2)
void copy_meta_single_by_name_nocheck_ex(const file_info &p_source, const char *p_name, t_size p_name_length)
virtual void info_remove_mask(const bit_array &p_mask)=0
Removes technical info entries indicated by specified bit mask.
bool meta_exists_ex(const char *p_name, t_size p_name_length) const
virtual void meta_remove_mask(const bit_array &p_mask)=0
Removes metadata entries according to specified bit mask.
static bool g_is_meta_equal(const file_info &p_item1, const file_info &p_item2)
bool is_encoding_lossy() const
double string_to_float(const char *src, t_size max)
t_size meta_add_ex(const char *p_name, t_size p_name_length, const char *p_value, t_size p_value_length)
virtual void copy_meta(const file_info &p_source)
Copies metadata from specified file_info object.
const char * info_get_ex(const char *p_name, t_size p_name_length) const
void meta_remove_value(t_size p_index, t_size p_value)
virtual t_size meta_enum_value_count(t_size p_index) const =0
Retrieves count of values in metadata entry of specified index. The value is always equal to or great...
const char * info_get(const char *p_name) const
void meta_remove_field_ex(const char *p_name, t_size p_name_length)
void meta_add_value_ex(t_size p_index, const char *p_value, t_size p_value_length)
int stricmp_ascii_ex(const char *const s1, t_size const len1, const char *const s2, t_size const len2)
virtual const char * info_enum_value(t_size p_index) const =0
Retrieves the value of specified technical info entry. Return value is a null-terminated UTF-8 encode...
void overwrite_meta(const file_info &p_source)
static bool g_equal(const replaygain_info &item1, const replaygain_info &item2)
virtual const char * meta_enum_value(t_size p_index, t_size p_value_number) const =0
Retrieves specified value from specified metadata entry. Return value is a null-terminated UTF-8 enco...
virtual void meta_insert_value_ex(t_size p_index, t_size p_value_index, const char *p_value, t_size p_value_length)=0
Inserts a new value into specified metadata entry.
void info_set_replaygain_album_gain(float value)
void meta_add_value(t_size p_index, const char *p_value)
Structure containing ReplayGain scan results from some playable object, also providing various helper...
static bool g_is_meta_equal_debug(const file_info &p_item1, const file_info &p_item2)
void info_set_int(const char *name, t_int64 value)
t_size meta_set_nocheck(const char *p_name, const char *p_value)
void meta_format_entry(t_size index, pfc::string_base &p_out, const char *separator=", ") const
bool info_remove_ex(const char *p_name, t_size p_name_length)
virtual t_size info_set_ex(const char *p_name, t_size p_name_length, const char *p_value, t_size p_value_length)=0
Creates a new technical info entry with specified name and specified value. If an entry of the same n...
Main interface class for information about some playable object.
const char * meta_get_ex(const char *p_name, t_size p_name_length, t_size p_index) const
virtual void copy(const file_info &p_source)
Copies entire file_info contents from specified file_info object.
t_size info_set_nocheck(const char *p_name, const char *p_value)
virtual t_size meta_get_count() const =0
Retrieves count of metadata entries.
void copy_info_single_nocheck(const file_info &p_source, t_size p_index)
virtual void copy_info(const file_info &p_source)
Copies technical info from specified file_info object.
virtual t_size info_find_ex(const char *p_name, t_size p_name_length) const
Finds technical info entry of specified name. Returns index of found entry on success, infinite on failure.
void copy_meta_single_by_name_ex(const file_info &p_source, const char *p_name, t_size p_name_length)
void meta_remove_index(t_size p_index)
void copy_meta_single_rename_ex(const file_info &p_source, t_size p_index, const char *p_new_name, t_size p_new_name_length)
t_size meta_calc_total_value_count() const
void copy_meta_single(const file_info &p_source, t_size p_index)
t_size info_set(const char *p_name, const char *p_value)
void info_set_replaygain_track_gain(float value)
virtual void set_replaygain(const replaygain_info &p_info)=0
Sets ReplayGain information.
static bool is_valid_field_name_char(char p_char)
virtual void meta_remove_values(t_size p_index, const bit_array &p_mask)=0
Removes values according to specified bit mask from specified metadata entry. If all values are remov...
t_int64 info_get_int(const char *name) const
t_int64 info_get_length_samples() const
void set(const _t_key &p_key, const _t_value &p_value)
void info_set_replaygain_album_peak(float value)
void copy_info_single(const file_info &p_source, t_size p_index)
virtual t_size meta_find_ex(const char *p_name, t_size p_name_length) const
Finds index of metadata entry of specified name. Returns infinite when not found. ...
t_size info_find(const char *p_name) const
void float_to_string(char *out, t_size out_max, double val, unsigned precision, bool b_sign)
bool is_valid_utf8(const char *param, t_size max=~0)
t_uint64 t_filesize
Type used for file size related variables.
bool set_from_meta_ex(const char *p_name, t_size p_name_len, const char *p_value, t_size p_value_len)
int stricmp_ascii(const char *s1, const char *s2)
static bool is_valid_bps(t_int64 val)
void info_set_float(const char *name, double value, unsigned precision, bool force_sign=false, const char *unit=0)
void copy_meta_single_nocheck(const file_info &p_source, t_size p_index)
bool meta_format(const char *p_name, pfc::string_base &p_out, const char *separator=", ") const
bool info_set_replaygain_ex(const char *p_name, t_size p_name_len, const char *p_value, t_size p_value_len)
bool are_meta_fields_identical(t_size p_index1, t_size p_index2) const
void info_remove_index(t_size p_index)
virtual replaygain_info get_replaygain() const =0
Retrieves ReplayGain information.
void copy_info_single_by_name_nocheck_ex(const file_info &p_source, const char *p_name, t_size p_name_length)
void info_calculate_bitrate(t_filesize p_filesize, double p_length)
void info_set_replaygain_track_peak(float value)
virtual const char * info_enum_name(t_size p_index) const =0
Retrieves the name of specified technical info entry. Return value is a null-terminated UTF-8 encoded...
void info_set_replaygain_auto_ex(const char *p_name, t_size p_name_len, const char *p_value, t_size p_value_len)
virtual void set_length(double p_length)=0
Sets audio duration, in seconds. Note that the reported duration should not be assumed to be the exa...
t_size meta_find(const char *p_name) const
bool info_exists_ex(const char *p_name, t_size p_name_length) const
virtual t_size info_get_count() const =0
Retrieves number of technical info entries.
bool query(const _t_key &p_key, _t_value &p_value) const
virtual const char * meta_enum_name(t_size p_index) const =0
Retrieves the name of metadata entry of specified index. Return value is a null-terminated UTF-8 enco...