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.
This commit is contained in:
parent
a4607ff6be
commit
6e5b53d1a9
4 changed files with 45 additions and 78 deletions
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -37,24 +37,49 @@
|
|||
#include "audio_provider_dummy.h"
|
||||
#include "utils.h"
|
||||
|
||||
DummyAudioProvider::DummyAudioProvider(unsigned long dur_ms, bool _noise) {
|
||||
noise = _noise;
|
||||
#include <wx/uri.h>
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue