Redesign AudioProviderFactory
Register functions which create each type of provider rather than the provider types themselves so that the concrete types don't need to be publicly exposed, and use a static list of providers rather than registering them at runtime.
This commit is contained in:
parent
7dd764db6b
commit
938025acb1
20 changed files with 263 additions and 489 deletions
|
@ -117,13 +117,6 @@
|
||||||
<ClInclude Include="$(SrcDir)audio_player_oss.h" />
|
<ClInclude Include="$(SrcDir)audio_player_oss.h" />
|
||||||
<ClInclude Include="$(SrcDir)audio_player_portaudio.h" />
|
<ClInclude Include="$(SrcDir)audio_player_portaudio.h" />
|
||||||
<ClInclude Include="$(SrcDir)audio_player_pulse.h" />
|
<ClInclude Include="$(SrcDir)audio_player_pulse.h" />
|
||||||
<ClInclude Include="$(SrcDir)audio_provider_avs.h" />
|
|
||||||
<ClInclude Include="$(SrcDir)audio_provider_convert.h" />
|
|
||||||
<ClInclude Include="$(SrcDir)audio_provider_dummy.h" />
|
|
||||||
<ClInclude Include="$(SrcDir)audio_provider_ffmpegsource.h" />
|
|
||||||
<ClInclude Include="$(SrcDir)audio_provider_hd.h" />
|
|
||||||
<ClInclude Include="$(SrcDir)audio_provider_lock.h" />
|
|
||||||
<ClInclude Include="$(SrcDir)audio_provider_ram.h" />
|
|
||||||
<ClInclude Include="$(SrcDir)audio_renderer.h" />
|
<ClInclude Include="$(SrcDir)audio_renderer.h" />
|
||||||
<ClInclude Include="$(SrcDir)audio_renderer_spectrum.h" />
|
<ClInclude Include="$(SrcDir)audio_renderer_spectrum.h" />
|
||||||
<ClInclude Include="$(SrcDir)audio_renderer_waveform.h" />
|
<ClInclude Include="$(SrcDir)audio_renderer_waveform.h" />
|
||||||
|
|
|
@ -177,24 +177,6 @@
|
||||||
<ClInclude Include="$(SrcDir)ass_style_storage.h">
|
<ClInclude Include="$(SrcDir)ass_style_storage.h">
|
||||||
<Filter>ASS</Filter>
|
<Filter>ASS</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="$(SrcDir)audio_provider_ram.h">
|
|
||||||
<Filter>Audio\Providers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="$(SrcDir)audio_provider_avs.h">
|
|
||||||
<Filter>Audio\Providers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="$(SrcDir)audio_provider_convert.h">
|
|
||||||
<Filter>Audio\Providers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="$(SrcDir)audio_provider_dummy.h">
|
|
||||||
<Filter>Audio\Providers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="$(SrcDir)audio_provider_ffmpegsource.h">
|
|
||||||
<Filter>Audio\Providers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="$(SrcDir)audio_provider_hd.h">
|
|
||||||
<Filter>Audio\Providers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="$(SrcDir)audio_box.h">
|
<ClInclude Include="$(SrcDir)audio_box.h">
|
||||||
<Filter>Audio\UI</Filter>
|
<Filter>Audio\UI</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -645,9 +627,6 @@
|
||||||
<ClInclude Include="$(SrcDir)scintilla_text_selection_controller.h">
|
<ClInclude Include="$(SrcDir)scintilla_text_selection_controller.h">
|
||||||
<Filter>Main UI\Edit box</Filter>
|
<Filter>Main UI\Edit box</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="$(SrcDir)audio_provider_lock.h">
|
|
||||||
<Filter>Audio\Providers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="$(SrcDir)dialog_manager.h">
|
<ClInclude Include="$(SrcDir)dialog_manager.h">
|
||||||
<Filter>Utilities\UI utilities</Filter>
|
<Filter>Utilities\UI utilities</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
#include "audio_controller.h"
|
#include "audio_controller.h"
|
||||||
|
|
||||||
#include "ass_file.h"
|
#include "ass_file.h"
|
||||||
#include "audio_provider_dummy.h"
|
|
||||||
#include "audio_timing.h"
|
#include "audio_timing.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "include/aegisub/audio_player.h"
|
#include "include/aegisub/audio_player.h"
|
||||||
|
|
|
@ -34,13 +34,7 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "audio_provider_avs.h"
|
#include "include/aegisub/audio_provider.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"
|
|
||||||
#include "audio_provider_ram.h"
|
|
||||||
|
|
||||||
#include "audio_controller.h"
|
#include "audio_controller.h"
|
||||||
#include "dialog_progress.h"
|
#include "dialog_progress.h"
|
||||||
|
@ -53,9 +47,6 @@
|
||||||
#include <libaegisub/log.h>
|
#include <libaegisub/log.h>
|
||||||
#include <libaegisub/util.h>
|
#include <libaegisub/util.h>
|
||||||
|
|
||||||
// Defined in audio_provider_pcm.cpp
|
|
||||||
std::unique_ptr<AudioProvider> CreatePCMAudioProvider(agi::fs::path const& filename);
|
|
||||||
|
|
||||||
void AudioProvider::GetAudioWithVolume(void *buf, int64_t start, int64_t count, double volume) const {
|
void AudioProvider::GetAudioWithVolume(void *buf, int64_t start, int64_t count, double volume) const {
|
||||||
GetAudio(buf, start, count);
|
GetAudio(buf, start, count);
|
||||||
|
|
||||||
|
@ -110,68 +101,96 @@ void AudioProvider::GetAudio(void *buf, int64_t start, int64_t count) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<AudioProvider> CreateDummyAudioProvider(agi::fs::path const& filename);
|
||||||
|
std::unique_ptr<AudioProvider> CreatePCMAudioProvider(agi::fs::path const& filename);
|
||||||
|
std::unique_ptr<AudioProvider> CreateAvisynthAudioProvider(agi::fs::path const& filename);
|
||||||
|
std::unique_ptr<AudioProvider> CreateFFmpegSourceAudioProvider(agi::fs::path const& filename);
|
||||||
|
|
||||||
|
std::unique_ptr<AudioProvider> CreateConvertAudioProvider(std::unique_ptr<AudioProvider> source_provider);
|
||||||
|
std::unique_ptr<AudioProvider> CreateLockAudioProvider(std::unique_ptr<AudioProvider> source_provider);
|
||||||
|
std::unique_ptr<AudioProvider> CreateHDAudioProvider(std::unique_ptr<AudioProvider> source_provider, agi::BackgroundRunner *br);
|
||||||
|
std::unique_ptr<AudioProvider> CreateRAMAudioProvider(std::unique_ptr<AudioProvider> source_provider, agi::BackgroundRunner *br);
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct provider_creator {
|
using factory_fn = std::unique_ptr<AudioProvider> (*)(agi::fs::path const&);
|
||||||
|
struct factory {
|
||||||
|
const char *name;
|
||||||
|
factory_fn create;
|
||||||
|
bool hidden;
|
||||||
|
};
|
||||||
|
|
||||||
|
const factory providers[] = {
|
||||||
|
{"Dummy", CreateDummyAudioProvider, true},
|
||||||
|
{"PCM", CreatePCMAudioProvider, true},
|
||||||
|
#ifdef WITH_FFMS2
|
||||||
|
{"FFmpegSource", CreateFFmpegSourceAudioProvider, false},
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_AVISYNTH
|
||||||
|
{"Avisynth", CreateAvisynthAudioProvider, false},
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> AudioProviderFactory::GetClasses() {
|
||||||
|
std::vector<std::string> list;
|
||||||
|
for (auto const& provider : providers) {
|
||||||
|
if (!provider.hidden)
|
||||||
|
list.push_back(provider.name);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<AudioProvider> AudioProviderFactory::GetProvider(agi::fs::path const& filename) {
|
||||||
|
auto preferred = OPT_GET("Audio/Provider")->GetString();
|
||||||
|
std::vector<const factory *> sorted;
|
||||||
|
auto preferred_insertion_point = sorted.end();
|
||||||
|
for (auto const& provider : providers) {
|
||||||
|
if (provider.hidden)
|
||||||
|
sorted.push_back(&provider);
|
||||||
|
else if (preferred_insertion_point == sorted.end()) {
|
||||||
|
sorted.push_back(&provider);
|
||||||
|
preferred_insertion_point = prev(sorted.end());
|
||||||
|
}
|
||||||
|
else if (preferred == provider.name)
|
||||||
|
sorted.insert(preferred_insertion_point, &provider);
|
||||||
|
else
|
||||||
|
sorted.push_back(&provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<AudioProvider> provider;
|
||||||
bool found_file = false;
|
bool found_file = false;
|
||||||
bool found_audio = false;
|
bool found_audio = false;
|
||||||
std::string msg;
|
std::string msg;
|
||||||
|
|
||||||
template<typename Factory>
|
for (auto const& factory : sorted) {
|
||||||
std::unique_ptr<AudioProvider> try_create(std::string const& name, Factory&& create) {
|
|
||||||
try {
|
try {
|
||||||
std::unique_ptr<AudioProvider> provider = create();
|
provider = factory->create(filename);
|
||||||
if (provider)
|
if (!provider) continue;
|
||||||
LOG_I("audio_provider") << "Using audio provider: " << name;
|
LOG_I("audio_provider") << "Using audio provider: " << factory->name;
|
||||||
return provider;
|
break;
|
||||||
}
|
}
|
||||||
catch (agi::fs::FileNotFound const& err) {
|
catch (agi::fs::FileNotFound const& err) {
|
||||||
LOG_D("audio_provider") << err.GetChainedMessage();
|
LOG_D("audio_provider") << err.GetChainedMessage();
|
||||||
msg += name + ": " + err.GetMessage() + " not found.\n";
|
msg += std::string(factory->name) + ": " + err.GetMessage() + " not found.\n";
|
||||||
}
|
}
|
||||||
catch (agi::AudioDataNotFoundError const& err) {
|
catch (agi::AudioDataNotFoundError const& err) {
|
||||||
LOG_D("audio_provider") << err.GetChainedMessage();
|
LOG_D("audio_provider") << err.GetChainedMessage();
|
||||||
found_file = true;
|
found_file = true;
|
||||||
msg += name + ": " + err.GetChainedMessage() + "\n";
|
msg += std::string(factory->name) + ": " + err.GetChainedMessage() + "\n";
|
||||||
}
|
}
|
||||||
catch (agi::AudioOpenError const& err) {
|
catch (agi::AudioOpenError const& err) {
|
||||||
LOG_D("audio_provider") << err.GetChainedMessage();
|
LOG_D("audio_provider") << err.GetChainedMessage();
|
||||||
found_audio = true;
|
found_audio = true;
|
||||||
found_file = true;
|
found_file = true;
|
||||||
msg += name + ": " + err.GetChainedMessage() + "\n";
|
msg += std::string(factory->name) + ": " + err.GetChainedMessage() + "\n";
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
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 (!provider) {
|
||||||
if (creator.found_audio)
|
if (found_audio)
|
||||||
throw agi::AudioProviderOpenError(creator.msg, nullptr);
|
throw agi::AudioProviderOpenError(msg, nullptr);
|
||||||
if (creator.found_file)
|
if (found_file)
|
||||||
throw agi::AudioDataNotFoundError(creator.msg, nullptr);
|
throw agi::AudioDataNotFoundError(msg, nullptr);
|
||||||
throw agi::fs::FileNotFound(filename);
|
throw agi::fs::FileNotFound(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,24 +203,15 @@ std::unique_ptr<AudioProvider> AudioProviderFactory::GetProvider(agi::fs::path c
|
||||||
// Change provider to RAM/HD cache if needed
|
// Change provider to RAM/HD cache if needed
|
||||||
int cache = OPT_GET("Audio/Cache/Type")->GetInt();
|
int cache = OPT_GET("Audio/Cache/Type")->GetInt();
|
||||||
if (!cache || !needsCache)
|
if (!cache || !needsCache)
|
||||||
return agi::util::make_unique<LockAudioProvider>(std::move(provider));
|
return CreateLockAudioProvider(std::move(provider));
|
||||||
|
|
||||||
DialogProgress progress(wxGetApp().frame, _("Load audio"));
|
DialogProgress progress(wxGetApp().frame, _("Load audio"));
|
||||||
|
|
||||||
// Convert to RAM
|
// Convert to RAM
|
||||||
if (cache == 1) return agi::util::make_unique<RAMAudioProvider>(std::move(provider), &progress);
|
if (cache == 1) return CreateRAMAudioProvider(std::move(provider), &progress);
|
||||||
|
|
||||||
// Convert to HD
|
// Convert to HD
|
||||||
if (cache == 2) return agi::util::make_unique<HDAudioProvider>(std::move(provider), &progress);
|
if (cache == 2) return CreateHDAudioProvider(std::move(provider), &progress);
|
||||||
|
|
||||||
throw agi::AudioCacheOpenError("Unknown caching method", nullptr);
|
throw agi::AudioCacheOpenError("Unknown caching method", nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioProviderFactory::RegisterProviders() {
|
|
||||||
#ifdef WITH_AVISYNTH
|
|
||||||
Register<AvisynthAudioProvider>("Avisynth");
|
|
||||||
#endif
|
|
||||||
#ifdef WITH_FFMS2
|
|
||||||
Register<FFmpegSourceAudioProvider>("FFmpegSource");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
|
@ -35,8 +35,10 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#ifdef WITH_AVISYNTH
|
#ifdef WITH_AVISYNTH
|
||||||
#include "audio_provider_avs.h"
|
#include "include/aegisub/audio_provider.h"
|
||||||
|
|
||||||
|
#include "avisynth.h"
|
||||||
|
#include "avisynth_wrap.h"
|
||||||
#include "audio_controller.h"
|
#include "audio_controller.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
@ -45,9 +47,24 @@
|
||||||
#include <libaegisub/charset_conv.h>
|
#include <libaegisub/charset_conv.h>
|
||||||
#include <libaegisub/fs.h>
|
#include <libaegisub/fs.h>
|
||||||
#include <libaegisub/path.h>
|
#include <libaegisub/path.h>
|
||||||
|
#include <libaegisub/util.h>
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
class AvisynthAudioProvider final : public AudioProvider {
|
||||||
|
AviSynthWrapper avs_wrapper;
|
||||||
|
PClip clip;
|
||||||
|
|
||||||
|
void LoadFromClip(AVSValue clip);
|
||||||
|
void FillBuffer(void *buf, int64_t start, int64_t count) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AvisynthAudioProvider(agi::fs::path const& filename);
|
||||||
|
|
||||||
|
bool NeedsCache() const override { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
AvisynthAudioProvider::AvisynthAudioProvider(agi::fs::path const& filename) {
|
AvisynthAudioProvider::AvisynthAudioProvider(agi::fs::path const& filename) {
|
||||||
this->filename = filename;
|
this->filename = filename;
|
||||||
|
|
||||||
|
@ -128,4 +145,9 @@ void AvisynthAudioProvider::LoadFromClip(AVSValue clip) {
|
||||||
void AvisynthAudioProvider::FillBuffer(void *buf, int64_t start, int64_t count) const {
|
void AvisynthAudioProvider::FillBuffer(void *buf, int64_t start, int64_t count) const {
|
||||||
clip->GetAudio(buf, start, count, avs_wrapper.GetEnv());
|
clip->GetAudio(buf, start, count, avs_wrapper.GetEnv());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<AudioProvider> CreateAvisynthAudioProvider(agi::fs::path const& file) {
|
||||||
|
return agi::util::make_unique<AvisynthAudioProvider>(file);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
// Copyright (c) 2005-2006, Rodrigo Braz Monteiro, Fredrik Mellbin
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of the Aegisub Group nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
//
|
|
||||||
// Aegisub Project http://www.aegisub.org/
|
|
||||||
|
|
||||||
/// @file audio_provider_avs.h
|
|
||||||
/// @see audio_provider_avs.cpp
|
|
||||||
/// @ingroup audio_input
|
|
||||||
///
|
|
||||||
|
|
||||||
#ifdef WITH_AVISYNTH
|
|
||||||
#include "include/aegisub/audio_provider.h"
|
|
||||||
|
|
||||||
#include "avisynth.h"
|
|
||||||
#include "avisynth_wrap.h"
|
|
||||||
|
|
||||||
class AvisynthAudioProvider final : public AudioProvider {
|
|
||||||
AviSynthWrapper avs_wrapper;
|
|
||||||
PClip clip;
|
|
||||||
|
|
||||||
void LoadFromClip(AVSValue clip);
|
|
||||||
void FillBuffer(void *buf, int64_t start, int64_t count) const;
|
|
||||||
|
|
||||||
public:
|
|
||||||
AvisynthAudioProvider(agi::fs::path const& filename);
|
|
||||||
|
|
||||||
bool NeedsCache() const { return true; }
|
|
||||||
};
|
|
||||||
#endif
|
|
|
@ -21,10 +21,9 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "audio_provider_convert.h"
|
#include "include/aegisub/audio_provider.h"
|
||||||
|
|
||||||
#include "audio_controller.h"
|
#include "audio_controller.h"
|
||||||
#include "include/aegisub/audio_provider.h"
|
|
||||||
|
|
||||||
#include <libaegisub/log.h>
|
#include <libaegisub/log.h>
|
||||||
#include <libaegisub/util.h>
|
#include <libaegisub/util.h>
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
// Copyright (c) 2011, Thomas Goyne <plorkyeran@aegisub.org>
|
|
||||||
//
|
|
||||||
// Permission to use, copy, modify, and distribute this software for any
|
|
||||||
// purpose with or without fee is hereby granted, provided that the above
|
|
||||||
// copyright notice and this permission notice appear in all copies.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
//
|
|
||||||
// Aegisub Project http://www.aegisub.org/
|
|
||||||
|
|
||||||
/// @file audio_provider_convert.h
|
|
||||||
/// @see audio_provider_convert.cpp
|
|
||||||
/// @ingroup audio_input
|
|
||||||
///
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
class AudioProvider;
|
|
||||||
|
|
||||||
/// Get an audio provider which supplies audio in a format supported by Aegisub's players
|
|
||||||
std::unique_ptr<AudioProvider> CreateConvertAudioProvider(std::unique_ptr<AudioProvider> source_provider);
|
|
|
@ -34,10 +34,10 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "audio_provider_dummy.h"
|
#include "include/aegisub/audio_provider.h"
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
#include <libaegisub/fs.h>
|
#include <libaegisub/fs.h>
|
||||||
|
#include <libaegisub/util.h>
|
||||||
|
|
||||||
#include <boost/algorithm/string/predicate.hpp>
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
|
|
||||||
|
@ -61,25 +61,35 @@
|
||||||
* in every channel even if one would be LFE.
|
* in every channel even if one would be LFE.
|
||||||
* "ln", length of signal in samples. ln/sr gives signal length in seconds.
|
* "ln", length of signal in samples. ln/sr gives signal length in seconds.
|
||||||
*/
|
*/
|
||||||
DummyAudioProvider::DummyAudioProvider(agi::fs::path const& uri) {
|
|
||||||
if (!boost::starts_with(uri.string(), "dummy-audio:"))
|
|
||||||
throw agi::fs::FileNotFound(std::string("Not a dummy audio URI"));
|
|
||||||
|
|
||||||
noise = boost::contains(uri.string(), ":noise?");
|
namespace {
|
||||||
channels = 1;
|
class DummyAudioProvider final : public AudioProvider {
|
||||||
sample_rate = 44100;
|
bool noise;
|
||||||
bytes_per_sample = 2;
|
void FillBuffer(void *buf, int64_t start, int64_t count) const override {
|
||||||
float_samples = false;
|
|
||||||
num_samples = (int64_t)5*30*60*1000 * sample_rate / 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DummyAudioProvider::FillBuffer(void *buf, int64_t, int64_t count) const {
|
|
||||||
if (noise) {
|
if (noise) {
|
||||||
short *workbuf = (short*)buf;
|
auto workbuf = static_cast<uint16_t *>(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 {
|
||||||
memset(buf, 0, count * bytes_per_sample);
|
memset(buf, 0, count * bytes_per_sample);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
DummyAudioProvider(agi::fs::path const& uri) {
|
||||||
|
noise = boost::contains(uri.string(), ":noise?");
|
||||||
|
channels = 1;
|
||||||
|
sample_rate = 44100;
|
||||||
|
bytes_per_sample = 2;
|
||||||
|
float_samples = false;
|
||||||
|
num_samples = (int64_t)5*30*60*1000 * sample_rate / 1000;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<AudioProvider> CreateDummyAudioProvider(agi::fs::path const& file) {
|
||||||
|
if (!boost::starts_with(file.string(), "dummy-audio:"))
|
||||||
|
return {};
|
||||||
|
return agi::util::make_unique<DummyAudioProvider>(file);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
// Copyright (c) 2006, Niels Martin Hansen
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of the Aegisub Group nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
//
|
|
||||||
// Aegisub Project http://www.aegisub.org/
|
|
||||||
|
|
||||||
/// @file audio_provider_dummy.h
|
|
||||||
/// @see audio_provider_dummy.cpp
|
|
||||||
/// @ingroup audio_input
|
|
||||||
///
|
|
||||||
|
|
||||||
#include "include/aegisub/audio_provider.h"
|
|
||||||
|
|
||||||
class DummyAudioProvider final : public AudioProvider {
|
|
||||||
bool noise;
|
|
||||||
void FillBuffer(void *buf, int64_t start, int64_t count) const override;
|
|
||||||
|
|
||||||
public:
|
|
||||||
DummyAudioProvider(agi::fs::path const& uri);
|
|
||||||
};
|
|
|
@ -35,15 +35,37 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#ifdef WITH_FFMS2
|
#ifdef WITH_FFMS2
|
||||||
#include "audio_provider_ffmpegsource.h"
|
#include "include/aegisub/audio_provider.h"
|
||||||
|
|
||||||
#include "audio_controller.h"
|
#include "audio_controller.h"
|
||||||
|
#include "ffmpegsource_common.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
|
||||||
#include <libaegisub/fs.h>
|
#include <libaegisub/fs.h>
|
||||||
|
#include <libaegisub/util.h>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
class FFmpegSourceAudioProvider final : public AudioProvider, FFmpegSourceProvider {
|
||||||
|
/// audio source object
|
||||||
|
agi::scoped_holder<FFMS_AudioSource*, void (FFMS_CC *)(FFMS_AudioSource*)> AudioSource;
|
||||||
|
|
||||||
|
mutable char FFMSErrMsg[1024]; ///< FFMS error message
|
||||||
|
mutable FFMS_ErrorInfo ErrInfo; ///< FFMS error codes/messages
|
||||||
|
|
||||||
|
void LoadAudio(agi::fs::path const& filename);
|
||||||
|
void FillBuffer(void *Buf, int64_t Start, int64_t Count) const override {
|
||||||
|
if (FFMS_GetAudio(AudioSource, Buf, Start, Count, &ErrInfo))
|
||||||
|
throw AudioDecodeError(std::string("Failed to get audio samples: ") + ErrInfo.Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
FFmpegSourceAudioProvider(agi::fs::path const& filename);
|
||||||
|
|
||||||
|
bool NeedsCache() const override { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
/// @brief Constructor
|
/// @brief Constructor
|
||||||
/// @param filename The filename to open
|
/// @param filename The filename to open
|
||||||
FFmpegSourceAudioProvider::FFmpegSourceAudioProvider(agi::fs::path const& filename) try
|
FFmpegSourceAudioProvider::FFmpegSourceAudioProvider(agi::fs::path const& filename) try
|
||||||
|
@ -182,8 +204,10 @@ void FFmpegSourceAudioProvider::LoadAudio(agi::fs::path const& filename) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void FFmpegSourceAudioProvider::FillBuffer(void *Buf, int64_t Start, int64_t Count) const {
|
|
||||||
if (FFMS_GetAudio(AudioSource, Buf, Start, Count, &ErrInfo))
|
|
||||||
throw AudioDecodeError(std::string("Failed to get audio samples: ") + ErrInfo.Buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<AudioProvider> CreateFFmpegSourceAudioProvider(agi::fs::path const& file) {
|
||||||
|
return agi::util::make_unique<FFmpegSourceAudioProvider>(file);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* WITH_FFMS2 */
|
#endif /* WITH_FFMS2 */
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
// Copyright (c) 2008-2009, Karl Blomster
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of the Aegisub Group nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
//
|
|
||||||
// Aegisub Project http://www.aegisub.org/
|
|
||||||
|
|
||||||
/// @file audio_provider_ffmpegsource.h
|
|
||||||
/// @see audio_provider_ffmpegsource.cpp
|
|
||||||
/// @ingroup audio_input ffms
|
|
||||||
///
|
|
||||||
|
|
||||||
#ifdef WITH_FFMS2
|
|
||||||
#include "include/aegisub/audio_provider.h"
|
|
||||||
|
|
||||||
#include "ffmpegsource_common.h"
|
|
||||||
|
|
||||||
/// @class FFmpegSourceAudioProvider
|
|
||||||
/// @brief Implements audio loading with the FFMS library.
|
|
||||||
class FFmpegSourceAudioProvider final : public AudioProvider, FFmpegSourceProvider {
|
|
||||||
/// audio source object
|
|
||||||
agi::scoped_holder<FFMS_AudioSource*, void (FFMS_CC *)(FFMS_AudioSource*)> AudioSource;
|
|
||||||
|
|
||||||
mutable char FFMSErrMsg[1024]; ///< FFMS error message
|
|
||||||
mutable FFMS_ErrorInfo ErrInfo; ///< FFMS error codes/messages
|
|
||||||
|
|
||||||
void LoadAudio(agi::fs::path const& filename);
|
|
||||||
void FillBuffer(void *buf, int64_t start, int64_t count) const override;
|
|
||||||
|
|
||||||
public:
|
|
||||||
FFmpegSourceAudioProvider(agi::fs::path const& filename);
|
|
||||||
|
|
||||||
bool NeedsCache() const override { return true; }
|
|
||||||
};
|
|
||||||
#endif
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "audio_provider_hd.h"
|
#include "include/aegisub/audio_provider.h"
|
||||||
|
|
||||||
#include "audio_controller.h"
|
#include "audio_controller.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
|
@ -33,10 +33,22 @@
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
#include <boost/interprocess/detail/os_thread_functions.hpp>
|
#include <boost/interprocess/detail/os_thread_functions.hpp>
|
||||||
|
#include <wx/intl.h>
|
||||||
|
|
||||||
HDAudioProvider::HDAudioProvider(std::unique_ptr<AudioProvider> src, agi::BackgroundRunner *br)
|
namespace {
|
||||||
: AudioProviderWrapper(std::move(src))
|
class HDAudioProvider final : public AudioProviderWrapper {
|
||||||
{
|
std::unique_ptr<agi::temp_file_mapping> file;
|
||||||
|
|
||||||
|
void FillBuffer(void *buf, int64_t start, int64_t count) const override {
|
||||||
|
start *= channels * bytes_per_sample;
|
||||||
|
count *= channels * bytes_per_sample;
|
||||||
|
memcpy(buf, file->read(start, count), count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
HDAudioProvider(std::unique_ptr<AudioProvider> src, agi::BackgroundRunner *br)
|
||||||
|
: AudioProviderWrapper(std::move(src))
|
||||||
|
{
|
||||||
auto path = OPT_GET("Audio/Cache/HD/Location")->GetString();
|
auto path = OPT_GET("Audio/Cache/HD/Location")->GetString();
|
||||||
if (path == "default")
|
if (path == "default")
|
||||||
path = "?temp";
|
path = "?temp";
|
||||||
|
@ -64,12 +76,10 @@ HDAudioProvider::HDAudioProvider(std::unique_ptr<AudioProvider> src, agi::Backgr
|
||||||
if (ps->IsCancelled()) return;
|
if (ps->IsCancelled()) return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
HDAudioProvider::~HDAudioProvider() { }
|
std::unique_ptr<AudioProvider> CreateHDAudioProvider(std::unique_ptr<AudioProvider> src, agi::BackgroundRunner *br) {
|
||||||
|
return agi::util::make_unique<HDAudioProvider>(std::move(src), br);
|
||||||
void HDAudioProvider::FillBuffer(void *buf, int64_t start, int64_t count) const {
|
|
||||||
start *= channels * bytes_per_sample;
|
|
||||||
count *= channels * bytes_per_sample;
|
|
||||||
memcpy(buf, file->read(start, count), count);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
// Copyright (c) 2014, Thomas Goyne <plorkyeran@aegisub.org>
|
|
||||||
//
|
|
||||||
// Permission to use, copy, modify, and distribute this software for any
|
|
||||||
// purpose with or without fee is hereby granted, provided that the above
|
|
||||||
// copyright notice and this permission notice appear in all copies.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
//
|
|
||||||
// Aegisub Project http://www.aegisub.org/
|
|
||||||
|
|
||||||
#include "include/aegisub/audio_provider.h"
|
|
||||||
|
|
||||||
namespace agi {
|
|
||||||
class BackgroundRunner;
|
|
||||||
class temp_file_mapping;
|
|
||||||
}
|
|
||||||
|
|
||||||
class HDAudioProvider final : public AudioProviderWrapper {
|
|
||||||
std::unique_ptr<agi::temp_file_mapping> file;
|
|
||||||
|
|
||||||
void FillBuffer(void *buf, int64_t start, int64_t count) const override;
|
|
||||||
|
|
||||||
public:
|
|
||||||
HDAudioProvider(std::unique_ptr<AudioProvider> source, agi::BackgroundRunner *br);
|
|
||||||
~HDAudioProvider();
|
|
||||||
};
|
|
|
@ -18,14 +18,30 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "audio_provider_lock.h"
|
#include "include/aegisub/audio_provider.h"
|
||||||
|
|
||||||
LockAudioProvider::LockAudioProvider(std::unique_ptr<AudioProvider> src)
|
#include <libaegisub/util.h>
|
||||||
: AudioProviderWrapper(std::move(src))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void LockAudioProvider::FillBuffer(void *buf, int64_t start, int64_t count) const {
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
class LockAudioProvider final : public AudioProviderWrapper {
|
||||||
|
mutable std::mutex mutex;
|
||||||
|
|
||||||
|
void FillBuffer(void *buf, int64_t start, int64_t count) const override {
|
||||||
std::unique_lock<std::mutex> lock(mutex);
|
std::unique_lock<std::mutex> lock(mutex);
|
||||||
source->GetAudio(buf, start, count);
|
source->GetAudio(buf, start, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
LockAudioProvider(std::unique_ptr<AudioProvider> src)
|
||||||
|
: AudioProviderWrapper(std::move(src))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<AudioProvider> CreateLockAudioProvider(std::unique_ptr<AudioProvider> src) {
|
||||||
|
return agi::util::make_unique<LockAudioProvider>(std::move(src));
|
||||||
}
|
}
|
|
@ -1,30 +0,0 @@
|
||||||
// Copyright (c) 2012, Thomas Goyne <plorkyeran@aegisub.org>
|
|
||||||
//
|
|
||||||
// Permission to use, copy, modify, and distribute this software for any
|
|
||||||
// purpose with or without fee is hereby granted, provided that the above
|
|
||||||
// copyright notice and this permission notice appear in all copies.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
|
|
||||||
/// @file audio_provider_lock.h
|
|
||||||
/// @brief An audio provider adapter for un-threadsafe audio providers
|
|
||||||
/// @ingroup audio_input
|
|
||||||
|
|
||||||
#include "include/aegisub/audio_provider.h"
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <mutex>
|
|
||||||
|
|
||||||
class LockAudioProvider final : public AudioProviderWrapper {
|
|
||||||
mutable std::mutex mutex;
|
|
||||||
|
|
||||||
void FillBuffer(void *buf, int64_t start, int64_t count) const override;
|
|
||||||
public:
|
|
||||||
LockAudioProvider(std::unique_ptr<AudioProvider> source);
|
|
||||||
};
|
|
|
@ -34,21 +34,36 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "audio_provider_ram.h"
|
#include "include/aegisub/audio_provider.h"
|
||||||
|
|
||||||
#include "audio_controller.h"
|
#include "audio_controller.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "options.h"
|
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
#include <libaegisub/background_runner.h>
|
#include <libaegisub/background_runner.h>
|
||||||
|
#include <libaegisub/util.h>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <boost/container/stable_vector.hpp>
|
||||||
|
#include <wx/intl.h>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
#define CacheBits 22
|
#define CacheBits 22
|
||||||
#define CacheBlockSize (1 << CacheBits)
|
#define CacheBlockSize (1 << CacheBits)
|
||||||
|
|
||||||
RAMAudioProvider::RAMAudioProvider(std::unique_ptr<AudioProvider> src, agi::BackgroundRunner *br)
|
class RAMAudioProvider final : public AudioProviderWrapper {
|
||||||
: AudioProviderWrapper(std::move(src))
|
#ifdef _MSC_VER
|
||||||
{
|
boost::container::stable_vector<char[1 << 22]> blockcache;
|
||||||
|
#else
|
||||||
|
boost::container::stable_vector<std::array<char, 1 << 22>> blockcache;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void FillBuffer(void *buf, int64_t start, int64_t count) const override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RAMAudioProvider(std::unique_ptr<AudioProvider> src, agi::BackgroundRunner *br)
|
||||||
|
: AudioProviderWrapper(std::move(src))
|
||||||
|
{
|
||||||
try {
|
try {
|
||||||
blockcache.resize((source->GetNumSamples() * source->GetBytesPerSample() + CacheBlockSize - 1) >> CacheBits);
|
blockcache.resize((source->GetNumSamples() * source->GetBytesPerSample() + CacheBlockSize - 1) >> CacheBits);
|
||||||
}
|
}
|
||||||
|
@ -56,22 +71,18 @@ RAMAudioProvider::RAMAudioProvider(std::unique_ptr<AudioProvider> src, agi::Back
|
||||||
throw agi::AudioCacheOpenError("Couldn't open audio, not enough ram available.", nullptr);
|
throw agi::AudioCacheOpenError("Couldn't open audio, not enough ram available.", nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
br->Run(std::bind(&RAMAudioProvider::FillCache, this, source.get(), std::placeholders::_1));
|
br->Run([&](agi::ProgressSink *ps) {
|
||||||
}
|
|
||||||
|
|
||||||
void RAMAudioProvider::FillCache(AudioProvider *source, agi::ProgressSink *ps) {
|
|
||||||
ps->SetMessage(from_wx(_("Reading into RAM")));
|
ps->SetMessage(from_wx(_("Reading into RAM")));
|
||||||
|
|
||||||
int64_t readsize = CacheBlockSize / source->GetBytesPerSample();
|
int64_t readsize = CacheBlockSize / source->GetBytesPerSample();
|
||||||
for (size_t i = 0; i < blockcache.size(); i++) {
|
for (size_t i = 0; i < blockcache.size(); i++) {
|
||||||
|
if (ps->IsCancelled()) return;
|
||||||
ps->SetProgress(i + 1, blockcache.size());
|
ps->SetProgress(i + 1, blockcache.size());
|
||||||
source->GetAudio(&blockcache[i][0], i * readsize, std::min<int64_t>(readsize, num_samples - i * readsize));
|
source->GetAudio(&blockcache[i][0], i * readsize, std::min<int64_t>(readsize, num_samples - i * readsize));
|
||||||
|
|
||||||
if (ps->IsCancelled()) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
void RAMAudioProvider::FillBuffer(void *buf, int64_t start, int64_t count) const {
|
void RAMAudioProvider::FillBuffer(void *buf, int64_t start, int64_t count) const {
|
||||||
char *charbuf = static_cast<char *>(buf);
|
char *charbuf = static_cast<char *>(buf);
|
||||||
|
@ -90,3 +101,8 @@ void RAMAudioProvider::FillBuffer(void *buf, int64_t start, int64_t count) const
|
||||||
bytesremaining -= readsize;
|
bytesremaining -= readsize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<AudioProvider> CreateRAMAudioProvider(std::unique_ptr<AudioProvider> src, agi::BackgroundRunner *br) {
|
||||||
|
return agi::util::make_unique<RAMAudioProvider>(std::move(src), br);
|
||||||
|
}
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
// Copyright (c) 2006, Rodrigo Braz Monteiro
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of the Aegisub Group nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
//
|
|
||||||
// Aegisub Project http://www.aegisub.org/
|
|
||||||
|
|
||||||
/// @file audio_provider_ram.h
|
|
||||||
/// @see audio_provider_ram.cpp
|
|
||||||
/// @ingroup audio_input
|
|
||||||
///
|
|
||||||
|
|
||||||
#include "include/aegisub/audio_provider.h"
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <boost/container/stable_vector.hpp>
|
|
||||||
|
|
||||||
namespace agi {
|
|
||||||
class BackgroundRunner;
|
|
||||||
class ProgressSink;
|
|
||||||
}
|
|
||||||
|
|
||||||
class RAMAudioProvider final : public AudioProviderWrapper {
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
boost::container::stable_vector<char[1 << 22]> blockcache;
|
|
||||||
#else
|
|
||||||
boost::container::stable_vector<std::array<char, 1 << 22>> blockcache;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void FillCache(AudioProvider *source, agi::ProgressSink *ps);
|
|
||||||
void FillBuffer(void *buf, int64_t start, int64_t count) const override;
|
|
||||||
|
|
||||||
public:
|
|
||||||
RAMAudioProvider(std::unique_ptr<AudioProvider> source, agi::BackgroundRunner *br);
|
|
||||||
};
|
|
|
@ -34,8 +34,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "factory_manager.h"
|
|
||||||
|
|
||||||
#include <libaegisub/exception.h>
|
#include <libaegisub/exception.h>
|
||||||
#include <libaegisub/fs_fwd.h>
|
#include <libaegisub/fs_fwd.h>
|
||||||
|
|
||||||
|
@ -90,9 +88,8 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class AudioProviderFactory final : public Factory<AudioProvider, agi::fs::path> {
|
struct AudioProviderFactory {
|
||||||
public:
|
static std::vector<std::string> GetClasses();
|
||||||
static void RegisterProviders();
|
|
||||||
|
|
||||||
/// Get a provider for the file
|
/// Get a provider for the file
|
||||||
/// @param filename URI to open
|
/// @param filename URI to open
|
||||||
|
|
|
@ -35,7 +35,6 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "include/aegisub/audio_player.h"
|
#include "include/aegisub/audio_player.h"
|
||||||
#include "include/aegisub/audio_provider.h"
|
|
||||||
#include "include/aegisub/spellchecker.h"
|
#include "include/aegisub/spellchecker.h"
|
||||||
#include "include/aegisub/subtitles_provider.h"
|
#include "include/aegisub/subtitles_provider.h"
|
||||||
#include "plugin_manager.h"
|
#include "plugin_manager.h"
|
||||||
|
@ -46,7 +45,6 @@
|
||||||
|
|
||||||
void RegisterBuiltInPlugins() {
|
void RegisterBuiltInPlugins() {
|
||||||
VideoProviderFactory::RegisterProviders();
|
VideoProviderFactory::RegisterProviders();
|
||||||
AudioProviderFactory::RegisterProviders();
|
|
||||||
AudioPlayerFactory::RegisterProviders();
|
AudioPlayerFactory::RegisterProviders();
|
||||||
SubtitlesProviderFactory::RegisterProviders();
|
SubtitlesProviderFactory::RegisterProviders();
|
||||||
SpellCheckerFactory::RegisterProviders();
|
SpellCheckerFactory::RegisterProviders();
|
||||||
|
|
Loading…
Reference in a new issue