mirror of https://github.com/odrling/Aegisub
Extract common stuff for wrapper audio providers to a base class
This commit is contained in:
parent
07ad40dd3f
commit
703b1fc3a7
|
@ -31,30 +31,12 @@
|
|||
|
||||
#include <limits>
|
||||
|
||||
/// Base class for all wrapping converters
|
||||
class AudioProviderConverter : public AudioProvider {
|
||||
protected:
|
||||
std::unique_ptr<AudioProvider> source;
|
||||
public:
|
||||
AudioProviderConverter(std::unique_ptr<AudioProvider> src)
|
||||
: source(std::move(src))
|
||||
{
|
||||
channels = source->GetChannels();
|
||||
num_samples = source->GetNumSamples();
|
||||
sample_rate = source->GetSampleRate();
|
||||
bytes_per_sample = source->GetBytesPerSample();
|
||||
float_samples = source->AreSamplesFloat();
|
||||
}
|
||||
|
||||
agi::fs::path GetFilename() const { return source->GetFilename(); }
|
||||
};
|
||||
|
||||
/// Anything integral -> 16 bit signed machine-endian audio converter
|
||||
template<class Target>
|
||||
class BitdepthConvertAudioProvider : public AudioProviderConverter {
|
||||
class BitdepthConvertAudioProvider : public AudioProviderWrapper {
|
||||
int src_bytes_per_sample;
|
||||
public:
|
||||
BitdepthConvertAudioProvider(std::unique_ptr<AudioProvider> src) : AudioProviderConverter(std::move(src)) {
|
||||
BitdepthConvertAudioProvider(std::unique_ptr<AudioProvider> src) : AudioProviderWrapper(std::move(src)) {
|
||||
if (bytes_per_sample > 8)
|
||||
throw agi::AudioProviderOpenError("Audio format converter: audio with bitdepths greater than 64 bits/sample is currently unsupported", 0);
|
||||
|
||||
|
@ -92,9 +74,9 @@ public:
|
|||
|
||||
/// Floating point -> 16 bit signed machine-endian audio converter
|
||||
template<class Source, class Target>
|
||||
class FloatConvertAudioProvider : public AudioProviderConverter {
|
||||
class FloatConvertAudioProvider : public AudioProviderWrapper {
|
||||
public:
|
||||
FloatConvertAudioProvider(std::unique_ptr<AudioProvider> src) : AudioProviderConverter(std::move(src)) {
|
||||
FloatConvertAudioProvider(std::unique_ptr<AudioProvider> src) : AudioProviderWrapper(std::move(src)) {
|
||||
bytes_per_sample = sizeof(Target);
|
||||
float_samples = false;
|
||||
}
|
||||
|
@ -123,10 +105,10 @@ public:
|
|||
};
|
||||
|
||||
/// Non-mono 16-bit signed machine-endian -> mono 16-bit signed machine endian converter
|
||||
class DownmixAudioProvider : public AudioProviderConverter {
|
||||
class DownmixAudioProvider : public AudioProviderWrapper {
|
||||
int src_channels;
|
||||
public:
|
||||
DownmixAudioProvider(std::unique_ptr<AudioProvider> src) : AudioProviderConverter(std::move(src)) {
|
||||
DownmixAudioProvider(std::unique_ptr<AudioProvider> src) : AudioProviderWrapper(std::move(src)) {
|
||||
if (bytes_per_sample != 2)
|
||||
throw agi::InternalError("DownmixAudioProvider requires 16-bit input", 0);
|
||||
if (channels == 1)
|
||||
|
@ -154,9 +136,9 @@ public:
|
|||
|
||||
/// Sample doubler with linear interpolation for the agi::util::make_unique<samples>
|
||||
/// Requires 16-bit mono input
|
||||
class SampleDoublingAudioProvider : public AudioProviderConverter {
|
||||
class SampleDoublingAudioProvider : public AudioProviderWrapper {
|
||||
public:
|
||||
SampleDoublingAudioProvider(std::unique_ptr<AudioProvider> src) : AudioProviderConverter(std::move(src)) {
|
||||
SampleDoublingAudioProvider(std::unique_ptr<AudioProvider> src) : AudioProviderWrapper(std::move(src)) {
|
||||
if (source->GetBytesPerSample() != 2)
|
||||
throw agi::InternalError("UpsampleAudioProvider requires 16-bit input", 0);
|
||||
if (source->GetChannels() != 1)
|
||||
|
|
|
@ -89,14 +89,9 @@ public:
|
|||
|
||||
}
|
||||
|
||||
HDAudioProvider::HDAudioProvider(std::unique_ptr<AudioProvider> src, agi::BackgroundRunner *br) {
|
||||
bytes_per_sample = src->GetBytesPerSample();
|
||||
num_samples = src->GetNumSamples();
|
||||
channels = src->GetChannels();
|
||||
sample_rate = src->GetSampleRate();
|
||||
filename = src->GetFilename();
|
||||
float_samples = src->AreSamplesFloat();
|
||||
|
||||
HDAudioProvider::HDAudioProvider(std::unique_ptr<AudioProvider> src, agi::BackgroundRunner *br)
|
||||
: AudioProviderWrapper(std::move(src))
|
||||
{
|
||||
// Check free space
|
||||
if ((uint64_t)num_samples * channels * bytes_per_sample > agi::fs::FreeSpace(cache_dir()))
|
||||
throw agi::AudioCacheOpenError("Not enough free disk space in " + cache_dir().string() + " to cache the audio", 0);
|
||||
|
@ -106,9 +101,9 @@ HDAudioProvider::HDAudioProvider(std::unique_ptr<AudioProvider> src, agi::Backgr
|
|||
try {
|
||||
{
|
||||
agi::io::Save out(diskCacheFilename, true);
|
||||
br->Run(bind(&HDAudioProvider::FillCache, this, src.get(), &out.Get(), std::placeholders::_1));
|
||||
br->Run(bind(&HDAudioProvider::FillCache, this, source.get(), &out.Get(), std::placeholders::_1));
|
||||
}
|
||||
cache_provider = agi::util::make_unique<RawAudioProvider>(diskCacheFilename, src.get());
|
||||
cache_provider = agi::util::make_unique<RawAudioProvider>(diskCacheFilename, source.get());
|
||||
}
|
||||
catch (...) {
|
||||
agi::fs::Remove(diskCacheFilename);
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace agi {
|
|||
class ProgressSink;
|
||||
}
|
||||
|
||||
class HDAudioProvider : public AudioProvider {
|
||||
class HDAudioProvider : public AudioProviderWrapper {
|
||||
/// Name of the file which the decoded audio is written to
|
||||
agi::fs::path diskCacheFilename;
|
||||
/// Audio provider which reads from the decoded cache
|
||||
|
|
|
@ -21,13 +21,8 @@
|
|||
#include "audio_provider_lock.h"
|
||||
|
||||
LockAudioProvider::LockAudioProvider(std::unique_ptr<AudioProvider> src)
|
||||
: source(std::move(src))
|
||||
: AudioProviderWrapper(std::move(src))
|
||||
{
|
||||
channels = source->GetChannels();
|
||||
num_samples = source->GetNumSamples();
|
||||
sample_rate = source->GetSampleRate();
|
||||
bytes_per_sample = source->GetBytesPerSample();
|
||||
float_samples = source->AreSamplesFloat();
|
||||
}
|
||||
|
||||
void LockAudioProvider::FillBuffer(void *buf, int64_t start, int64_t count) const {
|
||||
|
|
|
@ -21,8 +21,7 @@
|
|||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
class LockAudioProvider : public AudioProvider {
|
||||
std::unique_ptr<const AudioProvider> source;
|
||||
class LockAudioProvider : public AudioProviderWrapper {
|
||||
mutable std::mutex mutex;
|
||||
|
||||
void FillBuffer(void *buf, int64_t start, int64_t count) const;
|
||||
|
|
|
@ -46,23 +46,17 @@
|
|||
#define CacheBits 22
|
||||
#define CacheBlockSize (1 << CacheBits)
|
||||
|
||||
RAMAudioProvider::RAMAudioProvider(std::unique_ptr<AudioProvider> src, agi::BackgroundRunner *br) {
|
||||
RAMAudioProvider::RAMAudioProvider(std::unique_ptr<AudioProvider> src, agi::BackgroundRunner *br)
|
||||
: AudioProviderWrapper(std::move(src))
|
||||
{
|
||||
try {
|
||||
blockcache.resize((src->GetNumSamples() * src->GetBytesPerSample() + CacheBlockSize - 1) >> CacheBits);
|
||||
blockcache.resize((source->GetNumSamples() * source->GetBytesPerSample() + CacheBlockSize - 1) >> CacheBits);
|
||||
}
|
||||
catch (std::bad_alloc const&) {
|
||||
throw agi::AudioCacheOpenError("Couldn't open audio, not enough ram available.", 0);
|
||||
}
|
||||
|
||||
// Copy parameters
|
||||
bytes_per_sample = src->GetBytesPerSample();
|
||||
num_samples = src->GetNumSamples();
|
||||
channels = src->GetChannels();
|
||||
sample_rate = src->GetSampleRate();
|
||||
filename = src->GetFilename();
|
||||
float_samples = src->AreSamplesFloat();
|
||||
|
||||
br->Run(std::bind(&RAMAudioProvider::FillCache, this, src.get(), std::placeholders::_1));
|
||||
br->Run(std::bind(&RAMAudioProvider::FillCache, this, source.get(), std::placeholders::_1));
|
||||
}
|
||||
|
||||
void RAMAudioProvider::FillCache(AudioProvider *source, agi::ProgressSink *ps) {
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace agi {
|
|||
class ProgressSink;
|
||||
}
|
||||
|
||||
class RAMAudioProvider : public AudioProvider {
|
||||
class RAMAudioProvider : public AudioProviderWrapper {
|
||||
#ifdef _MSC_VER
|
||||
boost::container::stable_vector<char[1 << 22]> blockcache;
|
||||
#else
|
||||
|
|
|
@ -73,6 +73,23 @@ public:
|
|||
virtual bool NeedsCache() const { return false; }
|
||||
};
|
||||
|
||||
/// Helper base class for an audio provider which wraps another provider
|
||||
class AudioProviderWrapper : public AudioProvider {
|
||||
protected:
|
||||
std::unique_ptr<AudioProvider> source;
|
||||
public:
|
||||
AudioProviderWrapper(std::unique_ptr<AudioProvider> src)
|
||||
: source(std::move(src))
|
||||
{
|
||||
channels = source->GetChannels();
|
||||
num_samples = source->GetNumSamples();
|
||||
sample_rate = source->GetSampleRate();
|
||||
bytes_per_sample = source->GetBytesPerSample();
|
||||
float_samples = source->AreSamplesFloat();
|
||||
filename = source->GetFilename();
|
||||
}
|
||||
};
|
||||
|
||||
class AudioProviderFactory : public Factory1<AudioProvider, agi::fs::path> {
|
||||
public:
|
||||
static void RegisterProviders();
|
||||
|
|
Loading…
Reference in New Issue