1
0

StreamEncoder.h 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. /*
  2. * StreamEncoder.h
  3. * ---------------
  4. * Purpose: Exporting streamed music files.
  5. * Notes : none
  6. * Authors: Joern Heusipp
  7. * OpenMPT Devs
  8. * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
  9. */
  10. #pragma once
  11. #include "openmpt/all/BuildSettings.hpp"
  12. #include "mpt/base/bit.hpp"
  13. #include "openmpt/soundbase/SampleFormat.hpp"
  14. #include "../soundlib/Tagging.h"
  15. #include <iosfwd>
  16. #include <string>
  17. #include <vector>
  18. OPENMPT_NAMESPACE_BEGIN
  19. inline constexpr int opus_bitrates [] = {
  20. 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 192, 224, 256, 320, 384, 448, 510
  21. };
  22. inline constexpr int vorbis_bitrates [] = {
  23. 32, 48, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 500
  24. };
  25. inline constexpr int layer3_bitrates [] = {
  26. 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 192, 224, 256, 320
  27. };
  28. inline constexpr int mpeg1layer3_bitrates [] = {
  29. 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320
  30. };
  31. inline constexpr uint32 opus_samplerates [] = {
  32. 48000,
  33. 24000, 16000,
  34. 12000, 8000
  35. };
  36. inline constexpr uint32 opus_all_samplerates [] = {
  37. 48000, 44100, 32000,
  38. 24000, 22050, 16000,
  39. 12000, 11025, 8000
  40. };
  41. inline constexpr uint32 vorbis_samplerates [] = {
  42. 48000, 44100, 32000,
  43. 24000, 22050, 16000,
  44. 12000, 11025, 8000
  45. };
  46. inline constexpr uint32 layer3_samplerates [] = {
  47. 48000, 44100, 32000,
  48. 24000, 22050, 16000
  49. };
  50. inline constexpr uint32 mpeg1layer3_samplerates [] = {
  51. 48000, 44100, 32000
  52. };
  53. namespace Encoder
  54. {
  55. enum Mode
  56. {
  57. ModeCBR = 1<<0,
  58. ModeABR = 1<<1,
  59. ModeVBR = 1<<2,
  60. ModeQuality = 1<<3,
  61. ModeLossless = 1<<4,
  62. ModeInvalid = 0
  63. };
  64. struct Format
  65. {
  66. enum class Encoding
  67. {
  68. Float = 1,
  69. Integer = 2,
  70. Alaw = 3,
  71. ulaw = 4,
  72. Unsigned = 5,
  73. };
  74. Encoding encoding;
  75. uint8 bits;
  76. mpt::endian endian;
  77. bool operator==(const Format &other) const
  78. {
  79. return encoding == other.encoding && bits == other.bits && endian == other.endian;
  80. }
  81. bool operator!=(const Format& other) const
  82. {
  83. return encoding != other.encoding || bits != other.bits || endian != other.endian;
  84. }
  85. int32 AsInt() const
  86. {
  87. return (static_cast<int32>(endian == mpt::endian::little) << 16) | (static_cast<int32>(encoding) << 8) | static_cast<int32>(bits);
  88. }
  89. static Format FromInt(int32 val)
  90. {
  91. Encoder::Format f;
  92. f.bits = val & 0xff;
  93. f.encoding = static_cast<Encoder::Format::Encoding>((val >> 8) & 0xff);
  94. f.endian = ((val >> 16) & 0xff) ? mpt::endian::little : mpt::endian::big;
  95. return f;
  96. }
  97. SampleFormat GetSampleFormat() const
  98. {
  99. SampleFormat result = SampleFormat::Invalid;
  100. switch(encoding)
  101. {
  102. case Encoding::Float:
  103. switch(bits)
  104. {
  105. case 32:
  106. result = SampleFormat::Float32;
  107. break;
  108. case 64:
  109. result = SampleFormat::Float64;
  110. break;
  111. }
  112. break;
  113. case Encoding::Integer:
  114. switch(bits)
  115. {
  116. case 8:
  117. result = SampleFormat::Int8;
  118. break;
  119. case 16:
  120. result = SampleFormat::Int16;
  121. break;
  122. case 24:
  123. result = SampleFormat::Int24;
  124. break;
  125. case 32:
  126. result = SampleFormat::Int32;
  127. break;
  128. }
  129. break;
  130. case Encoding::Alaw:
  131. switch (bits)
  132. {
  133. case 16:
  134. result = SampleFormat::Int16;
  135. break;
  136. }
  137. break;
  138. case Encoding::ulaw:
  139. switch (bits)
  140. {
  141. case 16:
  142. result = SampleFormat::Int16;
  143. break;
  144. }
  145. break;
  146. case Encoding::Unsigned:
  147. switch (bits)
  148. {
  149. case 8:
  150. result = SampleFormat::Unsigned8;
  151. break;
  152. }
  153. break;
  154. }
  155. return result;
  156. }
  157. };
  158. struct Traits
  159. {
  160. mpt::PathString fileExtension;
  161. mpt::ustring fileShortDescription;
  162. mpt::ustring encoderSettingsName;
  163. mpt::ustring fileDescription;
  164. bool canTags = false;
  165. std::vector<mpt::ustring> genres;
  166. int modesWithFixedGenres = 0;
  167. bool canCues = false;
  168. int maxChannels = 0;
  169. std::vector<uint32> samplerates;
  170. int modes = Encoder::ModeInvalid;
  171. std::vector<int> bitrates;
  172. std::vector<Format> formats;
  173. uint32 defaultSamplerate = 48000;
  174. uint16 defaultChannels = 2;
  175. Encoder::Mode defaultMode = Encoder::ModeInvalid;
  176. int defaultBitrate = 0;
  177. float defaultQuality = 0.0f;
  178. Format defaultFormat = { Encoder::Format::Encoding::Float, 32, mpt::endian::little };
  179. int defaultDitherType = 1;
  180. };
  181. struct StreamSettings
  182. {
  183. int32 FLACCompressionLevel = 5; // 8
  184. uint32 AUPaddingAlignHint = 4096;
  185. uint32 MP3ID3v2MinPadding = 1024;
  186. uint32 MP3ID3v2PaddingAlignHint = 4096;
  187. bool MP3ID3v2WriteReplayGainTXXX = true;
  188. int32 MP3LameQuality = 3; // 0
  189. bool MP3LameID3v2UseLame = false;
  190. bool MP3LameCalculateReplayGain = true;
  191. bool MP3LameCalculatePeakSample = true;
  192. int32 OpusComplexity = -1; // 10
  193. };
  194. struct Settings
  195. {
  196. bool Cues;
  197. bool Tags;
  198. uint32 Samplerate;
  199. uint16 Channels;
  200. Encoder::Mode Mode;
  201. int Bitrate;
  202. float Quality;
  203. Encoder::Format Format;
  204. int Dither;
  205. StreamSettings Details;
  206. };
  207. } // namespace Encoder
  208. class IAudioStreamEncoder
  209. {
  210. protected:
  211. IAudioStreamEncoder() { }
  212. public:
  213. virtual ~IAudioStreamEncoder() = default;
  214. public:
  215. virtual SampleFormat GetSampleFormat() const = 0;
  216. virtual void WriteInterleaved(std::size_t frameCount, const double *interleaved) = 0;
  217. virtual void WriteInterleaved(std::size_t frameCount, const float *interleaved) = 0;
  218. virtual void WriteInterleaved(std::size_t frameCount, const int32 *interleaved) = 0;
  219. virtual void WriteInterleaved(std::size_t frameCount, const int24 *interleaved) = 0;
  220. virtual void WriteInterleaved(std::size_t frameCount, const int16 *interleaved) = 0;
  221. virtual void WriteInterleaved(std::size_t frameCount, const int8 *interleaved) = 0;
  222. virtual void WriteInterleaved(std::size_t frameCount, const uint8 *interleaved) = 0;
  223. virtual void WriteCues(const std::vector<uint64> &cues) = 0; // optional
  224. virtual void WriteFinalize() = 0;
  225. };
  226. std::pair<bool, std::size_t> WriteInterleavedLE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const double *interleaved);
  227. std::pair<bool, std::size_t> WriteInterleavedLE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const float *interleaved);
  228. std::pair<bool, std::size_t> WriteInterleavedLE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const int32 *interleaved);
  229. std::pair<bool, std::size_t> WriteInterleavedLE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const int24 *interleaved);
  230. std::pair<bool, std::size_t> WriteInterleavedLE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const int16 *interleaved);
  231. std::pair<bool, std::size_t> WriteInterleavedLE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const int8 *interleaved);
  232. std::pair<bool, std::size_t> WriteInterleavedLE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const uint8 *interleaved);
  233. std::pair<bool, std::size_t> WriteInterleavedBE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const double *interleaved);
  234. std::pair<bool, std::size_t> WriteInterleavedBE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const float *interleaved);
  235. std::pair<bool, std::size_t> WriteInterleavedBE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const int32 *interleaved);
  236. std::pair<bool, std::size_t> WriteInterleavedBE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const int24 *interleaved);
  237. std::pair<bool, std::size_t> WriteInterleavedBE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const int16 *interleaved);
  238. std::pair<bool, std::size_t> WriteInterleavedBE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const int8 *interleaved);
  239. std::pair<bool, std::size_t> WriteInterleavedBE(std::ostream &f, uint16 channels, Encoder::Format format, std::size_t frameCount, const uint8 *interleaved);
  240. class StreamWriterBase
  241. : public IAudioStreamEncoder
  242. {
  243. protected:
  244. std::ostream &f;
  245. std::streampos fStart;
  246. std::vector<char> buf;
  247. public:
  248. StreamWriterBase(std::ostream &stream);
  249. virtual ~StreamWriterBase();
  250. public:
  251. SampleFormat GetSampleFormat() const override;
  252. void WriteInterleaved(std::size_t frameCount, const double *interleaved) override;
  253. void WriteInterleaved(std::size_t frameCount, const float *interleaved) override;
  254. void WriteInterleaved(std::size_t frameCount, const int32 *interleaved) override;
  255. void WriteInterleaved(std::size_t frameCount, const int24 *interleaved) override;
  256. void WriteInterleaved(std::size_t frameCount, const int16 *interleaved) override;
  257. void WriteInterleaved(std::size_t frameCount, const int8 *interleaved) override;
  258. void WriteInterleaved(std::size_t frameCount, const uint8 *interleaved) override;
  259. void WriteCues(const std::vector<uint64> &cues) override;
  260. void WriteFinalize() override;
  261. protected:
  262. void WriteBuffer();
  263. };
  264. class EncoderFactoryBase
  265. {
  266. private:
  267. Encoder::Traits m_Traits;
  268. protected:
  269. EncoderFactoryBase() { }
  270. virtual ~EncoderFactoryBase() = default;
  271. void SetTraits(const Encoder::Traits &traits);
  272. public:
  273. virtual std::unique_ptr<IAudioStreamEncoder> ConstructStreamEncoder(std::ostream &file, const Encoder::Settings &settings, const FileTags &tags) const = 0;
  274. const Encoder::Traits &GetTraits() const
  275. {
  276. return m_Traits;
  277. }
  278. virtual bool IsBitrateSupported(int samplerate, int channels, int bitrate) const;
  279. virtual mpt::ustring DescribeQuality(float quality) const;
  280. virtual mpt::ustring DescribeBitrateVBR(int bitrate) const;
  281. virtual mpt::ustring DescribeBitrateABR(int bitrate) const;
  282. virtual mpt::ustring DescribeBitrateCBR(int bitrate) const;
  283. virtual bool IsAvailable() const = 0;
  284. };
  285. OPENMPT_NAMESPACE_END