33#if defined _WIN32 && !defined __CYGWIN__
39#if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__
40 #include <sys/types.h>
44 #define __STDC_FORMAT_MACROS
48#if defined _MSC_VER || defined __MINGW32__ || defined __CYGWIN__ || defined __EMX__
55#if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__
56 #if defined __BORLANDC__
59 #include <sys/utime.h>
62 #include <sys/types.h>
93#if JUCE_INCLUDE_FLAC_CODE || ! defined (JUCE_INCLUDE_FLAC_CODE)
95 #undef PACKAGE_VERSION
96 #define PACKAGE_VERSION "1.4.3"
98 #define FLAC__NO_DLL 1
100 JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312 4505 4365 4005 4334 181 111 6340 6308 6297 6001 6320)
102 #define HAVE_LROUND 1
106 #define FLAC__SYS_DARWIN 1
110 #define SIZE_MAX 0xffffffff
113 JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE (
"-Wconversion",
114 "-Wdeprecated-register",
116 "-Wimplicit-fallthrough",
117 "-Wlanguage-extension-token",
123 "-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 #if JUCE_ARM && JUCE_64BIT
136 #define FLAC__CPU_ARM64 1
138 #if JUCE_USE_ARM_NEON
139 #define FLAC__HAS_NEONINTRIN 1
140 #define FLAC__HAS_A64NEONINTRIN 1
144 #define flac_max jmax
145 #define flac_min jmin
147 #pragma push_macro ("DEBUG")
148 #pragma push_macro ("NDEBUG")
157 #include "flac/all.h"
158 #include "flac/libFLAC/bitmath.c"
159 #include "flac/libFLAC/bitreader.c"
160 #include "flac/libFLAC/bitwriter.c"
161 #include "flac/libFLAC/cpu.c"
162 #include "flac/libFLAC/crc.c"
163 #include "flac/libFLAC/fixed.c"
164 #include "flac/libFLAC/float.c"
165 #include "flac/libFLAC/format.c"
166 #include "flac/libFLAC/lpc_flac.c"
167 #include "flac/libFLAC/lpc_intrin_neon.c"
168 #include "flac/libFLAC/md5.c"
169 #include "flac/libFLAC/memory.c"
170 #include "flac/libFLAC/stream_decoder.c"
171 #include "flac/libFLAC/stream_encoder.c"
172 #include "flac/libFLAC/stream_encoder_framing.c"
173 #include "flac/libFLAC/window_flac.c"
176 #pragma pop_macro ("DEBUG")
177 #pragma pop_macro ("NDEBUG")
179 #undef PACKAGE_VERSION
181 JUCE_END_IGNORE_WARNINGS_GCC_LIKE
182 JUCE_END_IGNORE_WARNINGS_MSVC
185 #include <FLAC/all.h>
195template <
typename Item>
205 decoder = FlacNamespace::FLAC__stream_decoder_new();
210 this) == FlacNamespace::FLAC__STREAM_DECODER_INIT_STATUS_OK;
216 if (lengthInSamples == 0 && sampleRate > 0)
234 FlacNamespace::FLAC__stream_decoder_delete (
decoder);
237 void useMetadata (
const FlacNamespace::FLAC__StreamMetadata_StreamInfo& info)
239 sampleRate = info.sample_rate;
240 bitsPerSample = info.bits_per_sample;
241 lengthInSamples = (
unsigned int) info.total_samples;
242 numChannels = info.channels;
244 reservoir.setSize ((
int) numChannels, 2 * (
int) info.max_blocksize,
false,
false,
true);
289 bufferedRange = emptyRange (bufferedRange.getEnd());
307 void useSamples (
const FlacNamespace::FLAC__int32*
const buffer[],
int numSamples)
311 lengthInSamples += numSamples;
315 if (numSamples >
reservoir.getNumSamples())
316 reservoir.setSize ((
int) numChannels, numSamples,
false,
false,
true);
320 for (
int i = 0; i < (
int) numChannels; ++i)
322 auto* src = buffer[i];
325 while (src ==
nullptr && n > 0)
330 auto* dest =
reinterpret_cast<int*
> (
reservoir.getWritePointer (i));
332 for (
int j = 0;
j < numSamples; ++
j)
337 bufferedRange.setLength (numSamples);
342 static FlacNamespace::FLAC__StreamDecoderReadStatus
readCallback_ (
const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__byte buffer[],
size_t* bytes,
void*
client_data)
345 return FlacNamespace::FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
351 return FlacNamespace::FLAC__STREAM_DECODER_SEEK_STATUS_OK;
357 return FlacNamespace::FLAC__STREAM_DECODER_TELL_STATUS_OK;
363 return FlacNamespace::FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
371 static FlacNamespace::FLAC__StreamDecoderWriteStatus
writeCallback_ (
const FlacNamespace::FLAC__StreamDecoder*,
372 const FlacNamespace::FLAC__Frame* frame,
373 const FlacNamespace::FLAC__int32*
const buffer[],
377 return FlacNamespace::FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
381 const FlacNamespace::FLAC__StreamMetadata*
metadata,
387 static void errorCallback_ (
const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__StreamDecoderErrorStatus,
void*)
392 FlacNamespace::FLAC__StreamDecoder*
decoder;
394 Range<int64> bufferedRange;
409 encoder = FlacNamespace::FLAC__stream_encoder_new();
425 this) == FlacNamespace::FLAC__STREAM_ENCODER_INIT_STATUS_OK;
432 FlacNamespace::FLAC__stream_encoder_finish (
encoder);
441 FlacNamespace::FLAC__stream_encoder_delete (
encoder);
456 temp.malloc (numChannels * (
size_t) numSamples);
457 channels.calloc (numChannels + 1);
459 for (
unsigned int i = 0; i < numChannels; ++i)
464 auto* destData = temp.get() + i * (
size_t) numSamples;
465 channels[i] = destData;
467 for (
int j = 0;
j < numSamples; ++
j)
477 bool writeData (
const void*
const data,
const int size)
const
479 return output->write (data, (
size_t) size);
482 static void packUint32 (FlacNamespace::FLAC__uint32
val, FlacNamespace::FLAC__byte* b,
const int bytes)
486 for (
int i = 0; i < bytes; ++i)
488 *(--b) = (FlacNamespace::FLAC__byte) (
val & 0xff);
496 auto& info =
metadata->data.stream_info;
500 const unsigned int bitsMinus1 = info.bits_per_sample - 1;
503 packUint32 (info.max_blocksize, buffer + 2, 2);
504 packUint32 (info.min_framesize, buffer + 4, 3);
505 packUint32 (info.max_framesize, buffer + 7, 3);
506 buffer[10] = (
uint8) ((info.sample_rate >> 12) & 0xff);
507 buffer[11] = (
uint8) ((info.sample_rate >> 4) & 0xff);
509 buffer[13] = (
FLAC__byte) (((
bitsMinus1 & 0x0f) << 4) | (
unsigned int) ((info.total_samples >> 32) & 0x0f));
511 memcpy (buffer + 18, info.md5sum, 16);
524 static FlacNamespace::FLAC__StreamEncoderWriteStatus
encodeWriteCallback (
const FlacNamespace::FLAC__StreamEncoder*,
525 const FlacNamespace::FLAC__byte buffer[],
532 ? FlacNamespace::FLAC__STREAM_ENCODER_WRITE_STATUS_OK
536 static FlacNamespace::FLAC__StreamEncoderSeekStatus
encodeSeekCallback (
const FlacNamespace::FLAC__StreamEncoder*, FlacNamespace::FLAC__uint64,
void*)
538 return FlacNamespace::FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED;
544 return FlacNamespace::FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED;
547 return FlacNamespace::FLAC__STREAM_ENCODER_TELL_STATUS_OK;
558 FlacNamespace::FLAC__StreamEncoder*
encoder;
566FlacAudioFormat::FlacAudioFormat() : AudioFormat (
flacFormatName,
".flac") {}
567FlacAudioFormat::~FlacAudioFormat() {}
569Array<int> FlacAudioFormat::getPossibleSampleRates()
571 return { 8000, 11025, 12000, 16000, 22050, 32000, 44100, 48000,
572 88200, 96000, 176400, 192000, 352800, 384000 };
575Array<int> FlacAudioFormat::getPossibleBitDepths()
580bool FlacAudioFormat::canDoStereo() {
return true; }
581bool FlacAudioFormat::canDoMono() {
return true; }
582bool FlacAudioFormat::isCompressed() {
return true; }
584AudioFormatReader* FlacAudioFormat::createReaderFor (InputStream* in,
const bool deleteStreamIfOpeningFails)
588 if (r->sampleRate > 0)
591 if (! deleteStreamIfOpeningFails)
597AudioFormatWriter* FlacAudioFormat::createWriterFor (OutputStream* out,
599 unsigned int numberOfChannels,
601 const StringPairArray& ,
602 int qualityOptionIndex)
604 if (out !=
nullptr && getPossibleBitDepths().contains (bitsPerSample))
607 (uint32) bitsPerSample, qualityOptionIndex));
615StringArray FlacAudioFormat::getQualityOptions()
617 return {
"0 (Fastest)",
"1",
"2",
"3",
"4",
"5 (Default)",
"6",
"7",
"8 (Highest quality)" };
static constexpr Range emptyRange(const ValueType start) noexcept
Returns a range with the specified start position and a length of zero.
constexpr Type jmin(Type a, Type b)
Returns the smaller of two values.
constexpr Type jmax(Type a, Type b)
Returns the larger of two values.
unsigned long long uint64
A platform-independent 64-bit unsigned integer type.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
unsigned int uint32
A platform-independent 32-bit unsigned integer type.
unsigned char uint8
A platform-independent 8-bit unsigned integer type.
long long int64
A platform-independent 64-bit integer type.
void zeromem(void *memory, size_t numBytes) noexcept
Fills a block of memory with zeros.
static Range< Index > doBufferedRead(Range< Index > rangeToRead, GetBufferedRange &&getBufferedRange, ReadFromReservoir &&readFromReservoir, FillReservoir &&fillReservoir)
Attempts to read the requested range from some kind of input stream, with intermediate buffering in a...