Add remaining files
[juce-lv2.git] / juce / source / src / audio / audio_file_formats / juce_FlacAudioFormat.cpp
blob3091c9af99b3260aaf7970754ecc1d8e6b656b7a
1 /*
2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #include "../../core/juce_TargetPlatform.h"
27 #include "../../../juce_Config.h"
29 #if JUCE_USE_FLAC
31 #if JUCE_WINDOWS
32 #include <windows.h>
33 #endif
35 #include "../../core/juce_StandardHeader.h"
37 BEGIN_JUCE_NAMESPACE
39 namespace FlacNamespace
41 #if JUCE_INCLUDE_FLAC_CODE
42 #if JUCE_MSVC
43 #pragma warning (disable: 4505 181 111)
44 #endif
46 #define FLAC__NO_DLL 1
48 #if ! defined (SIZE_MAX)
49 #define SIZE_MAX 0xffffffff
50 #endif
52 #define __STDC_LIMIT_MACROS 1
53 #include "flac/all.h"
54 #include "flac/libFLAC/bitmath.c"
55 #include "flac/libFLAC/bitreader.c"
56 #include "flac/libFLAC/bitwriter.c"
57 #include "flac/libFLAC/cpu.c"
58 #include "flac/libFLAC/crc.c"
59 #include "flac/libFLAC/fixed.c"
60 #include "flac/libFLAC/float.c"
61 #include "flac/libFLAC/format.c"
62 #include "flac/libFLAC/lpc_flac.c"
63 #include "flac/libFLAC/md5.c"
64 #include "flac/libFLAC/memory.c"
65 #include "flac/libFLAC/stream_decoder.c"
66 #include "flac/libFLAC/stream_encoder.c"
67 #include "flac/libFLAC/stream_encoder_framing.c"
68 #include "flac/libFLAC/window_flac.c"
69 #else
70 #include <FLAC/all.h>
71 #endif
74 #undef max
75 #undef min
77 #include "juce_FlacAudioFormat.h"
78 #include "../../text/juce_LocalisedStrings.h"
79 #include "../../memory/juce_ScopedPointer.h"
82 //==============================================================================
83 static const char* const flacFormatName = "FLAC file";
84 static const char* const flacExtensions[] = { ".flac", 0 };
87 //==============================================================================
88 class FlacReader : public AudioFormatReader
90 public:
91 //==============================================================================
92 FlacReader (InputStream* const in)
93 : AudioFormatReader (in, TRANS (flacFormatName)),
94 reservoir (2, 0),
95 reservoirStart (0),
96 samplesInReservoir (0),
97 scanningForLength (false)
99 using namespace FlacNamespace;
100 lengthInSamples = 0;
102 decoder = FLAC__stream_decoder_new();
104 ok = FLAC__stream_decoder_init_stream (decoder,
105 readCallback_, seekCallback_, tellCallback_, lengthCallback_,
106 eofCallback_, writeCallback_, metadataCallback_, errorCallback_,
107 this) == FLAC__STREAM_DECODER_INIT_STATUS_OK;
109 if (ok)
111 FLAC__stream_decoder_process_until_end_of_metadata (decoder);
113 if (lengthInSamples == 0 && sampleRate > 0)
115 // the length hasn't been stored in the metadata, so we'll need to
116 // work it out the length the hard way, by scanning the whole file..
117 scanningForLength = true;
118 FLAC__stream_decoder_process_until_end_of_stream (decoder);
119 scanningForLength = false;
120 const int64 tempLength = lengthInSamples;
122 FLAC__stream_decoder_reset (decoder);
123 FLAC__stream_decoder_process_until_end_of_metadata (decoder);
124 lengthInSamples = tempLength;
129 ~FlacReader()
131 FlacNamespace::FLAC__stream_decoder_delete (decoder);
134 void useMetadata (const FlacNamespace::FLAC__StreamMetadata_StreamInfo& info)
136 sampleRate = info.sample_rate;
137 bitsPerSample = info.bits_per_sample;
138 lengthInSamples = (unsigned int) info.total_samples;
139 numChannels = info.channels;
141 reservoir.setSize (numChannels, 2 * info.max_blocksize, false, false, true);
144 // returns the number of samples read
145 bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer,
146 int64 startSampleInFile, int numSamples)
148 using namespace FlacNamespace;
150 if (! ok)
151 return false;
153 while (numSamples > 0)
155 if (startSampleInFile >= reservoirStart
156 && startSampleInFile < reservoirStart + samplesInReservoir)
158 const int num = (int) jmin ((int64) numSamples,
159 reservoirStart + samplesInReservoir - startSampleInFile);
161 jassert (num > 0);
163 for (int i = jmin (numDestChannels, reservoir.getNumChannels()); --i >= 0;)
164 if (destSamples[i] != nullptr)
165 memcpy (destSamples[i] + startOffsetInDestBuffer,
166 reservoir.getSampleData (i, (int) (startSampleInFile - reservoirStart)),
167 sizeof (int) * num);
169 startOffsetInDestBuffer += num;
170 startSampleInFile += num;
171 numSamples -= num;
173 else
175 if (startSampleInFile >= (int) lengthInSamples)
177 samplesInReservoir = 0;
179 else if (startSampleInFile < reservoirStart
180 || startSampleInFile > reservoirStart + jmax (samplesInReservoir, 511))
182 // had some problems with flac crashing if the read pos is aligned more
183 // accurately than this. Probably fixed in newer versions of the library, though.
184 reservoirStart = (int) (startSampleInFile & ~511);
185 samplesInReservoir = 0;
186 FLAC__stream_decoder_seek_absolute (decoder, (FLAC__uint64) reservoirStart);
188 else
190 reservoirStart += samplesInReservoir;
191 samplesInReservoir = 0;
192 FLAC__stream_decoder_process_single (decoder);
195 if (samplesInReservoir == 0)
196 break;
200 if (numSamples > 0)
202 for (int i = numDestChannels; --i >= 0;)
203 if (destSamples[i] != nullptr)
204 zeromem (destSamples[i] + startOffsetInDestBuffer,
205 sizeof (int) * numSamples);
208 return true;
211 void useSamples (const FlacNamespace::FLAC__int32* const buffer[], int numSamples)
213 if (scanningForLength)
215 lengthInSamples += numSamples;
217 else
219 if (numSamples > reservoir.getNumSamples())
220 reservoir.setSize (numChannels, numSamples, false, false, true);
222 const int bitsToShift = 32 - bitsPerSample;
224 for (int i = 0; i < (int) numChannels; ++i)
226 const FlacNamespace::FLAC__int32* src = buffer[i];
228 int n = i;
229 while (src == 0 && n > 0)
230 src = buffer [--n];
232 if (src != nullptr)
234 int* dest = reinterpret_cast<int*> (reservoir.getSampleData(i));
236 for (int j = 0; j < numSamples; ++j)
237 dest[j] = src[j] << bitsToShift;
241 samplesInReservoir = numSamples;
245 //==============================================================================
246 static FlacNamespace::FLAC__StreamDecoderReadStatus readCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__byte buffer[], size_t* bytes, void* client_data)
248 using namespace FlacNamespace;
249 *bytes = (size_t) static_cast <const FlacReader*> (client_data)->input->read (buffer, (int) *bytes);
250 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
253 static FlacNamespace::FLAC__StreamDecoderSeekStatus seekCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__uint64 absolute_byte_offset, void* client_data)
255 using namespace FlacNamespace;
256 static_cast <const FlacReader*> (client_data)->input->setPosition ((int) absolute_byte_offset);
257 return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
260 static FlacNamespace::FLAC__StreamDecoderTellStatus tellCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__uint64* absolute_byte_offset, void* client_data)
262 using namespace FlacNamespace;
263 *absolute_byte_offset = static_cast <const FlacReader*> (client_data)->input->getPosition();
264 return FLAC__STREAM_DECODER_TELL_STATUS_OK;
267 static FlacNamespace::FLAC__StreamDecoderLengthStatus lengthCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__uint64* stream_length, void* client_data)
269 using namespace FlacNamespace;
270 *stream_length = static_cast <const FlacReader*> (client_data)->input->getTotalLength();
271 return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
274 static FlacNamespace::FLAC__bool eofCallback_ (const FlacNamespace::FLAC__StreamDecoder*, void* client_data)
276 return static_cast <const FlacReader*> (client_data)->input->isExhausted();
279 static FlacNamespace::FLAC__StreamDecoderWriteStatus writeCallback_ (const FlacNamespace::FLAC__StreamDecoder*,
280 const FlacNamespace::FLAC__Frame* frame,
281 const FlacNamespace::FLAC__int32* const buffer[],
282 void* client_data)
284 using namespace FlacNamespace;
285 static_cast <FlacReader*> (client_data)->useSamples (buffer, frame->header.blocksize);
286 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
289 static void metadataCallback_ (const FlacNamespace::FLAC__StreamDecoder*,
290 const FlacNamespace::FLAC__StreamMetadata* metadata,
291 void* client_data)
293 static_cast <FlacReader*> (client_data)->useMetadata (metadata->data.stream_info);
296 static void errorCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__StreamDecoderErrorStatus, void*)
300 private:
301 FlacNamespace::FLAC__StreamDecoder* decoder;
302 AudioSampleBuffer reservoir;
303 int reservoirStart, samplesInReservoir;
304 bool ok, scanningForLength;
306 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FlacReader);
310 //==============================================================================
311 class FlacWriter : public AudioFormatWriter
313 public:
314 //==============================================================================
315 FlacWriter (OutputStream* const out, double sampleRate_,
316 int numChannels_, int bitsPerSample_, int qualityOptionIndex)
317 : AudioFormatWriter (out, TRANS (flacFormatName),
318 sampleRate_, numChannels_, bitsPerSample_)
320 using namespace FlacNamespace;
321 encoder = FLAC__stream_encoder_new();
323 if (qualityOptionIndex > 0)
324 FLAC__stream_encoder_set_compression_level (encoder, jmin (8, qualityOptionIndex));
326 FLAC__stream_encoder_set_do_mid_side_stereo (encoder, numChannels == 2);
327 FLAC__stream_encoder_set_loose_mid_side_stereo (encoder, numChannels == 2);
328 FLAC__stream_encoder_set_channels (encoder, numChannels);
329 FLAC__stream_encoder_set_bits_per_sample (encoder, jmin ((unsigned int) 24, bitsPerSample));
330 FLAC__stream_encoder_set_sample_rate (encoder, (unsigned int) sampleRate);
331 FLAC__stream_encoder_set_blocksize (encoder, 0);
332 FLAC__stream_encoder_set_do_escape_coding (encoder, true);
334 ok = FLAC__stream_encoder_init_stream (encoder,
335 encodeWriteCallback, encodeSeekCallback,
336 encodeTellCallback, encodeMetadataCallback,
337 this) == FLAC__STREAM_ENCODER_INIT_STATUS_OK;
340 ~FlacWriter()
342 if (ok)
344 FlacNamespace::FLAC__stream_encoder_finish (encoder);
345 output->flush();
347 else
349 output = 0; // to stop the base class deleting this, as it needs to be returned
350 // to the caller of createWriter()
353 FlacNamespace::FLAC__stream_encoder_delete (encoder);
356 //==============================================================================
357 bool write (const int** samplesToWrite, int numSamples)
359 using namespace FlacNamespace;
360 if (! ok)
361 return false;
363 HeapBlock<int*> channels;
364 HeapBlock<int> temp;
365 const int bitsToShift = 32 - bitsPerSample;
367 if (bitsToShift > 0)
369 temp.malloc (numSamples * numChannels);
370 channels.calloc (numChannels + 1);
372 for (unsigned int i = 0; i < numChannels; ++i)
374 if (samplesToWrite[i] == nullptr)
375 break;
377 int* const destData = temp.getData() + i * numSamples;
378 channels[i] = destData;
380 for (int j = 0; j < numSamples; ++j)
381 destData[j] = (samplesToWrite[i][j] >> bitsToShift);
384 samplesToWrite = const_cast<const int**> (channels.getData());
387 return FLAC__stream_encoder_process (encoder, (const FLAC__int32**) samplesToWrite, numSamples) != 0;
390 bool writeData (const void* const data, const int size) const
392 return output->write (data, size);
395 static void packUint32 (FlacNamespace::FLAC__uint32 val, FlacNamespace::FLAC__byte* b, const int bytes)
397 b += bytes;
399 for (int i = 0; i < bytes; ++i)
401 *(--b) = (FlacNamespace::FLAC__byte) (val & 0xff);
402 val >>= 8;
406 void writeMetaData (const FlacNamespace::FLAC__StreamMetadata* metadata)
408 using namespace FlacNamespace;
409 const FLAC__StreamMetadata_StreamInfo& info = metadata->data.stream_info;
411 unsigned char buffer [FLAC__STREAM_METADATA_STREAMINFO_LENGTH];
412 const unsigned int channelsMinus1 = info.channels - 1;
413 const unsigned int bitsMinus1 = info.bits_per_sample - 1;
415 packUint32 (info.min_blocksize, buffer, 2);
416 packUint32 (info.max_blocksize, buffer + 2, 2);
417 packUint32 (info.min_framesize, buffer + 4, 3);
418 packUint32 (info.max_framesize, buffer + 7, 3);
419 buffer[10] = (uint8) ((info.sample_rate >> 12) & 0xff);
420 buffer[11] = (uint8) ((info.sample_rate >> 4) & 0xff);
421 buffer[12] = (uint8) (((info.sample_rate & 0x0f) << 4) | (channelsMinus1 << 1) | (bitsMinus1 >> 4));
422 buffer[13] = (FLAC__byte) (((bitsMinus1 & 0x0f) << 4) | (unsigned int) ((info.total_samples >> 32) & 0x0f));
423 packUint32 ((FLAC__uint32) info.total_samples, buffer + 14, 4);
424 memcpy (buffer + 18, info.md5sum, 16);
426 const bool seekOk = output->setPosition (4);
427 (void) seekOk;
429 // if this fails, you've given it an output stream that can't seek! It needs
430 // to be able to seek back to write the header
431 jassert (seekOk);
433 output->writeIntBigEndian (FLAC__STREAM_METADATA_STREAMINFO_LENGTH);
434 output->write (buffer, FLAC__STREAM_METADATA_STREAMINFO_LENGTH);
437 //==============================================================================
438 static FlacNamespace::FLAC__StreamEncoderWriteStatus encodeWriteCallback (const FlacNamespace::FLAC__StreamEncoder*,
439 const FlacNamespace::FLAC__byte buffer[],
440 size_t bytes,
441 unsigned int /*samples*/,
442 unsigned int /*current_frame*/,
443 void* client_data)
445 using namespace FlacNamespace;
446 return static_cast <FlacWriter*> (client_data)->writeData (buffer, (int) bytes)
447 ? FLAC__STREAM_ENCODER_WRITE_STATUS_OK
448 : FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
451 static FlacNamespace::FLAC__StreamEncoderSeekStatus encodeSeekCallback (const FlacNamespace::FLAC__StreamEncoder*, FlacNamespace::FLAC__uint64, void*)
453 using namespace FlacNamespace;
454 return FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED;
457 static FlacNamespace::FLAC__StreamEncoderTellStatus encodeTellCallback (const FlacNamespace::FLAC__StreamEncoder*, FlacNamespace::FLAC__uint64* absolute_byte_offset, void* client_data)
459 using namespace FlacNamespace;
460 if (client_data == 0)
461 return FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED;
463 *absolute_byte_offset = (FLAC__uint64) static_cast <FlacWriter*> (client_data)->output->getPosition();
464 return FLAC__STREAM_ENCODER_TELL_STATUS_OK;
467 static void encodeMetadataCallback (const FlacNamespace::FLAC__StreamEncoder*, const FlacNamespace::FLAC__StreamMetadata* metadata, void* client_data)
469 static_cast <FlacWriter*> (client_data)->writeMetaData (metadata);
472 bool ok;
474 private:
475 FlacNamespace::FLAC__StreamEncoder* encoder;
477 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FlacWriter);
481 //==============================================================================
482 FlacAudioFormat::FlacAudioFormat()
483 : AudioFormat (TRANS (flacFormatName), StringArray (flacExtensions))
487 FlacAudioFormat::~FlacAudioFormat()
491 const Array <int> FlacAudioFormat::getPossibleSampleRates()
493 const int rates[] = { 22050, 32000, 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000, 0 };
494 return Array <int> (rates);
497 const Array <int> FlacAudioFormat::getPossibleBitDepths()
499 const int depths[] = { 16, 24, 0 };
500 return Array <int> (depths);
503 bool FlacAudioFormat::canDoStereo() { return true; }
504 bool FlacAudioFormat::canDoMono() { return true; }
505 bool FlacAudioFormat::isCompressed() { return true; }
507 AudioFormatReader* FlacAudioFormat::createReaderFor (InputStream* in,
508 const bool deleteStreamIfOpeningFails)
510 ScopedPointer<FlacReader> r (new FlacReader (in));
512 if (r->sampleRate > 0)
513 return r.release();
515 if (! deleteStreamIfOpeningFails)
516 r->input = nullptr;
518 return nullptr;
521 AudioFormatWriter* FlacAudioFormat::createWriterFor (OutputStream* out,
522 double sampleRate,
523 unsigned int numberOfChannels,
524 int bitsPerSample,
525 const StringPairArray& /*metadataValues*/,
526 int qualityOptionIndex)
528 if (getPossibleBitDepths().contains (bitsPerSample))
530 ScopedPointer<FlacWriter> w (new FlacWriter (out, sampleRate, numberOfChannels, bitsPerSample, qualityOptionIndex));
532 if (w->ok)
533 return w.release();
536 return nullptr;
539 StringArray FlacAudioFormat::getQualityOptions()
541 const char* options[] = { "0 (Fastest)", "1", "2", "3", "4", "5 (Default)","6", "7", "8 (Highest quality)", 0 };
542 return StringArray (options);
545 END_JUCE_NAMESPACE
547 #endif