diff options
Diffstat (limited to 'Src/external_dependencies/openmpt-trunk/mptrack/StreamEncoder.h')
-rw-r--r-- | Src/external_dependencies/openmpt-trunk/mptrack/StreamEncoder.h | 328 |
1 files changed, 328 insertions, 0 deletions
diff --git a/Src/external_dependencies/openmpt-trunk/mptrack/StreamEncoder.h b/Src/external_dependencies/openmpt-trunk/mptrack/StreamEncoder.h new file mode 100644 index 00000000..a2322c26 --- /dev/null +++ b/Src/external_dependencies/openmpt-trunk/mptrack/StreamEncoder.h @@ -0,0 +1,328 @@ +/* + * StreamEncoder.h + * --------------- + * 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. + */ + +#pragma once + +#include "openmpt/all/BuildSettings.hpp" + +#include "mpt/base/bit.hpp" +#include "openmpt/soundbase/SampleFormat.hpp" +#include "../soundlib/Tagging.h" + +#include <iosfwd> +#include <string> +#include <vector> + + +OPENMPT_NAMESPACE_BEGIN + + + +inline constexpr int opus_bitrates [] = { + 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 192, 224, 256, 320, 384, 448, 510 +}; +inline constexpr int vorbis_bitrates [] = { + 32, 48, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 500 +}; +inline constexpr int layer3_bitrates [] = { + 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 192, 224, 256, 320 +}; +inline constexpr int mpeg1layer3_bitrates [] = { + 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 +}; +inline constexpr uint32 opus_samplerates [] = { + 48000, + 24000, 16000, + 12000, 8000 +}; +inline constexpr uint32 opus_all_samplerates [] = { + 48000, 44100, 32000, + 24000, 22050, 16000, + 12000, 11025, 8000 +}; +inline constexpr uint32 vorbis_samplerates [] = { + 48000, 44100, 32000, + 24000, 22050, 16000, + 12000, 11025, 8000 +}; +inline constexpr uint32 layer3_samplerates [] = { + 48000, 44100, 32000, + 24000, 22050, 16000 +}; +inline constexpr uint32 mpeg1layer3_samplerates [] = { + 48000, 44100, 32000 +}; + + +namespace Encoder +{ + + enum Mode + { + ModeCBR = 1<<0, + ModeABR = 1<<1, + ModeVBR = 1<<2, + ModeQuality = 1<<3, + ModeLossless = 1<<4, + ModeInvalid = 0 + }; + + struct Format + { + enum class Encoding + { + Float = 1, + Integer = 2, + Alaw = 3, + ulaw = 4, + Unsigned = 5, + }; + Encoding encoding; + uint8 bits; + mpt::endian endian; + bool operator==(const Format &other) const + { + return encoding == other.encoding && bits == other.bits && endian == other.endian; + } + bool operator!=(const Format& other) const + { + return encoding != other.encoding || bits != other.bits || endian != other.endian; + } + int32 AsInt() const + { + return (static_cast<int32>(endian == mpt::endian::little) << 16) | (static_cast<int32>(encoding) << 8) | static_cast<int32>(bits); + } + static Format FromInt(int32 val) + { + Encoder::Format f; + f.bits = val & 0xff; + f.encoding = static_cast<Encoder::Format::Encoding>((val >> 8) & 0xff); + f.endian = ((val >> 16) & 0xff) ? mpt::endian::little : mpt::endian::big; + return f; + } + SampleFormat GetSampleFormat() const + { + SampleFormat result = SampleFormat::Invalid; + switch(encoding) + { + case Encoding::Float: + switch(bits) + { + case 32: + result = SampleFormat::Float32; + break; + case 64: + result = SampleFormat::Float64; + break; + } + break; + case Encoding::Integer: + switch(bits) + { + case 8: + result = SampleFormat::Int8; + break; + case 16: + result = SampleFormat::Int16; + break; + case 24: + result = SampleFormat::Int24; + break; + case 32: + result = SampleFormat::Int32; + break; + } + break; + case Encoding::Alaw: + switch (bits) + { + case 16: + result = SampleFormat::Int16; + break; + } + break; + case Encoding::ulaw: + switch (bits) + { + case 16: + result = SampleFormat::Int16; + break; + } + break; + case Encoding::Unsigned: + switch (bits) + { + case 8: + result = SampleFormat::Unsigned8; + break; + } + break; + } + return result; + } + }; + + struct Traits + { + + mpt::PathString fileExtension; + mpt::ustring fileShortDescription; + mpt::ustring encoderSettingsName; + + mpt::ustring fileDescription; + + bool canTags = false; + std::vector<mpt::ustring> genres; + int modesWithFixedGenres = 0; + + bool canCues = false; + + int maxChannels = 0; + std::vector<uint32> samplerates; + + int modes = Encoder::ModeInvalid; + std::vector<int> bitrates; + std::vector<Format> formats; + + uint32 defaultSamplerate = 48000; + uint16 defaultChannels = 2; + + Encoder::Mode defaultMode = Encoder::ModeInvalid; + int defaultBitrate = 0; + float defaultQuality = 0.0f; + Format defaultFormat = { Encoder::Format::Encoding::Float, 32, mpt::endian::little }; + int defaultDitherType = 1; + }; + + struct StreamSettings + { + int32 FLACCompressionLevel = 5; // 8 + uint32 AUPaddingAlignHint = 4096; + uint32 MP3ID3v2MinPadding = 1024; + uint32 MP3ID3v2PaddingAlignHint = 4096; + bool MP3ID3v2WriteReplayGainTXXX = true; + int32 MP3LameQuality = 3; // 0 + bool MP3LameID3v2UseLame = false; + bool MP3LameCalculateReplayGain = true; + bool MP3LameCalculatePeakSample = true; + int32 OpusComplexity = -1; // 10 + }; + + struct Settings + { + + bool Cues; + bool Tags; + + uint32 Samplerate; + uint16 Channels; + + Encoder::Mode Mode; + int Bitrate; + float Quality; + Encoder::Format Format; + int Dither; + + StreamSettings Details; + + }; + +} // namespace Encoder + + +class IAudioStreamEncoder +{ +protected: + IAudioStreamEncoder() { } +public: + virtual ~IAudioStreamEncoder() = default; +public: + virtual SampleFormat GetSampleFormat() const = 0; + virtual void WriteInterleaved(std::size_t frameCount, const double *interleaved) = 0; + virtual void WriteInterleaved(std::size_t frameCount, const float *interleaved) = 0; + virtual void WriteInterleaved(std::size_t frameCount, const int32 *interleaved) = 0; + virtual void WriteInterleaved(std::size_t frameCount, const int24 *interleaved) = 0; + virtual void WriteInterleaved(std::size_t frameCount, const int16 *interleaved) = 0; + virtual void WriteInterleaved(std::size_t frameCount, const int8 *interleaved) = 0; + virtual void WriteInterleaved(std::size_t frameCount, const uint8 *interleaved) = 0; + virtual void WriteCues(const std::vector<uint64> &cues) = 0; // optional + virtual void WriteFinalize() = 0; +}; + + + +std::pair<bool, std::size_t> WriteInterleavedLE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const double *interleaved); +std::pair<bool, std::size_t> WriteInterleavedLE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const float *interleaved); +std::pair<bool, std::size_t> WriteInterleavedLE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const int32 *interleaved); +std::pair<bool, std::size_t> WriteInterleavedLE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const int24 *interleaved); +std::pair<bool, std::size_t> WriteInterleavedLE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const int16 *interleaved); +std::pair<bool, std::size_t> WriteInterleavedLE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const int8 *interleaved); +std::pair<bool, std::size_t> WriteInterleavedLE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const uint8 *interleaved); + +std::pair<bool, std::size_t> WriteInterleavedBE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const double *interleaved); +std::pair<bool, std::size_t> WriteInterleavedBE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const float *interleaved); +std::pair<bool, std::size_t> WriteInterleavedBE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const int32 *interleaved); +std::pair<bool, std::size_t> WriteInterleavedBE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const int24 *interleaved); +std::pair<bool, std::size_t> WriteInterleavedBE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const int16 *interleaved); +std::pair<bool, std::size_t> WriteInterleavedBE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const int8 *interleaved); +std::pair<bool, std::size_t> WriteInterleavedBE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const uint8 *interleaved); + + + +class StreamWriterBase + : public IAudioStreamEncoder +{ +protected: + std::ostream &f; + std::streampos fStart; + std::vector<char> buf; +public: + StreamWriterBase(std::ostream &stream); + virtual ~StreamWriterBase(); +public: + SampleFormat GetSampleFormat() const override; + void WriteInterleaved(std::size_t frameCount, const double *interleaved) override; + void WriteInterleaved(std::size_t frameCount, const float *interleaved) override; + void WriteInterleaved(std::size_t frameCount, const int32 *interleaved) override; + void WriteInterleaved(std::size_t frameCount, const int24 *interleaved) override; + void WriteInterleaved(std::size_t frameCount, const int16 *interleaved) override; + void WriteInterleaved(std::size_t frameCount, const int8 *interleaved) override; + void WriteInterleaved(std::size_t frameCount, const uint8 *interleaved) override; + void WriteCues(const std::vector<uint64> &cues) override; + void WriteFinalize() override; +protected: + void WriteBuffer(); +}; + + +class EncoderFactoryBase +{ +private: + Encoder::Traits m_Traits; +protected: + EncoderFactoryBase() { } + virtual ~EncoderFactoryBase() = default; + void SetTraits(const Encoder::Traits &traits); +public: + virtual std::unique_ptr<IAudioStreamEncoder> ConstructStreamEncoder(std::ostream &file, const Encoder::Settings &settings, const FileTags &tags) const = 0; + const Encoder::Traits &GetTraits() const + { + return m_Traits; + } + virtual bool IsBitrateSupported(int samplerate, int channels, int bitrate) const; + virtual mpt::ustring DescribeQuality(float quality) const; + virtual mpt::ustring DescribeBitrateVBR(int bitrate) const; + virtual mpt::ustring DescribeBitrateABR(int bitrate) const; + virtual mpt::ustring DescribeBitrateCBR(int bitrate) const; + virtual bool IsAvailable() const = 0; +}; + + +OPENMPT_NAMESPACE_END |