From 703b1fc3a75499907579e05937c76b3d9e9992d4 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Thu, 26 Sep 2013 20:18:29 -0700 Subject: [PATCH] Extract common stuff for wrapper audio providers to a base class --- aegisub/src/audio_provider_convert.cpp | 34 +++++--------------- aegisub/src/audio_provider_hd.cpp | 15 +++------ aegisub/src/audio_provider_hd.h | 2 +- aegisub/src/audio_provider_lock.cpp | 7 +--- aegisub/src/audio_provider_lock.h | 3 +- aegisub/src/audio_provider_ram.cpp | 16 +++------ aegisub/src/audio_provider_ram.h | 2 +- aegisub/src/include/aegisub/audio_provider.h | 17 ++++++++++ 8 files changed, 39 insertions(+), 57 deletions(-) diff --git a/aegisub/src/audio_provider_convert.cpp b/aegisub/src/audio_provider_convert.cpp index 05e109c67..bdc3e9240 100644 --- a/aegisub/src/audio_provider_convert.cpp +++ b/aegisub/src/audio_provider_convert.cpp @@ -31,30 +31,12 @@ #include -/// Base class for all wrapping converters -class AudioProviderConverter : public AudioProvider { -protected: - std::unique_ptr source; -public: - AudioProviderConverter(std::unique_ptr 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 BitdepthConvertAudioProvider : public AudioProviderConverter { +class BitdepthConvertAudioProvider : public AudioProviderWrapper { int src_bytes_per_sample; public: - BitdepthConvertAudioProvider(std::unique_ptr src) : AudioProviderConverter(std::move(src)) { + BitdepthConvertAudioProvider(std::unique_ptr 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 FloatConvertAudioProvider : public AudioProviderConverter { +class FloatConvertAudioProvider : public AudioProviderWrapper { public: - FloatConvertAudioProvider(std::unique_ptr src) : AudioProviderConverter(std::move(src)) { + FloatConvertAudioProvider(std::unique_ptr 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 src) : AudioProviderConverter(std::move(src)) { + DownmixAudioProvider(std::unique_ptr 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 /// Requires 16-bit mono input -class SampleDoublingAudioProvider : public AudioProviderConverter { +class SampleDoublingAudioProvider : public AudioProviderWrapper { public: - SampleDoublingAudioProvider(std::unique_ptr src) : AudioProviderConverter(std::move(src)) { + SampleDoublingAudioProvider(std::unique_ptr src) : AudioProviderWrapper(std::move(src)) { if (source->GetBytesPerSample() != 2) throw agi::InternalError("UpsampleAudioProvider requires 16-bit input", 0); if (source->GetChannels() != 1) diff --git a/aegisub/src/audio_provider_hd.cpp b/aegisub/src/audio_provider_hd.cpp index 2b0b8967d..ed29eaad7 100644 --- a/aegisub/src/audio_provider_hd.cpp +++ b/aegisub/src/audio_provider_hd.cpp @@ -89,14 +89,9 @@ public: } -HDAudioProvider::HDAudioProvider(std::unique_ptr 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 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 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(diskCacheFilename, src.get()); + cache_provider = agi::util::make_unique(diskCacheFilename, source.get()); } catch (...) { agi::fs::Remove(diskCacheFilename); diff --git a/aegisub/src/audio_provider_hd.h b/aegisub/src/audio_provider_hd.h index c59ed739b..abb32c309 100644 --- a/aegisub/src/audio_provider_hd.h +++ b/aegisub/src/audio_provider_hd.h @@ -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 diff --git a/aegisub/src/audio_provider_lock.cpp b/aegisub/src/audio_provider_lock.cpp index 5ca6b8b93..d4ecbdf2c 100644 --- a/aegisub/src/audio_provider_lock.cpp +++ b/aegisub/src/audio_provider_lock.cpp @@ -21,13 +21,8 @@ #include "audio_provider_lock.h" LockAudioProvider::LockAudioProvider(std::unique_ptr 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 { diff --git a/aegisub/src/audio_provider_lock.h b/aegisub/src/audio_provider_lock.h index c6653b775..75f012b14 100644 --- a/aegisub/src/audio_provider_lock.h +++ b/aegisub/src/audio_provider_lock.h @@ -21,8 +21,7 @@ #include #include -class LockAudioProvider : public AudioProvider { - std::unique_ptr source; +class LockAudioProvider : public AudioProviderWrapper { mutable std::mutex mutex; void FillBuffer(void *buf, int64_t start, int64_t count) const; diff --git a/aegisub/src/audio_provider_ram.cpp b/aegisub/src/audio_provider_ram.cpp index ba80eddf9..c8cdd69d9 100644 --- a/aegisub/src/audio_provider_ram.cpp +++ b/aegisub/src/audio_provider_ram.cpp @@ -46,23 +46,17 @@ #define CacheBits 22 #define CacheBlockSize (1 << CacheBits) -RAMAudioProvider::RAMAudioProvider(std::unique_ptr src, agi::BackgroundRunner *br) { +RAMAudioProvider::RAMAudioProvider(std::unique_ptr 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) { diff --git a/aegisub/src/audio_provider_ram.h b/aegisub/src/audio_provider_ram.h index e307ce7e8..feb392c27 100644 --- a/aegisub/src/audio_provider_ram.h +++ b/aegisub/src/audio_provider_ram.h @@ -42,7 +42,7 @@ namespace agi { class ProgressSink; } -class RAMAudioProvider : public AudioProvider { +class RAMAudioProvider : public AudioProviderWrapper { #ifdef _MSC_VER boost::container::stable_vector blockcache; #else diff --git a/aegisub/src/include/aegisub/audio_provider.h b/aegisub/src/include/aegisub/audio_provider.h index 5ba8ce814..ba91933e3 100644 --- a/aegisub/src/include/aegisub/audio_provider.h +++ b/aegisub/src/include/aegisub/audio_provider.h @@ -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 source; +public: + AudioProviderWrapper(std::unique_ptr 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 { public: static void RegisterProviders();