diff options
author | Max Kellermann <max@duempel.org> | 2013-11-30 13:19:07 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2013-11-30 13:22:25 +0100 |
commit | 92004f2e7e6ec8479805313b0bdac7258d53c74e (patch) | |
tree | e8d522cd55c015e145816f6df6db8316ea6cad6a /src/pcm/ChannelsConverter.cxx | |
parent | 0eefc7a43ce13876cdfb434e2a890a16befcb847 (diff) |
pcm/PcmConvert: move code to new class PcmChannelsConverter
Diffstat (limited to 'src/pcm/ChannelsConverter.cxx')
-rw-r--r-- | src/pcm/ChannelsConverter.cxx | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/src/pcm/ChannelsConverter.cxx b/src/pcm/ChannelsConverter.cxx new file mode 100644 index 000000000..5895fb15d --- /dev/null +++ b/src/pcm/ChannelsConverter.cxx @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2003-2013 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "ChannelsConverter.hxx" +#include "PcmChannels.hxx" +#include "PcmConvert.hxx" +#include "util/ConstBuffer.hxx" +#include "util/Error.hxx" + +#include <assert.h> + +bool +PcmChannelsConverter::Open(SampleFormat _format, + unsigned _src_channels, unsigned _dest_channels, + gcc_unused Error &error) +{ + assert(_format != SampleFormat::UNDEFINED); + + switch (_format) { + case SampleFormat::S16: + case SampleFormat::S24_P32: + case SampleFormat::S32: + case SampleFormat::FLOAT: + break; + + default: + error.Format(pcm_convert_domain, + "PCM channel conversion for %s is not implemented", + sample_format_to_string(format)); + return false; + } + + format = _format; + src_channels = _src_channels; + dest_channels = _dest_channels; + return true; +} + +void +PcmChannelsConverter::Close() +{ +#ifndef NDEBUG + format = SampleFormat::UNDEFINED; +#endif +} + +ConstBuffer<void> +PcmChannelsConverter::Convert(ConstBuffer<void> src, Error &error) +{ + const void *result = nullptr; + size_t result_size = 0; + + switch (format) { + case SampleFormat::UNDEFINED: + case SampleFormat::S8: + case SampleFormat::DSD: + assert(false); + gcc_unreachable(); + + case SampleFormat::S16: + result = pcm_convert_channels_16(buffer, dest_channels, + src_channels, + (const int16_t *)src.data, + src.size, &result_size); + break; + + case SampleFormat::S24_P32: + result = pcm_convert_channels_24(buffer, dest_channels, + src_channels, + (const int32_t *)src.data, + src.size, &result_size); + break; + + case SampleFormat::S32: + result = pcm_convert_channels_32(buffer, dest_channels, + src_channels, + (const int32_t *)src.data, + src.size, &result_size); + break; + + case SampleFormat::FLOAT: + result = pcm_convert_channels_float(buffer, dest_channels, + src_channels, + (const float *)src.data, + src.size, &result_size); + break; + } + + if (result == nullptr) { + error.Format(pcm_convert_domain, + "Conversion from %u to %u channels " + "is not implemented", + src_channels, dest_channels); + return nullptr; + } + + return { result, result_size }; +} |