From 6e5b53d1a9595bd77dfcbf22b73b053efa890638 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Sat, 22 Dec 2012 09:30:47 -0800 Subject: [PATCH] Move the logic for which AudioProvider to create out of AudioController Audio providers should be responsible for determining whether or not they can open a URI, since it's not really possible for anything else to. As such move the (lack of) parsing of dummy audio URIs to DummyAudioProvider, and try to create DummyAudioProviders in AudioProvider::CreateProvider. --- aegisub/src/audio_controller.cpp | 77 +++------------------------- aegisub/src/audio_provider.cpp | 5 +- aegisub/src/audio_provider_dummy.cpp | 39 +++++++++++--- aegisub/src/audio_provider_dummy.h | 2 +- 4 files changed, 45 insertions(+), 78 deletions(-) diff --git a/aegisub/src/audio_controller.cpp b/aegisub/src/audio_controller.cpp index 367d1ac8c..06294b765 100644 --- a/aegisub/src/audio_controller.cpp +++ b/aegisub/src/audio_controller.cpp @@ -163,78 +163,17 @@ void AudioController::OpenAudio(const wxString &url) if (!url) throw agi::InternalError("AudioController::OpenAudio() was passed an empty string. This must not happen.", 0); - wxString path_part; - AudioProvider *new_provider = 0; - - if (url.StartsWith("dummy-audio:", &path_part)) - { - /* - * scheme ::= "dummy-audio" ":" signal-specifier "?" signal-parameters - * signal-specifier ::= "silence" | "noise" | "sine" "/" frequency - * frequency ::= integer - * signal-parameters ::= signal-parameter [ "&" signal-parameters ] - * signal-parameter ::= signal-parameter-name "=" integer - * signal-parameter-name ::= "sr" | "bd" | "ch" | "ln" - * - * Signal types: - * "silence", a silent signal is generated. - * "noise", a white noise signal is generated. - * "sine", a sine wave is generated at the specified frequency. - * - * Signal parameters: - * "sr", sample rate to generate signal at. - * "bd", bit depth to generate signal at (usually 16). - * "ch", number of channels to generate, usually 1 or 2. The same signal is generated - * in every channel even if one would be LFE. - * "ln", length of signal in samples. ln/sr gives signal length in seconds. - */ - new_provider = new DummyAudioProvider(5*30*60*1000, path_part.StartsWith("noise")); + try { + new_provider = AudioProviderFactory::GetProvider(url); + StandardPaths::SetPathValue("?audio", wxFileName(url).GetPath()); } - else if (url.StartsWith("video-audio:", &path_part)) - { - /* - * scheme ::= "video-audio" ":" stream-type - * stream-type ::= "stream" | "cache" - * - * Stream types: - * - * "stream", the audio is streamed as required directly from the video provider, - * and cannot be used to drive an audio display. Seeking is unreliable. - * - * "cache", the entire audio is cached to memory or disk. Audio displays can be - * driven and seeking is reliable. Opening takes longer because the entire audio - * stream has to be decoded and stored. - */ + catch (agi::UserCancelException const&) { + throw; } - else if (url.StartsWith("file:", &path_part)) - { - /* - * scheme ::= "file" ":" "//" file-system-path - * - * On Unix-like systems, the file system path is regular. On Windows-systems, the - * path uses forward slashes instead of back-slashes and the drive letter is - * preceded by a slash. - * - * URL-encoding?? - */ - } - else - { - /* - * Assume it's not a URI but instead a filename in the platform's native format. - */ - try { - new_provider = AudioProviderFactory::GetProvider(url); - StandardPaths::SetPathValue("?audio", wxFileName(url).GetPath()); - } - catch (agi::UserCancelException const&) { - throw; - } - catch (...) { - config::mru->Remove("Audio", STD_STR(url)); - throw; - } + catch (...) { + config::mru->Remove("Audio", STD_STR(url)); + throw; } CloseAudio(); diff --git a/aegisub/src/audio_provider.cpp b/aegisub/src/audio_provider.cpp index 55c443834..aecc23797 100644 --- a/aegisub/src/audio_provider.cpp +++ b/aegisub/src/audio_provider.cpp @@ -39,6 +39,7 @@ #include "audio_provider_avs.h" #include "audio_provider_convert.h" +#include "audio_provider_dummy.h" #include "audio_provider_ffmpegsource.h" #include "audio_provider_hd.h" #include "audio_provider_lock.h" @@ -146,8 +147,10 @@ AudioProvider *AudioProviderFactory::GetProvider(wxString const& filename) { provider_creator creator; AudioProvider *provider = nullptr; + provider = creator.try_create("Dummy audio provider", [&]() { return new DummyAudioProvider(filename); }); + // Try a PCM provider first - if (!OPT_GET("Provider/Audio/PCM/Disable")->GetBool()) + if (!provider && !OPT_GET("Provider/Audio/PCM/Disable")->GetBool()) provider = creator.try_create("PCM audio provider", [&]() { return CreatePCMAudioProvider(filename); }); if (!provider) { diff --git a/aegisub/src/audio_provider_dummy.cpp b/aegisub/src/audio_provider_dummy.cpp index 229b6b4e5..28a672e91 100644 --- a/aegisub/src/audio_provider_dummy.cpp +++ b/aegisub/src/audio_provider_dummy.cpp @@ -37,24 +37,49 @@ #include "audio_provider_dummy.h" #include "utils.h" -DummyAudioProvider::DummyAudioProvider(unsigned long dur_ms, bool _noise) { - noise = _noise; +#include + +/* + * scheme ::= "dummy-audio" ":" signal-specifier "?" signal-parameters + * signal-specifier ::= "silence" | "noise" | "sine" "/" frequency + * frequency ::= integer + * signal-parameters ::= signal-parameter [ "&" signal-parameters ] + * signal-parameter ::= signal-parameter-name "=" integer + * signal-parameter-name ::= "sr" | "bd" | "ch" | "ln" + * + * Signal types: + * "silence", a silent signal is generated. + * "noise", a white noise signal is generated. + * "sine", a sine wave is generated at the specified frequency. + * + * Signal parameters: + * "sr", sample rate to generate signal at. + * "bd", bit depth to generate signal at (usually 16). + * "ch", number of channels to generate, usually 1 or 2. The same signal is generated + * in every channel even if one would be LFE. + * "ln", length of signal in samples. ln/sr gives signal length in seconds. + */ +DummyAudioProvider::DummyAudioProvider(wxString uri) +{ + wxURI parsed(uri); + if (parsed.GetScheme() != "dummy-audio") + throw agi::FileNotFoundError("Not a dummy audio URI"); + + noise = parsed.GetPath() == "noise"; channels = 1; sample_rate = 44100; bytes_per_sample = 2; float_samples = false; - num_samples = (int64_t)dur_ms * sample_rate / 1000; + num_samples = (int64_t)5*30*60*1000 * sample_rate / 1000; } void DummyAudioProvider::FillBuffer(void *buf, int64_t, int64_t count) const { - short *workbuf = (short*)buf; - if (noise) { + short *workbuf = (short*)buf; while (count-- > 0) *workbuf++ = (rand() - RAND_MAX/2) * 10000 / RAND_MAX; } else { - while (count-- > 0) - *workbuf++ = 0; + memset(buf, 0, count * bytes_per_sample); } } diff --git a/aegisub/src/audio_provider_dummy.h b/aegisub/src/audio_provider_dummy.h index 0fcbdd64c..1dbcaf975 100644 --- a/aegisub/src/audio_provider_dummy.h +++ b/aegisub/src/audio_provider_dummy.h @@ -39,7 +39,7 @@ class DummyAudioProvider : public AudioProvider { void FillBuffer(void *buf, int64_t start, int64_t count) const; public: - DummyAudioProvider(unsigned long dur_ms, bool _noise); + DummyAudioProvider(wxString uri); bool AreSamplesNativeEndian() const { return true; } };