diff --git a/aegisub/build/aegisub_vs2008/aegisub_vs2008.vcproj b/aegisub/build/aegisub_vs2008/aegisub_vs2008.vcproj index 4d501a70e..9bca1bb19 100644 --- a/aegisub/build/aegisub_vs2008/aegisub_vs2008.vcproj +++ b/aegisub/build/aegisub_vs2008/aegisub_vs2008.vcproj @@ -465,14 +465,6 @@ RelativePath="..\..\src\audio_provider_convert.h" > - - - - diff --git a/aegisub/build/msbuild/Aegisub/Aegisub.vcxproj b/aegisub/build/msbuild/Aegisub/Aegisub.vcxproj index faa9cb2e1..374f49dcd 100644 --- a/aegisub/build/msbuild/Aegisub/Aegisub.vcxproj +++ b/aegisub/build/msbuild/Aegisub/Aegisub.vcxproj @@ -76,7 +76,6 @@ - @@ -252,7 +251,6 @@ - diff --git a/aegisub/build/msbuild/Aegisub/Aegisub.vcxproj.filters b/aegisub/build/msbuild/Aegisub/Aegisub.vcxproj.filters index 9eede2120..ed030b2c6 100644 --- a/aegisub/build/msbuild/Aegisub/Aegisub.vcxproj.filters +++ b/aegisub/build/msbuild/Aegisub/Aegisub.vcxproj.filters @@ -183,9 +183,6 @@ Audio\Providers - - Audio\Providers - Audio\Providers @@ -692,9 +689,6 @@ Audio\Providers - - Audio\Providers - Audio\Providers diff --git a/aegisub/src/Makefile b/aegisub/src/Makefile index cc3c2168c..0fc65eaf9 100644 --- a/aegisub/src/Makefile +++ b/aegisub/src/Makefile @@ -134,7 +134,6 @@ SRC += \ audio_player.cpp \ audio_provider.cpp \ audio_provider_convert.cpp \ - audio_provider_downmix.cpp \ audio_provider_hd.cpp \ audio_provider_pcm.cpp \ audio_provider_ram.cpp \ diff --git a/aegisub/src/audio_provider_convert.cpp b/aegisub/src/audio_provider_convert.cpp index e08df165d..bb22166dd 100644 --- a/aegisub/src/audio_provider_convert.cpp +++ b/aegisub/src/audio_provider_convert.cpp @@ -1,29 +1,16 @@ -// Copyright (c) 2008, Rodrigo Braz Monteiro -// All rights reserved. +// Copyright (c) 2011, Thomas Goyne // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: +// 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. // -// * 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. +// 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/ // @@ -36,185 +23,164 @@ #include "config.h" -#include "aegisub_endian.h" #include "audio_provider_convert.h" -#include "audio_provider_downmix.h" +#include "aegisub_endian.h" +#include "include/aegisub/audio_provider.h" -/// @brief Constructor -/// @param src -/// -ConvertAudioProvider::ConvertAudioProvider(AudioProvider *src) : source(src) { - channels = source->GetChannels(); - num_samples = source->GetNumSamples(); - sample_rate = source->GetSampleRate(); - bytes_per_sample = 2; +#include - sampleMult = 1; - if (sample_rate < 16000) sampleMult = 4; - else if (sample_rate < 32000) sampleMult = 2; - sample_rate *= sampleMult; - num_samples *= sampleMult; -} - -/// @brief Convert to 16-bit -/// @param src -/// @param dst -/// @param count -/// -void ConvertAudioProvider::Make16Bit(const char *src, short *dst, int64_t count) const { - for (int64_t i=0;i source; +public: + AudioProviderConverter(AudioProvider *src) : source(src) { + channels = source->GetChannels(); + num_samples = source->GetNumSamples(); + sample_rate = source->GetSampleRate(); + bytes_per_sample = source->GetBytesPerSample(); } -} -////////////////////// -// Change sample rate -// This requres 16-bit input -// The SampleConverter is a class overloading operator() with a function from short to short -template + bool AreSamplesNativeEndian() const { return true; } + wxString GetFilename() const { return source->GetFilename(); } +}; -/// @brief DOCME -/// @param src -/// @param dst -/// @param count -/// @param converter -/// -void ConvertAudioProvider::ChangeSampleRate(const short *src, short *dst, int64_t count, const SampleConverter &converter) const { - // Upsample by 2 - if (sampleMult == 2) { - int64_t size = count/2; - short cur; - short next = 0; - for (int64_t i=0;iGetBytesPerSample() != 2) + throw agi::InternalError("EndianSwapAudioProvider only supports 16-bit audio", 0); + if (src->AreSamplesNativeEndian()) + throw agi::InternalError("EndianSwapAudioProvider used on provider that doesn't need it", 0); + } + + void GetAudio(void *buf, int64_t start, int64_t count) const { + source->GetAudio(buf, start, count); + count *= channels; + int16_t *buf16 = reinterpret_cast(buf); + for (int64_t i = 0; i < count; ++i) + buf16[i] = Endian::Reverse((uint16_t)buf16[i]); + } +}; + +/// unsigned 8 bit -> signed machine-endian 16 bit audio converter +class UpconvertAudioProvider : public AudioProviderConverter { +public: + UpconvertAudioProvider(AudioProvider *src) : AudioProviderConverter(src) { + if (src->GetBytesPerSample() != 1) + throw agi::InternalError("UpconvertAudioProvider only supports 8-bit input", 0); + bytes_per_sample = 2; + } + + void GetAudio(void *buf, int64_t start, int64_t count) const { + source->GetAudio(buf, start, count); + + count *= channels; + int8_t *buf8 = reinterpret_cast(buf); + // walking backwards so that the conversion can be done in place + for (int64_t i = count - 1; i >= 0; --i) { + buf8[i * 2 + 1] = 0; + buf8[i * 2] = buf8[i]; } - if (count%2) *(dst++) = next; + } +}; + +/// Non-mono 16-bit signed machine-endian -> mono 16-bit signed machine endian converter +class DownmixAudioProvider : public AudioProviderConverter { + mutable std::vector src_buf; + int src_channels; +public: + DownmixAudioProvider(AudioProvider *src) : AudioProviderConverter(src) { + if (bytes_per_sample != 2) + throw agi::InternalError("DownmixAudioProvider requires 16-bit input", 0); + if (channels == 1) + throw agi::InternalError("DownmixAudioProvider requires multi-channel input", 0); + src_channels = channels; + channels = 1; } - // Upsample by 4 - else if (sampleMult == 4) { - int64_t size = count/4; - short cur; - short next = 0; - for (int64_t i=0;iGetAudio(&src_buf[0], start, count); + + int16_t *dst = reinterpret_cast(buf); + // Just average the channels together while (count-- > 0) { - *dst++ = converter(*src++); + int sum = 0; + for (int c = 0; c < src_channels; ++c) + sum += src_buf[count * src_channels + c]; + dst[count] = static_cast(sum / src_channels); } } -} - -/// DOCME -struct NullSampleConverter { - inline short operator()(const short val) const { - return val; - } }; -/// DOCME -struct EndianSwapSampleConverter { - inline short operator()(const short val) const { - return (short)Endian::Reverse((uint16_t)val); - }; +/// Sample doubler with linear interpolation for the new samples +/// Requires 16-bit mono input +class SampleDoublingAudioProvider : public AudioProviderConverter { +public: + SampleDoublingAudioProvider(AudioProvider *src) : AudioProviderConverter(src) { + if (src->GetBytesPerSample() != 2) + throw agi::InternalError("UpsampleAudioProvider requires 16-bit input", 0); + if (src->GetChannels() != 1) + throw agi::InternalError("UpsampleAudioProvider requires mono input", 0); + + sample_rate *= 2; + num_samples *= 2; + } + + void GetAudio(void *buf, int64_t start, int64_t count) const { + if (count == 0) return; + + bool not_end = start + count < num_samples; + int64_t src_count = count / 2; + source->GetAudio(buf, start / 2, src_count + not_end); + + int16_t *buf16 = reinterpret_cast(buf); + + if (!not_end) { + // We weren't able to request a sample past the end so just + // duplicate the last sample + buf16[src_count] = buf16[src_count + 1]; + } + + if (count % 2) + buf16[count - 1] = buf16[src_count]; + + // walking backwards so that the conversion can be done in place + for (int64_t i = src_count - 1; i >= 0; --i) { + buf16[i * 2] = buf16[i]; + buf16[i * 2 + 1] = (int16_t)(((int32_t)buf16[i] + buf16[i + 1]) / 2); + } + } }; - -/// @brief Get audio -/// @param destination -/// @param start -/// @param count -/// -void ConvertAudioProvider::GetAudio(void *destination, int64_t start, int64_t count) const { - // Bits per sample - int srcBps = source->GetBytesPerSample(); - - // Nothing to do - if (sampleMult == 1 && srcBps == 2) { - source->GetAudio(destination,start,count); - } - - // Convert - else { - // Allocate buffers with sufficient size for the entire operation - size_t fullSize = count; - int64_t srcCount = count / sampleMult; - short *buffer1 = NULL; - short *buffer2 = NULL; - short *last = NULL; - - // Read audio - buffer1 = new short[fullSize * channels]; - source->GetAudio(buffer1,start/sampleMult,srcCount); - - // Convert from 8-bit to 16-bit - if (srcBps == 1) { - if (sampleMult == 1) { - Make16Bit((const char*)buffer1,(short*)destination,srcCount * channels); - } - else { - buffer2 = new short[fullSize * channels]; - Make16Bit((const char*)buffer1,buffer2,srcCount * channels); - last = buffer2; - } - } - - // Already 16-bit - else if (srcBps == 2) last = buffer1; - - // Convert sample rate - if (sampleMult != 1 && source->AreSamplesNativeEndian()) { - ChangeSampleRate(last,(short*)destination,count * channels, NullSampleConverter()); - } - else if (!source->AreSamplesNativeEndian()) { - ChangeSampleRate(last,(short*)destination,count * channels, EndianSwapSampleConverter()); - } - - delete [] buffer1; - delete [] buffer2; - } -} - - -/// @brief See if we need to downmix the number of channels -/// @param source_provider -/// AudioProvider *CreateConvertAudioProvider(AudioProvider *source_provider) { AudioProvider *provider = source_provider; - // Aegisub requires 16 bit samples, - // some audio players break with low samplerates, - // everything breaks with wrong-ended samples. - if (provider->GetBytesPerSample() != 2 || - provider->GetSampleRate() < 32000 || - !provider->AreSamplesNativeEndian()) - { - // @todo add support for more bitdepths (i.e. 24- and 32-bit audio) - if (provider->GetBytesPerSample() > 2) + // Ensure 16-bit audio with proper endianness + switch (provider->GetBytesPerSample()) { + case 1: + provider = new UpconvertAudioProvider(provider); + break; + case 2: + if (!provider->AreSamplesNativeEndian()) + provider = new EndianSwapAudioProvider(provider); + break; + default: throw AudioOpenError("Audio format converter: audio with bitdepths greater than 16 bits/sample is currently unsupported"); - - provider = new ConvertAudioProvider(provider); } - // We also require mono audio for historical reasons + // We currently only support mono audio if (provider->GetChannels() != 1) - { - provider = new DownmixingAudioProvider(provider); - } + provider = new DownmixAudioProvider(provider); + + // Some players don't like low sample rate audio + while (provider->GetSampleRate() < 32000) + provider = new SampleDoublingAudioProvider(provider); return provider; } diff --git a/aegisub/src/audio_provider_convert.h b/aegisub/src/audio_provider_convert.h index 79b3e2ef8..b458a5e11 100644 --- a/aegisub/src/audio_provider_convert.h +++ b/aegisub/src/audio_provider_convert.h @@ -1,29 +1,16 @@ -// Copyright (c) 2008, Rodrigo Braz Monteiro -// All rights reserved. +// Copyright (c) 2011, Thomas Goyne // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: +// 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. // -// * 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. +// 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/ // @@ -34,37 +21,7 @@ /// @ingroup audio_input /// -#include "include/aegisub/audio_provider.h" - -#ifndef AGI_PRE -#include -#endif - -/// DOCME -/// @class ConvertAudioProvider -/// @brief DOCME -/// -/// DOCME -class ConvertAudioProvider : public AudioProvider { - /// DOCME - int sampleMult; - - /// DOCME - std::tr1::shared_ptr source; - void Make16Bit(const char *src, short *dst, int64_t count) const; - template - void ChangeSampleRate(const short *src, short *dst, int64_t count, const SampleConverter &converter) const; - -public: - ConvertAudioProvider(AudioProvider *source); - - /// By its nature, the ConvertAudioProvider always delivers machine endian. - /// That's one of the points of it! - bool AreSamplesNativeEndian() const { return true; } - - void GetAudio(void *buf, int64_t start, int64_t count) const; - - wxString GetFilename() const { return source->GetFilename(); } -}; +class AudioProvider; +/// Get an audio provider which supplies audio in a format supported by Aegisub's players AudioProvider *CreateConvertAudioProvider(AudioProvider *source_provider); diff --git a/aegisub/src/audio_provider_downmix.cpp b/aegisub/src/audio_provider_downmix.cpp deleted file mode 100644 index a8c277e95..000000000 --- a/aegisub/src/audio_provider_downmix.cpp +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) 2007-2008, 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/ -// -// $Id$ - -/// @file audio_provider_downmix.cpp -/// @brief Intermediate audio provider downmixing the signal to mono -/// @ingroup audio_input -/// - - -////////////////// -// Headers -#include "config.h" - -#include "audio_provider_downmix.h" - - -/// @brief Constructor -/// @param source -/// -DownmixingAudioProvider::DownmixingAudioProvider(AudioProvider *source) : provider(source) { - filename = source->GetFilename(); - channels = 1; // target - src_channels = source->GetChannels(); - num_samples = source->GetNumSamples(); - bytes_per_sample = source->GetBytesPerSample(); - sample_rate = source->GetSampleRate(); - - if (!(bytes_per_sample == 1 || bytes_per_sample == 2)) - throw AudioOpenError("Downmixing Audio Provider: Can only downmix 8 and 16 bit audio"); - if (!source->AreSamplesNativeEndian()) - throw AudioOpenError("Downmixing Audio Provider: Source must have machine endian samples"); -} - -/// @brief Actual work happens here -/// @param buf -/// @param start -/// @param count -/// -void DownmixingAudioProvider::GetAudio(void *buf, int64_t start, int64_t count) const { - if (count == 0) return; - - // We can do this ourselves - if (start >= num_samples) { - if (bytes_per_sample == 1) - // 8 bit formats are usually unsigned with bias 127 - memset(buf, 127, count); - else - // While everything else is signed - memset(buf, 0, count*bytes_per_sample); - - return; - } - - // So alloc some temporary memory for this - // Depending on use, this might be made faster by using - // a pre-allocced block of memory...? - char *tmp = new char[count*bytes_per_sample*src_channels]; - - try { - provider->GetAudio(tmp, start, count); - } - catch (...) { - delete tmp; - throw; - } - - // Now downmix - // Just average the samples over the channels (really bad if they're out of phase!) - // XXX: Assuming here that sample data are in machine endian, an upstream provider should ensure that - if (bytes_per_sample == 1) { - uint8_t *src = (uint8_t *)tmp; - uint8_t *dst = (uint8_t *)buf; - - while (count > 0) { - int sum = 0; - for (int c = 0; c < src_channels; c++) - sum += *(src++); - *(dst++) = (uint8_t)(sum / src_channels); - count--; - } - } - else if (bytes_per_sample == 2) { - int16_t *src = (int16_t *)tmp; - int16_t *dst = (int16_t *)buf; - - while (count > 0) { - int sum = 0; - for (int c = 0; c < src_channels; c++) - sum += *(src++); - *(dst++) = (int16_t)(sum / src_channels); - count--; - } - } - - // Done downmixing, free the work buffer - delete[] tmp; -} diff --git a/aegisub/src/audio_provider_downmix.h b/aegisub/src/audio_provider_downmix.h deleted file mode 100644 index af79d316d..000000000 --- a/aegisub/src/audio_provider_downmix.h +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2007-2008, 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/ -// -// $Id$ - -/// @file audio_provider_downmix.h -/// @see audio_provider_downmix.cpp -/// @ingroup audio_input -/// - -#include "include/aegisub/audio_provider.h" - -#ifndef AGI_PRE -#include -#endif - -/// DOCME -/// @class DownmixingAudioProvider -/// @brief DOCME -/// -/// DOCME -class DownmixingAudioProvider : public AudioProvider { - std::tr1::shared_ptr provider; - - /// DOCME - int src_channels; -public: - DownmixingAudioProvider(AudioProvider *source); - - /// @brief Downmixing requires samples to be native endian beforehand - /// - bool AreSamplesNativeEndian() const { return true; } - - void GetAudio(void *buf, int64_t start, int64_t count) const; -};