34#if defined _WIN32 && !defined __CYGWIN__
40#if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__
41 #include <sys/types.h>
45 #define __STDC_FORMAT_MACROS
49#if defined _MSC_VER || defined __MINGW32__ || defined __CYGWIN__ || defined __EMX__
56#if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__
57 #if defined __BORLANDC__
60 #include <sys/utime.h>
63 #include <sys/types.h>
92namespace FlacNamespace
94#if JUCE_INCLUDE_FLAC_CODE || ! defined (JUCE_INCLUDE_FLAC_CODE)
97 #define VERSION "1.3.1"
99 #define FLAC__NO_DLL 1
102 #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312 4505 4365 4005 4334 181 111)
104 #define HAVE_LROUND 1
108 #define FLAC__SYS_DARWIN 1
112 #define SIZE_MAX 0xffffffff
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"
127 #define FLAC__CPU_IA32 1
130 #define FLAC__CPU_X86_64 1
132 #define FLAC__HAS_X86INTRIN 1
135 #undef __STDC_LIMIT_MACROS
136 #define __STDC_LIMIT_MACROS 1
137 #define flac_max jmax
138 #define flac_min jmin
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"
158 #include <FLAC/all.h>
162 #pragma clang diagnostic pop
170static const char*
const flacFormatName =
"FLAC file";
174class FlacReader :
public AudioFormatReader
180 decoder = FlacNamespace::FLAC__stream_decoder_new();
185 this) == FlacNamespace::FLAC__STREAM_DECODER_INIT_STATUS_OK;
191 if (lengthInSamples == 0 && sampleRate > 0)
209 FlacNamespace::FLAC__stream_decoder_delete (
decoder);
212 void useMetadata (
const FlacNamespace::FLAC__StreamMetadata_StreamInfo&
info)
214 sampleRate =
info.sample_rate;
215 bitsPerSample =
info.bits_per_sample;
216 lengthInSamples = (
unsigned int)
info.total_samples;
217 numChannels =
info.channels;
219 reservoir.setSize ((
int) numChannels, 2 * (
int)
info.max_blocksize,
false,
false,
true);
229 while (numSamples > 0)
234 auto num = (
int) jmin ((int64) numSamples,
286 void useSamples (
const FlacNamespace::FLAC__int32*
const buffer[],
int numSamples)
290 lengthInSamples += numSamples;
294 if (numSamples >
reservoir.getNumSamples())
295 reservoir.setSize ((
int) numChannels, numSamples,
false,
false,
true);
299 for (
int i = 0; i < (
int) numChannels; ++i)
301 auto*
src = buffer[i];
304 while (
src ==
nullptr &&
n > 0)
309 auto* dest =
reinterpret_cast<int*
> (
reservoir.getWritePointer(i));
311 for (
int j = 0;
j < numSamples; ++
j)
321 static FlacNamespace::FLAC__StreamDecoderReadStatus
readCallback_ (
const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__byte buffer[],
size_t*
bytes,
void*
client_data)
324 return FlacNamespace::FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
330 return FlacNamespace::FLAC__STREAM_DECODER_SEEK_STATUS_OK;
336 return FlacNamespace::FLAC__STREAM_DECODER_TELL_STATUS_OK;
342 return FlacNamespace::FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
350 static FlacNamespace::FLAC__StreamDecoderWriteStatus
writeCallback_ (
const FlacNamespace::FLAC__StreamDecoder*,
351 const FlacNamespace::FLAC__Frame*
frame,
352 const FlacNamespace::FLAC__int32*
const buffer[],
356 return FlacNamespace::FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
360 const FlacNamespace::FLAC__StreamMetadata* metadata,
366 static void errorCallback_ (
const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__StreamDecoderErrorStatus,
void*)
371 FlacNamespace::FLAC__StreamDecoder*
decoder;
376 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (
FlacReader)
381class FlacWriter :
public AudioFormatWriter
388 encoder = FlacNamespace::FLAC__stream_encoder_new();
404 this) == FlacNamespace::FLAC__STREAM_ENCODER_INIT_STATUS_OK;
411 FlacNamespace::FLAC__stream_encoder_finish (
encoder);
420 FlacNamespace::FLAC__stream_encoder_delete (
encoder);
435 temp.malloc (numChannels * (
size_t) numSamples);
436 channels.calloc (numChannels + 1);
438 for (
unsigned int i = 0; i < numChannels; ++i)
446 for (
int j = 0;
j < numSamples; ++
j)
456 bool writeData (
const void*
const data,
const int size)
const
458 return output->write (
data, (
size_t)
size);
461 static void packUint32 (FlacNamespace::FLAC__uint32
val, FlacNamespace::FLAC__byte*
b,
const int bytes)
465 for (
int i = 0; i <
bytes; ++i)
467 *(--
b) = (FlacNamespace::FLAC__byte) (
val & 0xff);
472 void writeMetaData (
const FlacNamespace::FLAC__StreamMetadata* metadata)
475 auto&
info = metadata->data.stream_info;
485 buffer[10] = (uint8) ((
info.sample_rate >> 12) & 0xff);
486 buffer[11] = (uint8) ((
info.sample_rate >> 4) & 0xff);
504 static FlacNamespace::FLAC__StreamEncoderWriteStatus
encodeWriteCallback (
const FlacNamespace::FLAC__StreamEncoder*,
505 const FlacNamespace::FLAC__byte buffer[],
512 ? FlacNamespace::FLAC__STREAM_ENCODER_WRITE_STATUS_OK
516 static FlacNamespace::FLAC__StreamEncoderSeekStatus
encodeSeekCallback (
const FlacNamespace::FLAC__StreamEncoder*, FlacNamespace::FLAC__uint64,
void*)
518 return FlacNamespace::FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED;
524 return FlacNamespace::FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED;
527 return FlacNamespace::FLAC__STREAM_ENCODER_TELL_STATUS_OK;
538 FlacNamespace::FLAC__StreamEncoder*
encoder;
541 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (
FlacWriter)
546FlacAudioFormat::FlacAudioFormat() : AudioFormat (flacFormatName,
".flac") {}
547FlacAudioFormat::~FlacAudioFormat() {}
549Array<int> FlacAudioFormat::getPossibleSampleRates()
551 return { 8000, 11025, 12000, 16000, 22050, 32000, 44100, 48000,
552 88200, 96000, 176400, 192000, 352800, 384000 };
555Array<int> FlacAudioFormat::getPossibleBitDepths()
560bool FlacAudioFormat::canDoStereo() {
return true; }
561bool FlacAudioFormat::canDoMono() {
return true; }
562bool FlacAudioFormat::isCompressed() {
return true; }
564AudioFormatReader* FlacAudioFormat::createReaderFor (InputStream* in,
const bool deleteStreamIfOpeningFails)
566 std::unique_ptr<FlacReader> r (
new FlacReader (in));
568 if (r->sampleRate > 0)
571 if (! deleteStreamIfOpeningFails)
577AudioFormatWriter* FlacAudioFormat::createWriterFor (OutputStream* out,
579 unsigned int numberOfChannels,
581 const StringPairArray& ,
582 int qualityOptionIndex)
584 if (out !=
nullptr && getPossibleBitDepths().contains (bitsPerSample))
586 std::unique_ptr<FlacWriter> w (
new FlacWriter (out, sampleRate, numberOfChannels,
587 (uint32) bitsPerSample, qualityOptionIndex));
595StringArray FlacAudioFormat::getQualityOptions()
597 return {
"0 (Fastest)",
"1",
"2",
"3",
"4",
"5 (Default)",
"6",
"7",
"8 (Highest quality)" };
int size() const noexcept
Returns the current number of elements in the array.
Array()=default
Creates an empty array.
ElementType * data() const noexcept
Returns a pointer to the first element in the array.