From c190406ac91000cbca5f05f59695596807a8f315 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96zg=C3=BCr?= Date: Mon, 30 Sep 2024 13:15:06 +0300 Subject: [PATCH] added version macros, resume/pause methods to AudioObject --- CMakeLists.txt | 2 +- HephAudio/HeaderFiles/AudioObject.h | 75 ++++++++----- HephAudio/HeaderFiles/HephAudioShared.h | 29 +++++ HephAudio/HephAudio.vcxitems | 1 + HephAudio/HephAudio.vcxitems.filters | 1 + HephAudio/SourceFiles/AudioObject.cpp | 15 +++ HephAudio/SourceFiles/HephAudioShared.cpp | 26 +++++ .../SourceFiles/NativeAudio/NativeAudio.cpp | 103 ++++++++---------- HephCommon/HeaderFiles/HephShared.h | 42 ++++++- HephCommon/SourceFiles/HephShared.cpp | 24 ++++ docs/Doxyfile | 2 +- 11 files changed, 235 insertions(+), 85 deletions(-) create mode 100644 HephAudio/SourceFiles/HephAudioShared.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 46aa7283..20b6f035 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.25) set(HEPHAUDIO_VERSION_MAJOR 2) set(HEPHAUDIO_VERSION_MINOR 2) -set(HEPHAUDIO_VERSION_PATCH 2) +set(HEPHAUDIO_VERSION_PATCH 3) set(HEPHAUDIO_VERSION ${HEPHAUDIO_VERSION_MAJOR}.${HEPHAUDIO_VERSION_MINOR}.${HEPHAUDIO_VERSION_PATCH}) option(ENABLE_STATIC "ENABLE_STATIC" Off) diff --git a/HephAudio/HeaderFiles/AudioObject.h b/HephAudio/HeaderFiles/AudioObject.h index a7f3cd5b..f69b8777 100644 --- a/HephAudio/HeaderFiles/AudioObject.h +++ b/HephAudio/HeaderFiles/AudioObject.h @@ -10,117 +10,138 @@ /** * indicates to play the audio object infinitely. - * + * */ #define HEPHAUDIO_INFINITE_LOOP (0) -/** - * The default handler for the \link HephAudio::AudioObject::OnRender AudioObject::OnRender \endlink event. - * Plays the audio data as is. - * - */ + /** + * @copydoc HephAudio::AudioObject::DefaultRenderHandler + * + */ #define HEPHAUDIO_RENDER_HANDLER_DEFAULT &HephAudio::AudioObject::DefaultRenderHandler -/** - * An handler for the \link HephAudio::AudioObject::OnRender AudioObject::OnRender \endlink event. - * Converts the audio data to the render format before playing. - * - */ + /** + * @copydoc HephAudio::AudioObject::MatchFormatRenderHandler + * + */ #define HEPHAUDIO_RENDER_HANDLER_MATCH_FORMAT &HephAudio::AudioObject::MatchFormatRenderHandler namespace HephAudio { /** * @brief stores information that's necessary to play audio. - * + * */ struct HEPH_API AudioObject { /** * unique identifier of the object. - * + * */ Heph::Guid id; /** * path of the file the object is created with, or empty if created via \link HephAudio::Native::NativeAudio::CreateAudioObject NativeAudio::CreateAudioObject. - * + * */ std::filesystem::path filePath; /** * name of the object. - * + * */ std::string name; /** - * indicates whether the object is paused. + * indicates whether the object is paused. * If true, the object will not be played until this field is set to false. - * + * */ bool isPaused; /** * number of times the object will be played. * Set this to #HEPHAUDIO_INFINITE_LOOP in order to play it infinite times. - * + * */ uint32_t playCount; /** * loudness of the audio between 0 and 1. - * + * * @important values above 1 may cause distortion. */ double volume; /** * contains the audio data. - * + * */ AudioBuffer buffer; /** * index of the first audio frame that will be rendered (played) next. - * + * */ size_t frameIndex; /** * event that will be invoked each time before rendering (playing) audio data. - * + * */ Heph::Event OnRender; /** * event that will be invoked each time when the object finishes playing. - * + * */ Heph::Event OnFinishedPlaying; - + /** @copydoc default_constructor */ AudioObject(); /** @copydoc move_constructor */ AudioObject(AudioObject&& rhs) noexcept; - + AudioObject& operator=(AudioObject&& rhs) noexcept; /** * calculates the playback position between 0 and 1. - * + * */ double GetPosition() const; /** * sets the playback position. - * + * * @param position between 0 and 1. */ void SetPosition(double position); + /** + * stops playing the audio object. + * + */ + void Pause(); + + /** + * starts playing the audio object. + * + */ + void Resume(); + + /** + * the default handler for the \link HephAudio::AudioObject::OnRender AudioObject::OnRender \endlink event. + * Plays the audio data as is. + * + */ static void DefaultRenderHandler(const Heph::EventParams& eventParams); + + /** + * an handler for the \link HephAudio::AudioObject::OnRender AudioObject::OnRender \endlink event. + * Converts the audio data to the render format before playing. + * + */ static void MatchFormatRenderHandler(const Heph::EventParams& eventParams); }; } \ No newline at end of file diff --git a/HephAudio/HeaderFiles/HephAudioShared.h b/HephAudio/HeaderFiles/HephAudioShared.h index b5052fab..b754b3c4 100644 --- a/HephAudio/HeaderFiles/HephAudioShared.h +++ b/HephAudio/HeaderFiles/HephAudioShared.h @@ -8,6 +8,30 @@ #error 32-bit is not supported! #endif +/** + * full version as string litteral. + * +*/ +#define HEPHAUDIO_VERSION HEPH_TOSTRING(HEPHAUDIO_VERSION_MAJOR ##.## HEPHAUDIO_VERSION_MINOR ##.## HEPHAUDIO_VERSION_PATCH) + +/** + * major part of the version. + * +*/ +#define HEPHAUDIO_VERSION_MAJOR 2 + +/** + * minor part of the version. + * +*/ +#define HEPHAUDIO_VERSION_MINOR 2 + +/** + * patch part of the version. + * +*/ +#define HEPHAUDIO_VERSION_PATCH 3 + #define HEPHAUDIO_FORMAT_TAG_PCM (0x0001) #define HEPHAUDIO_FORMAT_TAG_IEEE_FLOAT (0x0003) #define HEPHAUDIO_FORMAT_TAG_ALAW (0x0006) @@ -137,6 +161,11 @@ typedef float heph_audio_sample_t; namespace HephAudio { + HEPH_API const char* GetVersion(); + HEPH_API unsigned int GetVersionMajor(); + HEPH_API unsigned int GetVersionMinor(); + HEPH_API unsigned int GetVersionPatch(); + /** * converts decibel to gain (between -1 and 1). * diff --git a/HephAudio/HephAudio.vcxitems b/HephAudio/HephAudio.vcxitems index 274a8080..82b52009 100644 --- a/HephAudio/HephAudio.vcxitems +++ b/HephAudio/HephAudio.vcxitems @@ -91,6 +91,7 @@ + diff --git a/HephAudio/HephAudio.vcxitems.filters b/HephAudio/HephAudio.vcxitems.filters index 1838967b..a96410f3 100644 --- a/HephAudio/HephAudio.vcxitems.filters +++ b/HephAudio/HephAudio.vcxitems.filters @@ -383,5 +383,6 @@ + \ No newline at end of file diff --git a/HephAudio/SourceFiles/AudioObject.cpp b/HephAudio/SourceFiles/AudioObject.cpp index 56059089..7be6bad4 100644 --- a/HephAudio/SourceFiles/AudioObject.cpp +++ b/HephAudio/SourceFiles/AudioObject.cpp @@ -25,6 +25,7 @@ namespace HephAudio rhs.OnRender.ClearAll(); rhs.OnFinishedPlaying.ClearAll(); } + AudioObject& AudioObject::operator=(AudioObject&& rhs) noexcept { if (this != &rhs) @@ -46,11 +47,13 @@ namespace HephAudio return *this; } + double AudioObject::GetPosition() const { const double position = ((double)this->frameIndex) / this->buffer.FrameCount(); return HEPH_MATH_MIN(position, 1.0); } + void AudioObject::SetPosition(double position) { if (position > 1.0) @@ -65,6 +68,17 @@ namespace HephAudio } this->frameIndex = position * this->buffer.FrameCount(); } + + void AudioObject::Pause() + { + this->isPaused = true; + } + + void AudioObject::Resume() + { + this->isPaused = false; + } + void AudioObject::DefaultRenderHandler(const EventParams& eventParams) { AudioRenderEventArgs* pRenderArgs = (AudioRenderEventArgs*)eventParams.pArgs; @@ -74,6 +88,7 @@ namespace HephAudio pRenderArgs->pAudioObject->frameIndex += pRenderArgs->renderFrameCount; pRenderResult->isFinishedPlaying = pRenderArgs->pAudioObject->frameIndex >= pRenderArgs->pAudioObject->buffer.FrameCount(); } + void AudioObject::MatchFormatRenderHandler(const Heph::EventParams& eventParams) { AudioRenderEventArgs* pRenderArgs = (AudioRenderEventArgs*)eventParams.pArgs; diff --git a/HephAudio/SourceFiles/HephAudioShared.cpp b/HephAudio/SourceFiles/HephAudioShared.cpp new file mode 100644 index 00000000..c312b77d --- /dev/null +++ b/HephAudio/SourceFiles/HephAudioShared.cpp @@ -0,0 +1,26 @@ +#include "HephAudioShared.h" + +namespace HephAudio +{ + static const char* const __version = HEPHAUDIO_VERSION; + + const char* GetVersion() + { + return __version; + } + + unsigned int GetVersionMajor() + { + return HEPHAUDIO_VERSION_MAJOR; + } + + unsigned int GetVersionMinor() + { + return HEPHAUDIO_VERSION_MINOR; + } + + unsigned int GetVersionPatch() + { + return HEPHAUDIO_VERSION_PATCH; + } +} \ No newline at end of file diff --git a/HephAudio/SourceFiles/NativeAudio/NativeAudio.cpp b/HephAudio/SourceFiles/NativeAudio/NativeAudio.cpp index 2974c259..a0590229 100644 --- a/HephAudio/SourceFiles/NativeAudio/NativeAudio.cpp +++ b/HephAudio/SourceFiles/NativeAudio/NativeAudio.cpp @@ -69,41 +69,34 @@ namespace HephAudio AudioObject* NativeAudio::Play(const std::filesystem::path& filePath, uint32_t playCount, bool isPaused) { - try - { - HEPHAUDIO_LOG("Playing \"" + filePath.filename().string() + "\"", HEPH_CL_INFO); + HEPHAUDIO_LOG("Playing \"" + filePath.filename().string() + "\"", HEPH_CL_INFO); - std::lock_guard lockGuard(this->audioObjectsMutex); + std::lock_guard lockGuard(this->audioObjectsMutex); - AudioObject& audioObject = this->audioObjects.emplace_back(); + AudioObject& audioObject = this->audioObjects.emplace_back(); - audioObject.filePath = filePath; - audioObject.name = filePath.filename().string(); + audioObject.filePath = filePath; + audioObject.name = filePath.filename().string(); - this->pAudioDecoder->ChangeFile(filePath); - audioObject.buffer = this->pAudioDecoder->Decode(); + this->pAudioDecoder->ChangeFile(filePath); + audioObject.buffer = this->pAudioDecoder->Decode(); - audioObject.playCount = playCount; - audioObject.isPaused = isPaused; + audioObject.playCount = playCount; + audioObject.isPaused = isPaused; - return &audioObject; - } - catch (Exception ex) - { - return nullptr; - } + return &audioObject; } - + AudioObject* NativeAudio::Load(const std::filesystem::path& filePath) { return this->Load(filePath, 1, true); } - + AudioObject* NativeAudio::Load(const std::filesystem::path& filePath, uint32_t playCount) { return this->Load(filePath, playCount, true); } - + AudioObject* NativeAudio::Load(const std::filesystem::path& filePath, uint32_t playCount, bool isPaused) { std::lock_guard lockGuard(this->audioObjectsMutex); @@ -115,18 +108,18 @@ namespace HephAudio } return pao; } - + AudioObject* NativeAudio::CreateAudioObject(const std::string& name, size_t bufferFrameCount, AudioChannelLayout channelLayout, uint16_t sampleRate) { std::lock_guard lockGuard(this->audioObjectsMutex); - AudioObject& audioObject = audioObjects.emplace_back(); + AudioObject& audioObject = this->audioObjects.emplace_back(); audioObject.name = name; audioObject.buffer = AudioBuffer(bufferFrameCount, channelLayout, sampleRate); return &audioObject; } - + bool NativeAudio::DestroyAudioObject(AudioObject* pAudioObject) { std::lock_guard lockGuard(this->audioObjectsMutex); @@ -140,7 +133,7 @@ namespace HephAudio } return false; } - + bool NativeAudio::DestroyAudioObject(const Heph::Guid& audioObjectId) { std::lock_guard lockGuard(this->audioObjectsMutex); @@ -154,7 +147,7 @@ namespace HephAudio } return false; } - + bool NativeAudio::AudioObjectExists(AudioObject* pAudioObject) const { std::lock_guard lockGuard(this->audioObjectsMutex); @@ -170,7 +163,7 @@ namespace HephAudio } return false; } - + bool NativeAudio::AudioObjectExists(const Guid& audioObjectId) const { std::lock_guard lockGuard(this->audioObjectsMutex); @@ -183,7 +176,7 @@ namespace HephAudio } return false; } - + AudioObject* NativeAudio::GetAudioObject(size_t index) { std::lock_guard lockGuard(this->audioObjectsMutex); @@ -194,7 +187,7 @@ namespace HephAudio } return &audioObjects[index]; } - + AudioObject* NativeAudio::GetAudioObject(const Heph::Guid& audioObjectId) { std::lock_guard lockGuard(this->audioObjectsMutex); @@ -207,7 +200,7 @@ namespace HephAudio } return nullptr; } - + AudioObject* NativeAudio::GetAudioObject(const std::string& audioObjectName) { std::lock_guard lockGuard(this->audioObjectsMutex); @@ -220,78 +213,78 @@ namespace HephAudio } return nullptr; } - + size_t NativeAudio::GetAudioObjectCount() const { std::lock_guard lockGuard(this->audioObjectsMutex); return this->audioObjects.size(); } - + void NativeAudio::ResumeCapture() { this->isCapturePaused = false; } - + void NativeAudio::PauseCapture() { this->isCapturePaused = true; } - + bool NativeAudio::IsCapturePaused() const { return this->isCapturePaused; } - + uint32_t NativeAudio::GetDeviceEnumerationPeriod() const { return this->deviceEnumerationPeriod_ms; } - + void NativeAudio::SetDeviceEnumerationPeriod(uint32_t deviceEnumerationPeriod_ms) { this->deviceEnumerationPeriod_ms = deviceEnumerationPeriod_ms; } - + const AudioFormatInfo& NativeAudio::GetRenderFormat() const { return this->renderFormat; } - + const AudioFormatInfo& NativeAudio::GetCaptureFormat() const { return this->captureFormat; } - + void NativeAudio::InitializeRender() { this->InitializeRender(nullptr, HEPHAUDIO_INTERNAL_FORMAT(HEPHAUDIO_CH_LAYOUT_STEREO, 48000)); } - + void NativeAudio::InitializeRender(AudioChannelLayout channelLayout, uint32_t sampleRate) { this->InitializeRender(nullptr, HEPHAUDIO_INTERNAL_FORMAT(channelLayout, sampleRate)); } - + void NativeAudio::InitializeRender(AudioFormatInfo format) { this->InitializeRender(nullptr, format); } - + void NativeAudio::InitializeCapture() { this->InitializeCapture(nullptr, HEPHAUDIO_INTERNAL_FORMAT(HEPHAUDIO_CH_LAYOUT_STEREO, 48000)); } - + void NativeAudio::InitializeCapture(AudioChannelLayout channelLayout, uint32_t sampleRate) { this->InitializeCapture(nullptr, HEPHAUDIO_INTERNAL_FORMAT(channelLayout, sampleRate)); } - + void NativeAudio::InitializeCapture(AudioFormatInfo format) { this->InitializeCapture(nullptr, format); } - + AudioDevice NativeAudio::GetAudioDeviceById(const std::string& deviceId) const { std::vector devices = GetAudioDevices(AudioDeviceType::All); @@ -304,7 +297,7 @@ namespace HephAudio } return AudioDevice(); } - + AudioDevice NativeAudio::GetRenderDevice() const { AudioDevice renderDevice = GetAudioDeviceById(renderDeviceId); @@ -315,7 +308,7 @@ namespace HephAudio } return renderDevice; } - + AudioDevice NativeAudio::GetCaptureDevice() const { AudioDevice captureDevice = GetAudioDeviceById(captureDeviceId); @@ -326,7 +319,7 @@ namespace HephAudio } return captureDevice; } - + AudioDevice NativeAudio::GetDefaultAudioDevice(AudioDeviceType deviceType) const { if (deviceType == AudioDeviceType::All || deviceType == AudioDeviceType::Null) @@ -346,7 +339,7 @@ namespace HephAudio return AudioDevice(); } - + std::vector NativeAudio::GetAudioDevices(AudioDeviceType deviceType) const { std::vector result; @@ -368,7 +361,7 @@ namespace HephAudio return result; } - + void NativeAudio::CheckAudioDevices() { AudioDeviceEventArgs deviceEventArgs = AudioDeviceEventArgs(this, AudioDevice()); @@ -427,7 +420,7 @@ namespace HephAudio } } } - + void NativeAudio::JoinRenderThread() { if (renderThread.joinable()) @@ -435,7 +428,7 @@ namespace HephAudio renderThread.join(); } } - + void NativeAudio::JoinCaptureThread() { if (captureThread.joinable()) @@ -443,7 +436,7 @@ namespace HephAudio captureThread.join(); } } - + void NativeAudio::JoinDeviceThread() { if (deviceThread.joinable()) @@ -451,7 +444,7 @@ namespace HephAudio deviceThread.join(); } } - + EncodedAudioBuffer NativeAudio::Mix(uint32_t frameCount) { std::lock_guard lockGuard(this->audioObjectsMutex); @@ -517,7 +510,7 @@ namespace HephAudio this->pAudioEncoder->Encode(mixBuffer, encodedBuffer); return encodedBuffer; } - + size_t NativeAudio::GetAOCountToMix() const { std::lock_guard lockGuard(this->audioObjectsMutex); @@ -531,7 +524,7 @@ namespace HephAudio } return result; } - + double NativeAudio::GetFinalAOVolume(AudioObject* pAudioObject) const { return pAudioObject->volume; diff --git a/HephCommon/HeaderFiles/HephShared.h b/HephCommon/HeaderFiles/HephShared.h index 3d935a0d..e9001334 100644 --- a/HephCommon/HeaderFiles/HephShared.h +++ b/HephCommon/HeaderFiles/HephShared.h @@ -34,6 +34,30 @@ * */ +/** + * full version as string litteral. + * +*/ +#define HEPH_VERSION HEPH_TOSTRING(HEPH_VERSION_MAJOR ##.## HEPH_VERSION_MINOR ##.## HEPH_VERSION_PATCH) + +/** + * major part of the version. + * +*/ +#define HEPH_VERSION_MAJOR 2 + +/** + * minor part of the version. + * +*/ +#define HEPH_VERSION_MINOR 2 + +/** + * patch part of the version. + * +*/ +#define HEPH_VERSION_PATCH 3 + #if defined(_MSVC_LANG) #define CPP_VERSION _MSVC_LANG @@ -135,8 +159,24 @@ #define HEPH_FUNC __func__ #endif + +/** + * converts \a x to string litteral without expanding the parameter. +*/ +#define HEPH_STRINGIFY(x) #x + +/** + * converts \a x to string litteral with expanding the parameter. +*/ +#define HEPH_TOSTRING(x) HEPH_STRINGIFY(x) + namespace Heph { + HEPH_API const char* GetVersion(); + HEPH_API unsigned int GetVersionMajor(); + HEPH_API unsigned int GetVersionMinor(); + HEPH_API unsigned int GetVersionPatch(); + enum Endian : uint8_t { Little = 0x00, @@ -148,7 +188,7 @@ namespace Heph * endianness of the current system. * */ - HEPH_API extern Endian systemEndian; + extern HEPH_API Endian systemEndian; /** * changes the endianness of the provided data. diff --git a/HephCommon/SourceFiles/HephShared.cpp b/HephCommon/SourceFiles/HephShared.cpp index 236a86e8..501509c0 100644 --- a/HephCommon/SourceFiles/HephShared.cpp +++ b/HephCommon/SourceFiles/HephShared.cpp @@ -2,11 +2,34 @@ namespace Heph { + static const char* const __version = HEPH_VERSION; + + const char* GetVersion() + { + return __version; + } + + unsigned int GetVersionMajor() + { + return HEPH_VERSION_MAJOR; + } + + unsigned int GetVersionMinor() + { + return HEPH_VERSION_MINOR; + } + + unsigned int GetVersionPatch() + { + return HEPH_VERSION_PATCH; + } + Endian GetSystemEndian() { uint16_t n = 0x0001; return (*(uint8_t*)&n == 1) ? Endian::Little : Endian::Big; } + void ChangeEndian(uint8_t* pData, uint8_t dataSize) { const uint8_t halfDataSize = dataSize / 2; @@ -17,5 +40,6 @@ namespace Heph pData[dataSize - i - 1] = temp; } } + Endian systemEndian = Heph::GetSystemEndian(); } \ No newline at end of file diff --git a/docs/Doxyfile b/docs/Doxyfile index 7af3f636..6ae33a98 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -48,7 +48,7 @@ PROJECT_NAME = "HephAudio" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = "v2.2.2" +PROJECT_NUMBER = "v2.2.3" # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a