diff --git a/src/Audio.hh b/src/Audio.hh new file mode 100644 index 0000000000000000000000000000000000000000..67ef33151b2557b21d7fd632be432f40e84be73e --- /dev/null +++ b/src/Audio.hh @@ -0,0 +1,133 @@ +#ifndef VIVY_AUDIO_H +#define VIVY_AUDIO_H + +#ifndef __cplusplus +#error "This is a C++ header" +#endif + +extern "C" { +#include <libavutil/opt.h> +#include <libavcodec/avcodec.h> +#include <libavformat/avformat.h> +#include <libswresample/swresample.h> +#include <libavcodec/avfft.h> +} + +#include "Utils.hh" +#include <QtGlobal> +#include <QMap> +#include <QVector> +#include <memory.h> + +namespace Vivy +{ +/* Hold all the data for a stream in an audio file. Should only be owned by the + * AudioFormatCtx class. + */ +class AudioStreamCodec final { + VIVY_UNMOVABLE_OBJECT(AudioStreamCodec) + + // All the needed deleters + static inline constexpr auto codecContexteleter = [](AVCodecContext *ptr) noexcept -> void { + if (ptr) + avcodec_free_context(&ptr); + }; + static constexpr inline auto dataDeleter = [](double *ptr) noexcept -> void { + if (ptr) + av_free(ptr); + }; + static constexpr inline auto avFrameDeleter = [](AVFrame *ptr) noexcept -> void { + if (ptr) + av_frame_free(&ptr); + }; + + static constexpr inline auto swrContenxtDeleter = [](SwrContext *swr) noexcept -> void { + if (swr) + swr_free(&swr); + }; + + // All the used types + using AVCodecContextPtr = std::unique_ptr<AVCodecContext, decltype(codecContexteleter)>; + using DataPtr = std::shared_ptr<double[]>; + using DataWeakPtr = std::weak_ptr<double[]>; + using AVFramePtr = std::unique_ptr<AVFrame, decltype(avFrameDeleter)>; + using SwrContextPtr = std::unique_ptr<SwrContext, decltype(swrContenxtDeleter)>; + +public: + AudioStreamCodec(AVStream *); + ~AudioStreamCodec(); + + // Decode the stream + void decodeData(); + size_t getDecodedDataSize() const noexcept; + DataWeakPtr getDecodedData() const noexcept; + + // Some getters + int getChannels() const noexcept; + int getSampleRate() const noexcept; + const char *getName() const noexcept; + AVCodecID getCodecId() const noexcept; + qint64 getBitRate() const noexcept; + +private: + bool initFromStream() noexcept; // Init all the object + void cleanupForReuse() noexcept; // Free everything, can now use initFromStream again + + // Check if ready + bool isReadyForUse() const noexcept; + bool isResampled() const noexcept; + + // Codec related informations + AVCodecID codecId{ AV_CODEC_ID_NONE }; + AVCodecContextPtr codecContext{ nullptr }; + AVCodecParameters *codecParams{ nullptr }; + AVCodec *codec{ nullptr }; + + // Stream is held by AudioFormatCtx + AVStream *audioStream{ nullptr }; + bool isInitFromStream{ false }; + + // Resampled frame data + SwrContextPtr dataSwrContext{ nullptr, swrContenxtDeleter }; + AVFramePtr dataFrame{ nullptr, avFrameDeleter }; + DataPtr dataPtr{ nullptr, dataDeleter }; + size_t dataSize{ 0 }; +}; + +/* Facility for pointers to AudioStreamCodec objects */ +using AudioStreamCodecPtr = std::shared_ptr<AudioStreamCodec>; +using AudioStreamCodecWeakPtr = std::weak_ptr<AudioStreamCodec>; + +/* The memory representation of an audio file. It is created inplace and should + * not be moved around. It should be used to get the properties of an audio + * file and its streams. The user can use a stream from the file and get data + * from it. + */ +class AudioFormatCtx final { + VIVY_UNMOVABLE_OBJECT(AudioFormatCtx) + +public: + AudioFormatCtx(const QString &path); + ~AudioFormatCtx() noexcept; + + int getStreamCount() const noexcept; + AudioStreamCodecWeakPtr getStream(int) const noexcept; + +private: + /* Regarding the format */ + static inline constexpr auto avFormatContextDeleter = + [](AVFormatContext *ptr) noexcept -> void { + if (ptr) + avformat_free_context(ptr); + }; + using AVFormatContextPtr = std::unique_ptr<AVFormatContext, decltype(avFormatContextDeleter)>; + AVFormatContextPtr format{ nullptr }; + + /* Usefull information */ + QString filePath; + QVector<uint> audioStreamIndexes{}; + QMap<uint, AudioStreamCodecPtr> audioCodecs{}; +}; +} + +#endif // VIVY_AUDIO_H diff --git a/src/AudioUtils.cc b/src/AudioUtils.cc index cab709b2e0fb4111bf335f389e605a12b90932e4..fde8a4cc30ba1f37e04d8b18585b4f44c3b4dca6 100644 --- a/src/AudioUtils.cc +++ b/src/AudioUtils.cc @@ -1,4 +1,5 @@ #include "AudioUtils.hh" +#include "Audio.hh" // Will be renamed into AudioUtils.hh ... #define MAXPIXVALUE 7 /* Some magix AV magic stuff */