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)
|
if (!url)
|
||||||
throw agi::InternalError("AudioController::OpenAudio() was passed an empty string. This must not happen.", 0);
|
throw agi::InternalError("AudioController::OpenAudio() was passed an empty string. This must not happen.", 0);
|
||||||
|
|
||||||
wxString path_part;
|
|
||||||
|
|
||||||
AudioProvider *new_provider = 0;
|
AudioProvider *new_provider = 0;
|
||||||
|
try {
|
||||||
if (url.StartsWith("dummy-audio:", &path_part))
|
new_provider = AudioProviderFactory::GetProvider(url);
|
||||||
{
|
StandardPaths::SetPathValue("?audio", wxFileName(url).GetPath());
|
||||||
/*
|
|
||||||
* 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"));
|
|
||||||
}
|
}
|
||||||
else if (url.StartsWith("video-audio:", &path_part))
|
catch (agi::UserCancelException const&) {
|
||||||
{
|
throw;
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
else if (url.StartsWith("file:", &path_part))
|
catch (...) {
|
||||||
{
|
config::mru->Remove("Audio", STD_STR(url));
|
||||||
/*
|
throw;
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseAudio();
|
CloseAudio();
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
|
|
||||||
#include "audio_provider_avs.h"
|
#include "audio_provider_avs.h"
|
||||||
#include "audio_provider_convert.h"
|
#include "audio_provider_convert.h"
|
||||||
|
#include "audio_provider_dummy.h"
|
||||||
#include "audio_provider_ffmpegsource.h"
|
#include "audio_provider_ffmpegsource.h"
|
||||||
#include "audio_provider_hd.h"
|
#include "audio_provider_hd.h"
|
||||||
#include "audio_provider_lock.h"
|
#include "audio_provider_lock.h"
|
||||||
|
@ -146,8 +147,10 @@ AudioProvider *AudioProviderFactory::GetProvider(wxString const& filename) {
|
||||||
provider_creator creator;
|
provider_creator creator;
|
||||||
AudioProvider *provider = nullptr;
|
AudioProvider *provider = nullptr;
|
||||||
|
|
||||||
|
provider = creator.try_create("Dummy audio provider", [&]() { return new DummyAudioProvider(filename); });
|
||||||
|
|
||||||
// Try a PCM provider first
|
// 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); });
|
provider = creator.try_create("PCM audio provider", [&]() { return CreatePCMAudioProvider(filename); });
|
||||||
|
|
||||||
if (!provider) {
|
if (!provider) {
|
||||||
|
|
|
@ -37,24 +37,49 @@
|
||||||
#include "audio_provider_dummy.h"
|
#include "audio_provider_dummy.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
DummyAudioProvider::DummyAudioProvider(unsigned long dur_ms, bool _noise) {
|
#include <wx/uri.h>
|
||||||
noise = _noise;
|
|
||||||
|
/*
|
||||||
|
* 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;
|
channels = 1;
|
||||||
sample_rate = 44100;
|
sample_rate = 44100;
|
||||||
bytes_per_sample = 2;
|
bytes_per_sample = 2;
|
||||||
float_samples = false;
|
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 {
|
void DummyAudioProvider::FillBuffer(void *buf, int64_t, int64_t count) const {
|
||||||
short *workbuf = (short*)buf;
|
|
||||||
|
|
||||||
if (noise) {
|
if (noise) {
|
||||||
|
short *workbuf = (short*)buf;
|
||||||
while (count-- > 0)
|
while (count-- > 0)
|
||||||
*workbuf++ = (rand() - RAND_MAX/2) * 10000 / RAND_MAX;
|
*workbuf++ = (rand() - RAND_MAX/2) * 10000 / RAND_MAX;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
while (count-- > 0)
|
memset(buf, 0, count * bytes_per_sample);
|
||||||
*workbuf++ = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ class DummyAudioProvider : public AudioProvider {
|
||||||
void FillBuffer(void *buf, int64_t start, int64_t count) const;
|
void FillBuffer(void *buf, int64_t start, int64_t count) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DummyAudioProvider(unsigned long dur_ms, bool _noise);
|
DummyAudioProvider(wxString uri);
|
||||||
|
|
||||||
bool AreSamplesNativeEndian() const { return true; }
|
bool AreSamplesNativeEndian() const { return true; }
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue