Ejemplo n.º 1
0
std::unique_ptr<AudioProvider> AudioProviderFactory::GetProvider(agi::fs::path const& filename) {
	provider_creator creator;
	std::unique_ptr<AudioProvider> provider;

	provider = creator.try_create("Dummy audio provider", [&]() {
		return agi::util::make_unique<DummyAudioProvider>(filename);
	});

	// Try a PCM provider first
	if (!provider && !OPT_GET("Provider/Audio/PCM/Disable")->GetBool())
		provider = creator.try_create("PCM audio provider", [&]() { return CreatePCMAudioProvider(filename); });

	if (!provider) {
		std::vector<std::string> list = GetClasses(OPT_GET("Audio/Provider")->GetString());
		if (list.empty()) throw agi::NoAudioProvidersError("No audio providers are available.", nullptr);

		for (auto const& name : list) {
			provider = creator.try_create(name, [&]() { return Create(name, filename); });
			if (provider) break;
		}
	}

	if (!provider) {
		if (creator.found_audio)
			throw agi::AudioProviderOpenError(creator.msg, nullptr);
		if (creator.found_file)
			throw agi::AudioDataNotFoundError(creator.msg, nullptr);
		throw agi::fs::FileNotFound(filename);
	}

	bool needsCache = provider->NeedsCache();

	// Give it a converter if needed
	if (provider->GetBytesPerSample() != 2 || provider->GetSampleRate() < 32000 || provider->GetChannels() != 1)
		provider = CreateConvertAudioProvider(std::move(provider));

	// Change provider to RAM/HD cache if needed
	int cache = OPT_GET("Audio/Cache/Type")->GetInt();
	if (!cache || !needsCache)
		return agi::util::make_unique<LockAudioProvider>(std::move(provider));

	DialogProgress progress(wxGetApp().frame, _("Load audio"));

	// Convert to RAM
	if (cache == 1) return agi::util::make_unique<RAMAudioProvider>(std::move(provider), &progress);

	// Convert to HD
	if (cache == 2) return agi::util::make_unique<HDAudioProvider>(std::move(provider), &progress);

	throw agi::AudioCacheOpenError("Unknown caching method", nullptr);
}
Ejemplo n.º 2
0
std::unique_ptr<AudioProvider> AudioProviderFactory::GetProvider(agi::fs::path const& filename, agi::BackgroundRunner *br) {
	auto preferred = OPT_GET("Audio/Provider")->GetString();
	auto sorted = GetSorted(boost::make_iterator_range(std::begin(providers), std::end(providers)), preferred);

	std::unique_ptr<AudioProvider> provider;
	bool found_file = false;
	bool found_audio = false;
	std::string msg_all;     // error messages from all attempted providers
	std::string msg_partial; // error messages from providers that could partially load the file (knows container, missing codec)

	for (auto const& factory : sorted) {
		try {
			provider = factory->create(filename, br);
			if (!provider) continue;
			LOG_I("audio_provider") << "Using audio provider: " << factory->name;
			break;
		}
		catch (agi::fs::FileNotFound const& err) {
			LOG_D("audio_provider") << err.GetChainedMessage();
			msg_all += std::string(factory->name) + ": " + err.GetMessage() + " not found.\n";
		}
		catch (agi::AudioDataNotFoundError const& err) {
			LOG_D("audio_provider") << err.GetChainedMessage();
			found_file = true;
			msg_all += std::string(factory->name) + ": " + err.GetChainedMessage() + "\n";
		}
		catch (agi::AudioOpenError const& err) {
			LOG_D("audio_provider") << err.GetChainedMessage();
			found_audio = true;
			found_file = true;
			std::string thismsg = std::string(factory->name) + ": " + err.GetChainedMessage() + "\n";
			msg_all += thismsg;
			msg_partial += thismsg;
		}
	}

	if (!provider) {
		if (found_audio)
			throw agi::AudioProviderOpenError(msg_partial, nullptr);
		if (found_file)
			throw agi::AudioDataNotFoundError(msg_all, nullptr);
		throw agi::fs::FileNotFound(filename);
	}

	bool needsCache = provider->NeedsCache();

	// Give it a converter if needed
	if (provider->GetBytesPerSample() != 2 || provider->GetSampleRate() < 32000 || provider->GetChannels() != 1)
		provider = CreateConvertAudioProvider(std::move(provider));

	// Change provider to RAM/HD cache if needed
	int cache = OPT_GET("Audio/Cache/Type")->GetInt();
	if (!cache || !needsCache)
		return CreateLockAudioProvider(std::move(provider));

	// Convert to RAM
	if (cache == 1) return CreateRAMAudioProvider(std::move(provider));

	// Convert to HD
	if (cache == 2) return CreateHDAudioProvider(std::move(provider));

	throw agi::AudioCacheOpenError("Unknown caching method", nullptr);
}
Ejemplo n.º 3
0
AudioProvider *AudioProviderFactory::GetProvider(wxString const& filename, int cache) {
	AudioProvider *provider = 0;
	bool found_file = false;
	bool found_audio = false;
	std::string msg;

	if (!OPT_GET("Provider/Audio/PCM/Disable")->GetBool()) {
		// Try a PCM provider first
		try {
			provider = CreatePCMAudioProvider(filename);
			LOG_D("audio_provider") << "Using PCM provider";
		}
		catch (agi::FileNotFoundError const& err) {
			msg = "PCM audio provider: " + err.GetMessage() + " not found.\n";
		}
		catch (agi::AudioOpenError const& err) {
			found_file = true;
			msg += err.GetChainedMessage() + "\n";
		}
	}

	if (!provider) {
		std::vector<std::string> list = GetClasses(OPT_GET("Audio/Provider")->GetString());
		if (list.empty()) throw agi::NoAudioProvidersError("No audio providers are available.", 0);

		for (size_t i = 0; i < list.size() ; ++i) {
			try {
				provider = Create(list[i], filename);
				if (provider) {
					LOG_D("audio_provider") << "Using audio provider: " << list[i];
					break;
				}
			}
			catch (agi::FileNotFoundError const& err) {
				msg += list[i] + ": " + err.GetMessage() + " not found.\n";
			}
			catch (agi::AudioDataNotFoundError const& err) {
				found_file = true;
				msg += list[i] + ": " + err.GetChainedMessage() + "\n";
			}
			catch (agi::AudioOpenError const& err) {
				found_audio = true;
				found_file = true;
				msg += list[i] + ": " + err.GetChainedMessage() + "\n";
			}
		}
	}

	if (!provider) {
		if (found_audio)
			throw agi::AudioProviderOpenError(msg, 0);
		if (found_file)
			throw agi::AudioDataNotFoundError(msg, 0);
		throw agi::FileNotFoundError(STD_STR(filename));
	}

	bool needsCache = provider->NeedsCache();

	// Give it a converter if needed
	if (provider->GetBytesPerSample() != 2 || provider->GetSampleRate() < 32000 || provider->GetChannels() != 1)
		provider = CreateConvertAudioProvider(provider);

	// Change provider to RAM/HD cache if needed
	if (cache == -1) cache = OPT_GET("Audio/Cache/Type")->GetInt();
	if (!cache || !needsCache) {
		return new LockAudioProvider(provider);
	}

	DialogProgress progress(wxGetApp().frame, _("Load audio"));

	// Convert to RAM
	if (cache == 1) return new RAMAudioProvider(provider, &progress);

	// Convert to HD
	if (cache == 2) return new HDAudioProvider(provider, &progress);

	throw agi::AudioCacheOpenError("Unknown caching method", 0);
}