OpenShot Library | libopenshot-audio  0.1.9
juce_FlacAudioFormat.cpp
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2017 - ROLI Ltd.
6 
7  JUCE is an open source library subject to commercial or open-source
8  licensing.
9 
10  By using JUCE, you agree to the terms of both the JUCE 5 End-User License
11  Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
12  27th April 2017).
13 
14  End User License Agreement: www.juce.com/juce-5-licence
15  Privacy Policy: www.juce.com/juce-5-privacy-policy
16 
17  Or: You may also use this code under the terms of the GPL v3 (see
18  www.gnu.org/licenses).
19 
20  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
21  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
22  DISCLAIMED.
23 
24  ==============================================================================
25 */
26 
27 namespace juce
28 {
29 
30 #if JUCE_USE_FLAC
31 
32 }
33 
34 #if defined _WIN32 && !defined __CYGWIN__
35  #include <io.h>
36 #else
37  #include <unistd.h>
38 #endif
39 
40 #if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__
41  #include <sys/types.h> /* for off_t */
42 #endif
43 
44 #if HAVE_INTTYPES_H
45  #define __STDC_FORMAT_MACROS
46  #include <inttypes.h>
47 #endif
48 
49 #if defined _MSC_VER || defined __MINGW32__ || defined __CYGWIN__ || defined __EMX__
50  #include <io.h> /* for _setmode(), chmod() */
51  #include <fcntl.h> /* for _O_BINARY */
52 #else
53  #include <unistd.h> /* for chown(), unlink() */
54 #endif
55 
56 #if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__
57  #if defined __BORLANDC__
58  #include <utime.h> /* for utime() */
59  #else
60  #include <sys/utime.h> /* for utime() */
61  #endif
62 #else
63  #include <sys/types.h> /* some flavors of BSD (like OS X) require this to get time_t */
64  #include <utime.h> /* for utime() */
65 #endif
66 
67 #if defined _MSC_VER
68  #if _MSC_VER >= 1600
69  #include <stdint.h>
70  #else
71  #include <limits.h>
72  #endif
73 #endif
74 
75 #ifdef _WIN32
76  #include <stdio.h>
77  #include <sys/stat.h>
78  #include <stdarg.h>
79  #include <windows.h>
80 #endif
81 
82 #ifdef DEBUG
83  #include <assert.h>
84 #endif
85 
86 #include <stdlib.h>
87 #include <stdio.h>
88 
89 namespace juce
90 {
91 
92 namespace FlacNamespace
93 {
94 #if JUCE_INCLUDE_FLAC_CODE || ! defined (JUCE_INCLUDE_FLAC_CODE)
95 
96  #undef VERSION
97  #define VERSION "1.3.1"
98 
99  #define FLAC__NO_DLL 1
100 
101  #if JUCE_MSVC
102  #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312 4505 4365 4005 4334 181 111)
103  #else
104  #define HAVE_LROUND 1
105  #endif
106 
107  #if JUCE_MAC
108  #define FLAC__SYS_DARWIN 1
109  #endif
110 
111  #ifndef SIZE_MAX
112  #define SIZE_MAX 0xffffffff
113  #endif
114 
115  #if JUCE_CLANG
116  #pragma clang diagnostic push
117  #pragma clang diagnostic ignored "-Wconversion"
118  #pragma clang diagnostic ignored "-Wshadow"
119  #pragma clang diagnostic ignored "-Wdeprecated-register"
120  #if __has_warning("-Wzero-as-null-pointer-constant")
121  #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
122  #endif
123  #endif
124 
125  #if JUCE_INTEL
126  #if JUCE_32BIT
127  #define FLAC__CPU_IA32 1
128  #endif
129  #if JUCE_64BIT
130  #define FLAC__CPU_X86_64 1
131  #endif
132  #define FLAC__HAS_X86INTRIN 1
133  #endif
134 
135  #undef __STDC_LIMIT_MACROS
136  #define __STDC_LIMIT_MACROS 1
137  #define flac_max jmax
138  #define flac_min jmin
139  #undef DEBUG // (some flac code dumps debug trace if the app defines this macro)
140  #include "flac/all.h"
141  #include "flac/libFLAC/bitmath.c"
142  #include "flac/libFLAC/bitreader.c"
143  #include "flac/libFLAC/bitwriter.c"
144  #include "flac/libFLAC/cpu.c"
145  #include "flac/libFLAC/crc.c"
146  #include "flac/libFLAC/fixed.c"
147  #include "flac/libFLAC/float.c"
148  #include "flac/libFLAC/format.c"
149  #include "flac/libFLAC/lpc_flac.c"
150  #include "flac/libFLAC/md5.c"
151  #include "flac/libFLAC/memory.c"
152  #include "flac/libFLAC/stream_decoder.c"
153  #include "flac/libFLAC/stream_encoder.c"
154  #include "flac/libFLAC/stream_encoder_framing.c"
155  #include "flac/libFLAC/window_flac.c"
156  #undef VERSION
157 #else
158  #include <FLAC/all.h>
159 #endif
160 
161  #if JUCE_CLANG
162  #pragma clang diagnostic pop
163  #endif
164 }
165 
166 #undef max
167 #undef min
168 
169 //==============================================================================
170 static const char* const flacFormatName = "FLAC file";
171 
172 
173 //==============================================================================
174 class FlacReader : public AudioFormatReader
175 {
176 public:
177  FlacReader (InputStream* in) : AudioFormatReader (in, flacFormatName)
178  {
179  lengthInSamples = 0;
180  decoder = FlacNamespace::FLAC__stream_decoder_new();
181 
182  ok = FLAC__stream_decoder_init_stream (decoder,
183  readCallback_, seekCallback_, tellCallback_, lengthCallback_,
184  eofCallback_, writeCallback_, metadataCallback_, errorCallback_,
185  this) == FlacNamespace::FLAC__STREAM_DECODER_INIT_STATUS_OK;
186 
187  if (ok)
188  {
189  FLAC__stream_decoder_process_until_end_of_metadata (decoder);
190 
191  if (lengthInSamples == 0 && sampleRate > 0)
192  {
193  // the length hasn't been stored in the metadata, so we'll need to
194  // work it out the length the hard way, by scanning the whole file..
195  scanningForLength = true;
196  FLAC__stream_decoder_process_until_end_of_stream (decoder);
197  scanningForLength = false;
198  auto tempLength = lengthInSamples;
199 
200  FLAC__stream_decoder_reset (decoder);
201  FLAC__stream_decoder_process_until_end_of_metadata (decoder);
202  lengthInSamples = tempLength;
203  }
204  }
205  }
206 
207  ~FlacReader() override
208  {
209  FlacNamespace::FLAC__stream_decoder_delete (decoder);
210  }
211 
212  void useMetadata (const FlacNamespace::FLAC__StreamMetadata_StreamInfo& info)
213  {
214  sampleRate = info.sample_rate;
215  bitsPerSample = info.bits_per_sample;
216  lengthInSamples = (unsigned int) info.total_samples;
217  numChannels = info.channels;
218 
219  reservoir.setSize ((int) numChannels, 2 * (int) info.max_blocksize, false, false, true);
220  }
221 
222  // returns the number of samples read
223  bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer,
224  int64 startSampleInFile, int numSamples) override
225  {
226  if (! ok)
227  return false;
228 
229  while (numSamples > 0)
230  {
231  if (startSampleInFile >= reservoirStart
232  && startSampleInFile < reservoirStart + samplesInReservoir)
233  {
234  auto num = (int) jmin ((int64) numSamples,
235  reservoirStart + samplesInReservoir - startSampleInFile);
236 
237  jassert (num > 0);
238 
239  for (int i = jmin (numDestChannels, reservoir.getNumChannels()); --i >= 0;)
240  if (destSamples[i] != nullptr)
241  memcpy (destSamples[i] + startOffsetInDestBuffer,
242  reservoir.getReadPointer (i, (int) (startSampleInFile - reservoirStart)),
243  sizeof (int) * (size_t) num);
244 
245  startOffsetInDestBuffer += num;
246  startSampleInFile += num;
247  numSamples -= num;
248  }
249  else
250  {
251  if (startSampleInFile >= lengthInSamples)
252  {
253  samplesInReservoir = 0;
254  }
255  else if (startSampleInFile < reservoirStart
256  || startSampleInFile > reservoirStart + jmax (samplesInReservoir, 511))
257  {
258  // had some problems with flac crashing if the read pos is aligned more
259  // accurately than this. Probably fixed in newer versions of the library, though.
260  reservoirStart = (int) (startSampleInFile & ~511);
261  samplesInReservoir = 0;
262  FLAC__stream_decoder_seek_absolute (decoder, (FlacNamespace::FLAC__uint64) reservoirStart);
263  }
264  else
265  {
266  reservoirStart += samplesInReservoir;
267  samplesInReservoir = 0;
268  FLAC__stream_decoder_process_single (decoder);
269  }
270 
271  if (samplesInReservoir == 0)
272  break;
273  }
274  }
275 
276  if (numSamples > 0)
277  {
278  for (int i = numDestChannels; --i >= 0;)
279  if (destSamples[i] != nullptr)
280  zeromem (destSamples[i] + startOffsetInDestBuffer, sizeof (int) * (size_t) numSamples);
281  }
282 
283  return true;
284  }
285 
286  void useSamples (const FlacNamespace::FLAC__int32* const buffer[], int numSamples)
287  {
288  if (scanningForLength)
289  {
290  lengthInSamples += numSamples;
291  }
292  else
293  {
294  if (numSamples > reservoir.getNumSamples())
295  reservoir.setSize ((int) numChannels, numSamples, false, false, true);
296 
297  auto bitsToShift = 32 - bitsPerSample;
298 
299  for (int i = 0; i < (int) numChannels; ++i)
300  {
301  auto* src = buffer[i];
302  int n = i;
303 
304  while (src == nullptr && n > 0)
305  src = buffer [--n];
306 
307  if (src != nullptr)
308  {
309  auto* dest = reinterpret_cast<int*> (reservoir.getWritePointer(i));
310 
311  for (int j = 0; j < numSamples; ++j)
312  dest[j] = src[j] << bitsToShift;
313  }
314  }
315 
316  samplesInReservoir = numSamples;
317  }
318  }
319 
320  //==============================================================================
321  static FlacNamespace::FLAC__StreamDecoderReadStatus readCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__byte buffer[], size_t* bytes, void* client_data)
322  {
323  *bytes = (size_t) static_cast<const FlacReader*> (client_data)->input->read (buffer, (int) *bytes);
324  return FlacNamespace::FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
325  }
326 
327  static FlacNamespace::FLAC__StreamDecoderSeekStatus seekCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__uint64 absolute_byte_offset, void* client_data)
328  {
329  static_cast<const FlacReader*> (client_data)->input->setPosition ((int) absolute_byte_offset);
330  return FlacNamespace::FLAC__STREAM_DECODER_SEEK_STATUS_OK;
331  }
332 
333  static FlacNamespace::FLAC__StreamDecoderTellStatus tellCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__uint64* absolute_byte_offset, void* client_data)
334  {
335  *absolute_byte_offset = (uint64) static_cast<const FlacReader*> (client_data)->input->getPosition();
336  return FlacNamespace::FLAC__STREAM_DECODER_TELL_STATUS_OK;
337  }
338 
339  static FlacNamespace::FLAC__StreamDecoderLengthStatus lengthCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__uint64* stream_length, void* client_data)
340  {
341  *stream_length = (uint64) static_cast<const FlacReader*> (client_data)->input->getTotalLength();
342  return FlacNamespace::FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
343  }
344 
345  static FlacNamespace::FLAC__bool eofCallback_ (const FlacNamespace::FLAC__StreamDecoder*, void* client_data)
346  {
347  return static_cast<const FlacReader*> (client_data)->input->isExhausted();
348  }
349 
350  static FlacNamespace::FLAC__StreamDecoderWriteStatus writeCallback_ (const FlacNamespace::FLAC__StreamDecoder*,
351  const FlacNamespace::FLAC__Frame* frame,
352  const FlacNamespace::FLAC__int32* const buffer[],
353  void* client_data)
354  {
355  static_cast<FlacReader*> (client_data)->useSamples (buffer, (int) frame->header.blocksize);
356  return FlacNamespace::FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
357  }
358 
359  static void metadataCallback_ (const FlacNamespace::FLAC__StreamDecoder*,
360  const FlacNamespace::FLAC__StreamMetadata* metadata,
361  void* client_data)
362  {
363  static_cast<FlacReader*> (client_data)->useMetadata (metadata->data.stream_info);
364  }
365 
366  static void errorCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__StreamDecoderErrorStatus, void*)
367  {
368  }
369 
370 private:
371  FlacNamespace::FLAC__StreamDecoder* decoder;
372  AudioBuffer<float> reservoir;
373  int reservoirStart = 0, samplesInReservoir = 0;
374  bool ok = false, scanningForLength = false;
375 
376  JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FlacReader)
377 };
378 
379 
380 //==============================================================================
381 class FlacWriter : public AudioFormatWriter
382 {
383 public:
384  FlacWriter (OutputStream* out, double rate, uint32 numChans, uint32 bits, int qualityOptionIndex)
385  : AudioFormatWriter (out, flacFormatName, rate, numChans, bits),
386  streamStartPos (output != nullptr ? jmax (output->getPosition(), 0ll) : 0ll)
387  {
388  encoder = FlacNamespace::FLAC__stream_encoder_new();
389 
390  if (qualityOptionIndex > 0)
391  FLAC__stream_encoder_set_compression_level (encoder, (uint32) jmin (8, qualityOptionIndex));
392 
393  FLAC__stream_encoder_set_do_mid_side_stereo (encoder, numChannels == 2);
394  FLAC__stream_encoder_set_loose_mid_side_stereo (encoder, numChannels == 2);
395  FLAC__stream_encoder_set_channels (encoder, numChannels);
396  FLAC__stream_encoder_set_bits_per_sample (encoder, jmin ((unsigned int) 24, bitsPerSample));
397  FLAC__stream_encoder_set_sample_rate (encoder, (unsigned int) sampleRate);
398  FLAC__stream_encoder_set_blocksize (encoder, 0);
399  FLAC__stream_encoder_set_do_escape_coding (encoder, true);
400 
401  ok = FLAC__stream_encoder_init_stream (encoder,
402  encodeWriteCallback, encodeSeekCallback,
403  encodeTellCallback, encodeMetadataCallback,
404  this) == FlacNamespace::FLAC__STREAM_ENCODER_INIT_STATUS_OK;
405  }
406 
407  ~FlacWriter() override
408  {
409  if (ok)
410  {
411  FlacNamespace::FLAC__stream_encoder_finish (encoder);
412  output->flush();
413  }
414  else
415  {
416  output = nullptr; // to stop the base class deleting this, as it needs to be returned
417  // to the caller of createWriter()
418  }
419 
420  FlacNamespace::FLAC__stream_encoder_delete (encoder);
421  }
422 
423  //==============================================================================
424  bool write (const int** samplesToWrite, int numSamples) override
425  {
426  if (! ok)
427  return false;
428 
429  HeapBlock<int*> channels;
430  HeapBlock<int> temp;
431  auto bitsToShift = 32 - (int) bitsPerSample;
432 
433  if (bitsToShift > 0)
434  {
435  temp.malloc (numChannels * (size_t) numSamples);
436  channels.calloc (numChannels + 1);
437 
438  for (unsigned int i = 0; i < numChannels; ++i)
439  {
440  if (samplesToWrite[i] == nullptr)
441  break;
442 
443  auto* destData = temp.get() + i * (size_t) numSamples;
444  channels[i] = destData;
445 
446  for (int j = 0; j < numSamples; ++j)
447  destData[j] = (samplesToWrite[i][j] >> bitsToShift);
448  }
449 
450  samplesToWrite = const_cast<const int**> (channels.get());
451  }
452 
453  return FLAC__stream_encoder_process (encoder, (const FlacNamespace::FLAC__int32**) samplesToWrite, (unsigned) numSamples) != 0;
454  }
455 
456  bool writeData (const void* const data, const int size) const
457  {
458  return output->write (data, (size_t) size);
459  }
460 
461  static void packUint32 (FlacNamespace::FLAC__uint32 val, FlacNamespace::FLAC__byte* b, const int bytes)
462  {
463  b += bytes;
464 
465  for (int i = 0; i < bytes; ++i)
466  {
467  *(--b) = (FlacNamespace::FLAC__byte) (val & 0xff);
468  val >>= 8;
469  }
470  }
471 
472  void writeMetaData (const FlacNamespace::FLAC__StreamMetadata* metadata)
473  {
474  using namespace FlacNamespace;
475  auto& info = metadata->data.stream_info;
476 
477  unsigned char buffer[FLAC__STREAM_METADATA_STREAMINFO_LENGTH];
478  const unsigned int channelsMinus1 = info.channels - 1;
479  const unsigned int bitsMinus1 = info.bits_per_sample - 1;
480 
481  packUint32 (info.min_blocksize, buffer, 2);
482  packUint32 (info.max_blocksize, buffer + 2, 2);
483  packUint32 (info.min_framesize, buffer + 4, 3);
484  packUint32 (info.max_framesize, buffer + 7, 3);
485  buffer[10] = (uint8) ((info.sample_rate >> 12) & 0xff);
486  buffer[11] = (uint8) ((info.sample_rate >> 4) & 0xff);
487  buffer[12] = (uint8) (((info.sample_rate & 0x0f) << 4) | (channelsMinus1 << 1) | (bitsMinus1 >> 4));
488  buffer[13] = (FLAC__byte) (((bitsMinus1 & 0x0f) << 4) | (unsigned int) ((info.total_samples >> 32) & 0x0f));
489  packUint32 ((FLAC__uint32) info.total_samples, buffer + 14, 4);
490  memcpy (buffer + 18, info.md5sum, 16);
491 
492  const bool seekOk = output->setPosition (streamStartPos + 4);
493  ignoreUnused (seekOk);
494 
495  // if this fails, you've given it an output stream that can't seek! It needs
496  // to be able to seek back to write the header
497  jassert (seekOk);
498 
499  output->writeIntBigEndian (FLAC__STREAM_METADATA_STREAMINFO_LENGTH);
500  output->write (buffer, FLAC__STREAM_METADATA_STREAMINFO_LENGTH);
501  }
502 
503  //==============================================================================
504  static FlacNamespace::FLAC__StreamEncoderWriteStatus encodeWriteCallback (const FlacNamespace::FLAC__StreamEncoder*,
505  const FlacNamespace::FLAC__byte buffer[],
506  size_t bytes,
507  unsigned int /*samples*/,
508  unsigned int /*current_frame*/,
509  void* client_data)
510  {
511  return static_cast<FlacWriter*> (client_data)->writeData (buffer, (int) bytes)
512  ? FlacNamespace::FLAC__STREAM_ENCODER_WRITE_STATUS_OK
513  : FlacNamespace::FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
514  }
515 
516  static FlacNamespace::FLAC__StreamEncoderSeekStatus encodeSeekCallback (const FlacNamespace::FLAC__StreamEncoder*, FlacNamespace::FLAC__uint64, void*)
517  {
518  return FlacNamespace::FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED;
519  }
520 
521  static FlacNamespace::FLAC__StreamEncoderTellStatus encodeTellCallback (const FlacNamespace::FLAC__StreamEncoder*, FlacNamespace::FLAC__uint64* absolute_byte_offset, void* client_data)
522  {
523  if (client_data == nullptr)
524  return FlacNamespace::FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED;
525 
526  *absolute_byte_offset = (FlacNamespace::FLAC__uint64) static_cast<FlacWriter*> (client_data)->output->getPosition();
527  return FlacNamespace::FLAC__STREAM_ENCODER_TELL_STATUS_OK;
528  }
529 
530  static void encodeMetadataCallback (const FlacNamespace::FLAC__StreamEncoder*, const FlacNamespace::FLAC__StreamMetadata* metadata, void* client_data)
531  {
532  static_cast<FlacWriter*> (client_data)->writeMetaData (metadata);
533  }
534 
535  bool ok = false;
536 
537 private:
538  FlacNamespace::FLAC__StreamEncoder* encoder;
539  int64 streamStartPos;
540 
541  JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FlacWriter)
542 };
543 
544 
545 //==============================================================================
546 FlacAudioFormat::FlacAudioFormat() : AudioFormat (flacFormatName, ".flac") {}
547 FlacAudioFormat::~FlacAudioFormat() {}
548 
550 {
551  return { 8000, 11025, 12000, 16000, 22050, 32000, 44100, 48000,
552  88200, 96000, 176400, 192000, 352800, 384000 };
553 }
554 
556 {
557  return { 16, 24 };
558 }
559 
560 bool FlacAudioFormat::canDoStereo() { return true; }
561 bool FlacAudioFormat::canDoMono() { return true; }
562 bool FlacAudioFormat::isCompressed() { return true; }
563 
564 AudioFormatReader* FlacAudioFormat::createReaderFor (InputStream* in, const bool deleteStreamIfOpeningFails)
565 {
566  std::unique_ptr<FlacReader> r (new FlacReader (in));
567 
568  if (r->sampleRate > 0)
569  return r.release();
570 
571  if (! deleteStreamIfOpeningFails)
572  r->input = nullptr;
573 
574  return nullptr;
575 }
576 
577 AudioFormatWriter* FlacAudioFormat::createWriterFor (OutputStream* out,
578  double sampleRate,
579  unsigned int numberOfChannels,
580  int bitsPerSample,
581  const StringPairArray& /*metadataValues*/,
582  int qualityOptionIndex)
583 {
584  if (out != nullptr && getPossibleBitDepths().contains (bitsPerSample))
585  {
586  std::unique_ptr<FlacWriter> w (new FlacWriter (out, sampleRate, numberOfChannels,
587  (uint32) bitsPerSample, qualityOptionIndex));
588  if (w->ok)
589  return w.release();
590  }
591 
592  return nullptr;
593 }
594 
596 {
597  return { "0 (Fastest)", "1", "2", "3", "4", "5 (Default)","6", "7", "8 (Highest quality)" };
598 }
599 
600 #endif
601 
602 } // namespace juce
Array< int > getPossibleSampleRates() override
Returns a set of sample rates that the format can read and write.
StringArray getQualityOptions() override
Returns a list of different qualities that can be used when writing.
bool isCompressed() override
Returns true if the format uses compressed data.
bool canDoStereo() override
Returns true if the format can do 2-channel audio.
bool canDoMono() override
Returns true if the format can do 1-channel audio.
Array< int > getPossibleBitDepths() override
Returns a set of bit depths that the format can read and write.
AudioFormatWriter * createWriterFor(OutputStream *streamToWriteTo, double sampleRateToUse, unsigned int numberOfChannels, int bitsPerSample, const StringPairArray &metadataValues, int qualityOptionIndex) override
Tries to create an object that can write to a stream with this audio format.
AudioFormatReader * createReaderFor(InputStream *sourceStream, bool deleteStreamIfOpeningFails) override
Tries to create an object that can read from a stream containing audio data in this format...