mirror of
https://github.com/SFML/SFML.git
synced 2025-01-19 07:45:13 +08:00
Modernize memory management of FLAC pointers
This commit is contained in:
parent
f3341359eb
commit
95465a3359
@ -184,6 +184,14 @@ void streamError(const FLAC__StreamDecoder*, FLAC__StreamDecoderErrorStatus, voi
|
||||
|
||||
namespace sf::priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
void SoundFileReaderFlac::FlacStreamDecoderDeleter::operator()(FLAC__StreamDecoder* decoder) const
|
||||
{
|
||||
FLAC__stream_decoder_finish(decoder);
|
||||
FLAC__stream_decoder_delete(decoder);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool SoundFileReaderFlac::check(InputStream& stream)
|
||||
{
|
||||
@ -218,18 +226,11 @@ bool SoundFileReaderFlac::check(InputStream& stream)
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
SoundFileReaderFlac::~SoundFileReaderFlac()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool SoundFileReaderFlac::open(InputStream& stream, Info& info)
|
||||
{
|
||||
// Create the decoder
|
||||
m_decoder = FLAC__stream_decoder_new();
|
||||
m_decoder.reset(FLAC__stream_decoder_new());
|
||||
if (!m_decoder)
|
||||
{
|
||||
err() << "Failed to open FLAC file (failed to allocate the decoder)" << std::endl;
|
||||
@ -238,7 +239,7 @@ bool SoundFileReaderFlac::open(InputStream& stream, Info& info)
|
||||
|
||||
// Initialize the decoder with our callbacks
|
||||
m_clientData.stream = &stream;
|
||||
FLAC__stream_decoder_init_stream(m_decoder,
|
||||
FLAC__stream_decoder_init_stream(m_decoder.get(),
|
||||
&streamRead,
|
||||
&streamSeek,
|
||||
&streamTell,
|
||||
@ -250,9 +251,9 @@ bool SoundFileReaderFlac::open(InputStream& stream, Info& info)
|
||||
&m_clientData);
|
||||
|
||||
// Read the header
|
||||
if (!FLAC__stream_decoder_process_until_end_of_metadata(m_decoder))
|
||||
if (!FLAC__stream_decoder_process_until_end_of_metadata(m_decoder.get()))
|
||||
{
|
||||
close();
|
||||
m_decoder.reset();
|
||||
err() << "Failed to open FLAC file (failed to read metadata)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
@ -279,13 +280,14 @@ void SoundFileReaderFlac::seek(std::uint64_t sampleOffset)
|
||||
{
|
||||
// The "write" callback will populate the leftovers buffer with the first batch of samples from the
|
||||
// seek destination, and since we want that data in this typical case, we don't re-clear it afterward
|
||||
FLAC__stream_decoder_seek_absolute(m_decoder, sampleOffset / m_clientData.info.channelCount);
|
||||
FLAC__stream_decoder_seek_absolute(m_decoder.get(), sampleOffset / m_clientData.info.channelCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
// FLAC decoder can't skip straight to EOF, so we short-seek by one sample and skip the rest
|
||||
FLAC__stream_decoder_seek_absolute(m_decoder, (m_clientData.info.sampleCount / m_clientData.info.channelCount) - 1);
|
||||
FLAC__stream_decoder_skip_single_frame(m_decoder);
|
||||
FLAC__stream_decoder_seek_absolute(m_decoder.get(),
|
||||
(m_clientData.info.sampleCount / m_clientData.info.channelCount) - 1);
|
||||
FLAC__stream_decoder_skip_single_frame(m_decoder.get());
|
||||
|
||||
// This was re-populated during the seek, but we're skipping everything in this, so we need it emptied
|
||||
m_clientData.leftovers.clear();
|
||||
@ -331,27 +333,15 @@ std::uint64_t SoundFileReaderFlac::read(std::int16_t* samples, std::uint64_t max
|
||||
{
|
||||
// Everything happens in the "write" callback
|
||||
// This will break on any fatal error (does not include EOF)
|
||||
if (!FLAC__stream_decoder_process_single(m_decoder))
|
||||
if (!FLAC__stream_decoder_process_single(m_decoder.get()))
|
||||
break;
|
||||
|
||||
// Break on EOF
|
||||
if (FLAC__stream_decoder_get_state(m_decoder) == FLAC__STREAM_DECODER_END_OF_STREAM)
|
||||
if (FLAC__stream_decoder_get_state(m_decoder.get()) == FLAC__STREAM_DECODER_END_OF_STREAM)
|
||||
break;
|
||||
}
|
||||
|
||||
return maxCount - m_clientData.remaining;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void SoundFileReaderFlac::close()
|
||||
{
|
||||
if (m_decoder)
|
||||
{
|
||||
FLAC__stream_decoder_finish(m_decoder);
|
||||
FLAC__stream_decoder_delete(m_decoder);
|
||||
m_decoder = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sf::priv
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <SFML/Audio/SoundFileReader.hpp>
|
||||
|
||||
#include <FLAC/stream_decoder.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
|
||||
@ -52,12 +53,6 @@ public:
|
||||
////////////////////////////////////////////////////////////
|
||||
[[nodiscard]] static bool check(InputStream& stream);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Default constructor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
~SoundFileReaderFlac() override;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Open a sound file for reading
|
||||
///
|
||||
@ -108,16 +103,14 @@ public:
|
||||
};
|
||||
|
||||
private:
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Close the open FLAC file
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void close();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
FLAC__StreamDecoder* m_decoder{}; //!< FLAC decoder
|
||||
struct FlacStreamDecoderDeleter
|
||||
{
|
||||
void operator()(FLAC__StreamDecoder* decoder) const;
|
||||
};
|
||||
std::unique_ptr<FLAC__StreamDecoder, FlacStreamDecoderDeleter> m_decoder; //!< FLAC decoder
|
||||
ClientData m_clientData; //!< Structure passed to the decoder callbacks
|
||||
};
|
||||
|
||||
|
@ -39,6 +39,14 @@
|
||||
|
||||
namespace sf::priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
void SoundFileWriterFlac::FlacStreamEncoderDeleter::operator()(FLAC__StreamEncoder* encoder) const
|
||||
{
|
||||
FLAC__stream_encoder_finish(encoder);
|
||||
FLAC__stream_encoder_delete(encoder);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool SoundFileWriterFlac::check(const std::filesystem::path& filename)
|
||||
{
|
||||
@ -46,18 +54,11 @@ bool SoundFileWriterFlac::check(const std::filesystem::path& filename)
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
SoundFileWriterFlac::~SoundFileWriterFlac()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool SoundFileWriterFlac::open(const std::filesystem::path& filename, unsigned int sampleRate, unsigned int channelCount)
|
||||
{
|
||||
// Create the encoder
|
||||
m_encoder = FLAC__stream_encoder_new();
|
||||
m_encoder.reset(FLAC__stream_encoder_new());
|
||||
if (!m_encoder)
|
||||
{
|
||||
err() << "Failed to write flac file (failed to allocate encoder)\n"
|
||||
@ -66,16 +67,16 @@ bool SoundFileWriterFlac::open(const std::filesystem::path& filename, unsigned i
|
||||
}
|
||||
|
||||
// Setup the encoder
|
||||
FLAC__stream_encoder_set_channels(m_encoder, channelCount);
|
||||
FLAC__stream_encoder_set_bits_per_sample(m_encoder, 16);
|
||||
FLAC__stream_encoder_set_sample_rate(m_encoder, sampleRate);
|
||||
FLAC__stream_encoder_set_channels(m_encoder.get(), channelCount);
|
||||
FLAC__stream_encoder_set_bits_per_sample(m_encoder.get(), 16);
|
||||
FLAC__stream_encoder_set_sample_rate(m_encoder.get(), sampleRate);
|
||||
|
||||
// Initialize the output stream
|
||||
if (FLAC__stream_encoder_init_file(m_encoder, filename.string().c_str(), nullptr, nullptr) !=
|
||||
if (FLAC__stream_encoder_init_file(m_encoder.get(), filename.string().c_str(), nullptr, nullptr) !=
|
||||
FLAC__STREAM_ENCODER_INIT_STATUS_OK)
|
||||
{
|
||||
err() << "Failed to write flac file (failed to open the file)\n" << formatDebugPathInfo(filename) << std::endl;
|
||||
close();
|
||||
m_encoder.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -98,7 +99,7 @@ void SoundFileWriterFlac::write(const std::int16_t* samples, std::uint64_t count
|
||||
m_samples32.assign(samples, samples + frames * m_channelCount);
|
||||
|
||||
// Write them to the FLAC stream
|
||||
FLAC__stream_encoder_process_interleaved(m_encoder, m_samples32.data(), frames);
|
||||
FLAC__stream_encoder_process_interleaved(m_encoder.get(), m_samples32.data(), frames);
|
||||
|
||||
// Next chunk
|
||||
count -= m_samples32.size();
|
||||
@ -106,19 +107,4 @@ void SoundFileWriterFlac::write(const std::int16_t* samples, std::uint64_t count
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void SoundFileWriterFlac::close()
|
||||
{
|
||||
if (m_encoder)
|
||||
{
|
||||
// Close the output stream
|
||||
FLAC__stream_encoder_finish(m_encoder);
|
||||
|
||||
// Destroy the encoder
|
||||
FLAC__stream_encoder_delete(m_encoder);
|
||||
m_encoder = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sf::priv
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
#include <FLAC/stream_encoder.h>
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
|
||||
@ -53,12 +54,6 @@ public:
|
||||
////////////////////////////////////////////////////////////
|
||||
[[nodiscard]] static bool check(const std::filesystem::path& filename);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Destructor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
~SoundFileWriterFlac() override;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Open a sound file for writing
|
||||
///
|
||||
@ -81,16 +76,14 @@ public:
|
||||
void write(const std::int16_t* samples, std::uint64_t count) override;
|
||||
|
||||
private:
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Close the file
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void close();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
FLAC__StreamEncoder* m_encoder{}; //!< FLAC stream encoder
|
||||
struct FlacStreamEncoderDeleter
|
||||
{
|
||||
void operator()(FLAC__StreamEncoder* encoder) const;
|
||||
};
|
||||
std::unique_ptr<FLAC__StreamEncoder, FlacStreamEncoderDeleter> m_encoder; //!< FLAC stream encoder
|
||||
unsigned int m_channelCount{}; //!< Number of channels
|
||||
std::vector<std::int32_t> m_samples32; //!< Conversion buffer
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user