Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 21 additions & 10 deletions include/Aulib/Decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <SDL_rwops.h>
#include <SDL_stdinc.h>
#include <chrono>
#include <cstdint>
#include <memory>
#include <string>
#include <type_traits>
Expand All @@ -13,11 +14,19 @@ struct SDL_RWops;

namespace Aulib {

template <typename T>
struct Decoder_priv;

/*!
* \brief Abstract base class for audio decoders.
*/
template <typename T>
class AULIB_EXPORT Decoder
{
static_assert(
std::is_same<T, float>::value or std::is_same<T, int32_t>::value,
"Only float and int32_t are supported");

public:
Decoder();
virtual ~Decoder();
Expand All @@ -34,10 +43,10 @@ class AULIB_EXPORT Decoder
* \return A suitable decoder or nullptr if none of the decoders can open the file.
*/
template <class... Decoders>
static auto decoderFor(const std::string& filename) -> std::unique_ptr<Decoder>;
static auto decoderFor(const std::string& filename) -> std::unique_ptr<Decoder<T>>;
//! \overload
template <class... Decoders>
static auto decoderFor(SDL_RWops* rwops) -> std::unique_ptr<Decoder>;
static auto decoderFor(SDL_RWops* rwops) -> std::unique_ptr<Decoder<T>>;
#endif

/*!
Expand All @@ -48,12 +57,12 @@ class AULIB_EXPORT Decoder
*
* \return A suitable decoder or nullptr if none of the decoders can open the file.
*/
static auto decoderFor(const std::string& filename) -> std::unique_ptr<Decoder>;
static auto decoderFor(const std::string& filename) -> std::unique_ptr<Decoder<T>>;
//! \overload
static auto decoderFor(SDL_RWops* rwops) -> std::unique_ptr<Decoder>;
static auto decoderFor(SDL_RWops* rwops) -> std::unique_ptr<Decoder<T>>;

auto isOpen() const -> bool;
auto decode(float buf[], int len, bool& callAgain) -> int;
auto decode(T buf[], int len, bool& callAgain) -> int;

virtual auto open(SDL_RWops* rwops) -> bool = 0;
virtual auto getChannels() const -> int = 0;
Expand All @@ -64,24 +73,26 @@ class AULIB_EXPORT Decoder

protected:
void setIsOpen(bool f);
virtual auto doDecoding(float buf[], int len, bool& callAgain) -> int = 0;
virtual auto doDecoding(T buf[], int len, bool& callAgain) -> int = 0;

private:
const std::unique_ptr<struct Decoder_priv> d;
const std::unique_ptr<Decoder_priv<T>> d;
};

#if __cplusplus >= 201603
template <typename T>
template <class... Decoders>
inline auto Decoder::decoderFor(const std::string& filename) -> std::unique_ptr<Decoder>
inline auto Decoder<T>::decoderFor(const std::string& filename) -> std::unique_ptr<Decoder<T>>
{
auto rwopsClose = [](SDL_RWops* rwops) { SDL_RWclose(rwops); };
std::unique_ptr<SDL_RWops, decltype(rwopsClose)> rwops(SDL_RWFromFile(filename.c_str(), "rb"),
rwopsClose);
return Decoder::decoderFor<Decoders...>(rwops.get());
}

template <typename T>
template <class... Decoders>
inline auto Decoder::decoderFor(SDL_RWops* rwops) -> std::unique_ptr<Decoder>
inline auto Decoder<T>::decoderFor(SDL_RWops* rwops) -> std::unique_ptr<Decoder<T>>
{
static_assert(sizeof...(Decoders) > 0, "Need at least one decoder type.");
static_assert((std::is_base_of_v<Aulib::Decoder, Decoders> && ...),
Expand All @@ -98,7 +109,7 @@ inline auto Decoder::decoderFor(SDL_RWops* rwops) -> std::unique_ptr<Decoder>
return ret;
};

std::unique_ptr<Decoder> decoder;
std::unique_ptr<Decoder<T>> decoder;
((tryDecoder(std::make_unique<Decoders>()) && (decoder = std::make_unique<Decoders>())) || ...);
return decoder;
}
Expand Down
5 changes: 3 additions & 2 deletions include/Aulib/DecoderAdlmidi.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ namespace Aulib {
* This decoder always generates samples at 49716Hz, the native rate of the OPL synths provided by
* libADLMIDI.
*/
class AULIB_EXPORT DecoderAdlmidi: public Decoder
template <typename T>
class AULIB_EXPORT DecoderAdlmidi: public Decoder<T>
{
public:
enum class Emulator
Expand Down Expand Up @@ -106,7 +107,7 @@ class AULIB_EXPORT DecoderAdlmidi: public Decoder
auto seekToTime(std::chrono::microseconds pos) -> bool override;

protected:
auto doDecoding(float buf[], int len, bool& callAgain) -> int override;
auto doDecoding(T buf[], int len, bool& callAgain) -> int override;

private:
std::unique_ptr<struct DecoderAdlmidi_priv> d;
Expand Down
5 changes: 3 additions & 2 deletions include/Aulib/DecoderBassmidi.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ namespace Aulib {
/*!
* \brief BASSMIDI decoder.
*/
class AULIB_EXPORT DecoderBassmidi: public Decoder
template <typename T>
class AULIB_EXPORT DecoderBassmidi: public Decoder<T>
{
public:
DecoderBassmidi();
Expand All @@ -35,7 +36,7 @@ class AULIB_EXPORT DecoderBassmidi: public Decoder
auto seekToTime(std::chrono::microseconds pos) -> bool override;

protected:
auto doDecoding(float buf[], int len, bool& callAgain) -> int override;
auto doDecoding(T buf[], int len, bool& callAgain) -> int override;

private:
const std::unique_ptr<struct DecoderBassmidi_priv> d;
Expand Down
5 changes: 3 additions & 2 deletions include/Aulib/DecoderDrflac.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ namespace Aulib {
/*!
* \brief dr_flac decoder.
*/
class AULIB_EXPORT DecoderDrflac: public Decoder
template <typename T>
class AULIB_EXPORT DecoderDrflac: public Decoder<T>
{
public:
DecoderDrflac();
Expand All @@ -22,7 +23,7 @@ class AULIB_EXPORT DecoderDrflac: public Decoder
auto seekToTime(std::chrono::microseconds pos) -> bool override;

protected:
auto doDecoding(float buf[], int len, bool& callAgain) -> int override;
auto doDecoding(T buf[], int len, bool& callAgain) -> int override;

private:
std::unique_ptr<struct DecoderDrflac_priv> d;
Expand Down
5 changes: 3 additions & 2 deletions include/Aulib/DecoderDrmp3.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ namespace Aulib {
/*!
* \brief dr_mp3 decoder.
*/
class AULIB_EXPORT DecoderDrmp3: public Decoder
template <typename T>
class AULIB_EXPORT DecoderDrmp3: public Decoder<T>
{
public:
DecoderDrmp3();
Expand All @@ -22,7 +23,7 @@ class AULIB_EXPORT DecoderDrmp3: public Decoder
auto seekToTime(std::chrono::microseconds pos) -> bool override;

protected:
auto doDecoding(float buf[], int len, bool& callAgain) -> int override;
auto doDecoding(T buf[], int len, bool& callAgain) -> int override;

private:
std::unique_ptr<struct DecoderDrmp3_priv> d;
Expand Down
5 changes: 3 additions & 2 deletions include/Aulib/DecoderDrwav.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ namespace Aulib {
/*!
* \brief dr_wav decoder.
*/
class AULIB_EXPORT DecoderDrwav: public Decoder
template <typename T>
class AULIB_EXPORT DecoderDrwav: public Decoder<T>
{
public:
DecoderDrwav();
Expand All @@ -23,7 +24,7 @@ class AULIB_EXPORT DecoderDrwav: public Decoder
auto seekToTime(std::chrono::microseconds pos) -> bool override;

protected:
auto doDecoding(float buf[], int len, bool& callAgain) -> int override;
auto doDecoding(T buf[], int len, bool& callAgain) -> int override;

private:
std::unique_ptr<struct DecoderDrwav_priv> d;
Expand Down
29 changes: 15 additions & 14 deletions include/Aulib/DecoderFlac.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@

namespace Aulib {

//! \brief Format of the input file.
enum class DecoderFlacFileFormat
{
//! Try and detect the format. Only works if the input is seekable.
Detect,
//! Assume input is raw FLAC.
Flac,
//! Assume input is FLAC data inside an Ogg container.
Ogg,
};

/*!
* \brief libFLAC decoder.
*
Expand All @@ -13,21 +24,11 @@ namespace Aulib {
*
* \note For Ogg support to work, libFLAC must have been built with Ogg support.
*/
class AULIB_EXPORT DecoderFlac: public Decoder
template <typename T>
class AULIB_EXPORT DecoderFlac: public Decoder<T>
{
public:
//! \brief Format of the input file.
enum class FileFormat
{
//! Try and detect the format. Only works if the input is seekable.
Detect,
//! Assume input is raw FLAC.
Flac,
//! Assume input is FLAC data inside an Ogg container.
Ogg,
};

DecoderFlac(FileFormat file_type = FileFormat::Detect);
DecoderFlac(DecoderFlacFileFormat file_type = DecoderFlacFileFormat::Detect);
~DecoderFlac() override;

auto open(SDL_RWops* rwops) -> bool override;
Expand All @@ -38,7 +39,7 @@ class AULIB_EXPORT DecoderFlac: public Decoder
auto seekToTime(std::chrono::microseconds pos) -> bool override;

protected:
auto doDecoding(float buf[], int len, bool& callAgain) -> int override;
auto doDecoding(T buf[], int len, bool& callAgain) -> int override;

private:
const std::unique_ptr<struct DecoderFlac_priv> d;
Expand Down
5 changes: 3 additions & 2 deletions include/Aulib/DecoderFluidsynth.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ namespace Aulib {
/*!
* \brief FluidSynth decoder.
*/
class AULIB_EXPORT DecoderFluidsynth: public Decoder
template <typename T>
class AULIB_EXPORT DecoderFluidsynth: public Decoder<T>
{
public:
DecoderFluidsynth();
Expand Down Expand Up @@ -52,7 +53,7 @@ class AULIB_EXPORT DecoderFluidsynth: public Decoder
auto seekToTime(std::chrono::microseconds pos) -> bool override;

protected:
auto doDecoding(float buf[], int len, bool& callAgain) -> int override;
auto doDecoding(T buf[], int len, bool& callAgain) -> int override;

private:
const std::unique_ptr<struct DecoderFluidsynth_priv> d;
Expand Down
5 changes: 3 additions & 2 deletions include/Aulib/DecoderModplug.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ namespace Aulib {
/*!
* \brief ModPlug decoder.
*/
class AULIB_EXPORT DecoderModplug: public Decoder
template <typename T>
class AULIB_EXPORT DecoderModplug: public Decoder<T>
{
public:
DecoderModplug();
Expand All @@ -22,7 +23,7 @@ class AULIB_EXPORT DecoderModplug: public Decoder
auto seekToTime(std::chrono::microseconds pos) -> bool override;

protected:
auto doDecoding(float buf[], int len, bool& callAgain) -> int override;
auto doDecoding(T buf[], int len, bool& callAgain) -> int override;

private:
const std::unique_ptr<struct DecoderModplug_priv> d;
Expand Down
5 changes: 3 additions & 2 deletions include/Aulib/DecoderMpg123.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ namespace Aulib {
/*!
* \brief mpg123 decoder.
*/
class AULIB_EXPORT DecoderMpg123: public Decoder
template <typename T>
class AULIB_EXPORT DecoderMpg123: public Decoder<T>
{
public:
DecoderMpg123();
Expand All @@ -22,7 +23,7 @@ class AULIB_EXPORT DecoderMpg123: public Decoder
auto seekToTime(std::chrono::microseconds pos) -> bool override;

protected:
auto doDecoding(float buf[], int len, bool& callAgain) -> int override;
auto doDecoding(T buf[], int len, bool& callAgain) -> int override;

private:
const std::unique_ptr<struct DecoderMpg123_priv> d;
Expand Down
5 changes: 3 additions & 2 deletions include/Aulib/DecoderMusepack.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ namespace Aulib {
/*!
* \brief libmpcdec decoder.
*/
class AULIB_EXPORT DecoderMusepack: public Decoder
template <typename T>
class AULIB_EXPORT DecoderMusepack: public Decoder<T>
{
public:
DecoderMusepack();
Expand All @@ -22,7 +23,7 @@ class AULIB_EXPORT DecoderMusepack: public Decoder
auto seekToTime(std::chrono::microseconds pos) -> bool override;

protected:
auto doDecoding(float buf[], int len, bool& callAgain) -> int override;
auto doDecoding(T buf[], int len, bool& callAgain) -> int override;

private:
const std::unique_ptr<struct DecoderMusepack_priv> d;
Expand Down
5 changes: 3 additions & 2 deletions include/Aulib/DecoderOpenmpt.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ namespace Aulib {
/*!
* \brief OpenMPT decoder.
*/
class AULIB_EXPORT DecoderOpenmpt: public Decoder
template <typename T>
class AULIB_EXPORT DecoderOpenmpt: public Decoder<T>
{
public:
DecoderOpenmpt();
Expand All @@ -22,7 +23,7 @@ class AULIB_EXPORT DecoderOpenmpt: public Decoder
auto seekToTime(std::chrono::microseconds pos) -> bool override;

protected:
auto doDecoding(float buf[], int len, bool& callAgain) -> int override;
auto doDecoding(T buf[], int len, bool& callAgain) -> int override;

private:
const std::unique_ptr<struct DecoderOpenmpt_priv> d;
Expand Down
5 changes: 3 additions & 2 deletions include/Aulib/DecoderOpus.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ namespace Aulib {
/*!
* \brief libopusfile decoder.
*/
class AULIB_EXPORT DecoderOpus: public Decoder
template <typename T>
class AULIB_EXPORT DecoderOpus: public Decoder<T>
{
public:
DecoderOpus();
Expand All @@ -22,7 +23,7 @@ class AULIB_EXPORT DecoderOpus: public Decoder
auto seekToTime(std::chrono::microseconds pos) -> bool override;

protected:
auto doDecoding(float buf[], int len, bool& callAgain) -> int override;
auto doDecoding(T buf[], int len, bool& callAgain) -> int override;

private:
const std::unique_ptr<struct DecoderOpus_priv> d;
Expand Down
5 changes: 3 additions & 2 deletions include/Aulib/DecoderSndfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ namespace Aulib {
/*!
* \brief Libsndfile decoder.
*/
class AULIB_EXPORT DecoderSndfile: public Decoder
template <typename T>
class AULIB_EXPORT DecoderSndfile: public Decoder<T>
{
public:
DecoderSndfile();
Expand All @@ -22,7 +23,7 @@ class AULIB_EXPORT DecoderSndfile: public Decoder
auto seekToTime(std::chrono::microseconds pos) -> bool override;

protected:
auto doDecoding(float buf[], int len, bool& callAgain) -> int override;
auto doDecoding(T buf[], int len, bool& callAgain) -> int override;

private:
const std::unique_ptr<struct DecoderSndfile_priv> d;
Expand Down
5 changes: 3 additions & 2 deletions include/Aulib/DecoderVorbis.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ namespace Aulib {
/*!
* \brief libvorbisfile decoder.
*/
class AULIB_EXPORT DecoderVorbis: public Decoder
template <typename T>
class AULIB_EXPORT DecoderVorbis: public Decoder<T>
{
public:
DecoderVorbis();
Expand All @@ -22,7 +23,7 @@ class AULIB_EXPORT DecoderVorbis: public Decoder
auto seekToTime(std::chrono::microseconds pos) -> bool override;

protected:
auto doDecoding(float buf[], int len, bool& callAgain) -> int override;
auto doDecoding(T buf[], int len, bool& callAgain) -> int override;

private:
const std::unique_ptr<struct DecoderVorbis_priv> d;
Expand Down
Loading