inline bool isTrackByArtist(const std::string& artist, const metadb_handle_ptr& track) { // todo: ignore slight differences, e.g. in punctuation service_ptr_t<metadb_info_container> outInfo; if(track->get_async_info_ref(outInfo)) { const file_info& fileInfo = outInfo->info(); for(t_size j = 0; j < fileInfo.meta_get_count_by_name("artist"); j++) { if(stricmp_utf8(fileInfo.meta_get("artist", j), artist.c_str()) == 0) { return true; } } for(t_size j = 0; j < fileInfo.meta_get_count_by_name("album artist"); j++) { if(stricmp_utf8(fileInfo.meta_get("album artist", j), artist.c_str()) == 0) { return true; } } } return false; }
virtual result on_token(const char * token) { reset(); if (!stricmp_utf8_partial(token,"/columnsui:")) { const char * ptr = strchr(token,':')+1; if (!stricmp_utf8(ptr,"help") || !stricmp_utf8(ptr,"?")) { HWND parent = core_api::get_main_window(); if (parent) static_api_ptr_t<ui_control>()->activate();//SetActiveWindow(parent); uMessageBox(parent,g_help_text,"Columns UI commandline help",0); return RESULT_PROCESSED; } else if (!stricmp_utf8_partial(ptr,"import:")) { ptr += 7; if (*ptr && *ptr =='\"') ptr++; unsigned len = strlen(ptr); const char * end = strchr(ptr, '\"'); if (end) len = end-ptr; pfc::string8 path(ptr, len); HWND parent = core_api::get_main_window(); if (parent) static_api_ptr_t<ui_control>()->activate(); if (uMessageBox(parent,uStringPrintf("Are you sure you want to import the %s configuration? Your current configuration will be lost.",pfc::string_filename(path).get_ptr()),"Import configuration?",MB_YESNO) == IDYES) { pfc::string_extension ext(path); if (!stricmp_utf8("fcl", ext)) g_import_layout(core_api::get_main_window(), path); else if (!stricmp_utf8("fcs", ext)) g_import(path); } return RESULT_PROCESSED; } /*else if (!stricmp_utf8_partial(ptr,"export:")) { ptr += 7; if (*ptr && *ptr =='\"') ptr++; unsigned len = strlen(ptr); const char * end = strchr(ptr, '\"'); if (end) len = end-ptr; pfc::string8 path(ptr, len); g_export(path); return RESULT_PROCESSED; }*/ } return RESULT_NOT_OURS; }
bool menu_manager::get_description(menu_item::type type,const char * name,string_base & out) { service_enum_t<menu_item> e; menu_item * ptr; string8_fastalloc action_name; for(ptr=e.first();ptr;ptr=e.next()) { if (ptr->get_type()==type) { unsigned action,num_actions = ptr->get_num_items(); for(action=0;action<num_actions;action++) { action_name.reset(); ptr->enum_item(action,action_name); if (!stricmp_utf8(name,action_name)) { bool rv = ptr->get_description(action,out); ptr->service_release(); if (!rv) out.reset(); return rv; } } } ptr->service_release(); } return false; }
static bool g_is_checked(const char * name,menu_item::type type, const ptr_list_base<metadb_handle> & data,const GUID & caller) { service_enum_t<menu_item> e; menu_item * ptr; bool done = false, rv = false; string8_fastalloc dummystring,action_name; for(ptr=e.first();ptr;ptr=e.next()) { if (ptr->get_type()==type) { unsigned action,num_actions = ptr->get_num_items(); for(action=0;action<num_actions;action++) { action_name.reset(); ptr->enum_item(action,action_name); if (!stricmp_utf8(name,action_name)) { unsigned displayflags = 0; if (ptr->get_display_data(action,data,dummystring,displayflags,caller)) { rv = !!(displayflags & menu_item::FLAG_CHECKED); done = true; break; } } } } ptr->service_release(); if (done) break; } return rv; }
static bool g_test_command(const char * name,menu_item::type m_type) { service_enum_t<menu_item> e; menu_item * ptr; bool done = false; string8_fastalloc action_name; for(ptr=e.first();ptr;ptr=e.next()) { if (ptr->get_type()==m_type) { unsigned action,num_actions = ptr->get_num_items(); for(action=0;action<num_actions;action++) { action_name.reset(); ptr->enum_item(action,action_name); if (!stricmp_utf8(name,action_name)) { done = true; break; } } } ptr->service_release(); if (done) break; } return done; }
void playlist_loader::g_save_playlist(const char * p_filename,const pfc::list_base_const_t<metadb_handle_ptr> & data,abort_callback & p_abort) { TRACK_CALL_TEXT("playlist_loader::g_save_playlist"); pfc::string8 filename; filesystem::g_get_canonical_path(p_filename,filename); try { service_ptr_t<file> r; filesystem::g_open(r,filename,filesystem::open_mode_write_new,p_abort); pfc::string_extension ext(filename); service_enum_t<playlist_loader> e; service_ptr_t<playlist_loader> l; if (e.first(l)) do { if (l->can_write() && !stricmp_utf8(ext,l->get_extension())) { try { TRACK_CODE("playlist_loader::write",l->write(filename,r,data,p_abort)); return; } catch(exception_io_data) {} } } while(e.next(l)); throw exception_io_data(); } catch(...) { try {filesystem::g_remove(filename,p_abort);} catch(...) {} throw; } }
bool doesTrackHaveSimilarTitle(const std::string& title, const metadb_handle_ptr& track) { // todo: ignore slight differences, e.g. in punctuation service_ptr_t<metadb_info_container> outInfo; if (!track->get_async_info_ref(outInfo)) { return false; } const file_info& fileInfo = outInfo->info(); if(!fileInfo.meta_exists("title")) { return false; } const std::string fileTitle = fileInfo.meta_get("title", 0); if(stricmp_utf8(fileTitle.c_str(), title.c_str()) == 0) { return true; } else if(fileTitlesMatchExcludingBracketsOnLhs(fileTitle, title)) { return true; } return false; }
bool menu_helpers::find_command_by_name(const char * p_name,service_ptr_t<contextmenu_item> & p_item,unsigned & p_index) { pfc::string8_fastalloc path,name; service_enum_t<contextmenu_item> e; service_ptr_t<contextmenu_item> ptr; if (e.first(ptr)) do { // if (ptr->get_type()==type) { unsigned action,num_actions = ptr->get_num_items(); for(action=0;action<num_actions;action++) { ptr->get_item_default_path(action,path); ptr->get_item_name(action,name); if (!path.is_empty()) path += "/"; path += name; if (!stricmp_utf8(p_name,path)) { p_item = ptr; p_index = action; return true; } } } } while(e.next(ptr)); return false; }
static bool run_command_internal(menu_item::type type,const char * name,const ptr_list_base<metadb_handle> & data,const GUID & caller) { service_enum_t<menu_item> e; menu_item * ptr; bool done = false; string8_fastalloc action_name; for(ptr=e.first();ptr;ptr=e.next()) { if (ptr->get_type()==type) { unsigned action,num_actions = ptr->get_num_items(); for(action=0;action<num_actions;action++) { action_name.reset(); ptr->enum_item(action,action_name); if (!stricmp_utf8(name,action_name)) { TRACK_CALL_TEXT(uStringPrintf("menu_manager::run_command()/\"%s\"",action_name.get_ptr())); ptr->perform_command(action,data,caller); done = true; break; } } } ptr->service_release(); if (done) break; } return done; }
void playlist_loader::g_load_playlist_filehint(file::ptr fileHint,const char * p_path,playlist_loader_callback & p_callback) { TRACK_CALL_TEXT("playlist_loader::g_load_playlist_filehint"); pfc::string8 filepath; filesystem::g_get_canonical_path(p_path,filepath); pfc::string_extension extension(filepath); service_ptr_t<file> l_file = fileHint; if (l_file.is_empty()) { filesystem::ptr fs; if (filesystem::g_get_interface(fs,filepath)) { if (fs->supports_content_types()) { fs->open(l_file,filepath,filesystem::open_mode_read,p_callback); } } } { service_enum_t<playlist_loader> e; if (l_file.is_valid()) { pfc::string8 content_type; if (l_file->get_content_type(content_type)) { service_ptr_t<playlist_loader> l; e.reset(); while(e.next(l)) { if (l->is_our_content_type(content_type)) { try { TRACK_CODE("playlist_loader::open",l->open(filepath,l_file,p_callback)); return; } catch(exception_io_unsupported_format) { l_file->reopen(p_callback); } } } } } if (extension.length()>0) { service_ptr_t<playlist_loader> l; e.reset(); while(e.next(l)) { if (stricmp_utf8(l->get_extension(),extension) == 0) { if (l_file.is_empty()) filesystem::g_open_read(l_file,filepath,p_callback); try { TRACK_CODE("playlist_loader::open",l->open(filepath,l_file,p_callback)); return; } catch(exception_io_unsupported_format) { l_file->reopen(p_callback); } } } } } throw exception_io_unsupported_format(); }
t_size g_get_info_secion_index_by_name (const char * p_name) { t_size i, count = tabsize(g_info_sections); for (i=0; i<count; i++) { if (!stricmp_utf8(p_name, g_info_sections[i].name)) return i; } return 4; }
int file_info::info_get_idx(const char * name) const { assert(is_valid_utf8(name)); int n,m=info_get_count(); for(n=0;n<m;n++) { if (!stricmp_utf8(name,info_enum_name(n))) return n; } return -1; }
void file_info::info_remove_field(const char * name) { assert(is_valid_utf8(name)); int n; for(n=info_get_count()-1;n>=0;n--) { if (!stricmp_utf8(name,info_enum_name(n))) info_remove(n); } }
void file_info::meta_remove_field(const char * name)//removes ALL fields of given name { assert(is_valid_utf8(name)); int n; for(n=meta_get_count()-1;n>=0;n--) { if (!stricmp_utf8(meta_enum_name(n),name)) meta_remove(n); } }
unsigned get_index_from_name(const char * name) { unsigned idx, max = get_count(); for(idx=0;idx<max;idx++) { const char * ptr = get_name_from_index(idx); assert(ptr); if (!stricmp_utf8(ptr,name)) return idx; } return order_invalid; }
int file_info::meta_get_count_by_name(const char* name) const { assert(is_valid_utf8(name)); int n,m=meta_get_count(); int rv=0; for(n=0;n<m;n++) { if (!stricmp_utf8(name,meta_enum_name(n))) rv++; } return rv; }
void file_info::merge(const pfc::list_base_const_t<const file_info*> & p_in) { t_size in_count = p_in.get_count(); if (in_count == 0) { meta_remove_all(); return; } else if (in_count == 1) { const file_info * info = p_in[0]; copy_meta(*info); set_replaygain(replaygain_info::g_merge(get_replaygain(),info->get_replaygain())); overwrite_info(*info); //copy_info_single_by_name(*info,"tagtype"); return; } merge_meta(*this,p_in); { pfc::string8_fastalloc tagtype; replaygain_info rg = get_replaygain(); t_size in_ptr; for(in_ptr = 0; in_ptr < in_count; in_ptr++ ) { const file_info * info = p_in[in_ptr]; rg = replaygain_info::g_merge(rg, info->get_replaygain()); t_size field_ptr, field_max = info->info_get_count(); for(field_ptr = 0; field_ptr < field_max; field_ptr++ ) { const char * field_name = info->info_enum_name(field_ptr), * field_value = info->info_enum_value(field_ptr); if (*field_value) { if (!stricmp_utf8(field_name,"tagtype")) { if (!tagtype.is_empty()) tagtype += "|"; tagtype += field_value; } } } } if (!tagtype.is_empty()) info_set("tagtype",tagtype); set_replaygain(rg); } }
unsigned playlist_switcher::find_playlist(const char * name) { unsigned n,max = get_num_playlists(); string8_fastalloc temp; for(n=0;n<max;n++) { temp.reset(); if (get_playlist_name(n,temp)) { if (!stricmp_utf8(temp,name)) return n; } } return (unsigned)(-1); }
int file_info::meta_get_idx(const char * name,int num) const { assert(is_valid_utf8(name)); int n,m=meta_get_count(); for(n=0;n<m;n++) { if (!stricmp_utf8(name,meta_enum_name(n))) { if (num==0) return n; num--; } } return -1; }
bool mainmenu_commands::g_find_by_name(const char * p_name,GUID & p_guid) { service_enum_t<mainmenu_commands> e; service_ptr_t<mainmenu_commands> ptr; pfc::string8_fastalloc temp; while(e.next(ptr)) { const t_uint32 count = ptr->get_command_count(); for(t_uint32 n=0; n<count; n++) { ptr->get_name(n,temp); if (stricmp_utf8(temp,p_name) == 0) { p_guid = ptr->get_command(n); return true; } } } return false; }
void ipod_write_shadowdb_v2(ipod_device_ptr_ref_t p_ipod, const char * m_path, const ipod::tasks::load_database_t & p_library, threaded_process_v2_t & p_status,abort_callback & p_abort) { pfc::string8 newpath; bool b_opened = false; //string_print_drive m_path(p_ipod->drive); try { pfc::string8 path = m_path, path_shuffle, path_pstate, path_stats; pfc::string8 backup_path; path << "\\iTunes\\" << "iTunesSD"; path_shuffle << m_path << "\\iTunes\\" << "iTunesShuffle"; path_pstate << m_path << "\\iTunes\\" << "iTunesPState"; path_stats << m_path << "\\iTunes\\" << "iTunesStats"; newpath << path << ".temp"; t_size i, count_tracks = p_library.m_tracks.get_count(), count_playlists = p_library.m_playlists.get_count(); const t_uint32 shdb_length = 0x40; const t_uint32 shtr_length = 372; const t_uint32 shth_length = (5 + count_tracks)*sizeof(t_uint32); iTunesSD2::writer header; header.write_lendian_t(iTunesSD2::shdb, p_abort); header.write_lendian_t(0x02000003, p_abort); header.write_lendian_t(shdb_length, p_abort); header.write_lendian_t(count_tracks, p_abort); header.write_lendian_t(count_playlists + 1, p_abort); header.write_lendian_t(t_uint32(0), p_abort); header.write_lendian_t(t_uint32(0), p_abort); header.write_lendian_t(t_uint8(0), p_abort); header.write_lendian_t(t_uint8(p_library.m_itunesprefs.m_voiceover_enabled ? 1 : 0), p_abort); //voiceover_enabled header.write_lendian_t(t_uint8(0), p_abort); header.write_lendian_t(t_uint8(0), p_abort); header.write_lendian_t(count_tracks, p_abort); header.write_lendian_t(shdb_length, p_abort); //shth offset header.write_lendian_t(shdb_length + shth_length + shtr_length*count_tracks, p_abort); //shph offset header.write_lendian_t(t_uint32(0), p_abort); header.write_lendian_t(t_uint32(0), p_abort); header.write_lendian_t(t_uint32(0), p_abort); header.write_lendian_t(t_uint32(0), p_abort); header.write_lendian_t(t_uint32(0), p_abort); { iTunesSD2::writer shth; shth.write_lendian_t(iTunesSD2::shth, p_abort); shth.write_lendian_t(shth_length, p_abort); shth.write_lendian_t(count_tracks, p_abort); shth.write_lendian_t(t_uint32(0), p_abort); shth.write_lendian_t(t_uint32(0), p_abort); for (i=0; i<count_tracks; i++) shth.write_lendian_t(shdb_length + shth_length + i*shtr_length, p_abort); header.write(shth, p_abort); } for (i=0; i<count_tracks; i++) { const pfc::rcptr_t<itunesdb::t_track> & p_track = p_library.m_tracks[i]; iTunesSD2::writer shtr; shtr.write_lendian_t(iTunesSD2::shtr, p_abort); shtr.write_lendian_t(shtr_length, p_abort); shtr.write_lendian_t(t_uint32(0), p_abort); //start pos shtr.write_lendian_t(p_track->length, p_abort); int volume = 0; if (p_ipod->m_device_properties.m_SupportsSoundCheck) { unsigned sc = p_library.m_tracks[i]->soundcheck; int voli = p_library.m_tracks[i]->volume; double volf = (double)voli / 255.0 + 1.0; if (volf == 0.0) { volume = -144; } else { double scdb = sc ? 10.0*log10 (1000.0 / (double)sc) : 0; //apple limit to [-12,+12] dB .... but let's not :) double vol = 20.0 * log10(volf); volume = round_float_signed(vol + scdb); if (volume < -48) volume = -144; //silencer ??? else if (volume > 18) volume = 18; } } else { volume = 100 + round_float_signed(100.0 + (double)p_library.m_tracks[i]->volume/255.0); volume = min(volume, 200); volume = max(volume, 0); } shtr.write_lendian_t(t_int32(volume)/*p_track->volume*/, p_abort); t_uint32 type=0; pfc::string_extension ext(p_library.m_tracks[i]->location); if (!stricmp_utf8(ext, "mp3")) type = 0x1; else if (!stricmp_utf8(ext, "mp4") || !stricmp_utf8(ext, "m4a") || !stricmp_utf8(ext, "aa") || !stricmp_utf8(ext, "m4b")) type = 0x2; else if (!stricmp_utf8(ext, "wav")) type = 0x4; shtr.write_lendian_t(type, p_abort); pfc::string8 path = p_library.m_tracks[i]->location; path.truncate (256); path.replace_byte(':','/'); t_size length_path = path.length(); shtr.write(path.get_ptr(), length_path, p_abort); t_size padding = 256 - length_path; for (;padding;padding--) shtr.write_lendian_t(t_uint8(0), p_abort); shtr.write_lendian_t(t_uint32(0), p_abort); shtr.write_lendian_t(t_uint8(!p_track->skip_on_shuffle), p_abort); shtr.write_lendian_t(t_uint8(p_track->remember_playback_position), p_abort); shtr.write_lendian_t(t_uint8(p_track->gapless_album), p_abort); shtr.write_lendian_t(t_uint8(0), p_abort); shtr.write_lendian_t(p_track->encoder_delay, p_abort); shtr.write_lendian_t(p_track->encoder_padding, p_abort); shtr.write_lendian_t(p_track->samplecount, p_abort); shtr.write_lendian_t(t_uint64(p_track->resync_frame_offset), p_abort); shtr.write_lendian_t(p_track->album_id, p_abort); shtr.write_lendian_t(t_uint16(p_track->tracknumber), p_abort); shtr.write_lendian_t(t_uint16(p_track->discnumber), p_abort); shtr.write_lendian_t(t_uint32(0), p_abort); shtr.write_lendian_t(t_uint32(0), p_abort); shtr.write_lendian_t(p_track->pid, p_abort); shtr.write_lendian_t(p_track->artist_id, p_abort); shtr.write_lendian_t(t_uint32(0), p_abort); shtr.write_lendian_t(t_uint32(0), p_abort); shtr.write_lendian_t(t_uint32(0), p_abort); shtr.write_lendian_t(t_uint32(0), p_abort); shtr.write_lendian_t(t_uint32(0), p_abort); shtr.write_lendian_t(t_uint32(0), p_abort); shtr.write_lendian_t(t_uint32(0), p_abort); shtr.write_lendian_t(t_uint32(0), p_abort); header.write(shtr, p_abort); } { const t_uint32 shph_length = (5+1+count_playlists)*sizeof(t_uint32); t_uint32 shpl_rolling_start = header.get_size()+shph_length; iTunesSD2::writer shph; shph.write_lendian_t(iTunesSD2::shph, p_abort); shph.write_lendian_t(shph_length, p_abort); shph.write_lendian_t(count_playlists+1, p_abort); shph.write_lendian_t(t_uint16(0xffff), p_abort); //wtf shph.write_lendian_t(t_uint16(0xffff), p_abort); //wtf shph.write_lendian_t(t_uint16(0xffff), p_abort); //wtf shph.write_lendian_t(t_uint16(0), p_abort); //wtf t_uint32 j; pfc::array_staticsize_t<iTunesSD2::writer> shpl_array(count_playlists + 1); { const t_uint32 shpl_size = (11 + count_tracks)*sizeof(t_uint32); iTunesSD2::writer & shpl = shpl_array[0]; shpl.write_lendian_t(iTunesSD2::shpl, p_abort); shpl.write_lendian_t(shpl_size, p_abort); shpl.write_lendian_t(count_tracks, p_abort); shpl.write_lendian_t(count_tracks, p_abort); shpl.write_lendian_t(t_uint64(0), p_abort); shpl.write_lendian_t(t_uint32(1), p_abort); shpl.write_lendian_t(t_uint32(0), p_abort); shpl.write_lendian_t(t_uint32(0), p_abort); shpl.write_lendian_t(t_uint32(0), p_abort); shpl.write_lendian_t(t_uint32(0), p_abort); for (j=0; j<count_tracks; j++) shpl.write_lendian_t(t_uint32(j), p_abort); } mmh::permutation_t permuation_track_id(count_tracks); mmh::g_sort_get_permutation_qsort_v2(p_library.m_tracks.get_ptr(), permuation_track_id, ipod::tasks::load_database_t::g_compare_track_id, false, false); for (i=0; i<count_playlists; i++) { const pfc::rcptr_t<itunesdb::t_playlist> & p_playlist = p_library.m_playlists[i]; t_size count_entries = p_playlist->items.get_count(); pfc::array_t<t_uint32> indices; indices.set_size(count_entries); t_size k=0; for (j=0; j<count_entries; j++) if (!p_playlist->items[j].is_podcast_group) { t_size index; if (p_library.m_tracks.bsearch_permutation_t(ipod::tasks::load_database_t::g_compare_track_id_with_id, p_playlist->items[j].track_id, permuation_track_id, index)) indices[k++] = index; } indices.set_size(k); const t_uint32 shpl_size = (11 + k)*sizeof(t_uint32); iTunesSD2::writer & shpl = shpl_array[1+i]; shpl.write_lendian_t(iTunesSD2::shpl, p_abort); shpl.write_lendian_t(shpl_size, p_abort); shpl.write_lendian_t(k, p_abort); shpl.write_lendian_t(k, p_abort); shpl.write_lendian_t(p_library.m_playlists[i]->id, p_abort); shpl.write_lendian_t(t_uint32(2), p_abort); shpl.write_lendian_t(t_uint32(0), p_abort); shpl.write_lendian_t(t_uint32(0), p_abort); shpl.write_lendian_t(t_uint32(0), p_abort); shpl.write_lendian_t(t_uint32(0), p_abort); for (j=0; j<k; j++) shpl.write_lendian_t(indices[j], p_abort); } for (i=0; i<count_playlists+1; i++) { shph.write_lendian_t(shpl_rolling_start, p_abort); shpl_rolling_start += shpl_array[i].get_size(); } for (i=0; i<count_playlists+1; i++) shph.write(shpl_array[i], p_abort); header.write(shph, p_abort); } service_ptr_t<file> p_file; filesystem::g_open_write_new(p_file, newpath, p_abort); b_opened=true; p_file->write(header.get_ptr(), header.get_size(), p_abort); p_file.release(); b_opened=false; abort_callback_dummy p_dummy_abort; backup_path << path.get_ptr() << ".backup"; if (filesystem::g_exists(backup_path, p_dummy_abort)) filesystem::g_remove(backup_path, p_dummy_abort); if (filesystem::g_exists(path, p_dummy_abort)) filesystem::g_move(path, backup_path, p_dummy_abort); filesystem::g_move(newpath, path, p_dummy_abort); if (filesystem::g_exists(path_shuffle, p_dummy_abort)) filesystem::g_remove(path_shuffle, p_dummy_abort); if (filesystem::g_exists(path_pstate, p_dummy_abort)) filesystem::g_remove(path_pstate, p_dummy_abort); if (filesystem::g_exists(path_stats, p_dummy_abort)) filesystem::g_remove(path_stats, p_dummy_abort); } catch (const exception_aborted &) { try { abort_callback_impl p_dummy_abort; if (b_opened) filesystem::g_remove(newpath, p_dummy_abort); } catch (const pfc::exception &) {} throw; } catch (const pfc::exception & ex) { try { abort_callback_impl p_dummy_abort; if (b_opened) filesystem::g_remove(newpath, p_dummy_abort); } catch (const pfc::exception &) {} throw pfc::exception //console::print (pfc::string_formatter() << "Error writing iTunesSD file : " << ex.what()); } }
float calculateTrackRating(const std::string& title, const metadb_handle_ptr& track) { service_ptr_t<metadb_info_container> outInfo; if(!track->get_async_info_ref(outInfo)) { // Don't pick it we can't get any info. return -1.0f; } const file_info& fileInfo = outInfo->info(); if (!fileInfo.meta_exists("title")) { // Don't pick it if it doesn't have a title. return -1.0f; } float totalRating = 0.0f; const std::string fileTitle = fileInfo.meta_get("title", 0); // Assume title is already roughly correct. if(stricmp_utf8(fileTitle.c_str(), title.c_str()) == 0) { static const float ratingForExactTitleMatch = 2.0f; totalRating += ratingForExactTitleMatch; } else { static const float ratingForTitleMatchWithBrackets = 1.0f; totalRating += ratingForTitleMatchWithBrackets; } if(fileInfo.meta_exists("PLAY_COUNTER")) { const int playCount = atoi(fileInfo.meta_get("PLAY_COUNTER",0)); static const float lowPlayCount = 0.0f; static const float highPlayCount = 10.0f; static const float lowPlayCountRating = 0.0f; static const float highPlayCountRating = 0.5f; const float playCountRating = maths::map(static_cast<float>(playCount), lowPlayCount, highPlayCount, lowPlayCountRating, highPlayCountRating); totalRating += playCountRating; } const auto bitrate = fileInfo.info_get_bitrate(); static const float lowBitrate = 0.0f; static const float highBitrate = 1000.0f; static const float lowBitrateRating = 0.0f; static const float highBitrateRating = 2.0f; const float bitrateRating = maths::map(static_cast<float>(bitrate), lowBitrate, highBitrate, lowBitrateRating, highBitrateRating); totalRating += bitrateRating; static const float releaseTypeWeighting = 3.0f; float releaseTypeRating = 0.55f; // Default for if nothing is set; assume it's somewhere between a live album and a soundtrack. if(fileInfo.meta_exists("musicbrainz album type") || fileInfo.meta_exists("releasetype")) { const std::string albumType = fileInfo.meta_exists("musicbrainz album type") ? fileInfo.meta_get("musicbrainz album type", 0) : fileInfo.meta_get("releasetype", 0); if(albumType == "album") { releaseTypeRating = 1.0f; } else if(albumType == "single") { releaseTypeRating = 0.9f; } else if(albumType == "compilation") { releaseTypeRating = 0.8f; } else if(albumType == "ep") { releaseTypeRating = 0.7f; } else if(albumType == "soundtrack") { releaseTypeRating = 0.6f; } else if(albumType == "live") { releaseTypeRating = 0.5f; } else if(albumType == "other") { releaseTypeRating = 0.4f; } else if(albumType == "remix") { releaseTypeRating = 0.3f; } else { releaseTypeRating = 1.0f; } } totalRating += releaseTypeRating * releaseTypeWeighting; static float albumArtistWeighting = 1.0f; float albumArtistRating = 1.0f; if(fileInfo.meta_exists("album artist") && fileInfo.meta_exists("artist")) { const std::string artist = fileInfo.meta_get("artist", 0); const std::string albumArtist = fileInfo.meta_get("album artist", 0); if(albumArtist == artist) { albumArtistRating = 1.0f; } else if(albumArtist == "Various Artists") { albumArtistRating = 0.333f; } else { // Artist appearing on someone else's album? albumArtistRating = 0.666f; } } totalRating += albumArtistRating * albumArtistWeighting; return totalRating; }
void ipod_write_shuffledb(ipod_device_ptr_ref_t p_ipod, const char * m_path, const ipod::tasks::load_database_t & p_library, threaded_process_v2_t & p_status,abort_callback & p_abort) { pfc::string8 newpath; bool b_opened = false; //string_print_drive m_path(p_ipod->drive); try { pfc::string8 path = m_path, path_shuffle, path_pstate, path_stats; pfc::string8 backup_path; path << "\\iTunes\\" << "iTunesSD"; path_shuffle << m_path << "\\iTunes\\" << "iTunesShuffle"; path_pstate << m_path << "\\iTunes\\" << "iTunesPState"; path_stats << m_path << "\\iTunes\\" << "iTunesStats"; newpath << path << ".temp"; itunessd::writer header; t_size i, count = p_library.m_tracks.get_count(); header.write_int(count, p_abort); header.write_int(0x010800, p_abort); header.write_int(0x12, p_abort); header.write_int(0, p_abort); header.write_int(0, p_abort); header.write_int(0, p_abort); for (i=0; i<count; i++) { itunessd::writer track; track.write_int(0x5aa501, p_abort); track.write_int(0, p_abort); track.write_int(0, p_abort); track.write_int(0, p_abort); track.write_int(0, p_abort); track.write_int(0, p_abort); track.write_int(0, p_abort); int volume = 0; if (p_ipod->m_device_properties.m_SupportsSoundCheck) { unsigned sc = p_library.m_tracks[i]->soundcheck; int voli = p_library.m_tracks[i]->volume; double volf = (double)voli / 255.0 + 1.0; if (volf == 0.0) { volume = -144; } else { double scdb = sc ? 10.0*log10 (1000.0 / (double)sc) : 0; //apple limit to [-12,+12] dB .... but let's not :) double vol = 20.0 * log10(volf); volume = round_float_signed(vol + scdb); if (volume < -48) volume = -144; //silencer ??? else if (volume > 18) volume = 18; } } else { volume = 100 + round_float_signed(100.0 + (double)p_library.m_tracks[i]->volume/255.0); volume = min(volume, 200); volume = max(volume, 0); } track.write_int(volume, p_abort); t_uint32 type=0; pfc::string_extension ext(p_library.m_tracks[i]->location); if (!stricmp_utf8(ext, "mp3")) type = 0x1; else if (!stricmp_utf8(ext, "mp4") || !stricmp_utf8(ext, "m4a") || !stricmp_utf8(ext, "aa") || !stricmp_utf8(ext, "m4b")) type = 0x2; else if (!stricmp_utf8(ext, "wav")) type = 0x4; track.write_int(type, p_abort); bool audiobook = (!stricmp_utf8(ext, "aa") || !stricmp_utf8(ext, "m4b")); pfc::string8 temp(p_library.m_tracks[i]->location); temp.replace_byte(':', '/'); pfc::array_t<WCHAR> buff; buff.set_size(256); buff.fill_null(); pfc::stringcvt::convert_utf8_to_wide(buff.get_ptr(), buff.get_size(), temp, pfc_infinite); track.write_int(buff.get_size()*sizeof(WCHAR), p_abort); //track.write_string(buff.get_ptr(), buff.get_size(), p_abort); track.write(buff.get_ptr(), buff.get_size()*sizeof(WCHAR), p_abort); track.write_int(0, p_abort); track.write_int(0, p_abort); track.write_int(0, p_abort); t_uint8 dummy=0; track.write_bendian_t(dummy, p_abort); dummy=!p_library.m_tracks[i]->skip_on_shuffle; track.write_bendian_t(dummy, p_abort); dummy= (audiobook || p_library.m_tracks[i]->remember_playback_position)?1:0; track.write_bendian_t(dummy, p_abort); dummy=0; track.write_bendian_t(dummy, p_abort); header.write_int(track.get_size()+3, p_abort); header.write(track.get_ptr(), track.get_size(), p_abort); } service_ptr_t<file> p_file; filesystem::g_open_write_new(p_file, newpath, p_abort); b_opened=true; p_file->write(header.get_ptr(), header.get_size(), p_abort); p_file.release(); b_opened=false; backup_path << path.get_ptr() << ".backup"; if (filesystem::g_exists(backup_path, p_abort)) filesystem::g_remove(backup_path, p_abort); if (filesystem::g_exists(path, p_abort)) filesystem::g_move(path, backup_path, p_abort); filesystem::g_move(newpath, path, p_abort); if (filesystem::g_exists(path_shuffle, p_abort)) filesystem::g_remove(path_shuffle, p_abort); if (filesystem::g_exists(path_pstate, p_abort)) filesystem::g_remove(path_pstate, p_abort); if (filesystem::g_exists(path_stats, p_abort)) filesystem::g_remove(path_stats, p_abort); } catch (const exception_aborted &) { try { abort_callback_impl p_dummy_abort; if (b_opened) filesystem::g_remove(newpath, p_dummy_abort); } catch (const pfc::exception &) {} throw; } catch (const pfc::exception & ex) { try { abort_callback_impl p_dummy_abort; if (b_opened) filesystem::g_remove(newpath, p_dummy_abort); } catch (const pfc::exception &) {} throw pfc::exception //console::print (pfc::string_formatter() << "Error writing iTunesSD file : " << ex.what()); } }
static int g_compare_field (const metadata_field_t & str2, const char * str1) { return stricmp_utf8(str2.m_name, str1); }
unsigned artwork_reader_ng_t::read_artwork(abort_callback & p_abort) { TRACK_CALL_TEXT("artwork_reader_ng_t::read_artwork"); m_bitmaps.remove_all(); bool b_loaded=false, b_extracter_attempted=false;; pfc::chain_list_v2_t<GUID>::const_iterator walk; album_art_extractor_instance_ptr p_extractor; { walk = m_requestIds.first(); for(; walk.is_valid(); ++walk) { bool b_found = false; album_art_data_ptr data; try { pfc::list_t<pfc::string8> to; if (m_repositories.query(*walk, to)) { pfc::string8 path; t_size i, count = to.get_count(); for (i=0; i<count && !b_found; i++) { if (m_handle->format_title_legacy(NULL, path, to[i], NULL)) { const char * image_extensions[] = {"jpg", "jpeg", "gif", "bmp", "png"}; t_size i, count = tabsize(image_extensions); bool b_absolute = path.find_first(':') != pfc_infinite || path.get_ptr()[0] == '\\'; pfc::string8 realPath; if (b_absolute) realPath = path; else realPath << pfc::string_directory(m_handle->get_path()) << "\\" << path; bool b_search = (realPath.find_first('*') != pfc_infinite) || (realPath.find_first('?') != pfc_infinite); bool b_search_matched = false; if (b_search) { const char * pMainPath = realPath; if (!stricmp_utf8_partial(pMainPath, "file://")) pMainPath += 7; puFindFile pSearcher = uFindFirstFile(pfc::string8() << pMainPath << ".*"); pfc::string8 searchPath = realPath; realPath.reset(); if (pSearcher) { do { const char * pResult = pSearcher->GetFileName(); for (i=0; i<count; i++) { if (!stricmp_utf8(pfc::string_extension(pResult), image_extensions[i])) { realPath << pfc::string_directory(searchPath) << "\\" << pResult; b_search_matched = true; break; } } } while (!b_search_matched && pSearcher->FindNext()); delete pSearcher; } } if (!b_search || b_search_matched) { { file::ptr file; if (b_search) { pfc::string8 canPath; filesystem::g_get_canonical_path(realPath, canPath); if (!filesystem::g_is_remote_or_unrecognized(canPath)) filesystem::g_open(file, canPath, filesystem::open_mode_read, p_abort); } else { for (i=0; i<count; i++) { pfc::string8 canPath; try { filesystem::g_get_canonical_path(pfc::string8() << realPath << "." << image_extensions[i], canPath); if (!filesystem::g_is_remote_or_unrecognized(canPath)) { filesystem::g_open(file, canPath, filesystem::open_mode_read, p_abort); break; } } catch (exception_io const &) { }; } } if (file.is_valid()) { service_ptr_t<album_art_data_impl> ptr = new service_impl_t<album_art_data_impl>; ptr->from_stream(file.get_ptr(), pfc::downcast_guarded<t_size>(file->get_size_ex(p_abort)), p_abort); b_found = true; data = ptr; } } } } } } } catch(const exception_aborted &) { throw; } catch (pfc::exception const &) { } #if 1 if (!b_found && m_native_artwork_reader_mode == artwork_panel::fb2k_artwork_embedded_and_external) { album_art_extractor_instance_v2::ptr artwork_api_v2; if (static_api_test_t<album_art_manager_v2>()) { artwork_api_v2 = static_api_ptr_t<album_art_manager_v2>()->open(pfc::list_single_ref_t<metadb_handle_ptr>(m_handle), pfc::list_single_ref_t<GUID>(*walk), p_abort); } else m_api->open(m_handle->get_path(),p_abort); { try { if (artwork_api_v2.is_valid()) data = artwork_api_v2->query(*walk, p_abort); else data = m_api->query(*walk,p_abort); b_found=true; } catch(const exception_aborted &) { throw; } catch (exception_io_not_found const &) { } catch(pfc::exception const & e) { console::formatter() << "Requested Album Art entry could not be retrieved: " << e.what(); } } } else if (!b_found && m_native_artwork_reader_mode == artwork_panel::fb2k_artwork_embedded) { { try { if (!b_extracter_attempted) { b_extracter_attempted=true; p_extractor = artwork_panel::g_get_album_art_extractor_instance(m_handle->get_path(),p_abort); } if (p_extractor.is_valid()) { data = p_extractor->query(*walk,p_abort); b_found=true; } } catch(const exception_aborted &) { throw; } catch (exception_io_not_found const &) { } catch(exception_io const & e) { console::formatter() << "Requested Album Art entry could not be retrieved: " << e.what(); } } } if (data.is_valid()) { m_bitmaps.set(*walk,pfc::rcnew_t< gdi_object_t<HBITMAP>::ptr_t >(g_create_hbitmap_from_data(data, m_cx, m_cy, m_back, m_reflection))); GdiFlush(); } } #endif #if 1 //if (!b_found) { walk = m_requestIds.first(); if (walk.is_valid() && !m_bitmaps.have_item(*walk)) { pfc::rcptr_t< gdi_object_t<HBITMAP>::ptr_t > bm; m_manager->request_nocover_image(bm, m_cx, m_cy, m_back, m_reflection, p_abort); if (bm.is_valid() && bm->is_valid()) { m_bitmaps.set(*walk,bm); GdiFlush(); } } } #endif } return 1; }
static int sortfunc(const pfc::rcptr_t<const t_entry> & p1, const pfc::rcptr_t<const t_entry> & p2) { return stricmp_utf8(p1->m_path, p2->m_path); }
LRESULT album_list_window::on_message(HWND wnd, UINT msg, WPARAM wp, LPARAM lp) { switch (msg) { case WM_CREATE: { list_wnd.add_item(this); initialised = true; modeless_dialog_manager::g_add(wnd); create_tree(); create_filter(); if (cfg_populate) refresh_tree(); static_api_ptr_t<library_manager_v3>()->register_callback(this); } break; /*case WM_GETMINMAXINFO: { LPMINMAXINFO mmi = LPMINMAXINFO(lp); mmi->ptMinTrackSize.y = cfg_height; return 0; }*/ case WM_SIZE: on_size(LOWORD(lp), HIWORD(lp)); break; /* case DM_GETDEFID: return (DC_HASDEFID<<16|IDOK); case WM_GETDLGCODE: return DLGC_DEFPUSHBUTTON;*/ // break; case WM_TIMER: if (wp == EDIT_TIMER_ID) { refresh_tree(); KillTimer(wnd, wp); m_timer = false; } break; case WM_COMMAND: switch (wp) { case IDC_FILTER | (EN_CHANGE << 16) : if (m_timer) KillTimer(wnd_edit, 500); m_timer = SetTimer(wnd, EDIT_TIMER_ID, 500, NULL) != 0; return TRUE; case IDOK: if (GetKeyState(VK_SHIFT) & KF_UP) do_playlist(p_selection, false); else if (GetKeyState(VK_CONTROL) & KF_UP) do_playlist(p_selection, true, true); else do_playlist(p_selection, true); return 0; } break; case WM_CONTEXTMENU: { enum { ID_SEND = 1, ID_ADD, ID_NEW, ID_AUTOSEND, ID_REMOVE, ID_REMOVEDEAD, ID_REFRESH, ID_FILT, ID_CONF, ID_VIEW_BASE }; HMENU menu = CreatePopupMenu(); POINT pt = { GET_X_LPARAM(lp), GET_Y_LPARAM(lp) }; service_ptr_t<contextmenu_manager> p_menu_manager; unsigned IDM_MANAGER_BASE = 0; HWND list = wnd_tv; HTREEITEM treeitem = NULL; TVHITTESTINFO ti; memset(&ti, 0, sizeof(ti)); if (pt.x != -1 && pt.y != -1) { ti.pt = pt; ScreenToClient(list, &ti.pt); uSendMessage(list, TVM_HITTEST, 0, (long)&ti); if (ti.hItem && (ti.flags & TVHT_ONITEM)) { //FIX THIS AND AUTOSEND //TreeView_Select(list, ti.hItem, TVGN_DROPHILITE); //uSendMessage(list,TVM_SELECTITEM,TVGN_DROPHILITE,(long)ti.hItem); treeitem = ti.hItem; } } else { treeitem = TreeView_GetSelection(list); RECT rc; if (treeitem && TreeView_GetItemRect(wnd_tv, treeitem, &rc, TRUE)) { MapWindowPoints(wnd_tv, HWND_DESKTOP, (LPPOINT)&rc, 2); pt.x = rc.left; pt.y = rc.top + (rc.bottom - rc.top) / 2; } else { GetMessagePos(&pt); } } TreeView_Select(list, treeitem, TVGN_DROPHILITE); HMENU menu_view = CreatePopupMenu(); unsigned n, m = cfg_view_list.get_count(); string8_fastalloc temp; temp.prealloc(32); uAppendMenu(menu_view, MF_STRING | (!stricmp_utf8(directory_structure_view_name, view) ? MF_CHECKED : 0), ID_VIEW_BASE + 0, directory_structure_view_name); list_t<string_simple, pfc::alloc_fast> views; views.add_item(string_simple(directory_structure_view_name)); for (n = 0; n<m; n++) { temp = cfg_view_list.get_name(n); string_simple item(temp.get_ptr()); if (item) { uAppendMenu(menu_view, MF_STRING | (!stricmp_utf8(temp, view) ? MF_CHECKED : 0), ID_VIEW_BASE + views.add_item(item), temp); } } IDM_MANAGER_BASE = ID_VIEW_BASE + views.get_count(); uAppendMenu(menu, MF_STRING | MF_POPUP, (UINT)menu_view, "View"); if (!m_populated && !cfg_populate) uAppendMenu(menu, MF_STRING, ID_REFRESH, "Populate"); uAppendMenu(menu, MF_STRING | (m_filter ? MF_CHECKED : 0), ID_FILT, "Filter"); uAppendMenu(menu, MF_STRING, ID_CONF, "Settings"); bool show_shortcuts = standard_config_objects::query_show_keyboard_shortcuts_in_menus(); node * p_node = NULL; TVITEMEX tvi; memset(&tvi, 0, sizeof(tvi)); tvi.hItem = treeitem; tvi.mask = TVIF_HANDLE | TVIF_PARAM; TreeView_GetItem(list, &tvi); p_node = (node*)tvi.lParam; if (treeitem && p_node) { uAppendMenu(menu, MF_SEPARATOR, 0, ""); uAppendMenu(menu, MF_STRING, ID_SEND, (show_shortcuts ? "&Send to playlist\tEnter" : "&Send to playlist")); uAppendMenu(menu, MF_STRING, ID_ADD, show_shortcuts ? "&Add to playlist\tShift+Enter" : "&Add to playlist"); uAppendMenu(menu, MF_STRING, ID_NEW, show_shortcuts ? "Send to &new playlist\tCtrl+Enter" : "Send to &new playlist"); uAppendMenu(menu, MF_STRING, ID_AUTOSEND, "Send to &autosend playlist"); if (!static_api_ptr_t<core_version_info_v2>()->test_version(0, 9, 6, 0)) { uAppendMenu(menu, MF_STRING, ID_REMOVE, "&Remove from library"); uAppendMenu(menu, MF_STRING, ID_REMOVEDEAD, "Remove &dead entries (slow)"); } uAppendMenu(menu, MF_SEPARATOR, 0, ""); contextmenu_manager::g_create(p_menu_manager); p_node->sort_entries(); if (p_menu_manager.is_valid()) { p_menu_manager->init_context(p_node->get_entries(), 0); p_menu_manager->win32_build_menu(menu, IDM_MANAGER_BASE, -1); menu_helpers::win32_auto_mnemonics(menu); } } int cmd = TrackPopupMenu(menu, TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, pt.x, pt.y, 0, get_wnd(), 0); DestroyMenu(menu); TreeView_Select(list, NULL, TVGN_DROPHILITE); if (cmd) { if (p_menu_manager.is_valid() && (unsigned)cmd >= IDM_MANAGER_BASE) { p_menu_manager->execute_by_id(cmd - IDM_MANAGER_BASE); } else if (cmd >= ID_VIEW_BASE) { unsigned n = cmd - ID_VIEW_BASE; if (n<views.get_count()) { view = views[n].get_ptr(); refresh_tree(); } } else if (cmd<ID_VIEW_BASE) { unsigned cmd2 = 0; switch (cmd) { case ID_NEW: do_playlist(p_node, true, true); break; case ID_SEND: do_playlist(p_node, true); break; case ID_ADD: do_playlist(p_node, false); break; case ID_AUTOSEND: do_autosend_playlist(p_node, view, true); break; case ID_CONF: { static_api_ptr_t<ui_control>()->show_preferences(g_guid_preferences_album_list_panel); } break; case ID_FILT: { m_filter = !m_filter; create_or_destroy_filter(); } break; case ID_REMOVE: p_node->remove_from_db(); break; case ID_REMOVEDEAD: p_node->remove_dead(); break; case ID_REFRESH: if (!m_populated && !cfg_populate) refresh_tree(); break; } if (cmd2) uSendMessage(get_wnd(), WM_COMMAND, cmd2, 0); } } p_menu_manager.release(); /* if (treeitem_context && (treeitem_context != treeitem) && cfg_autosend) TreeView_SelectItem(wnd_tv,treeitem);*/ } return 0; case WM_NOTIFY: { LPNMHDR hdr = (LPNMHDR)lp; switch (hdr->idFrom) { case IDC_TREE: { if (hdr->code == TVN_ITEMEXPANDING) { LPNMTREEVIEW param = (LPNMTREEVIEW)hdr; if (cfg_picmixer && (param->action == TVE_EXPAND)) { TreeView_CollapseOtherNodes(param->hdr.hwndFrom, param->itemNew.hItem); } } else if (hdr->code == TVN_SELCHANGED) { LPNMTREEVIEW param = (LPNMTREEVIEW)hdr; p_selection = (node*)param->itemNew.lParam; if ((param->action == TVC_BYMOUSE || param->action == TVC_BYKEYBOARD)) { if (cfg_autosend) do_autosend_playlist(p_selection, view); } if (m_selection_holder.is_valid()) { m_selection_holder->set_selection(p_selection.is_valid() ? p_selection->get_entries() : metadb_handle_list()); } #if 0 if (cfg_picmixer) { HTREEITEM ti_parent_old = TreeView_GetParent(param->hdr.hwndFrom, param->itemOld.hItem); HTREEITEM ti_parent_new = TreeView_GetParent(param->hdr.hwndFrom, param->itemNew.hItem); if (/*ti_parent_old != param->itemNew.hItem && */!TreeView_IsChild(param->hdr.hwndFrom, param->itemNew.hItem, param->itemOld.hItem)) { HTREEITEM ti = //TreeView_GetLevel(param->hdr.hwndFrom, param->itemNew.hItem) < TreeView_GetLevel(param->hdr.hwndFrom, param->itemOld.hItem) ? TreeView_GetCommonParentChild(param->hdr.hwndFrom, param->itemOld.hItem, param->itemNew.hItem) //: param->itemOld.hItem ; if (ti && ti != TVI_ROOT) TreeView_Expand(param->hdr.hwndFrom, ti, TVE_COLLAPSE); } if (ti_parent_new) { HTREEITEM child = TreeView_GetChild(param->hdr.hwndFrom, ti_parent_new); while (child) { if (child != param->itemNew.hItem) { } } } } #endif } } break; } } break; case WM_DESTROY: static_api_ptr_t<library_manager_v3>()->unregister_callback(this); modeless_dialog_manager::g_remove(wnd); destroy_tree(); destroy_filter(); m_selection_holder.release(); m_root.release(); p_selection.release(); if (initialised) { list_wnd.remove_item(this); if (list_wnd.get_count() == 0) { DeleteFont(g_font); g_font = 0; } initialised = false; } break; } return DefWindowProc(wnd, msg, wp, lp); }
static bool g_is_our_path(const char * p_path,const char * p_extension) {return stricmp_utf8(p_extension,"raw") == 0;}
int menu_helpers::name_to_guid_table::entry_compare(const entry & entry1,const entry & entry2) { return stricmp_utf8(entry1.m_name,entry2.m_name); }