LDFLAGS_FOR_BUILD+=@LDFLAGS_FOR_BUILD@
INCLUDES+=-I@abs_top_srcdir@/lib
INCLUDES+=-I@abs_top_srcdir@/xbmc
+INCLUDES+=-I@abs_top_srcdir@/xbmc/addons/include
INCLUDES+=-I@abs_top_srcdir@/addons/library.kodi.guilib
INCLUDES+=-I@abs_top_srcdir@/addons/library.xbmc.addon
INCLUDES+=-I@abs_top_srcdir@/addons/library.kodi.adsp
((CB_ADSPLib*)cb)->UnregisterMode(((AddonCB*)hdl)->addonData, mode);
}
+///-------------------------------------
+/// CAddonSoundPlay
+
+DLLEXPORT CAddonSoundPlay* ADSP_get_sound_play(void *hdl, void *cb, const char *filename)
+{
+ return new CAddonSoundPlay(hdl, cb, filename);
+}
+
+DLLEXPORT void ADSP_release_sound_play(CAddonSoundPlay* p)
+{
+ delete p;
+}
+
+CAddonSoundPlay::CAddonSoundPlay(void *hdl, void *cb, const char *filename)
+ : m_Filename(filename)
+{
+ m_PlayHandle = NULL;
+ if (!hdl || !cb)
+ fprintf(stderr, "libKODI_adsp-ERROR: ADSP_get_sound_play is called with NULL handle !!!\n");
+ else
+ {
+ m_Handle = hdl;
+ m_cb = cb;
+ m_PlayHandle = ((CB_ADSPLib*)m_cb)->SoundPlay_GetHandle(((AddonCB*)m_Handle)->addonData, m_Filename.c_str());
+ if (!m_PlayHandle)
+ fprintf(stderr, "libKODI_adsp-ERROR: ADSP_get_sound_play can't get callback table from KODI !!!\n");
+ }
+}
+
+CAddonSoundPlay::~CAddonSoundPlay()
+{
+ if (m_PlayHandle)
+ ((CB_ADSPLib*)m_cb)->SoundPlay_ReleaseHandle(((AddonCB*)m_Handle)->addonData, m_PlayHandle);
+}
+
+void CAddonSoundPlay::Play()
+{
+ if (m_PlayHandle)
+ ((CB_ADSPLib*)m_cb)->SoundPlay_Play(((AddonCB*)m_Handle)->addonData, m_PlayHandle);
+}
+
+void CAddonSoundPlay::Stop()
+{
+ if (m_PlayHandle)
+ ((CB_ADSPLib*)m_cb)->SoundPlay_Stop(((AddonCB*)m_Handle)->addonData, m_PlayHandle);
+}
+
+bool CAddonSoundPlay::IsPlaying()
+{
+ if (!m_PlayHandle)
+ return false;
+
+ return ((CB_ADSPLib*)m_cb)->SoundPlay_IsPlaying(((AddonCB*)m_Handle)->addonData, m_PlayHandle);
+}
+
+void CAddonSoundPlay::SetChannel(AE_DSP_CHANNEL channel)
+{
+ if (m_PlayHandle)
+ ((CB_ADSPLib*)m_cb)->SoundPlay_SetChannel(((AddonCB*)m_Handle)->addonData, m_PlayHandle, channel);
+}
+
+AE_DSP_CHANNEL CAddonSoundPlay::GetChannel()
+{
+ if (!m_PlayHandle)
+ return AE_DSP_CH_INVALID;
+ return ((CB_ADSPLib*)m_cb)->SoundPlay_GetChannel(((AddonCB*)m_Handle)->addonData, m_PlayHandle);
+}
+
+void CAddonSoundPlay::SetVolume(float volume)
+{
+ if (m_PlayHandle)
+ ((CB_ADSPLib*)m_cb)->SoundPlay_SetVolume(((AddonCB*)m_Handle)->addonData, m_PlayHandle, volume);
+}
+
+float CAddonSoundPlay::GetVolume()
+{
+ if (!m_PlayHandle)
+ return 0.0f;
+
+ return ((CB_ADSPLib*)m_cb)->SoundPlay_GetVolume(((AddonCB*)m_Handle)->addonData, m_PlayHandle);
+}
+
};
#include <stdint.h>
#include "../../addons/library.kodi.guilib/libKODI_guilib.h"
+#include "../../addons/library.kodi.adsp/libKODI_adsp.h"
#include "cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.h"
#include "addons/include/kodi_adsp_types.h"
#include "addons/include/xbmc_pvr_types.h"
typedef void (*ADSPRegisterMode)(void *addonData, AE_DSP_MODES::AE_DSP_MODE *mode);
typedef void (*ADSPUnregisterMode)(void *addonData, AE_DSP_MODES::AE_DSP_MODE *mode);
+typedef ADSPHANDLE (*ADSPSoundPlay_GetHandle)(void *addonData, const char *filename);
+typedef void (*ADSPSoundPlay_ReleaseHandle)(void *addonData, ADSPHANDLE handle);
+typedef void (*ADSPSoundPlay_Play)(void *addonData, ADSPHANDLE handle);
+typedef void (*ADSPSoundPlay_Stop)(void *addonData, ADSPHANDLE handle);
+typedef bool (*ADSPSoundPlay_IsPlaying)(void *addonData, ADSPHANDLE handle);
+typedef void (*ADSPSoundPlay_SetChannel)(void *addonData, ADSPHANDLE handle, AE_DSP_CHANNEL channel);
+typedef AE_DSP_CHANNEL (*ADSPSoundPlay_GetChannel)(void *addonData, ADSPHANDLE handle);
+typedef void (*ADSPSoundPlay_SetVolume)(void *addonData, ADSPHANDLE handle, float volume);
+typedef float (*ADSPSoundPlay_GetVolume)(void *addonData, ADSPHANDLE handle);
+
typedef struct CB_ADSPLib
{
ADSPAddMenuHook AddMenuHook;
ADSPRegisterMode RegisterMode;
ADSPUnregisterMode UnregisterMode;
+ ADSPSoundPlay_GetHandle SoundPlay_GetHandle;
+ ADSPSoundPlay_ReleaseHandle SoundPlay_ReleaseHandle;
+ ADSPSoundPlay_Play SoundPlay_Play;
+ ADSPSoundPlay_Stop SoundPlay_Stop;
+ ADSPSoundPlay_IsPlaying SoundPlay_IsPlaying;
+ ADSPSoundPlay_SetChannel SoundPlay_SetChannel;
+ ADSPSoundPlay_GetChannel SoundPlay_GetChannel;
+ ADSPSoundPlay_SetVolume SoundPlay_SetVolume;
+ ADSPSoundPlay_GetVolume SoundPlay_GetVolume;
} CB_ADSPLib;
typedef void (*PVRTransferEpgEntry)(void *userData, const ADDON_HANDLE handle, const EPG_TAG *epgentry);
m_callbacks->RemoveMenuHook = ADSPRemoveMenuHook;
m_callbacks->RegisterMode = ADSPRegisterMode;
m_callbacks->UnregisterMode = ADSPUnregisterMode;
+
+ m_callbacks->SoundPlay_GetHandle = ADSPSoundPlay_GetHandle;
+ m_callbacks->SoundPlay_ReleaseHandle = ADSPSoundPlay_ReleaseHandle;
+ m_callbacks->SoundPlay_Play = ADSPSoundPlay_Play;
+ m_callbacks->SoundPlay_Stop = ADSPSoundPlay_Stop;
+ m_callbacks->SoundPlay_IsPlaying = ADSPSoundPlay_IsPlaying;
+ m_callbacks->SoundPlay_SetChannel = ADSPSoundPlay_SetChannel;
+ m_callbacks->SoundPlay_GetChannel = ADSPSoundPlay_GetChannel;
+ m_callbacks->SoundPlay_SetVolume = ADSPSoundPlay_SetVolume;
+ m_callbacks->SoundPlay_GetVolume = ADSPSoundPlay_GetVolume;
}
CAddonCallbacksADSP::~CAddonCallbacksADSP()
transferMode.Delete();
}
+ADSPHANDLE CAddonCallbacksADSP::ADSPSoundPlay_GetHandle(void *addonData, const char *filename)
+{
+ CActiveAEDSPAddon *addon = GetAudioDSPAddon(addonData);
+ if (!filename || !addon)
+ {
+ CLog::Log(LOGERROR, "Audio DSP - %s - invalid sound play data", __FUNCTION__);
+ return NULL;
+ }
+
+ IAESound *sound = CAEFactory::MakeSound(filename);
+ if (!sound)
+ {
+ CLog::Log(LOGERROR, "Audio DSP - %s - failed to make sound play data", __FUNCTION__);
+ return NULL;
+ }
+
+ return sound;
+}
+
+void CAddonCallbacksADSP::ADSPSoundPlay_ReleaseHandle(void *addonData, ADSPHANDLE handle)
+{
+ CActiveAEDSPAddon *addon = GetAudioDSPAddon(addonData);
+ if (!handle || !addon)
+ {
+ CLog::Log(LOGERROR, "Audio DSP - %s - invalid sound play data", __FUNCTION__);
+ return;
+ }
+
+ CAEFactory::FreeSound((IAESound*)handle);
+}
+
+void CAddonCallbacksADSP::ADSPSoundPlay_Play(void *addonData, ADSPHANDLE handle)
+{
+ CActiveAEDSPAddon *addon = GetAudioDSPAddon(addonData);
+ if (!handle || !addon)
+ {
+ CLog::Log(LOGERROR, "Audio DSP - %s - invalid sound play data", __FUNCTION__);
+ return;
+ }
+ ((IAESound*)handle)->Play();
+}
+
+void CAddonCallbacksADSP::ADSPSoundPlay_Stop(void *addonData, ADSPHANDLE handle)
+{
+ CActiveAEDSPAddon *addon = GetAudioDSPAddon(addonData);
+ if (!handle || !addon)
+ {
+ CLog::Log(LOGERROR, "Audio DSP - %s - invalid sound play data", __FUNCTION__);
+ return;
+ }
+ ((IAESound*)handle)->Stop();
+}
+
+bool CAddonCallbacksADSP::ADSPSoundPlay_IsPlaying(void *addonData, ADSPHANDLE handle)
+{
+ CActiveAEDSPAddon *addon = GetAudioDSPAddon(addonData);
+ if (!handle || !addon)
+ {
+ CLog::Log(LOGERROR, "Audio DSP - %s - invalid sound play data", __FUNCTION__);
+ return false;
+ }
+ return ((IAESound*)handle)->IsPlaying();
+}
+
+void CAddonCallbacksADSP::ADSPSoundPlay_SetChannel(void *addonData, ADSPHANDLE handle, AE_DSP_CHANNEL channel)
+{
+ CActiveAEDSPAddon *addon = GetAudioDSPAddon(addonData);
+ if (!handle || !addon)
+ {
+ CLog::Log(LOGERROR, "Audio DSP - %s - invalid sound play data", __FUNCTION__);
+ return;
+ }
+
+ ((IAESound*)handle)->SetChannel(CActiveAEDSP::GetKODIChannel(channel));
+}
+
+AE_DSP_CHANNEL CAddonCallbacksADSP::ADSPSoundPlay_GetChannel(void *addonData, ADSPHANDLE handle)
+{
+ CActiveAEDSPAddon *addon = GetAudioDSPAddon(addonData);
+ if (!handle || !addon)
+ {
+ CLog::Log(LOGERROR, "Audio DSP - %s - invalid sound play data", __FUNCTION__);
+ return AE_DSP_CH_INVALID;
+ }
+
+ return CActiveAEDSP::GetDSPChannel(((IAESound*)handle)->GetChannel());
+}
+
+void CAddonCallbacksADSP::ADSPSoundPlay_SetVolume(void *addonData, ADSPHANDLE handle, float volume)
+{
+ CActiveAEDSPAddon *addon = GetAudioDSPAddon(addonData);
+ if (!handle || !addon)
+ {
+ CLog::Log(LOGERROR, "Audio DSP - %s - invalid sound play data", __FUNCTION__);
+ return;
+ }
+
+ ((IAESound*)handle)->SetVolume(volume);
+}
+
+float CAddonCallbacksADSP::ADSPSoundPlay_GetVolume(void *addonData, ADSPHANDLE handle)
+{
+ CActiveAEDSPAddon *addon = GetAudioDSPAddon(addonData);
+ if (!handle || !addon)
+ {
+ CLog::Log(LOGERROR, "Audio DSP - %s - invalid sound play data", __FUNCTION__);
+ return 0.0f;
+ }
+
+ return ((IAESound*)handle)->GetVolume();
+}
+
}; /* namespace ADDON */
*/
static void ADSPUnregisterMode(void* addonData, AE_DSP_MODES::AE_DSP_MODE* mode);
+ /*! @name KODI background sound play handling */
+ //@{
+ /*!
+ * @brief Get a handle to open a gui sound wave playback
+ * @param addonData A pointer to the add-on.
+ * @param filename the related wave file to open
+ * @return pointer to sound play handle
+ */
+ static ADSPHANDLE ADSPSoundPlay_GetHandle(void *addonData, const char *filename);
+
+ /*!
+ * @brief Release the selected handle on KODI
+ * @param addonData A pointer to the add-on.
+ * @param handle pointer to sound play handle
+ */
+ static void ADSPSoundPlay_ReleaseHandle(void *addonData, ADSPHANDLE handle);
+
+ /*!
+ * @brief Start the wave file playback
+ * @param addonData A pointer to the add-on.
+ * @param handle pointer to sound play handle
+ */
+ static void ADSPSoundPlay_Play(void *addonData, ADSPHANDLE handle);
+
+ /*!
+ * @brief Stop the wave file playback
+ * @param addonData A pointer to the add-on.
+ * @param handle pointer to sound play handle
+ */
+ static void ADSPSoundPlay_Stop(void *addonData, ADSPHANDLE handle);
+
+ /*!
+ * @brief Ask that the playback of wave is in progress
+ * @param addonData A pointer to the add-on.
+ * @param handle pointer to sound play handle
+ * @return true if playing
+ */
+ static bool ADSPSoundPlay_IsPlaying(void *addonData, ADSPHANDLE handle);
+
+ /*!
+ * @brief Set the optional playback channel position, if not used it is on all channels
+ * @param addonData A pointer to the add-on.
+ * @param handle pointer to sound play handle
+ * @param used channel pointer for the playback, AE_DSP_CH_INVALID for on all
+ */
+ static void ADSPSoundPlay_SetChannel(void *addonData, ADSPHANDLE handle, AE_DSP_CHANNEL channel);
+
+ /*!
+ * @brief Get the selected playback channel position
+ * @param addonData A pointer to the add-on.
+ * @param handle pointer to sound play handle
+ * @return the used channel pointer for the playback, AE_DSP_CH_INVALID for on all
+ */
+ static AE_DSP_CHANNEL ADSPSoundPlay_GetChannel(void *addonData, ADSPHANDLE handle);
+
+ /*!
+ * @brief Set the volume for the wave file playback
+ * @param addonData A pointer to the add-on.
+ * @param handle pointer to sound play handle
+ * @param volume for the file playback
+ */
+ static void ADSPSoundPlay_SetVolume(void *addonData, ADSPHANDLE handle, float volume);
+
+ /*!
+ * @brief Get the volume which is set for the playback
+ * @param addonData A pointer to the add-on.
+ * @param handle pointer to sound play handle
+ * @return current volume for the file playback
+ */
+ static float ADSPSoundPlay_GetVolume(void *addonData, ADSPHANDLE handle);
+ //@}
+
private:
static ActiveAE::CActiveAEDSPAddon* GetAudioDSPAddon(void* addonData);
m_audioCallback = NULL;
m_vizInitialized = false;
m_sinkHasVolume = false;
+ m_aeGUISoundForce = false;
m_stats.Reset(44100);
}
case CActiveAEDataProtocol::PLAYSOUND:
CActiveAESound *sound;
sound = *(CActiveAESound**)msg->data;
- if (m_settings.guisoundmode == AE_SOUND_OFF ||
- (m_settings.guisoundmode == AE_SOUND_IDLE && !m_streams.empty()))
- return;
if (sound)
{
+ m_aeGUISoundForce = m_settings.dspaddonsenabled && sound->GetChannel() != AE_CH_NULL;
+
+ if ((m_settings.guisoundmode == AE_SOUND_OFF ||
+ (m_settings.guisoundmode == AE_SOUND_IDLE && !m_streams.empty())) &&
+ !m_aeGUISoundForce)
+ return;
+
SoundState st = {sound, 0};
m_sounds_playing.push_back(st);
m_extTimeout = 0;
if (!CompareFormat(oldInternalFormat, m_internalFormat))
{
if (m_settings.guisoundmode == AE_SOUND_ALWAYS ||
- (m_settings.guisoundmode == AE_SOUND_IDLE && m_streams.empty()))
+ (m_settings.guisoundmode == AE_SOUND_IDLE && m_streams.empty()) ||
+ m_aeGUISoundForce)
{
std::vector<CActiveAESound*>::iterator it;
for (it = m_sounds.begin(); it != m_sounds.end(); ++it)
{
if (it->sound == sound)
{
+ if (sound->GetChannel() != AE_CH_NULL)
+ m_aeGUISoundForce = false;
m_sounds_playing.erase(it);
return;
}
void CActiveAE::ChangeResamplers()
{
-
std::list<CActiveAEStream*>::iterator it;
for(it=m_streams.begin(); it!=m_streams.end(); ++it)
{
*/
void CActiveAE::ResampleSounds()
{
- if (m_settings.guisoundmode == AE_SOUND_OFF ||
- (m_settings.guisoundmode == AE_SOUND_IDLE && !m_streams.empty()))
+ if ((m_settings.guisoundmode == AE_SOUND_OFF ||
+ (m_settings.guisoundmode == AE_SOUND_IDLE && !m_streams.empty())) &&
+ !m_aeGUISoundForce)
return;
std::vector<CActiveAESound*>::iterator it;
dst_config.bits_per_sample = CAEUtil::DataFormatToUsedBits(m_internalFormat.m_dataFormat);
dst_config.dither_bits = CAEUtil::DataFormatToDitherBits(m_internalFormat.m_dataFormat);
+ AEChannel testChannel = sound->GetChannel();
+ CAEChannelInfo outChannels;
+ if (sound->GetSound(true)->config.channels == 1 && testChannel != AE_CH_NULL)
+ {
+ for (unsigned int out=0; out < m_internalFormat.m_channelLayout.Count(); out++)
+ {
+ if (m_internalFormat.m_channelLayout[out] == AE_CH_FC && testChannel != AE_CH_FC) /// To become center clear on position test ??????
+ outChannels += AE_CH_FL;
+ else if (m_internalFormat.m_channelLayout[out] == testChannel)
+ outChannels += AE_CH_FC;
+ else
+ outChannels += m_internalFormat.m_channelLayout[out];
+ }
+ }
+
IAEResample *resampler = CAEResampleFactory::Create(AERESAMPLEFACTORY_QUICK_RESAMPLE);
resampler->Init(dst_config.channel_layout,
dst_config.channels,
orig_config.dither_bits,
false,
true,
- NULL,
+ outChannels.Count() > 0 ? &outChannels : NULL,
m_settings.resampleQuality,
false);
// polled via the interface
float m_aeVolume;
bool m_aeMuted;
+ bool m_aeGUISoundForce;
};
};
CActiveAESound::CActiveAESound(const std::string &filename) :
IAESound (filename),
m_filename (filename),
- m_volume (1.0f )
+ m_volume (1.0f ),
+ m_channel (AE_CH_NULL)
{
m_orig_sound = NULL;
m_dst_sound = NULL;
virtual void Stop();
virtual bool IsPlaying();
+ virtual void SetChannel(AEChannel channel) { m_channel = channel; }
+ virtual AEChannel GetChannel() { return m_channel; }
virtual void SetVolume(float volume) { m_volume = std::max(0.0f, std::min(1.0f, volume)); }
virtual float GetVolume() { return m_volume; }
bool m_isSeekPossible;
int m_fileSize;
float m_volume;
+ AEChannel m_channel;
CSoundPacket *m_orig_sound;
CSoundPacket *m_dst_sound;
*/
#include <string>
+#include "cores/AudioEngine/Utils/AEAudioFormat.h"
class IAESound
{
/* return true if the sound is currently playing */
virtual bool IsPlaying() = 0;
+ /* set the playback channel of this sound, AE_CH_NULL for all */
+ virtual void SetChannel(AEChannel channel) = 0;
+
+ /* get the current playback channel of this sound, AE_CH_NULL for all */
+ virtual AEChannel GetChannel() = 0;
+
/* set the playback volume of this sound */
virtual void SetVolume(float volume) = 0;