void run(threaded_process_status & p_status,abort_callback & p_abort) { try { const t_uint32 decode_flags = input_flag_no_seeking | input_flag_no_looping; // tell the decoders that we won't seek and that we don't want looping on formats that support looping. input_helper input; audio_hash.set_count(m_items.get_size()); for(t_size walk = 0; walk < m_items.get_size(); ++walk) { p_abort.check(); // in case the input we're working with fails at doing this p_status.set_progress(walk, m_items.get_size()); p_status.set_progress_secondary(0); p_status.set_item_path( m_items[walk]->get_path() ); input.open(NULL, m_items[walk], decode_flags, p_abort); double length; { // fetch the track length for proper dual progress display; file_info_impl info; // input.open should have preloaded relevant info, no need to query the input itself again. // Regular get_info() may not retrieve freshly loaded info yet at this point (it will start giving the new info when relevant info change callbacks are dispatched); we need to use get_info_async. if (m_items[walk]->get_info_async(info)) length = info.get_length(); else length = 0; } memset( &ctx, 0, sizeof( sha1_context ) ); sha1_starts( &ctx ); audio_chunk_impl_temporary l_chunk; double decoded = 0; while(input.run(l_chunk, p_abort)) { // main decode loop sha1_update(&ctx,(unsigned char*)l_chunk.get_data(),l_chunk.get_data_length()); //m_peak = l_chunk.get_peak(m_peak); if (length > 0) { // don't bother for unknown length tracks decoded += l_chunk.get_duration(); if (decoded > length) decoded = length; p_status.set_progress_secondary_float(decoded / length); } p_abort.check(); // in case the input we're working with fails at doing this } unsigned char sha1sum[20] ={0}; sha1_finish(&ctx,sha1sum); pfc::string_formatter msg; for(int i = 0; i < 20; i++ ) { msg <<pfc::format_hex(sha1sum[i]); audio_hash[walk] =msg; } } } catch(std::exception const & e) { m_failMsg = e.what(); } }
pfc::list_t<metadb_handle_ptr> get_sorted_playlist(const pfc::list_base_const_t<metadb_handle_ptr> &data, threaded_process_status &p_status, abort_callback &p_abort) { std::multimap<int, metadb_handle_ptr, std::greater<int>> temp; std::multimap<int, metadb_handle_ptr, std::greater<int>>::iterator it; pfc::list_t<metadb_handle_ptr> result; pfc::lores_timer timer; pfc::string8 message, msg; int size = data.get_count(); for (int i = 0; i < size; i++) { message.reset(); message << "Track " << i + 1 << " of " << size; p_status.set_item(message); p_status.set_progress(i + 1, size); timer.start(); const metadb_handle_ptr track = data[i]; int count = get_track_count(track, p_abort); msg.reset(); msg << count; console::print(msg); // don't make more than 5 requests per second // (averaged over a 5 minute period) if (timer.query() < 0.2) { p_abort.sleep(0.2); } if (i && (i % 100 == 0)) { p_abort.sleep(10); } if (count > 0) { temp.insert(std::pair<int, metadb_handle_ptr>(count, track)); } else { temp.insert(std::pair<int, metadb_handle_ptr>(0, track)); } } for (it = temp.begin(); it != temp.end(); it++) { metadb_handle_ptr track = it->second; result.add_item(track); } return result; }
virtual void run(threaded_process_status &p_status, abort_callback &p_abort) { try { p_status.set_item("Downloading track info from Last.fm..."); sorted_playlist = get_sorted_playlist(selected_items, p_status, p_abort); success = true; } catch (...) { popup_message::g_show("Error, see the console log", "foo_last_sort", popup_message::icon_error); } }
void RequestThread::run(threaded_process_status &p_status, abort_callback &p_abort) { Metadata *metadata = nullptr; try { metadata = query->perform(p_abort); // Extracting releases from 3 possible locations // /metadata/release if (auto release = metadata->extract_release()) { mbc->add(release); // /metadata/discid/release-list/release } else if (auto discid = metadata->get_discid()) { if (auto release_list = discid->get_release_list()) { auto id = discid->get_id(); auto count = release_list->count(); for (size_t i = 0; i < count; i++) { auto release = release_list->extract(0); // FIXME: this is incorrect, as only one of the discs has // this discid, but it won't affect anyone (release must // have two or more discs with the same amount of tracks, // and user must choose the wrong one). Will be fixed when // web service adds support for inc=discids param. for (size_t i = 0; i < release->medium_count(); i++) { release->get_medium(i)->set_discid(id); } mbc->add(release); } } // /metadata/release-list/release } else if (auto release_list = metadata->get_release_list()) { auto count = release_list->count(); for (size_t i = 0; i < count; i++) { release = release_list->get(i); // Progress and title p_status.set_progress(i + 1, count + 1); pfc::string8 title = "Fetching: "; title << release->get_artist_credit()->get_name() << " - " << release->get_title(); auto date = release->get_date(); if (date.get_year() != 0) { title << " (" << static_cast<pfc::string8>(date) << ")"; } p_status.set_title(title); Query query("release", release->get_id()); query.add_param("inc", "artists+labels+recordings+release-groups+artist-credits", false); auto release = query.perform(p_abort)->extract_release(); if (release != nullptr) { mbc->add(release); } } } // Removing discs from multidisc releases with different track count auto track_count = tracks->get_count(); for (size_t i = 0; i < mbc->count(); i++) { auto release = mbc->get(i); if (release->track_count() == track_count) continue; for (size_t j = 0; j < release->medium_count(); j++) { if (release->get_medium(j)->track_count() != track_count) { release->remove_medium(j); j--; } } if (release->medium_count() == 0) { mbc->remove(i); i--; } } if (mbc->count() == 0) { throw NotFound(); } MetadataProcessor::apply_all(*mbc); mbc->sort(); ShowWindow(window, SW_SHOW); } catch (GenericException e) { PostMessage(window, WM_CLOSE, 0, 0); popup_message::g_show(e.what(), COMPONENT_TITLE, popup_message::icon_error); } catch (...) { PostMessage(window, WM_CLOSE, 0, 0); delete metadata; delete query; throw; } delete metadata; delete query; }