SampleFormatFLAC.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729
  1. /*
  2. * SampleFormatFLAC.cpp
  3. * --------------------
  4. * Purpose: FLAC sample import.
  5. * Notes :
  6. * Authors: OpenMPT Devs
  7. * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
  8. */
  9. #include "stdafx.h"
  10. #include "Sndfile.h"
  11. #ifdef MODPLUG_TRACKER
  12. #include "../mptrack/TrackerSettings.h"
  13. #endif //MODPLUG_TRACKER
  14. #ifndef MODPLUG_NO_FILESAVE
  15. #include "../common/mptFileIO.h"
  16. #endif
  17. #include "../common/misc_util.h"
  18. #include "Tagging.h"
  19. #include "Loaders.h"
  20. #include "WAVTools.h"
  21. #include "../common/FileReader.h"
  22. #include "modsmp_ctrl.h"
  23. #include "openmpt/soundbase/Copy.hpp"
  24. #include "openmpt/soundbase/SampleConvert.hpp"
  25. #include "openmpt/soundbase/SampleDecode.hpp"
  26. #include "../soundlib/SampleCopy.h"
  27. #include "../soundlib/ModSampleCopy.h"
  28. #include "mpt/io/base.hpp"
  29. #include "mpt/io/io.hpp"
  30. #include "mpt/io/io_stdstream.hpp"
  31. //#include "mpt/crc/crc.hpp"
  32. #include "OggStream.h"
  33. #ifdef MPT_WITH_OGG
  34. #if MPT_COMPILER_CLANG
  35. #pragma clang diagnostic push
  36. #pragma clang diagnostic ignored "-Wreserved-id-macro"
  37. #endif // MPT_COMPILER_CLANG
  38. #include <ogg/ogg.h>
  39. #if MPT_COMPILER_CLANG
  40. #pragma clang diagnostic pop
  41. #endif // MPT_COMPILER_CLANG
  42. #endif // MPT_WITH_OGG
  43. #ifdef MPT_WITH_FLAC
  44. #if MPT_COMPILER_CLANG
  45. #pragma clang diagnostic push
  46. #pragma clang diagnostic ignored "-Wreserved-id-macro"
  47. #endif // MPT_COMPILER_CLANG
  48. #include <FLAC/stream_decoder.h>
  49. #include <FLAC/stream_encoder.h>
  50. #include <FLAC/metadata.h>
  51. #if MPT_COMPILER_CLANG
  52. #pragma clang diagnostic pop
  53. #endif // MPT_COMPILER_CLANG
  54. #endif // MPT_WITH_FLAC
  55. OPENMPT_NAMESPACE_BEGIN
  56. ///////////////////////////////////////////////////////////////////////////////////////////////////
  57. // FLAC Samples
  58. #ifdef MPT_WITH_FLAC
  59. struct FLACDecoder
  60. {
  61. FileReader &file;
  62. CSoundFile &sndFile;
  63. SAMPLEINDEX sample;
  64. bool ready;
  65. FLACDecoder(FileReader &f, CSoundFile &sf, SAMPLEINDEX smp) : file(f), sndFile(sf), sample(smp), ready(false) { }
  66. static FLAC__StreamDecoderReadStatus read_cb(const FLAC__StreamDecoder *, FLAC__byte buffer[], size_t *bytes, void *client_data)
  67. {
  68. FileReader &file = static_cast<FLACDecoder *>(client_data)->file;
  69. if(*bytes > 0)
  70. {
  71. FileReader::off_t readBytes = *bytes;
  72. LimitMax(readBytes, file.BytesLeft());
  73. file.ReadRaw(mpt::byte_cast<mpt::byte_span>(mpt::span(buffer, readBytes)));
  74. *bytes = readBytes;
  75. if(*bytes == 0)
  76. return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
  77. else
  78. return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
  79. } else
  80. {
  81. return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
  82. }
  83. }
  84. static FLAC__StreamDecoderSeekStatus seek_cb(const FLAC__StreamDecoder *, FLAC__uint64 absolute_byte_offset, void *client_data)
  85. {
  86. FileReader &file = static_cast<FLACDecoder *>(client_data)->file;
  87. if(!file.Seek(static_cast<FileReader::off_t>(absolute_byte_offset)))
  88. return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
  89. else
  90. return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
  91. }
  92. static FLAC__StreamDecoderTellStatus tell_cb(const FLAC__StreamDecoder *, FLAC__uint64 *absolute_byte_offset, void *client_data)
  93. {
  94. FileReader &file = static_cast<FLACDecoder *>(client_data)->file;
  95. *absolute_byte_offset = file.GetPosition();
  96. return FLAC__STREAM_DECODER_TELL_STATUS_OK;
  97. }
  98. static FLAC__StreamDecoderLengthStatus length_cb(const FLAC__StreamDecoder *, FLAC__uint64 *stream_length, void *client_data)
  99. {
  100. FileReader &file = static_cast<FLACDecoder *>(client_data)->file;
  101. *stream_length = file.GetLength();
  102. return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
  103. }
  104. static FLAC__bool eof_cb(const FLAC__StreamDecoder *, void *client_data)
  105. {
  106. FileReader &file = static_cast<FLACDecoder *>(client_data)->file;
  107. return file.NoBytesLeft();
  108. }
  109. static FLAC__StreamDecoderWriteStatus write_cb(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *const buffer[], void *client_data)
  110. {
  111. FLACDecoder &client = *static_cast<FLACDecoder *>(client_data);
  112. ModSample &sample = client.sndFile.GetSample(client.sample);
  113. if(frame->header.number.sample_number >= sample.nLength || !client.ready)
  114. {
  115. // We're reading beyond the sample size already, or we aren't even ready to decode yet!
  116. return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
  117. }
  118. // Number of samples to be copied in this call
  119. const SmpLength copySamples = std::min(static_cast<SmpLength>(frame->header.blocksize), static_cast<SmpLength>(sample.nLength - frame->header.number.sample_number));
  120. // Number of target channels
  121. const uint8 modChannels = sample.GetNumChannels();
  122. // Offset (in samples) into target data
  123. const size_t offset = static_cast<size_t>(frame->header.number.sample_number) * modChannels;
  124. // Source size in bytes
  125. const size_t srcSize = frame->header.blocksize * 4;
  126. // Source bit depth
  127. const unsigned int bps = frame->header.bits_per_sample;
  128. MPT_ASSERT((bps <= 8 && sample.GetElementarySampleSize() == 1) || (bps > 8 && sample.GetElementarySampleSize() == 2));
  129. MPT_ASSERT(modChannels <= FLAC__stream_decoder_get_channels(decoder));
  130. MPT_ASSERT(bps == FLAC__stream_decoder_get_bits_per_sample(decoder));
  131. MPT_UNREFERENCED_PARAMETER(decoder); // decoder is unused if ASSERTs are compiled out
  132. // Do the sample conversion
  133. for(uint8 chn = 0; chn < modChannels; chn++)
  134. {
  135. if(bps <= 8)
  136. {
  137. int8 *sampleData8 = sample.sample8() + offset;
  138. CopySample<SC::ConversionChain<SC::ConvertShift< int8, int32, 0>, SC::DecodeIdentity<int32> > >(sampleData8 + chn, copySamples, modChannels, buffer[chn], srcSize, 1);
  139. } else if(bps <= 16)
  140. {
  141. int16 *sampleData16 = sample.sample16() + offset;
  142. CopySample<SC::ConversionChain<SC::ConvertShift<int16, int32, 0>, SC::DecodeIdentity<int32> > >(sampleData16 + chn, copySamples, modChannels, buffer[chn], srcSize, 1);
  143. } else if(bps <= 24)
  144. {
  145. int16 *sampleData16 = sample.sample16() + offset;
  146. CopySample<SC::ConversionChain<SC::ConvertShift<int16, int32, 8>, SC::DecodeIdentity<int32> > >(sampleData16 + chn, copySamples, modChannels, buffer[chn], srcSize, 1);
  147. } else if(bps <= 32)
  148. {
  149. int16 *sampleData16 = sample.sample16() + offset;
  150. CopySample<SC::ConversionChain<SC::ConvertShift<int16, int32, 16>, SC::DecodeIdentity<int32> > >(sampleData16 + chn, copySamples, modChannels, buffer[chn], srcSize, 1);
  151. }
  152. }
  153. return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
  154. }
  155. static void metadata_cb(const FLAC__StreamDecoder *, const FLAC__StreamMetadata *metadata, void *client_data)
  156. {
  157. FLACDecoder &client = *static_cast<FLACDecoder *>(client_data);
  158. if(client.sample > client.sndFile.GetNumSamples())
  159. {
  160. client.sndFile.m_nSamples = client.sample;
  161. }
  162. ModSample &sample = client.sndFile.GetSample(client.sample);
  163. if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO && metadata->data.stream_info.total_samples != 0)
  164. {
  165. // Init sample information
  166. client.sndFile.DestroySampleThreadsafe(client.sample);
  167. client.sndFile.m_szNames[client.sample] = "";
  168. sample.Initialize();
  169. sample.uFlags.set(CHN_16BIT, metadata->data.stream_info.bits_per_sample > 8);
  170. sample.uFlags.set(CHN_STEREO, metadata->data.stream_info.channels > 1);
  171. sample.nLength = mpt::saturate_cast<SmpLength>(metadata->data.stream_info.total_samples);
  172. LimitMax(sample.nLength, MAX_SAMPLE_LENGTH);
  173. sample.nC5Speed = metadata->data.stream_info.sample_rate;
  174. client.ready = (sample.AllocateSample() != 0);
  175. } else if(metadata->type == FLAC__METADATA_TYPE_APPLICATION && !memcmp(metadata->data.application.id, "riff", 4) && client.ready)
  176. {
  177. // Try reading RIFF loop points and other sample information
  178. FileReader data(mpt::as_span(metadata->data.application.data, metadata->length));
  179. FileReader::ChunkList<RIFFChunk> chunks = data.ReadChunks<RIFFChunk>(2);
  180. // We're not really going to read a WAV file here because there will be only one RIFF chunk per metadata event, but we can still re-use the code for parsing RIFF metadata...
  181. WAVReader riffReader(data);
  182. riffReader.FindMetadataChunks(chunks);
  183. riffReader.ApplySampleSettings(sample, client.sndFile.GetCharsetInternal(), client.sndFile.m_szNames[client.sample]);
  184. } else if(metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT && client.ready)
  185. {
  186. // Try reading Vorbis Comments for sample title, sample rate and loop points
  187. SmpLength loopStart = 0, loopLength = 0;
  188. for(FLAC__uint32 i = 0; i < metadata->data.vorbis_comment.num_comments; i++)
  189. {
  190. const char *tag = mpt::byte_cast<const char *>(metadata->data.vorbis_comment.comments[i].entry);
  191. const FLAC__uint32 length = metadata->data.vorbis_comment.comments[i].length;
  192. if(length > 6 && !mpt::CompareNoCaseAscii(tag, "TITLE=", 6))
  193. {
  194. client.sndFile.m_szNames[client.sample] = mpt::ToCharset(client.sndFile.GetCharsetInternal(), mpt::Charset::UTF8, mpt::String::ReadBuf(mpt::String::maybeNullTerminated, tag + 6, length - 6));
  195. } else if(length > 11 && !mpt::CompareNoCaseAscii(tag, "SAMPLERATE=", 11))
  196. {
  197. uint32 sampleRate = ConvertStrTo<uint32>(tag + 11);
  198. if(sampleRate > 0) sample.nC5Speed = sampleRate;
  199. } else if(length > 10 && !mpt::CompareNoCaseAscii(tag, "LOOPSTART=", 10))
  200. {
  201. loopStart = ConvertStrTo<SmpLength>(tag + 10);
  202. } else if(length > 11 && !mpt::CompareNoCaseAscii(tag, "LOOPLENGTH=", 11))
  203. {
  204. loopLength = ConvertStrTo<SmpLength>(tag + 11);
  205. }
  206. }
  207. if(loopLength > 0)
  208. {
  209. sample.nLoopStart = loopStart;
  210. sample.nLoopEnd = loopStart + loopLength;
  211. sample.uFlags.set(CHN_LOOP);
  212. sample.SanitizeLoops();
  213. }
  214. }
  215. }
  216. static void error_cb(const FLAC__StreamDecoder *, FLAC__StreamDecoderErrorStatus, void *)
  217. {
  218. }
  219. };
  220. #endif // MPT_WITH_FLAC
  221. bool CSoundFile::ReadFLACSample(SAMPLEINDEX sample, FileReader &file)
  222. {
  223. #ifdef MPT_WITH_FLAC
  224. file.Rewind();
  225. bool isOgg = false;
  226. #ifdef MPT_WITH_OGG
  227. uint32 oggFlacBitstreamSerial = 0;
  228. #endif
  229. // Check whether we are dealing with native FLAC, OggFlac or no FLAC at all.
  230. if(file.ReadMagic("fLaC"))
  231. { // ok
  232. isOgg = false;
  233. #ifdef MPT_WITH_OGG
  234. } else if(file.ReadMagic("OggS"))
  235. { // use libogg to find the first OggFlac stream header
  236. file.Rewind();
  237. bool oggOK = false;
  238. bool needMoreData = true;
  239. constexpr long bufsize = 65536;
  240. std::size_t readSize = 0;
  241. char *buf = nullptr;
  242. ogg_sync_state oy;
  243. MemsetZero(oy);
  244. ogg_page og;
  245. MemsetZero(og);
  246. std::map<uint32, ogg_stream_state*> oggStreams;
  247. ogg_packet op;
  248. MemsetZero(op);
  249. if(ogg_sync_init(&oy) != 0)
  250. {
  251. return false;
  252. }
  253. while(needMoreData)
  254. {
  255. if(file.NoBytesLeft())
  256. { // stop at EOF
  257. oggOK = false;
  258. needMoreData = false;
  259. break;
  260. }
  261. buf = ogg_sync_buffer(&oy, bufsize);
  262. if(!buf)
  263. {
  264. oggOK = false;
  265. needMoreData = false;
  266. break;
  267. }
  268. readSize = file.ReadRaw(mpt::span(buf, bufsize)).size();
  269. if(ogg_sync_wrote(&oy, static_cast<long>(readSize)) != 0)
  270. {
  271. oggOK = false;
  272. needMoreData = false;
  273. break;
  274. }
  275. while(ogg_sync_pageout(&oy, &og) == 1)
  276. {
  277. if(!ogg_page_bos(&og))
  278. { // we stop scanning when seeing the first noo-begin-of-stream page
  279. oggOK = false;
  280. needMoreData = false;
  281. break;
  282. }
  283. uint32 serial = ogg_page_serialno(&og);
  284. if(!oggStreams[serial])
  285. { // previously unseen stream serial
  286. oggStreams[serial] = new ogg_stream_state();
  287. MemsetZero(*(oggStreams[serial]));
  288. if(ogg_stream_init(oggStreams[serial], serial) != 0)
  289. {
  290. delete oggStreams[serial];
  291. oggStreams.erase(serial);
  292. oggOK = false;
  293. needMoreData = false;
  294. break;
  295. }
  296. }
  297. if(ogg_stream_pagein(oggStreams[serial], &og) != 0)
  298. { // invalid page
  299. oggOK = false;
  300. needMoreData = false;
  301. break;
  302. }
  303. if(ogg_stream_packetout(oggStreams[serial], &op) != 1)
  304. { // partial or broken packet, continue with more data
  305. continue;
  306. }
  307. if(op.packetno != 0)
  308. { // non-begin-of-stream packet.
  309. // This should not appear on first page for any known ogg codec,
  310. // but deal gracefully with badly mused streams in that regard.
  311. continue;
  312. }
  313. FileReader packet(mpt::as_span(op.packet, op.bytes));
  314. if(packet.ReadIntLE<uint8>() == 0x7f && packet.ReadMagic("FLAC"))
  315. { // looks like OggFlac
  316. oggOK = true;
  317. oggFlacBitstreamSerial = serial;
  318. needMoreData = false;
  319. break;
  320. }
  321. }
  322. }
  323. while(oggStreams.size() > 0)
  324. {
  325. uint32 serial = oggStreams.begin()->first;
  326. ogg_stream_clear(oggStreams[serial]);
  327. delete oggStreams[serial];
  328. oggStreams.erase(serial);
  329. }
  330. ogg_sync_clear(&oy);
  331. if(!oggOK)
  332. {
  333. return false;
  334. }
  335. isOgg = true;
  336. #else // !MPT_WITH_OGG
  337. } else if(file.CanRead(78) && file.ReadMagic("OggS"))
  338. { // first OggFlac page is exactly 78 bytes long
  339. // only support plain OggFlac here with the FLAC logical bitstream being the first one
  340. uint8 oggPageVersion = file.ReadIntLE<uint8>();
  341. uint8 oggPageHeaderType = file.ReadIntLE<uint8>();
  342. uint64 oggPageGranulePosition = file.ReadIntLE<uint64>();
  343. uint32 oggPageBitstreamSerialNumber = file.ReadIntLE<uint32>();
  344. uint32 oggPageSequenceNumber = file.ReadIntLE<uint32>();
  345. uint32 oggPageChecksum = file.ReadIntLE<uint32>();
  346. uint8 oggPageSegments = file.ReadIntLE<uint8>();
  347. uint8 oggPageSegmentLength = file.ReadIntLE<uint8>();
  348. if(oggPageVersion != 0)
  349. { // unknown Ogg version
  350. return false;
  351. }
  352. if(!(oggPageHeaderType & 0x02) || (oggPageHeaderType& 0x01))
  353. { // not BOS or continuation
  354. return false;
  355. }
  356. if(oggPageGranulePosition != 0)
  357. { // not starting position
  358. return false;
  359. }
  360. if(oggPageSequenceNumber != 0)
  361. { // not first page
  362. return false;
  363. }
  364. // skip CRC check for now
  365. if(oggPageSegments != 1)
  366. { // first OggFlac page must contain exactly 1 segment
  367. return false;
  368. }
  369. if(oggPageSegmentLength != 51)
  370. { // segment length must be 51 bytes in OggFlac mapping
  371. return false;
  372. }
  373. if(file.ReadIntLE<uint8>() != 0x7f)
  374. { // OggFlac mapping demands 0x7f packet type
  375. return false;
  376. }
  377. if(!file.ReadMagic("FLAC"))
  378. { // OggFlac magic
  379. return false;
  380. }
  381. if(file.ReadIntLE<uint8>() != 0x01)
  382. { // OggFlac major version
  383. return false;
  384. }
  385. // by now, we are pretty confident that we are not parsing random junk
  386. isOgg = true;
  387. #endif // MPT_WITH_OGG
  388. } else
  389. {
  390. return false;
  391. }
  392. file.Rewind();
  393. FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new();
  394. if(decoder == nullptr)
  395. {
  396. return false;
  397. }
  398. #ifdef MPT_WITH_OGG
  399. if(isOgg)
  400. {
  401. // force flac decoding of the logical bitstream that actually is OggFlac
  402. if(!FLAC__stream_decoder_set_ogg_serial_number(decoder, oggFlacBitstreamSerial))
  403. {
  404. FLAC__stream_decoder_delete(decoder);
  405. return false;
  406. }
  407. }
  408. #endif
  409. // Give me all the metadata!
  410. FLAC__stream_decoder_set_metadata_respond_all(decoder);
  411. FLACDecoder client(file, *this, sample);
  412. // Init decoder
  413. FLAC__StreamDecoderInitStatus initStatus = isOgg ?
  414. FLAC__stream_decoder_init_ogg_stream(decoder, FLACDecoder::read_cb, FLACDecoder::seek_cb, FLACDecoder::tell_cb, FLACDecoder::length_cb, FLACDecoder::eof_cb, FLACDecoder::write_cb, FLACDecoder::metadata_cb, FLACDecoder::error_cb, &client)
  415. :
  416. FLAC__stream_decoder_init_stream(decoder, FLACDecoder::read_cb, FLACDecoder::seek_cb, FLACDecoder::tell_cb, FLACDecoder::length_cb, FLACDecoder::eof_cb, FLACDecoder::write_cb, FLACDecoder::metadata_cb, FLACDecoder::error_cb, &client)
  417. ;
  418. if(initStatus != FLAC__STREAM_DECODER_INIT_STATUS_OK)
  419. {
  420. FLAC__stream_decoder_delete(decoder);
  421. return false;
  422. }
  423. // Decode file
  424. FLAC__stream_decoder_process_until_end_of_stream(decoder);
  425. FLAC__stream_decoder_finish(decoder);
  426. FLAC__stream_decoder_delete(decoder);
  427. if(client.ready && Samples[sample].HasSampleData())
  428. {
  429. Samples[sample].Convert(MOD_TYPE_IT, GetType());
  430. Samples[sample].PrecomputeLoops(*this, false);
  431. return true;
  432. }
  433. #else
  434. MPT_UNREFERENCED_PARAMETER(sample);
  435. MPT_UNREFERENCED_PARAMETER(file);
  436. #endif // MPT_WITH_FLAC
  437. return false;
  438. }
  439. #ifdef MPT_WITH_FLAC
  440. // RAII-style helper struct for FLAC encoder
  441. struct FLAC__StreamEncoder_RAII
  442. {
  443. std::ostream &f;
  444. FLAC__StreamEncoder *encoder = nullptr;
  445. operator FLAC__StreamEncoder *() { return encoder; }
  446. FLAC__StreamEncoder_RAII(std::ostream &f_) : f(f_), encoder(FLAC__stream_encoder_new()) { }
  447. ~FLAC__StreamEncoder_RAII()
  448. {
  449. FLAC__stream_encoder_delete(encoder);
  450. }
  451. static FLAC__StreamEncoderWriteStatus StreamEncoderWriteCallback(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data)
  452. {
  453. mpt::ofstream & file = *reinterpret_cast<mpt::ofstream*>(client_data);
  454. MPT_UNUSED_VARIABLE(encoder);
  455. MPT_UNUSED_VARIABLE(samples);
  456. MPT_UNUSED_VARIABLE(current_frame);
  457. if(!mpt::IO::WriteRaw(file, mpt::as_span(buffer, bytes)))
  458. {
  459. return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
  460. }
  461. return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
  462. }
  463. static FLAC__StreamEncoderSeekStatus StreamEncoderSeekCallback(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data)
  464. {
  465. mpt::ofstream & file = *reinterpret_cast<mpt::ofstream*>(client_data);
  466. MPT_UNUSED_VARIABLE(encoder);
  467. if(!mpt::in_range<mpt::IO::Offset>(absolute_byte_offset))
  468. {
  469. return FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR;
  470. }
  471. if(!mpt::IO::SeekAbsolute(file, static_cast<mpt::IO::Offset>(absolute_byte_offset)))
  472. {
  473. return FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR;
  474. }
  475. return FLAC__STREAM_ENCODER_SEEK_STATUS_OK;
  476. }
  477. static FLAC__StreamEncoderTellStatus StreamEncoderTellCallback(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
  478. {
  479. mpt::ofstream & file = *reinterpret_cast<mpt::ofstream*>(client_data);
  480. MPT_UNUSED_VARIABLE(encoder);
  481. mpt::IO::Offset pos = mpt::IO::TellWrite(file);
  482. if(pos < 0)
  483. {
  484. return FLAC__STREAM_ENCODER_TELL_STATUS_ERROR;
  485. }
  486. if(!mpt::in_range<FLAC__uint64>(pos))
  487. {
  488. return FLAC__STREAM_ENCODER_TELL_STATUS_ERROR;
  489. }
  490. *absolute_byte_offset = static_cast<FLAC__uint64>(pos);
  491. return FLAC__STREAM_ENCODER_TELL_STATUS_OK;
  492. }
  493. };
  494. class FLAC__StreamMetadata_RAII : public std::vector<FLAC__StreamMetadata *>
  495. {
  496. public:
  497. FLAC__StreamMetadata_RAII(std::initializer_list<FLAC__StreamMetadata *> init)
  498. : std::vector<FLAC__StreamMetadata *>(init)
  499. { }
  500. ~FLAC__StreamMetadata_RAII()
  501. {
  502. for(auto m : *this)
  503. {
  504. FLAC__metadata_object_delete(m);
  505. }
  506. }
  507. };
  508. #endif
  509. #ifndef MODPLUG_NO_FILESAVE
  510. bool CSoundFile::SaveFLACSample(SAMPLEINDEX nSample, std::ostream &f) const
  511. {
  512. #ifdef MPT_WITH_FLAC
  513. const ModSample &sample = Samples[nSample];
  514. if(sample.uFlags[CHN_ADLIB])
  515. return false;
  516. FLAC__StreamEncoder_RAII encoder(f);
  517. if(encoder == nullptr)
  518. return false;
  519. uint32 sampleRate = sample.GetSampleRate(GetType());
  520. // First off, set up all the metadata...
  521. FLAC__StreamMetadata_RAII metadata =
  522. {
  523. FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT),
  524. FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION), // MPT sample information
  525. FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION), // Loop points
  526. FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION), // Cue points
  527. };
  528. unsigned numBlocks = 2;
  529. if(metadata[0])
  530. {
  531. // Store sample name
  532. FLAC__StreamMetadata_VorbisComment_Entry entry;
  533. FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(&entry, "TITLE", mpt::ToCharset(mpt::Charset::UTF8, GetCharsetInternal(), m_szNames[nSample]).c_str());
  534. FLAC__metadata_object_vorbiscomment_append_comment(metadata[0], entry, false);
  535. FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(&entry, "ENCODER", mpt::ToCharset(mpt::Charset::UTF8, Version::Current().GetOpenMPTVersionString()).c_str());
  536. FLAC__metadata_object_vorbiscomment_append_comment(metadata[0], entry, false);
  537. if(sampleRate > FLAC__MAX_SAMPLE_RATE)
  538. {
  539. // FLAC only supports a sample rate of up to 655350 Hz.
  540. // Store the real sample rate in a custom Vorbis comment.
  541. FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(&entry, "SAMPLERATE", mpt::afmt::val(sampleRate).c_str());
  542. FLAC__metadata_object_vorbiscomment_append_comment(metadata[0], entry, false);
  543. }
  544. }
  545. if(metadata[1])
  546. {
  547. // Write MPT sample information
  548. memcpy(metadata[1]->data.application.id, "riff", 4);
  549. struct
  550. {
  551. RIFFChunk header;
  552. WAVExtraChunk mptInfo;
  553. } chunk;
  554. chunk.header.id = RIFFChunk::idxtra;
  555. chunk.header.length = sizeof(WAVExtraChunk);
  556. chunk.mptInfo.ConvertToWAV(sample, GetType());
  557. const uint32 length = sizeof(RIFFChunk) + sizeof(WAVExtraChunk);
  558. FLAC__metadata_object_application_set_data(metadata[1], reinterpret_cast<FLAC__byte *>(&chunk), length, true);
  559. }
  560. if(metadata[numBlocks] && (sample.uFlags[CHN_LOOP | CHN_SUSTAINLOOP] || ModCommand::IsNote(sample.rootNote)))
  561. {
  562. // Store loop points / root note information
  563. memcpy(metadata[numBlocks]->data.application.id, "riff", 4);
  564. struct
  565. {
  566. RIFFChunk header;
  567. WAVSampleInfoChunk info;
  568. WAVSampleLoop loops[2];
  569. } chunk;
  570. chunk.header.id = RIFFChunk::idsmpl;
  571. chunk.header.length = sizeof(WAVSampleInfoChunk);
  572. chunk.info.ConvertToWAV(sample.GetSampleRate(GetType()), sample.rootNote);
  573. if(sample.uFlags[CHN_SUSTAINLOOP])
  574. {
  575. chunk.loops[chunk.info.numLoops++].ConvertToWAV(sample.nSustainStart, sample.nSustainEnd, sample.uFlags[CHN_PINGPONGSUSTAIN]);
  576. chunk.header.length += sizeof(WAVSampleLoop);
  577. }
  578. if(sample.uFlags[CHN_LOOP])
  579. {
  580. chunk.loops[chunk.info.numLoops++].ConvertToWAV(sample.nLoopStart, sample.nLoopEnd, sample.uFlags[CHN_PINGPONGLOOP]);
  581. chunk.header.length += sizeof(WAVSampleLoop);
  582. }
  583. const uint32 length = sizeof(RIFFChunk) + chunk.header.length;
  584. FLAC__metadata_object_application_set_data(metadata[numBlocks], reinterpret_cast<FLAC__byte *>(&chunk), length, true);
  585. numBlocks++;
  586. }
  587. if(metadata[numBlocks] && sample.HasCustomCuePoints())
  588. {
  589. // Store cue points
  590. memcpy(metadata[numBlocks]->data.application.id, "riff", 4);
  591. struct
  592. {
  593. RIFFChunk header;
  594. uint32le numPoints;
  595. WAVCuePoint cues[mpt::array_size<decltype(sample.cues)>::size];
  596. } chunk{};
  597. chunk.header.id = RIFFChunk::idcue_;
  598. chunk.header.length = 4 + sizeof(chunk.cues);
  599. chunk.numPoints = mpt::saturate_cast<uint32>(std::size(sample.cues));
  600. for(uint32 i = 0; i < std::size(sample.cues); i++)
  601. {
  602. chunk.cues[i].ConvertToWAV(i, sample.cues[i]);
  603. }
  604. const uint32 length = sizeof(RIFFChunk) + chunk.header.length;
  605. FLAC__metadata_object_application_set_data(metadata[numBlocks], reinterpret_cast<FLAC__byte *>(&chunk), length, true);
  606. numBlocks++;
  607. }
  608. // FLAC allows a maximum sample rate of 655350 Hz.
  609. // If the real rate is higher, we store it in a Vorbis comment above.
  610. LimitMax(sampleRate, FLAC__MAX_SAMPLE_RATE);
  611. if(!FLAC__format_sample_rate_is_subset(sampleRate))
  612. {
  613. // FLAC only supports 10 Hz granularity for frequencies above 65535 Hz if the streamable subset is chosen.
  614. FLAC__stream_encoder_set_streamable_subset(encoder, false);
  615. }
  616. FLAC__stream_encoder_set_channels(encoder, sample.GetNumChannels());
  617. FLAC__stream_encoder_set_bits_per_sample(encoder, sample.GetElementarySampleSize() * 8);
  618. FLAC__stream_encoder_set_sample_rate(encoder, sampleRate);
  619. FLAC__stream_encoder_set_total_samples_estimate(encoder, sample.nLength);
  620. FLAC__stream_encoder_set_metadata(encoder, metadata.data(), numBlocks);
  621. #ifdef MODPLUG_TRACKER
  622. FLAC__stream_encoder_set_compression_level(encoder, TrackerSettings::Instance().m_FLACCompressionLevel);
  623. #endif // MODPLUG_TRACKER
  624. bool success = FLAC__stream_encoder_init_stream(encoder, &FLAC__StreamEncoder_RAII::StreamEncoderWriteCallback, &FLAC__StreamEncoder_RAII::StreamEncoderSeekCallback, &FLAC__StreamEncoder_RAII::StreamEncoderTellCallback, nullptr, &encoder.f) == FLAC__STREAM_ENCODER_INIT_STATUS_OK;
  625. // Convert and encode sample data
  626. SmpLength framesRemain = sample.nLength, framesRead = 0;
  627. const uint8 numChannels = sample.GetNumChannels();
  628. FLAC__int32 buffer[mpt::IO::BUFFERSIZE_TINY];
  629. while(framesRemain && success)
  630. {
  631. const SmpLength copyFrames = std::min(framesRemain, mpt::saturate_cast<SmpLength>(std::size(buffer) / numChannels));
  632. // First, convert to a 32-bit integer buffer
  633. switch(sample.GetElementarySampleSize())
  634. {
  635. case 1: std::copy(sample.sample8() + framesRead * numChannels, sample.sample8() + (framesRead + copyFrames) * numChannels, std::begin(buffer)); break;
  636. case 2: std::copy(sample.sample16() + framesRead * numChannels, sample.sample16() + (framesRead + copyFrames) * numChannels, std::begin(buffer)); break;
  637. default: MPT_ASSERT_NOTREACHED();
  638. }
  639. // Now do the actual encoding
  640. success = FLAC__stream_encoder_process_interleaved(encoder, buffer, copyFrames) != static_cast<FLAC__bool>(false);
  641. framesRead += copyFrames;
  642. framesRemain -= copyFrames;
  643. }
  644. FLAC__stream_encoder_finish(encoder);
  645. return success;
  646. #else
  647. MPT_UNREFERENCED_PARAMETER(nSample);
  648. MPT_UNREFERENCED_PARAMETER(f);
  649. return false;
  650. #endif // MPT_WITH_FLAC
  651. }
  652. #endif // MODPLUG_NO_FILESAVE
  653. OPENMPT_NAMESPACE_END