aboutsummaryrefslogtreecommitdiff
path: root/Src/external_dependencies/openmpt-trunk/mptrack/StreamEncoder.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/external_dependencies/openmpt-trunk/mptrack/StreamEncoder.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/external_dependencies/openmpt-trunk/mptrack/StreamEncoder.cpp')
-rw-r--r--Src/external_dependencies/openmpt-trunk/mptrack/StreamEncoder.cpp342
1 files changed, 342 insertions, 0 deletions
diff --git a/Src/external_dependencies/openmpt-trunk/mptrack/StreamEncoder.cpp b/Src/external_dependencies/openmpt-trunk/mptrack/StreamEncoder.cpp
new file mode 100644
index 00000000..e6cca7c3
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/mptrack/StreamEncoder.cpp
@@ -0,0 +1,342 @@
+/*
+ * StreamEncoder.cpp
+ * -----------------
+ * Purpose: Exporting streamed music files.
+ * Notes : none
+ * Authors: Joern Heusipp
+ * OpenMPT Devs
+ * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
+ */
+
+#include "stdafx.h"
+
+#include "StreamEncoder.h"
+
+#include "mpt/io/base.hpp"
+#include "mpt/io/io.hpp"
+#include "mpt/io/io_stdstream.hpp"
+#include "mpt/io_write/buffer.hpp"
+
+#include "openmpt/soundbase/SampleEncode.hpp"
+#include "openmpt/soundbase/SampleFormat.hpp"
+
+#include <ostream>
+
+
+OPENMPT_NAMESPACE_BEGIN
+
+
+StreamWriterBase::StreamWriterBase(std::ostream &stream)
+ : f(stream)
+ , fStart(f.tellp())
+{
+ return;
+}
+
+StreamWriterBase::~StreamWriterBase()
+{
+ return;
+}
+
+
+
+template <mpt::endian endian, typename Tsample>
+static inline std::pair<bool, std::size_t> WriteInterleavedImpl(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const Tsample *interleaved)
+{
+ MPT_ASSERT(endian == format.endian);
+ MPT_ASSERT(format.GetSampleFormat() == SampleFormatTraits<Tsample>::sampleFormat());
+ bool success = true;
+ std::size_t written = 0;
+ MPT_MAYBE_CONSTANT_IF(endian == mpt::get_endian() && format.encoding != Encoder::Format::Encoding::Alaw && format.encoding != Encoder::Format::Encoding::ulaw)
+ {
+ if(!mpt::IO::WriteRaw(f, reinterpret_cast<const std::byte*>(interleaved), frameCount * channels * format.GetSampleFormat().GetSampleSize()))
+ {
+ success = false;
+ }
+ written += frameCount * channels * format.GetSampleFormat().GetSampleSize();
+ } else
+ {
+ std::array<std::byte, mpt::IO::BUFFERSIZE_TINY> fbuf;
+ mpt::IO::WriteBuffer<std::ostream> bf{f, fbuf};
+ if(format.encoding == Encoder::Format::Encoding::Alaw)
+ {
+ if constexpr(std::is_same<Tsample, int16>::value)
+ {
+ SC::EncodeALaw conv;
+ for(std::size_t frame = 0; frame < frameCount; ++frame)
+ {
+ for(uint16 channel = 0; channel < channels; ++channel)
+ {
+ std::byte sampledata = conv(interleaved[channel]);
+ mpt::IO::WriteRaw(bf, &sampledata, 1);
+ written += 1;
+ }
+ interleaved += channels;
+ }
+ }
+ } else if(format.encoding == Encoder::Format::Encoding::ulaw)
+ {
+ if constexpr(std::is_same<Tsample, int16>::value)
+ {
+ SC::EncodeuLaw conv;
+ for(std::size_t frame = 0; frame < frameCount; ++frame)
+ {
+ for(uint16 channel = 0; channel < channels; ++channel)
+ {
+ std::byte sampledata = conv(interleaved[channel]);
+ mpt::IO::WriteRaw(bf, &sampledata, 1);
+ written += 1;
+ }
+ interleaved += channels;
+ }
+ }
+ } else
+ {
+ if constexpr(std::is_floating_point<Tsample>::value)
+ {
+ std::vector<typename mpt::make_float_endian<endian, Tsample>::type> frameData(channels);
+ for(std::size_t frame = 0; frame < frameCount; ++frame)
+ {
+ for(uint16 channel = 0; channel < channels; ++channel)
+ {
+ frameData[channel] = typename mpt::make_float_endian<endian, Tsample>::type(interleaved[channel]);
+ }
+ mpt::IO::WriteRaw(bf, reinterpret_cast<const std::byte*>(frameData.data()), channels * format.GetSampleFormat().GetSampleSize());
+ written += channels * format.GetSampleFormat().GetSampleSize();
+ interleaved += channels;
+ }
+ } else if constexpr(std::is_same<Tsample, int24>::value)
+ {
+ MPT_ASSERT(!mpt::endian_is_weird());
+ for(std::size_t frame = 0; frame < frameCount; ++frame)
+ {
+ for(uint16 channel = 0; channel < channels; ++channel)
+ {
+ std::array<std::byte, 3> data;
+ std::memcpy(data.data(), interleaved, 3);
+ MPT_MAYBE_CONSTANT_IF(endian != mpt::get_endian())
+ {
+ std::reverse(data.begin(), data.end());
+ }
+ mpt::IO::Write(bf, data);
+ written += data.size();
+ interleaved += 3;
+ }
+ }
+ } else
+ {
+ std::vector<typename mpt::make_endian<endian, Tsample>::type> frameData(channels);
+ for(std::size_t frame = 0; frame < frameCount; ++frame)
+ {
+ for(uint16 channel = 0; channel < channels; ++channel)
+ {
+ frameData[channel] = interleaved[channel];
+ }
+ mpt::IO::WriteRaw(bf, reinterpret_cast<const std::byte*>(frameData.data()), channels * format.GetSampleFormat().GetSampleSize());
+ written += channels * format.GetSampleFormat().GetSampleSize();
+ interleaved += channels;
+ }
+ }
+ }
+ if(bf.HasWriteError())
+ {
+ success = false;
+ }
+ }
+ return std::make_pair(success, written);
+}
+
+std::pair<bool, std::size_t> WriteInterleavedLE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const double *interleaved)
+{
+ MPT_ASSERT(format.endian == mpt::endian::little);
+ return WriteInterleavedImpl<mpt::endian::little>(f, channels, format, frameCount, interleaved);
+}
+std::pair<bool, std::size_t> WriteInterleavedLE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const float *interleaved)
+{
+ MPT_ASSERT(format.endian == mpt::endian::little);
+ return WriteInterleavedImpl<mpt::endian::little>(f, channels, format, frameCount, interleaved);
+}
+std::pair<bool, std::size_t> WriteInterleavedLE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const int32 *interleaved)
+{
+ MPT_ASSERT(format.endian == mpt::endian::little);
+ return WriteInterleavedImpl<mpt::endian::little>(f, channels, format, frameCount, interleaved);
+}
+std::pair<bool, std::size_t> WriteInterleavedLE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const int24 *interleaved)
+{
+ MPT_ASSERT(format.endian == mpt::endian::little);
+ return WriteInterleavedImpl<mpt::endian::little>(f, channels, format, frameCount, interleaved);
+}
+std::pair<bool, std::size_t> WriteInterleavedLE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const int16 *interleaved)
+{
+ MPT_ASSERT(format.endian == mpt::endian::little);
+ return WriteInterleavedImpl<mpt::endian::little>(f, channels, format, frameCount, interleaved);
+}
+std::pair<bool, std::size_t> WriteInterleavedLE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const int8 *interleaved)
+{
+ MPT_ASSERT(format.endian == mpt::endian::little);
+ return WriteInterleavedImpl<mpt::endian::little>(f, channels, format, frameCount, interleaved);
+}
+std::pair<bool, std::size_t> WriteInterleavedLE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const uint8 *interleaved)
+{
+ MPT_ASSERT(format.endian == mpt::endian::little);
+ return WriteInterleavedImpl<mpt::endian::little>(f, channels, format, frameCount, interleaved);
+}
+
+std::pair<bool, std::size_t> WriteInterleavedBE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const double *interleaved)
+{
+ MPT_ASSERT(format.endian == mpt::endian::big);
+ return WriteInterleavedImpl<mpt::endian::big>(f, channels, format, frameCount, interleaved);
+}
+std::pair<bool, std::size_t> WriteInterleavedBE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const float *interleaved)
+{
+ MPT_ASSERT(format.endian == mpt::endian::big);
+ return WriteInterleavedImpl<mpt::endian::big>(f, channels, format, frameCount, interleaved);
+}
+std::pair<bool, std::size_t> WriteInterleavedBE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const int32 *interleaved)
+{
+ MPT_ASSERT(format.endian == mpt::endian::big);
+ return WriteInterleavedImpl<mpt::endian::big>(f, channels, format, frameCount, interleaved);
+}
+std::pair<bool, std::size_t> WriteInterleavedBE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const int24 *interleaved)
+{
+ MPT_ASSERT(format.endian == mpt::endian::big);
+ return WriteInterleavedImpl<mpt::endian::big>(f, channels, format, frameCount, interleaved);
+}
+std::pair<bool, std::size_t> WriteInterleavedBE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const int16 *interleaved)
+{
+ MPT_ASSERT(format.endian == mpt::endian::big);
+ return WriteInterleavedImpl<mpt::endian::big>(f, channels, format, frameCount, interleaved);
+}
+std::pair<bool, std::size_t> WriteInterleavedBE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const int8 *interleaved)
+{
+ MPT_ASSERT(format.endian == mpt::endian::big);
+ return WriteInterleavedImpl<mpt::endian::big>(f, channels, format, frameCount, interleaved);
+}
+std::pair<bool, std::size_t> WriteInterleavedBE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const uint8 *interleaved)
+{
+ MPT_ASSERT(format.endian == mpt::endian::big);
+ return WriteInterleavedImpl<mpt::endian::big>(f, channels, format, frameCount, interleaved);
+}
+
+
+
+SampleFormat StreamWriterBase::GetSampleFormat() const
+{
+ return SampleFormat::Float32;
+}
+
+
+void StreamWriterBase::WriteInterleaved(std::size_t frameCount, const double *interleaved)
+{
+ MPT_UNREFERENCED_PARAMETER(frameCount);
+ MPT_UNREFERENCED_PARAMETER(interleaved);
+ MPT_ASSERT_NOTREACHED();
+}
+
+void StreamWriterBase::WriteInterleaved(std::size_t frameCount, const float *interleaved)
+{
+ MPT_UNREFERENCED_PARAMETER(frameCount);
+ MPT_UNREFERENCED_PARAMETER(interleaved);
+ MPT_ASSERT_NOTREACHED();
+}
+
+void StreamWriterBase::WriteInterleaved(std::size_t frameCount, const int32 *interleaved)
+{
+ MPT_UNREFERENCED_PARAMETER(frameCount);
+ MPT_UNREFERENCED_PARAMETER(interleaved);
+ MPT_ASSERT_NOTREACHED();
+}
+
+void StreamWriterBase::WriteInterleaved(std::size_t frameCount, const int24 *interleaved)
+{
+ MPT_UNREFERENCED_PARAMETER(frameCount);
+ MPT_UNREFERENCED_PARAMETER(interleaved);
+ MPT_ASSERT_NOTREACHED();
+}
+
+void StreamWriterBase::WriteInterleaved(std::size_t frameCount, const int16 *interleaved)
+{
+ MPT_UNREFERENCED_PARAMETER(frameCount);
+ MPT_UNREFERENCED_PARAMETER(interleaved);
+ MPT_ASSERT_NOTREACHED();
+}
+
+void StreamWriterBase::WriteInterleaved(std::size_t frameCount, const int8 *interleaved)
+{
+ MPT_UNREFERENCED_PARAMETER(frameCount);
+ MPT_UNREFERENCED_PARAMETER(interleaved);
+ MPT_ASSERT_NOTREACHED();
+}
+
+void StreamWriterBase::WriteInterleaved(std::size_t frameCount, const uint8 *interleaved)
+{
+ MPT_UNREFERENCED_PARAMETER(frameCount);
+ MPT_UNREFERENCED_PARAMETER(interleaved);
+ MPT_ASSERT_NOTREACHED();
+}
+
+
+void StreamWriterBase::WriteCues(const std::vector<uint64> &cues)
+{
+ MPT_UNREFERENCED_PARAMETER(cues);
+}
+
+
+void StreamWriterBase::WriteFinalize()
+{
+ return;
+}
+
+
+void StreamWriterBase::WriteBuffer()
+{
+ if(!f)
+ {
+ return;
+ }
+ if(buf.empty())
+ {
+ return;
+ }
+ f.write(buf.data(), buf.size());
+ buf.resize(0);
+}
+
+
+void EncoderFactoryBase::SetTraits(const Encoder::Traits &traits)
+{
+ m_Traits = traits;
+}
+
+
+bool EncoderFactoryBase::IsBitrateSupported(int samplerate, int channels, int bitrate) const
+{
+ MPT_UNREFERENCED_PARAMETER(samplerate);
+ MPT_UNREFERENCED_PARAMETER(channels);
+ MPT_UNREFERENCED_PARAMETER(bitrate);
+ return true;
+}
+
+
+mpt::ustring EncoderFactoryBase::DescribeQuality(float quality) const
+{
+ return MPT_UFORMAT("VBR {}%")(static_cast<int>(quality * 100.0f));
+}
+
+mpt::ustring EncoderFactoryBase::DescribeBitrateVBR(int bitrate) const
+{
+ return MPT_UFORMAT("VBR {} kbit")(bitrate);
+}
+
+mpt::ustring EncoderFactoryBase::DescribeBitrateABR(int bitrate) const
+{
+ return MPT_UFORMAT("ABR {} kbit")(bitrate);
+}
+
+mpt::ustring EncoderFactoryBase::DescribeBitrateCBR(int bitrate) const
+{
+ return MPT_UFORMAT("CBR {} kbit")(bitrate);
+}
+
+
+OPENMPT_NAMESPACE_END