/* * Copyright (C) 2005-2018 Team Kodi * This file is part of Kodi - https://kodi.tv * * SPDX-License-Identifier: GPL-2.0-or-later * See LICENSES/README.md for more information. */ #pragma once #include "../AddonBase.h" #include "../c-api/addon-instance/visualization.h" #include "../gui/renderHelper.h" #ifdef __cplusplus namespace kodi { namespace addon { //============================================================================== /// @defgroup cpp_kodi_addon_visualization_Defs_VisualizationTrack class VisualizationTrack /// @ingroup cpp_kodi_addon_visualization_Defs /// @brief **Info tag data structure**\n /// Representation of available information of processed audio file. /// /// This is used to store all the necessary data of audio stream and to have on /// e.g. GUI for information. /// /// Called from @ref kodi::addon::CInstanceVisualization::UpdateTrack() with the /// information of the currently-playing song. /// /// ---------------------------------------------------------------------------- /// /// @copydetails cpp_kodi_addon_visualization_Defs_VisualizationTrack_Help /// ///@{ class VisualizationTrack { /*! \cond PRIVATE */ friend class CInstanceVisualization; /*! \endcond */ public: /*! \cond PRIVATE */ VisualizationTrack() = default; VisualizationTrack(const VisualizationTrack& tag) { *this = tag; } VisualizationTrack& operator=(const VisualizationTrack& right) { if (&right == this) return *this; m_title = right.m_title; m_artist = right.m_artist; m_album = right.m_album; m_albumArtist = right.m_albumArtist; m_genre = right.m_genre; m_comment = right.m_comment; m_lyrics = right.m_lyrics; m_trackNumber = right.m_trackNumber; m_discNumber = right.m_discNumber; m_duration = right.m_duration; m_year = right.m_year; m_rating = right.m_rating; return *this; } /*! \endcond */ /// @defgroup cpp_kodi_addon_visualization_Defs_VisualizationTrack_Help Value Help /// @ingroup cpp_kodi_addon_visualization_Defs_VisualizationTrack /// /// The following table contains values that can be set with @ref cpp_kodi_addon_visualization_Defs_VisualizationTrack : /// | Name | Type | Set call | Get call /// |------|------|----------|---------- /// | **Title of the current song.** | `std::string` | @ref VisualizationTrack::SetTitle "SetTitle" | @ref VisualizationTrack::GetTitle "GetTitle" /// | **Artist names, as a single string** | `std::string` | @ref VisualizationTrack::SetArtist "SetArtist" | @ref VisualizationTrack::GetArtist "GetArtist" /// | **Album that the current song is from.** | `std::string` | @ref VisualizationTrack::SetAlbum "SetAlbum" | @ref VisualizationTrack::GetAlbum "GetAlbum" /// | **Album artist names, as a single string** | `std::string` | @ref VisualizationTrack::SetAlbumArtist "SetAlbumArtist" | @ref VisualizationTrack::GetAlbumArtist "GetAlbumArtist" /// | **The genre name from the music tag, if present** | `std::string` | @ref VisualizationTrack::SetGenre "SetGenre" | @ref VisualizationTrack::GetGenre "GetGenre" /// | **Duration of the current song, in seconds** | `int` | @ref VisualizationTrack::SetDuration "SetDuration" | @ref VisualizationTrack::GetDuration "GetDuration" /// | **Track number of the current song** | `int` | @ref VisualizationTrack::SetTrack "SetTrack" | @ref VisualizationTrack::GetTrack "GetTrack" /// | **Disc number of the current song stored in the ID tag info** | `int` | @ref VisualizationTrack::SetDisc "SetDisc" | @ref VisualizationTrack::GetDisc "GetDisc" /// | **Year that the current song was released** | `int` | @ref VisualizationTrack::SetYear "SetYear" | @ref VisualizationTrack::GetYear "GetYear" /// | **Lyrics of the current song, if available** | `std::string` | @ref VisualizationTrack::SetLyrics "SetLyrics" | @ref VisualizationTrack::GetLyrics "GetLyrics" /// | **The user-defined rating of the current song** | `int` | @ref VisualizationTrack::SetRating "SetRating" | @ref VisualizationTrack::GetRating "GetRating" /// | **Comment of the current song stored in the ID tag info** | `std::string` | @ref VisualizationTrack::SetComment "SetComment" | @ref VisualizationTrack::GetComment "GetComment" /// /// @addtogroup cpp_kodi_addon_visualization_Defs_VisualizationTrack ///@{ /// @brief Set title of the current song. void SetTitle(const std::string& title) { m_title = title; } /// @brief Get title of the current song. const std::string& GetTitle() const { return m_title; } /// @brief Set artist names, as a single string- void SetArtist(const std::string& artist) { m_artist = artist; } /// @brief Get artist names, as a single string- const std::string& GetArtist() const { return m_artist; } /// @brief Set Album that the current song is from. void SetAlbum(const std::string& album) { m_album = album; } /// @brief Get Album that the current song is from. const std::string& GetAlbum() const { return m_album; } /// @brief Set album artist names, as a single stringalbum artist name void SetAlbumArtist(const std::string& albumArtist) { m_albumArtist = albumArtist; } /// @brief Get album artist names, as a single string- const std::string& GetAlbumArtist() const { return m_albumArtist; } /// @brief Set genre name from music as string if present. void SetGenre(const std::string& genre) { m_genre = genre; } /// @brief Get genre name from music as string if present. const std::string& GetGenre() const { return m_genre; } /// @brief Set the duration of music as integer from info. void SetDuration(int duration) { m_duration = duration; } /// @brief Get the duration of music as integer from info. int GetDuration() const { return m_duration; } /// @brief Set track number (if present) from music info as integer. void SetTrack(int trackNumber) { m_trackNumber = trackNumber; } /// @brief Get track number (if present). int GetTrack() const { return m_trackNumber; } /// @brief Set disk number (if present) from music info as integer. void SetDisc(int discNumber) { m_discNumber = discNumber; } /// @brief Get disk number (if present) int GetDisc() const { return m_discNumber; } /// @brief Set year that the current song was released. void SetYear(int year) { m_year = year; } /// @brief Get year that the current song was released. int GetYear() const { return m_year; } /// @brief Set string from lyrics. void SetLyrics(const std::string& lyrics) { m_lyrics = lyrics; } /// @brief Get string from lyrics. const std::string& GetLyrics() const { return m_lyrics; } /// @brief Set the user-defined rating of the current song. void SetRating(int rating) { m_rating = rating; } /// @brief Get the user-defined rating of the current song. int GetRating() const { return m_rating; } /// @brief Set additional information comment (if present). void SetComment(const std::string& comment) { m_comment = comment; } /// @brief Get additional information comment (if present). const std::string& GetComment() const { return m_comment; } ///@} private: VisualizationTrack(const VIS_TRACK* tag) { if (!tag) return; m_title = tag->title ? tag->title : ""; m_artist = tag->artist ? tag->artist : ""; m_album = tag->album ? tag->album : ""; m_albumArtist = tag->albumArtist ? tag->albumArtist : ""; m_genre = tag->genre ? tag->genre : ""; m_comment = tag->comment ? tag->comment : ""; m_lyrics = tag->lyrics ? tag->lyrics : ""; m_trackNumber = tag->trackNumber; m_discNumber = tag->discNumber; m_duration = tag->duration; m_year = tag->year; m_rating = tag->rating; } std::string m_title; std::string m_artist; std::string m_album; std::string m_albumArtist; std::string m_genre; std::string m_comment; std::string m_lyrics; int m_trackNumber = 0; int m_discNumber = 0; int m_duration = 0; int m_year = 0; int m_rating = 0; }; ///@} //------------------------------------------------------------------------------ //============================================================================== /// @defgroup cpp_kodi_addon_visualization_Defs Definitions, structures and enumerators /// @ingroup cpp_kodi_addon_visualization /// @brief **Visualization add-on instance definition values**\n /// All visualization functions associated data structures. /// /// Used to exchange the available options between Kodi and addon. /// //============================================================================== /// @addtogroup cpp_kodi_addon_visualization /// @brief \cpp_class{ kodi::addon::CInstanceVisualization } /// **Visualization add-on instance**\n /// [Music visualization](https://en.wikipedia.org/wiki/Music_visualization), /// or music visualisation, is a feature in Kodi that generates animated /// imagery based on a piece of music. The imagery is usually generated and /// rendered in real time synchronized to the music. /// /// Visualization techniques range from simple ones (e.g., a simulation of an /// oscilloscope display) to elaborate ones, which often include a plurality /// of composited effects. The changes in the music's loudness and frequency /// spectrum are among the properties used as input to the visualization. /// /// Include the header @ref Visualization.h "#include " /// to use this class. /// /// This interface allows the creation of visualizations for Kodi, based upon /// **DirectX** or/and **OpenGL** rendering with `C++` code. /// /// Additionally, there are several @ref cpp_kodi_addon_visualization_CB "other functions" /// available in which the child class can ask about the current hardware, /// including the device, display and several other parts. /// /// ---------------------------------------------------------------------------- /// /// **Here's an example on addon.xml:** /// ~~~~~~~~~~~~~{.xml} /// /// /// @ADDON_DEPENDS@ /// /// /// My visualization addon addon /// My visualization addon description /// @PLATFORM@ /// /// /// ~~~~~~~~~~~~~ /// /// Description to visualization related addon.xml values: /// | Name | Description /// |:------------------------------|---------------------------------------- /// | `point` | Addon type specification
At all addon types and for this kind always "xbmc.player.musicviz". /// | `library_@PLATFORM@` | Sets the used library name, which is automatically set by cmake at addon build. /// /// -------------------------------------------------------------------------- /// /// **Here is an example of the minimum required code to start a visualization:** /// ~~~~~~~~~~~~~{.cpp} /// #include /// /// class CMyVisualization : public kodi::addon::CAddonBase, /// public kodi::addon::CInstanceVisualization /// { /// public: /// CMyVisualization(); /// /// bool Start(int channels, int samplesPerSec, int bitsPerSample, std::string songName) override; /// void AudioData(const float* audioData, int audioDataLength, float* freqData, int freqDataLength) override; /// void Render() override; /// }; /// /// CMyVisualization::CMyVisualization() /// { /// ... /// } /// /// bool CMyVisualization::Start(int channels, int samplesPerSec, int bitsPerSample, std::string songName) /// { /// ... /// return true; /// } /// /// void CMyVisualization::AudioData(const float* audioData, int audioDataLength, float* freqData, int freqDataLength) /// { /// ... /// } /// /// void CMyVisualization::Render() /// { /// ... /// } /// /// ADDONCREATOR(CMyVisualization) /// ~~~~~~~~~~~~~ /// /// /// -------------------------------------------------------------------------- /// /// /// **Here is another example where the visualization is used together with /// other instance types:** /// /// ~~~~~~~~~~~~~{.cpp} /// #include /// /// class CMyVisualization : public kodi::addon::CInstanceVisualization /// { /// public: /// CMyVisualization(KODI_HANDLE instance, const std::string& version); /// /// bool Start(int channels, int samplesPerSec, int bitsPerSample, std::string songName) override; /// void AudioData(const float* audioData, int audioDataLength, float* freqData, int freqDataLength) override; /// void Render() override; /// }; /// /// CMyVisualization::CMyVisualization(KODI_HANDLE instance, const std::string& version) /// : kodi::addon::CInstanceAudioDecoder(instance, version) /// { /// ... /// } /// /// bool CMyVisualization::Start(int channels, int samplesPerSec, int bitsPerSample, std::string songName) /// { /// ... /// return true; /// } /// /// void CMyVisualization::AudioData(const float* audioData, int audioDataLength, float* freqData, int freqDataLength) /// { /// ... /// } /// /// void CMyVisualization::Render() /// { /// ... /// } /// /// /// //---------------------------------------------------------------------- /// /// class CMyAddon : public kodi::addon::CAddonBase /// { /// public: /// CMyAddon() { } /// ADDON_STATUS CreateInstance(int instanceType, /// const std::string& instanceID, /// KODI_HANDLE instance, /// const std::string& version, /// KODI_HANDLE& addonInstance) override; /// }; /// /// // If you use only one instance in your add-on, can be instanceType and /// // instanceID ignored /// ADDON_STATUS CMyAddon::CreateInstance(int instanceType, /// const std::string& instanceID, /// KODI_HANDLE instance, /// const std::string& version, /// KODI_HANDLE& addonInstance) /// { /// if (instanceType == ADDON_INSTANCE_VISUALIZATION) /// { /// kodi::Log(ADDON_LOG_INFO, "Creating my visualization"); /// addonInstance = new CMyVisualization(instance, version); /// return ADDON_STATUS_OK; /// } /// else if (...) /// { /// ... /// } /// return ADDON_STATUS_UNKNOWN; /// } /// /// ADDONCREATOR(CMyAddon) /// ~~~~~~~~~~~~~ /// /// The destruction of the example class `CMyVisualization` is called from /// Kodi's header. Manually deleting the add-on instance is not required. /// class ATTRIBUTE_HIDDEN CInstanceVisualization : public IAddonInstance { public: //============================================================================ /// /// @ingroup cpp_kodi_addon_visualization /// @brief Visualization class constructor /// /// Used by an add-on that only supports visualizations. /// CInstanceVisualization() : IAddonInstance(ADDON_INSTANCE_VISUALIZATION, GetKodiTypeVersion(ADDON_INSTANCE_VISUALIZATION)) { if (CAddonBase::m_interface->globalSingleInstance != nullptr) throw std::logic_error( "kodi::addon::CInstanceVisualization: Cannot create multiple instances of add-on."); SetAddonStruct(CAddonBase::m_interface->firstKodiInstance); CAddonBase::m_interface->globalSingleInstance = this; } //---------------------------------------------------------------------------- //========================================================================== /// @ingroup cpp_kodi_addon_visualization /// @brief Visualization class constructor used to support multiple instance /// types. /// /// @param[in] instance The instance value given to /// `kodi::addon::CAddonBase::CreateInstance(...)`. /// @param[in] kodiVersion [opt] Version used in Kodi for this instance, to /// allow compatibility to older Kodi versions. /// /// @note Recommended to set `kodiVersion`. /// /// /// -------------------------------------------------------------------------- /// /// **Here's example about the use of this:** /// ~~~~~~~~~~~~~{.cpp} /// class CMyVisualization : public kodi::addon::CInstanceAudioDecoder /// { /// public: /// CMyVisualization(KODI_HANDLE instance, const std::string& kodiVersion) /// : kodi::addon::CInstanceAudioDecoder(instance, kodiVersion) /// { /// ... /// } /// /// ... /// }; /// /// ADDON_STATUS CMyAddon::CreateInstance(int instanceType, /// const std::string& instanceID, /// KODI_HANDLE instance, /// const std::string& version, /// KODI_HANDLE& addonInstance) /// { /// kodi::Log(ADDON_LOG_INFO, "Creating my visualization"); /// addonInstance = new CMyVisualization(instance, version); /// return ADDON_STATUS_OK; /// } /// ~~~~~~~~~~~~~ /// explicit CInstanceVisualization(KODI_HANDLE instance, const std::string& kodiVersion = "") : IAddonInstance(ADDON_INSTANCE_VISUALIZATION, !kodiVersion.empty() ? kodiVersion : GetKodiTypeVersion(ADDON_INSTANCE_VISUALIZATION)) { if (CAddonBase::m_interface->globalSingleInstance != nullptr) throw std::logic_error("kodi::addon::CInstanceVisualization: Creation of multiple together " "with single instance way is not allowed!"); SetAddonStruct(instance); } //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization /// @brief Destructor. /// ~CInstanceVisualization() override = default; //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization /// @brief Used to notify the visualization that a new song has been started. /// /// @param[in] channels Number of channels in the stream /// @param[in] samplesPerSec Samples per second of stream /// @param[in] bitsPerSample Number of bits in one sample /// @param[in] songName The name of the currently-playing song /// @return true if start successful done /// virtual bool Start(int channels, int samplesPerSec, int bitsPerSample, std::string songName) { return true; } //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization /// @brief Used to inform the visualization that the rendering control was /// stopped. /// virtual void Stop() {} //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization /// @brief Pass audio data to the visualization. /// /// @param[in] audioData The raw audio data /// @param[in] audioDataLength Length of the audioData array /// @param[in] freqData The [FFT](https://en.wikipedia.org/wiki/Fast_Fourier_transform) /// of the audio data /// @param[in] freqDataLength Length of frequency data array /// /// Values **freqData** and **freqDataLength** are used if GetInfo() returns /// true for the `wantsFreq` parameter. Otherwise, **freqData** is set to /// `nullptr` and **freqDataLength** is `0`. /// virtual void AudioData(const float* audioData, int audioDataLength, float* freqData, int freqDataLength) { } //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization /// @brief Used to inform Kodi that the rendered region is dirty and need an /// update. /// /// @return True if dirty /// virtual bool IsDirty() { return true; } //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization /// @brief Used to indicate when the add-on should render. /// virtual void Render() {} //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization /// @brief Used to get the number of buffers from the current visualization. /// /// @param[out] wantsFreq Indicates whether the add-on wants FFT data. If set /// to true, the **freqData** and **freqDataLength** /// parameters of @ref AudioData() are used /// @param[out] syncDelay The number of buffers to delay before calling /// @ref AudioData() /// /// @note If this function is not implemented, it will default to /// `wantsFreq` = false and `syncDelay` = 0. /// virtual void GetInfo(bool& wantsFreq, int& syncDelay) { wantsFreq = false; syncDelay = 0; } //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization /// @brief Used to get a list of visualization presets the user can select. /// from /// /// @param[out] presets The vector list containing the names of presets that /// the user can select /// @return Return true if successful, or false if there are no presets to /// choose from /// virtual bool GetPresets(std::vector& presets) { return false; } //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization /// @brief Get the index of the current preset. /// /// @return Index number of the current preset /// virtual int GetActivePreset() { return -1; } //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization /// @brief Check if the add-on is locked to the current preset. /// /// @return True if locked to the current preset /// virtual bool IsLocked() { return false; } //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization /// @brief Load the previous visualization preset. /// /// @return Return true if the previous preset was loaded /// virtual bool PrevPreset() { return false; } //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization /// @brief Load the next visualization preset. /// /// @return Return true if the next preset was loaded /// virtual bool NextPreset() { return false; } //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization /// @brief Load a visualization preset. /// /// This function is called after a new preset is selected. /// /// @param[in] select Preset index to use /// @return Return true if the preset is loaded /// virtual bool LoadPreset(int select) { return false; } //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization /// @brief Switch to a new random preset. /// /// @return Return true if a random preset was loaded /// virtual bool RandomPreset() { return false; } //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization /// @brief Lock the current visualization preset, preventing it from changing. /// /// @param[in] lockUnlock If set to true, the preset should be locked /// @return Return true if the current preset is locked /// virtual bool LockPreset(bool lockUnlock) { return false; } //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization /// @brief Used to increase/decrease the visualization preset rating. /// /// @param[in] plusMinus If set to true the rating is increased, otherwise /// decreased /// @return Return true if the rating is modified /// virtual bool RatePreset(bool plusMinus) { return false; } //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization /// @brief Inform the visualization of the current album art image. /// /// @param[in] albumart Path to the current album art image /// @return Return true if the image is used /// virtual bool UpdateAlbumart(std::string albumart) { return false; } //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization /// @brief Inform the visualization of the current track's tag information. /// /// @param[in] track Visualization track information structure /// @return Return true if the track information is used /// /// -------------------------------------------------------------------------- /// /// @copydetails cpp_kodi_addon_visualization_Defs_VisualizationTrack_Help /// ///------------------------------------------------------------------------- /// /// **Example:** /// ~~~~~~~~~~~~~{.cpp} /// /// #include /// /// class CMyVisualization : public kodi::addon::CInstanceVisualization /// { /// public: /// CMyVisualization(KODI_HANDLE instance, const std::string& version); /// /// ... /// /// private: /// kodi::addon::VisualizationTrack m_runningTrack; /// }; /// /// bool CMyVisualization::UpdateTrack(const kodi::addon::VisualizationTrack& track) /// { /// m_runningTrack = track; /// return true; /// } /// /// ~~~~~~~~~~~~~ /// virtual bool UpdateTrack(const kodi::addon::VisualizationTrack& track) { return false; } //---------------------------------------------------------------------------- //============================================================================ /// @defgroup cpp_kodi_addon_visualization_CB Information functions /// @ingroup cpp_kodi_addon_visualization /// @brief **To get info about the device, display and several other parts**\n /// These are functions to query any values or to transfer them to Kodi. /// ///@{ //============================================================================ /// @ingroup cpp_kodi_addon_visualization_CB /// @brief To transfer available presets on addon. /// /// Used if @ref GetPresets not possible to use, e.g. where available presets /// are only known during @ref Start call. /// /// @param[in] presets List to store available presets. /// /// @note The function should only be called once, if possible /// inline void TransferPresets(const std::vector& presets) { m_instanceData->toKodi->clear_presets(m_instanceData->toKodi->kodiInstance); for (const auto& it : presets) m_instanceData->toKodi->transfer_preset(m_instanceData->toKodi->kodiInstance, it.c_str()); } //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization_CB /// @brief Device that represents the display adapter. /// /// @return A pointer to the used device with @ref cpp_kodi_Defs_HardwareContext "HardwareContext" /// /// @note This is only available on **DirectX**, It us unused (`nullptr`) on /// **OpenGL** /// ///------------------------------------------------------------------------- /// /// **Example:** /// ~~~~~~~~~~~~~{.cpp} /// #include /// .. /// // Note: Device() there is used inside addon child class about /// // kodi::addon::CInstanceVisualization /// ID3D11DeviceContext1* context = static_cast(kodi::addon::CInstanceVisualization::Device()); /// .. /// ~~~~~~~~~~~~~ /// inline kodi::HardwareContext Device() { return m_instanceData->props->device; } //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization_CB /// @brief Returns the X position of the rendering window. /// /// @return The X position, in pixels /// inline int X() { return m_instanceData->props->x; } //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization_CB /// @brief Returns the Y position of the rendering window. /// /// @return The Y position, in pixels /// inline int Y() { return m_instanceData->props->y; } //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization_CB /// @brief Returns the width of the rendering window. /// /// @return The width, in pixels /// inline int Width() { return m_instanceData->props->width; } //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization_CB /// @brief Returns the height of the rendering window. /// /// @return The height, in pixels /// inline int Height() { return m_instanceData->props->height; } //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization_CB /// @brief Pixel aspect ratio (often abbreviated PAR) is a ratio that /// describes how the width of a pixel compares to the height of that pixel. /// /// @return The pixel aspect ratio used by the display /// inline float PixelRatio() { return m_instanceData->props->pixelRatio; } //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization_CB /// @brief Used to get the name of the add-on defined in `addon.xml`. /// /// @return The add-on name /// inline std::string Name() { return m_instanceData->props->name; } //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization_CB /// @brief Used to get the full path where the add-on is installed. /// /// @return The add-on installation path /// inline std::string Presets() { return m_instanceData->props->presets; } //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_visualization_CB /// @brief Used to get the full path to the add-on's user profile. /// /// @note The trailing folder (consisting of the add-on's ID) is not created /// by default. If it is needed, you must call kodi::vfs::CreateDirectory() /// to create the folder. /// /// @return Path to the user profile /// inline std::string Profile() { return m_instanceData->props->profile; } //---------------------------------------------------------------------------- ///@} private: void SetAddonStruct(KODI_HANDLE instance) { if (instance == nullptr) throw std::logic_error("kodi::addon::CInstanceVisualization: Null pointer instance passed."); m_instanceData = static_cast(instance); m_instanceData->toAddon->addonInstance = this; m_instanceData->toAddon->start = ADDON_Start; m_instanceData->toAddon->stop = ADDON_Stop; m_instanceData->toAddon->audio_data = ADDON_AudioData; m_instanceData->toAddon->is_dirty = ADDON_IsDirty; m_instanceData->toAddon->render = ADDON_Render; m_instanceData->toAddon->get_info = ADDON_GetInfo; m_instanceData->toAddon->prev_preset = ADDON_PrevPreset; m_instanceData->toAddon->next_preset = ADDON_NextPreset; m_instanceData->toAddon->load_preset = ADDON_LoadPreset; m_instanceData->toAddon->random_preset = ADDON_RandomPreset; m_instanceData->toAddon->lock_preset = ADDON_LockPreset; m_instanceData->toAddon->rate_preset = ADDON_RatePreset; m_instanceData->toAddon->update_albumart = ADDON_UpdateAlbumart; m_instanceData->toAddon->update_track = ADDON_UpdateTrack; m_instanceData->toAddon->get_presets = ADDON_GetPresets; m_instanceData->toAddon->get_active_preset = ADDON_GetActivePreset; m_instanceData->toAddon->is_locked = ADDON_IsLocked; } inline static bool ADDON_Start(const AddonInstance_Visualization* addon, int channels, int samplesPerSec, int bitsPerSample, const char* songName) { CInstanceVisualization* thisClass = static_cast(addon->toAddon->addonInstance); thisClass->m_renderHelper = kodi::gui::GetRenderHelper(); return thisClass->Start(channels, samplesPerSec, bitsPerSample, songName); } inline static void ADDON_Stop(const AddonInstance_Visualization* addon) { CInstanceVisualization* thisClass = static_cast(addon->toAddon->addonInstance); thisClass->Stop(); thisClass->m_renderHelper = nullptr; } inline static void ADDON_AudioData(const AddonInstance_Visualization* addon, const float* audioData, int audioDataLength, float* freqData, int freqDataLength) { static_cast(addon->toAddon->addonInstance) ->AudioData(audioData, audioDataLength, freqData, freqDataLength); } inline static bool ADDON_IsDirty(const AddonInstance_Visualization* addon) { return static_cast(addon->toAddon->addonInstance)->IsDirty(); } inline static void ADDON_Render(const AddonInstance_Visualization* addon) { CInstanceVisualization* thisClass = static_cast(addon->toAddon->addonInstance); if (!thisClass->m_renderHelper) return; thisClass->m_renderHelper->Begin(); thisClass->Render(); thisClass->m_renderHelper->End(); } inline static void ADDON_GetInfo(const AddonInstance_Visualization* addon, VIS_INFO* info) { static_cast(addon->toAddon->addonInstance) ->GetInfo(info->bWantsFreq, info->iSyncDelay); } inline static unsigned int ADDON_GetPresets(const AddonInstance_Visualization* addon) { CInstanceVisualization* thisClass = static_cast(addon->toAddon->addonInstance); std::vector presets; if (thisClass->GetPresets(presets)) { for (const auto& it : presets) thisClass->m_instanceData->toKodi->transfer_preset(addon->toKodi->kodiInstance, it.c_str()); } return static_cast(presets.size()); } inline static int ADDON_GetActivePreset(const AddonInstance_Visualization* addon) { return static_cast(addon->toAddon->addonInstance)->GetActivePreset(); } inline static bool ADDON_PrevPreset(const AddonInstance_Visualization* addon) { return static_cast(addon->toAddon->addonInstance)->PrevPreset(); } inline static bool ADDON_NextPreset(const AddonInstance_Visualization* addon) { return static_cast(addon->toAddon->addonInstance)->NextPreset(); } inline static bool ADDON_LoadPreset(const AddonInstance_Visualization* addon, int select) { return static_cast(addon->toAddon->addonInstance)->LoadPreset(select); } inline static bool ADDON_RandomPreset(const AddonInstance_Visualization* addon) { return static_cast(addon->toAddon->addonInstance)->RandomPreset(); } inline static bool ADDON_LockPreset(const AddonInstance_Visualization* addon) { CInstanceVisualization* thisClass = static_cast(addon->toAddon->addonInstance); thisClass->m_presetLockedByUser = !thisClass->m_presetLockedByUser; return thisClass->LockPreset(thisClass->m_presetLockedByUser); } inline static bool ADDON_RatePreset(const AddonInstance_Visualization* addon, bool plus_minus) { return static_cast(addon->toAddon->addonInstance) ->RatePreset(plus_minus); } inline static bool ADDON_IsLocked(const AddonInstance_Visualization* addon) { return static_cast(addon->toAddon->addonInstance)->IsLocked(); } inline static bool ADDON_UpdateAlbumart(const AddonInstance_Visualization* addon, const char* albumart) { return static_cast(addon->toAddon->addonInstance) ->UpdateAlbumart(albumart); } inline static bool ADDON_UpdateTrack(const AddonInstance_Visualization* addon, const VIS_TRACK* track) { VisualizationTrack cppTrack(track); return static_cast(addon->toAddon->addonInstance) ->UpdateTrack(cppTrack); } std::shared_ptr m_renderHelper; bool m_presetLockedByUser = false; AddonInstance_Visualization* m_instanceData; }; } /* namespace addon */ } /* namespace kodi */ #endif /* __cplusplus */