The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

547 lines
21KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. #if JUCE_USE_FLAC
  19. namespace FlacNamespace
  20. {
  21. #if JUCE_INCLUDE_FLAC_CODE || ! defined (JUCE_INCLUDE_FLAC_CODE)
  22. #undef VERSION
  23. #define VERSION "1.2.1"
  24. #define FLAC__NO_DLL 1
  25. #if JUCE_MSVC
  26. #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312 4505 4365 4005 4334 181 111)
  27. #endif
  28. #if JUCE_MAC
  29. #define FLAC__SYS_DARWIN 1
  30. #endif
  31. #ifndef SIZE_MAX
  32. #define SIZE_MAX 0xffffffff
  33. #endif
  34. #if JUCE_CLANG
  35. #pragma clang diagnostic push
  36. #pragma clang diagnostic ignored "-Wconversion"
  37. #pragma clang diagnostic ignored "-Wshadow"
  38. #endif
  39. #define __STDC_LIMIT_MACROS 1
  40. #include "flac/all.h"
  41. #include "flac/libFLAC/bitmath.c"
  42. #include "flac/libFLAC/bitreader.c"
  43. #include "flac/libFLAC/bitwriter.c"
  44. #include "flac/libFLAC/cpu.c"
  45. #include "flac/libFLAC/crc.c"
  46. #include "flac/libFLAC/fixed.c"
  47. #include "flac/libFLAC/float.c"
  48. #include "flac/libFLAC/format.c"
  49. #include "flac/libFLAC/lpc_flac.c"
  50. #include "flac/libFLAC/md5.c"
  51. #include "flac/libFLAC/memory.c"
  52. #include "flac/libFLAC/stream_decoder.c"
  53. #include "flac/libFLAC/stream_encoder.c"
  54. #include "flac/libFLAC/stream_encoder_framing.c"
  55. #include "flac/libFLAC/window_flac.c"
  56. #undef VERSION
  57. #else
  58. #include <FLAC/all.h>
  59. #endif
  60. #if JUCE_CLANG
  61. #pragma clang diagnostic pop
  62. #endif
  63. }
  64. #undef max
  65. #undef min
  66. //==============================================================================
  67. static const char* const flacFormatName = "FLAC file";
  68. static const char* const flacExtensions[] = { ".flac", 0 };
  69. //==============================================================================
  70. class FlacReader : public AudioFormatReader
  71. {
  72. public:
  73. //==============================================================================
  74. FlacReader (InputStream* const in)
  75. : AudioFormatReader (in, TRANS (flacFormatName)),
  76. reservoir (2, 0),
  77. reservoirStart (0),
  78. samplesInReservoir (0),
  79. scanningForLength (false)
  80. {
  81. using namespace FlacNamespace;
  82. lengthInSamples = 0;
  83. decoder = FLAC__stream_decoder_new();
  84. ok = FLAC__stream_decoder_init_stream (decoder,
  85. readCallback_, seekCallback_, tellCallback_, lengthCallback_,
  86. eofCallback_, writeCallback_, metadataCallback_, errorCallback_,
  87. this) == FLAC__STREAM_DECODER_INIT_STATUS_OK;
  88. if (ok)
  89. {
  90. FLAC__stream_decoder_process_until_end_of_metadata (decoder);
  91. if (lengthInSamples == 0 && sampleRate > 0)
  92. {
  93. // the length hasn't been stored in the metadata, so we'll need to
  94. // work it out the length the hard way, by scanning the whole file..
  95. scanningForLength = true;
  96. FLAC__stream_decoder_process_until_end_of_stream (decoder);
  97. scanningForLength = false;
  98. const int64 tempLength = lengthInSamples;
  99. FLAC__stream_decoder_reset (decoder);
  100. FLAC__stream_decoder_process_until_end_of_metadata (decoder);
  101. lengthInSamples = tempLength;
  102. }
  103. }
  104. }
  105. ~FlacReader()
  106. {
  107. FlacNamespace::FLAC__stream_decoder_delete (decoder);
  108. }
  109. void useMetadata (const FlacNamespace::FLAC__StreamMetadata_StreamInfo& info)
  110. {
  111. sampleRate = info.sample_rate;
  112. bitsPerSample = info.bits_per_sample;
  113. lengthInSamples = (unsigned int) info.total_samples;
  114. numChannels = info.channels;
  115. reservoir.setSize ((int) numChannels, 2 * (int) info.max_blocksize, false, false, true);
  116. }
  117. // returns the number of samples read
  118. bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer,
  119. int64 startSampleInFile, int numSamples)
  120. {
  121. using namespace FlacNamespace;
  122. if (! ok)
  123. return false;
  124. while (numSamples > 0)
  125. {
  126. if (startSampleInFile >= reservoirStart
  127. && startSampleInFile < reservoirStart + samplesInReservoir)
  128. {
  129. const int num = (int) jmin ((int64) numSamples,
  130. reservoirStart + samplesInReservoir - startSampleInFile);
  131. jassert (num > 0);
  132. for (int i = jmin (numDestChannels, reservoir.getNumChannels()); --i >= 0;)
  133. if (destSamples[i] != nullptr)
  134. memcpy (destSamples[i] + startOffsetInDestBuffer,
  135. reservoir.getSampleData (i, (int) (startSampleInFile - reservoirStart)),
  136. sizeof (int) * (size_t) num);
  137. startOffsetInDestBuffer += num;
  138. startSampleInFile += num;
  139. numSamples -= num;
  140. }
  141. else
  142. {
  143. if (startSampleInFile >= (int) lengthInSamples)
  144. {
  145. samplesInReservoir = 0;
  146. }
  147. else if (startSampleInFile < reservoirStart
  148. || startSampleInFile > reservoirStart + jmax (samplesInReservoir, 511))
  149. {
  150. // had some problems with flac crashing if the read pos is aligned more
  151. // accurately than this. Probably fixed in newer versions of the library, though.
  152. reservoirStart = (int) (startSampleInFile & ~511);
  153. samplesInReservoir = 0;
  154. FLAC__stream_decoder_seek_absolute (decoder, (FLAC__uint64) reservoirStart);
  155. }
  156. else
  157. {
  158. reservoirStart += samplesInReservoir;
  159. samplesInReservoir = 0;
  160. FLAC__stream_decoder_process_single (decoder);
  161. }
  162. if (samplesInReservoir == 0)
  163. break;
  164. }
  165. }
  166. if (numSamples > 0)
  167. {
  168. for (int i = numDestChannels; --i >= 0;)
  169. if (destSamples[i] != nullptr)
  170. zeromem (destSamples[i] + startOffsetInDestBuffer, sizeof (int) * (size_t) numSamples);
  171. }
  172. return true;
  173. }
  174. void useSamples (const FlacNamespace::FLAC__int32* const buffer[], int numSamples)
  175. {
  176. if (scanningForLength)
  177. {
  178. lengthInSamples += numSamples;
  179. }
  180. else
  181. {
  182. if (numSamples > reservoir.getNumSamples())
  183. reservoir.setSize ((int) numChannels, numSamples, false, false, true);
  184. const unsigned int bitsToShift = 32 - bitsPerSample;
  185. for (int i = 0; i < (int) numChannels; ++i)
  186. {
  187. const FlacNamespace::FLAC__int32* src = buffer[i];
  188. int n = i;
  189. while (src == 0 && n > 0)
  190. src = buffer [--n];
  191. if (src != nullptr)
  192. {
  193. int* const dest = reinterpret_cast<int*> (reservoir.getSampleData(i));
  194. for (int j = 0; j < numSamples; ++j)
  195. dest[j] = src[j] << bitsToShift;
  196. }
  197. }
  198. samplesInReservoir = numSamples;
  199. }
  200. }
  201. //==============================================================================
  202. static FlacNamespace::FLAC__StreamDecoderReadStatus readCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__byte buffer[], size_t* bytes, void* client_data)
  203. {
  204. using namespace FlacNamespace;
  205. *bytes = (size_t) static_cast <const FlacReader*> (client_data)->input->read (buffer, (int) *bytes);
  206. return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
  207. }
  208. static FlacNamespace::FLAC__StreamDecoderSeekStatus seekCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__uint64 absolute_byte_offset, void* client_data)
  209. {
  210. using namespace FlacNamespace;
  211. static_cast <const FlacReader*> (client_data)->input->setPosition ((int) absolute_byte_offset);
  212. return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
  213. }
  214. static FlacNamespace::FLAC__StreamDecoderTellStatus tellCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__uint64* absolute_byte_offset, void* client_data)
  215. {
  216. using namespace FlacNamespace;
  217. *absolute_byte_offset = (uint64) static_cast <const FlacReader*> (client_data)->input->getPosition();
  218. return FLAC__STREAM_DECODER_TELL_STATUS_OK;
  219. }
  220. static FlacNamespace::FLAC__StreamDecoderLengthStatus lengthCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__uint64* stream_length, void* client_data)
  221. {
  222. using namespace FlacNamespace;
  223. *stream_length = (uint64) static_cast <const FlacReader*> (client_data)->input->getTotalLength();
  224. return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
  225. }
  226. static FlacNamespace::FLAC__bool eofCallback_ (const FlacNamespace::FLAC__StreamDecoder*, void* client_data)
  227. {
  228. return static_cast <const FlacReader*> (client_data)->input->isExhausted();
  229. }
  230. static FlacNamespace::FLAC__StreamDecoderWriteStatus writeCallback_ (const FlacNamespace::FLAC__StreamDecoder*,
  231. const FlacNamespace::FLAC__Frame* frame,
  232. const FlacNamespace::FLAC__int32* const buffer[],
  233. void* client_data)
  234. {
  235. using namespace FlacNamespace;
  236. static_cast <FlacReader*> (client_data)->useSamples (buffer, (int) frame->header.blocksize);
  237. return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
  238. }
  239. static void metadataCallback_ (const FlacNamespace::FLAC__StreamDecoder*,
  240. const FlacNamespace::FLAC__StreamMetadata* metadata,
  241. void* client_data)
  242. {
  243. static_cast <FlacReader*> (client_data)->useMetadata (metadata->data.stream_info);
  244. }
  245. static void errorCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__StreamDecoderErrorStatus, void*)
  246. {
  247. }
  248. private:
  249. FlacNamespace::FLAC__StreamDecoder* decoder;
  250. AudioSampleBuffer reservoir;
  251. int reservoirStart, samplesInReservoir;
  252. bool ok, scanningForLength;
  253. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FlacReader);
  254. };
  255. //==============================================================================
  256. class FlacWriter : public AudioFormatWriter
  257. {
  258. public:
  259. //==============================================================================
  260. FlacWriter (OutputStream* const out, double sampleRate_,
  261. uint32 numChannels_, uint32 bitsPerSample_, int qualityOptionIndex)
  262. : AudioFormatWriter (out, TRANS (flacFormatName),
  263. sampleRate_, numChannels_, bitsPerSample_)
  264. {
  265. using namespace FlacNamespace;
  266. encoder = FLAC__stream_encoder_new();
  267. if (qualityOptionIndex > 0)
  268. FLAC__stream_encoder_set_compression_level (encoder, (uint32) jmin (8, qualityOptionIndex));
  269. FLAC__stream_encoder_set_do_mid_side_stereo (encoder, numChannels == 2);
  270. FLAC__stream_encoder_set_loose_mid_side_stereo (encoder, numChannels == 2);
  271. FLAC__stream_encoder_set_channels (encoder, numChannels);
  272. FLAC__stream_encoder_set_bits_per_sample (encoder, jmin ((unsigned int) 24, bitsPerSample));
  273. FLAC__stream_encoder_set_sample_rate (encoder, (unsigned int) sampleRate);
  274. FLAC__stream_encoder_set_blocksize (encoder, 0);
  275. FLAC__stream_encoder_set_do_escape_coding (encoder, true);
  276. ok = FLAC__stream_encoder_init_stream (encoder,
  277. encodeWriteCallback, encodeSeekCallback,
  278. encodeTellCallback, encodeMetadataCallback,
  279. this) == FLAC__STREAM_ENCODER_INIT_STATUS_OK;
  280. }
  281. ~FlacWriter()
  282. {
  283. if (ok)
  284. {
  285. FlacNamespace::FLAC__stream_encoder_finish (encoder);
  286. output->flush();
  287. }
  288. else
  289. {
  290. output = nullptr; // to stop the base class deleting this, as it needs to be returned
  291. // to the caller of createWriter()
  292. }
  293. FlacNamespace::FLAC__stream_encoder_delete (encoder);
  294. }
  295. //==============================================================================
  296. bool write (const int** samplesToWrite, int numSamples)
  297. {
  298. using namespace FlacNamespace;
  299. if (! ok)
  300. return false;
  301. HeapBlock<int*> channels;
  302. HeapBlock<int> temp;
  303. const int bitsToShift = 32 - (int) bitsPerSample;
  304. if (bitsToShift > 0)
  305. {
  306. temp.malloc (numChannels * (size_t) numSamples);
  307. channels.calloc (numChannels + 1);
  308. for (unsigned int i = 0; i < numChannels; ++i)
  309. {
  310. if (samplesToWrite[i] == nullptr)
  311. break;
  312. int* const destData = temp.getData() + i * (size_t) numSamples;
  313. channels[i] = destData;
  314. for (int j = 0; j < numSamples; ++j)
  315. destData[j] = (samplesToWrite[i][j] >> bitsToShift);
  316. }
  317. samplesToWrite = const_cast <const int**> (channels.getData());
  318. }
  319. return FLAC__stream_encoder_process (encoder, (const FLAC__int32**) samplesToWrite, (size_t) numSamples) != 0;
  320. }
  321. bool writeData (const void* const data, const int size) const
  322. {
  323. return output->write (data, size);
  324. }
  325. static void packUint32 (FlacNamespace::FLAC__uint32 val, FlacNamespace::FLAC__byte* b, const int bytes)
  326. {
  327. b += bytes;
  328. for (int i = 0; i < bytes; ++i)
  329. {
  330. *(--b) = (FlacNamespace::FLAC__byte) (val & 0xff);
  331. val >>= 8;
  332. }
  333. }
  334. void writeMetaData (const FlacNamespace::FLAC__StreamMetadata* metadata)
  335. {
  336. using namespace FlacNamespace;
  337. const FLAC__StreamMetadata_StreamInfo& info = metadata->data.stream_info;
  338. unsigned char buffer [FLAC__STREAM_METADATA_STREAMINFO_LENGTH];
  339. const unsigned int channelsMinus1 = info.channels - 1;
  340. const unsigned int bitsMinus1 = info.bits_per_sample - 1;
  341. packUint32 (info.min_blocksize, buffer, 2);
  342. packUint32 (info.max_blocksize, buffer + 2, 2);
  343. packUint32 (info.min_framesize, buffer + 4, 3);
  344. packUint32 (info.max_framesize, buffer + 7, 3);
  345. buffer[10] = (uint8) ((info.sample_rate >> 12) & 0xff);
  346. buffer[11] = (uint8) ((info.sample_rate >> 4) & 0xff);
  347. buffer[12] = (uint8) (((info.sample_rate & 0x0f) << 4) | (channelsMinus1 << 1) | (bitsMinus1 >> 4));
  348. buffer[13] = (FLAC__byte) (((bitsMinus1 & 0x0f) << 4) | (unsigned int) ((info.total_samples >> 32) & 0x0f));
  349. packUint32 ((FLAC__uint32) info.total_samples, buffer + 14, 4);
  350. memcpy (buffer + 18, info.md5sum, 16);
  351. const bool seekOk = output->setPosition (4);
  352. (void) seekOk;
  353. // if this fails, you've given it an output stream that can't seek! It needs
  354. // to be able to seek back to write the header
  355. jassert (seekOk);
  356. output->writeIntBigEndian (FLAC__STREAM_METADATA_STREAMINFO_LENGTH);
  357. output->write (buffer, FLAC__STREAM_METADATA_STREAMINFO_LENGTH);
  358. }
  359. //==============================================================================
  360. static FlacNamespace::FLAC__StreamEncoderWriteStatus encodeWriteCallback (const FlacNamespace::FLAC__StreamEncoder*,
  361. const FlacNamespace::FLAC__byte buffer[],
  362. size_t bytes,
  363. unsigned int /*samples*/,
  364. unsigned int /*current_frame*/,
  365. void* client_data)
  366. {
  367. using namespace FlacNamespace;
  368. return static_cast <FlacWriter*> (client_data)->writeData (buffer, (int) bytes)
  369. ? FLAC__STREAM_ENCODER_WRITE_STATUS_OK
  370. : FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
  371. }
  372. static FlacNamespace::FLAC__StreamEncoderSeekStatus encodeSeekCallback (const FlacNamespace::FLAC__StreamEncoder*, FlacNamespace::FLAC__uint64, void*)
  373. {
  374. using namespace FlacNamespace;
  375. return FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED;
  376. }
  377. static FlacNamespace::FLAC__StreamEncoderTellStatus encodeTellCallback (const FlacNamespace::FLAC__StreamEncoder*, FlacNamespace::FLAC__uint64* absolute_byte_offset, void* client_data)
  378. {
  379. using namespace FlacNamespace;
  380. if (client_data == nullptr)
  381. return FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED;
  382. *absolute_byte_offset = (FLAC__uint64) static_cast <FlacWriter*> (client_data)->output->getPosition();
  383. return FLAC__STREAM_ENCODER_TELL_STATUS_OK;
  384. }
  385. static void encodeMetadataCallback (const FlacNamespace::FLAC__StreamEncoder*, const FlacNamespace::FLAC__StreamMetadata* metadata, void* client_data)
  386. {
  387. static_cast <FlacWriter*> (client_data)->writeMetaData (metadata);
  388. }
  389. bool ok;
  390. private:
  391. FlacNamespace::FLAC__StreamEncoder* encoder;
  392. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FlacWriter);
  393. };
  394. //==============================================================================
  395. FlacAudioFormat::FlacAudioFormat()
  396. : AudioFormat (TRANS (flacFormatName), StringArray (flacExtensions))
  397. {
  398. }
  399. FlacAudioFormat::~FlacAudioFormat()
  400. {
  401. }
  402. Array<int> FlacAudioFormat::getPossibleSampleRates()
  403. {
  404. const int rates[] = { 22050, 32000, 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000, 0 };
  405. return Array <int> (rates);
  406. }
  407. Array<int> FlacAudioFormat::getPossibleBitDepths()
  408. {
  409. const int depths[] = { 16, 24, 0 };
  410. return Array <int> (depths);
  411. }
  412. bool FlacAudioFormat::canDoStereo() { return true; }
  413. bool FlacAudioFormat::canDoMono() { return true; }
  414. bool FlacAudioFormat::isCompressed() { return true; }
  415. AudioFormatReader* FlacAudioFormat::createReaderFor (InputStream* in, const bool deleteStreamIfOpeningFails)
  416. {
  417. ScopedPointer<FlacReader> r (new FlacReader (in));
  418. if (r->sampleRate > 0)
  419. return r.release();
  420. if (! deleteStreamIfOpeningFails)
  421. r->input = nullptr;
  422. return nullptr;
  423. }
  424. AudioFormatWriter* FlacAudioFormat::createWriterFor (OutputStream* out,
  425. double sampleRate,
  426. unsigned int numberOfChannels,
  427. int bitsPerSample,
  428. const StringPairArray& /*metadataValues*/,
  429. int qualityOptionIndex)
  430. {
  431. if (getPossibleBitDepths().contains (bitsPerSample))
  432. {
  433. ScopedPointer<FlacWriter> w (new FlacWriter (out, sampleRate, numberOfChannels,
  434. (uint32) bitsPerSample, qualityOptionIndex));
  435. if (w->ok)
  436. return w.release();
  437. }
  438. return nullptr;
  439. }
  440. StringArray FlacAudioFormat::getQualityOptions()
  441. {
  442. const char* options[] = { "0 (Fastest)", "1", "2", "3", "4", "5 (Default)","6", "7", "8 (Highest quality)", 0 };
  443. return StringArray (options);
  444. }
  445. #endif