示例#1
0
	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();
		}
	}
示例#2
0
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;
}
示例#3
0
	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);
		}
	}
示例#4
0
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;
}