mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-09 23:34:20 +00:00
Merge 836b9ea9f6 into 0e43b31e50
This commit is contained in:
commit
c85110fb4f
3 changed files with 2110 additions and 5 deletions
|
|
@ -0,0 +1,46 @@
|
||||||
|
/* libFLAC - Free Lossless Audio Codec library
|
||||||
|
* Copyright (C) 2002-2009 Josh Coalson
|
||||||
|
* Copyright (C) 2011-2023 Xiph.Org Foundation
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FLAC__PRIVATE__METADATA_H
|
||||||
|
#define FLAC__PRIVATE__METADATA_H
|
||||||
|
|
||||||
|
#include "../../../metadata.h"
|
||||||
|
|
||||||
|
/* WATCHOUT: all malloc()ed data in the block is free()ed; this may not
|
||||||
|
* be a consistent state (e.g. PICTURE) or equivalent to the initial
|
||||||
|
* state after FLAC__metadata_object_new()
|
||||||
|
*/
|
||||||
|
void FLAC__metadata_object_delete_data(FLAC__StreamMetadata *object);
|
||||||
|
|
||||||
|
void FLAC__metadata_object_cuesheet_track_delete_data(FLAC__StreamMetadata_CueSheet_Track *object);
|
||||||
|
|
||||||
|
#endif
|
||||||
2018
modules/juce_audio_formats/codecs/flac/libFLAC/metadata_object.c
Normal file
2018
modules/juce_audio_formats/codecs/flac/libFLAC/metadata_object.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -174,6 +174,7 @@ namespace FlacNamespace
|
||||||
#include "flac/libFLAC/lpc_intrin_neon.c"
|
#include "flac/libFLAC/lpc_intrin_neon.c"
|
||||||
#include "flac/libFLAC/md5.c"
|
#include "flac/libFLAC/md5.c"
|
||||||
#include "flac/libFLAC/memory.c"
|
#include "flac/libFLAC/memory.c"
|
||||||
|
#include "flac/libFLAC/metadata_object.c"
|
||||||
#include "flac/libFLAC/stream_decoder.c"
|
#include "flac/libFLAC/stream_decoder.c"
|
||||||
#include "flac/libFLAC/stream_encoder.c"
|
#include "flac/libFLAC/stream_encoder.c"
|
||||||
#include "flac/libFLAC/stream_encoder_framing.c"
|
#include "flac/libFLAC/stream_encoder_framing.c"
|
||||||
|
|
@ -209,7 +210,7 @@ public:
|
||||||
{
|
{
|
||||||
lengthInSamples = 0;
|
lengthInSamples = 0;
|
||||||
decoder = FlacNamespace::FLAC__stream_decoder_new();
|
decoder = FlacNamespace::FLAC__stream_decoder_new();
|
||||||
|
FLAC__stream_decoder_set_metadata_respond (decoder, FlacNamespace::FLAC__METADATA_TYPE_VORBIS_COMMENT);
|
||||||
ok = FLAC__stream_decoder_init_stream (decoder,
|
ok = FLAC__stream_decoder_init_stream (decoder,
|
||||||
readCallback_, seekCallback_, tellCallback_, lengthCallback_,
|
readCallback_, seekCallback_, tellCallback_, lengthCallback_,
|
||||||
eofCallback_, writeCallback_, metadataCallback_, errorCallback_,
|
eofCallback_, writeCallback_, metadataCallback_, errorCallback_,
|
||||||
|
|
@ -249,6 +250,21 @@ public:
|
||||||
|
|
||||||
reservoir.setSize ((int) numChannels, 2 * (int) info.max_blocksize, false, false, true);
|
reservoir.setSize ((int) numChannels, 2 * (int) info.max_blocksize, false, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void useComments (const FlacNamespace::FLAC__StreamMetadata_VorbisComment& comments)
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < comments.num_comments; ++i)
|
||||||
|
{
|
||||||
|
const auto& comment = comments.comments[i];
|
||||||
|
char* name { nullptr };
|
||||||
|
char* value { nullptr };
|
||||||
|
|
||||||
|
if(FlacNamespace::FLAC__metadata_object_vorbiscomment_entry_to_name_value_pair(comment, &name, &value) && name && value)
|
||||||
|
{
|
||||||
|
metadataValues.set (CharPointer_UTF8 (name), CharPointer_UTF8 (value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool readSamples (int* const* destSamples, int numDestChannels, int startOffsetInDestBuffer,
|
bool readSamples (int* const* destSamples, int numDestChannels, int startOffsetInDestBuffer,
|
||||||
int64 startSampleInFile, int numSamples) override
|
int64 startSampleInFile, int numSamples) override
|
||||||
|
|
@ -387,7 +403,10 @@ public:
|
||||||
const FlacNamespace::FLAC__StreamMetadata* metadata,
|
const FlacNamespace::FLAC__StreamMetadata* metadata,
|
||||||
void* client_data)
|
void* client_data)
|
||||||
{
|
{
|
||||||
static_cast<FlacReader*> (client_data)->useMetadata (metadata->data.stream_info);
|
if(metadata->type == FlacNamespace::FLAC__METADATA_TYPE_STREAMINFO)
|
||||||
|
static_cast<FlacReader*> (client_data)->useMetadata (metadata->data.stream_info);
|
||||||
|
else if (metadata->type == FlacNamespace::FLAC__METADATA_TYPE_VORBIS_COMMENT)
|
||||||
|
static_cast<FlacReader*> (client_data)->useComments (metadata->data.vorbis_comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void errorCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__StreamDecoderErrorStatus, void*)
|
static void errorCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__StreamDecoderErrorStatus, void*)
|
||||||
|
|
@ -408,12 +427,14 @@ private:
|
||||||
class FlacWriter final : public AudioFormatWriter
|
class FlacWriter final : public AudioFormatWriter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FlacWriter (OutputStream* out, double rate, uint32 numChans, uint32 bits, int qualityOptionIndex)
|
FlacWriter (OutputStream* out, double rate, uint32 numChans, uint32 bits, const std::unordered_map<juce::String, juce::String>& metadataValues, int qualityOptionIndex)
|
||||||
: AudioFormatWriter (out, flacFormatName, rate, numChans, bits),
|
: AudioFormatWriter (out, flacFormatName, rate, numChans, bits),
|
||||||
streamStartPos (output != nullptr ? jmax (output->getPosition(), 0ll) : 0ll)
|
streamStartPos (output != nullptr ? jmax (output->getPosition(), 0ll) : 0ll)
|
||||||
{
|
{
|
||||||
encoder = FlacNamespace::FLAC__stream_encoder_new();
|
encoder = FlacNamespace::FLAC__stream_encoder_new();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (qualityOptionIndex > 0)
|
if (qualityOptionIndex > 0)
|
||||||
FLAC__stream_encoder_set_compression_level (encoder, (uint32) jmin (8, qualityOptionIndex));
|
FLAC__stream_encoder_set_compression_level (encoder, (uint32) jmin (8, qualityOptionIndex));
|
||||||
|
|
||||||
|
|
@ -424,7 +445,21 @@ public:
|
||||||
FLAC__stream_encoder_set_sample_rate (encoder, (unsigned int) sampleRate);
|
FLAC__stream_encoder_set_sample_rate (encoder, (unsigned int) sampleRate);
|
||||||
FLAC__stream_encoder_set_blocksize (encoder, 0);
|
FLAC__stream_encoder_set_blocksize (encoder, 0);
|
||||||
FLAC__stream_encoder_set_do_escape_coding (encoder, true);
|
FLAC__stream_encoder_set_do_escape_coding (encoder, true);
|
||||||
|
if(metadataValues.size() > 0)
|
||||||
|
{
|
||||||
|
metadata[0] = FLAC__metadata_object_new(FlacNamespace::FLAC__METADATA_TYPE_VORBIS_COMMENT);
|
||||||
|
metadata[1] = FLAC__metadata_object_new(FlacNamespace::FLAC__METADATA_TYPE_PADDING);
|
||||||
|
metadata[1]->length = 1024;
|
||||||
|
for(const auto& [key, value] : metadataValues)
|
||||||
|
{
|
||||||
|
FlacNamespace::FLAC__StreamMetadata_VorbisComment_Entry entry;
|
||||||
|
if(FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(&entry, key.toRawUTF8(), value.toRawUTF8()))
|
||||||
|
FLAC__metadata_object_vorbiscomment_append_comment (metadata[0], entry, false);
|
||||||
|
}
|
||||||
|
ok = FLAC__stream_encoder_set_metadata (encoder, metadata.data(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ok = FLAC__stream_encoder_init_stream (encoder,
|
ok = FLAC__stream_encoder_init_stream (encoder,
|
||||||
encodeWriteCallback, encodeSeekCallback,
|
encodeWriteCallback, encodeSeekCallback,
|
||||||
encodeTellCallback, encodeMetadataCallback,
|
encodeTellCallback, encodeMetadataCallback,
|
||||||
|
|
@ -443,6 +478,11 @@ public:
|
||||||
output = nullptr; // to stop the base class deleting this, as it needs to be returned
|
output = nullptr; // to stop the base class deleting this, as it needs to be returned
|
||||||
// to the caller of createWriter()
|
// to the caller of createWriter()
|
||||||
}
|
}
|
||||||
|
for(auto& object : metadata)
|
||||||
|
{
|
||||||
|
if(object)
|
||||||
|
FlacNamespace::FLAC__metadata_object_delete(object);
|
||||||
|
}
|
||||||
|
|
||||||
FlacNamespace::FLAC__stream_encoder_delete (encoder);
|
FlacNamespace::FLAC__stream_encoder_delete (encoder);
|
||||||
}
|
}
|
||||||
|
|
@ -525,7 +565,7 @@ public:
|
||||||
output->writeIntBigEndian (FLAC__STREAM_METADATA_STREAMINFO_LENGTH);
|
output->writeIntBigEndian (FLAC__STREAM_METADATA_STREAMINFO_LENGTH);
|
||||||
output->write (buffer, FLAC__STREAM_METADATA_STREAMINFO_LENGTH);
|
output->write (buffer, FLAC__STREAM_METADATA_STREAMINFO_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
static FlacNamespace::FLAC__StreamEncoderWriteStatus encodeWriteCallback (const FlacNamespace::FLAC__StreamEncoder*,
|
static FlacNamespace::FLAC__StreamEncoderWriteStatus encodeWriteCallback (const FlacNamespace::FLAC__StreamEncoder*,
|
||||||
const FlacNamespace::FLAC__byte buffer[],
|
const FlacNamespace::FLAC__byte buffer[],
|
||||||
|
|
@ -563,7 +603,7 @@ public:
|
||||||
private:
|
private:
|
||||||
FlacNamespace::FLAC__StreamEncoder* encoder;
|
FlacNamespace::FLAC__StreamEncoder* encoder;
|
||||||
int64 streamStartPos;
|
int64 streamStartPos;
|
||||||
|
std::array<FlacNamespace::FLAC__StreamMetadata*,2> metadata { { nullptr, nullptr } };
|
||||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FlacWriter)
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FlacWriter)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -610,6 +650,7 @@ std::unique_ptr<AudioFormatWriter> FlacAudioFormat::createWriterFor (std::unique
|
||||||
options.getSampleRate(),
|
options.getSampleRate(),
|
||||||
(uint32) options.getNumChannels(),
|
(uint32) options.getNumChannels(),
|
||||||
(uint32) options.getBitsPerSample(),
|
(uint32) options.getBitsPerSample(),
|
||||||
|
options.getMetadataValues(),
|
||||||
options.getQualityOptionIndex());
|
options.getQualityOptionIndex());
|
||||||
|
|
||||||
if (! writer->ok)
|
if (! writer->ok)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue