
/*! * file AwxAudioObjExt.cpp * brief Simple example Audio object for building outside from the xAF repo- Source file * details Implements a simple example fucntionality * details Project Extendable Audio Framework * copyright Harman/Becker Automotive Systems GmbH * 2022 * All rights reserved * author xAF Team */ /*! * xaf mandataory includes */ #include "AwxAudioObjExt.h" #include "XafMacros.h" #include "vector.h" VERSION_STRING_AO(AwxAudioObjExt, AWXAUDIOOBJEXT); AO_VERSION(AwxAudioObjExt, AWXAUDIOOBJEXT); /** here you can add all required include files required for the core functionality of your objects **/ #define MAX_CONFIG_MIN_GAIN_dB (0.0f) #define MAX_CONFIG_MAX_GAIN_dB (30.0f) #define MAX_GAIN_DEFAULT_GAIN_dB (10.0f) #define CONTROL_GAIN_MIN (-128.0f) #define GAINDB_CONVERSION_FACTOR (0.05f) CAwxAudioObjExt::CAwxAudioObjExt() : m_Coeffs(NULL) , m_Params(NULL), m_MemBlock(NULL), m_EnMemory(DISABLE_BLOCK) { } CAwxAudioObjExt::~CAwxAudioObjExt() { } void CAwxAudioObjExt::init() { m_Params = static_cast<xFloat32*>(m_MemRecPtrs[PARAM]); m_Coeffs = static_cast<xFloat32*>(m_MemRecPtrs[COEFF]); if (ENABLE_BLOCK == m_EnMemory) { m_MemBlock = static_cast<xFloat32*>(m_MemRecPtrs[FLOATARRAY]); } if (static_cast(GAIN_WITH_CONTROL) == m_Mode) { m_NumControlIn = 1; m_NumControlOut = 0; } else { m_NumControlIn = 0; m_NumControlOut = 0; } } void CAwxAudioObjExt::assignAdditionalConfig() { xInt8* addVars8Ptr = reinterpret_cast<xInt8*>(m_AdditionalSFDConfig); //Assigning additional configuration variable "Abstracted Tuning Memory". if (static_cast<void*>(NULL) != m_AdditionalSFDConfig) { m_EnMemory = addVars8Ptr[m_NumAudioIn * sizeof(xFloat32)]; } } xFloat32 CAwxAudioObjExt::getMaxGain(xSInt32 index) { xFloat32* addVars32Ptr = reinterpret_cast<xFloat32*>(m_AdditionalSFDConfig); xFloat32 value = addVars32Ptr[index]; return value; } xInt8* CAwxAudioObjExt::getSubBlockPtr(xUInt16 subBlock) { xInt8* ptr = NULL; // this is just an example of how memory could be split by an AO developer. There is no strict rule // how memory has to be split for each subblock switch(subBlock) { case 0: ptr = reinterpret_cast<xInt8*>(m_Params); break; case 1: ptr = reinterpret_cast<xInt8*>(m_MemBlock); break; default: // by default we will return a null ptr, hence wrong subBlock was provided break; } return ptr; } xSInt32 CAwxAudioObjExt::getSubBlockSize(xUInt16 subBlock) { xSInt32 subBlockSize = 0; // this is just an example of how memory could be split by an AO developer. There is no strict rule // how memory has to be split for each subblock switch(subBlock) { case 0: subBlockSize = static_cast(sizeof(xFloat32)) * static_cast(m_NumAudioIn) * NUM_PARAMS_PER_CHANNEL; break; case 1: subBlockSize = (nullptr != m_MemBlock) ? (static_cast(sizeof(xFloat32)) * FLOAT_ARRAY_SIZE) : 0; break; default: // by default we will return a null ptr, hence wrong subBlock was provided break; } return subBlockSize; } void CAwxAudioObjExt::calc(xAFAudio** inputs, xAFAudio** outputs) { if (static_cast(ENABLE_BLOCK) == m_EnMemory) { xSInt32 numAudioIn = static_cast(m_NumAudioIn); for (xSInt32 i = 0; i < numAudioIn; i++) { // for example if m_MemBlock[0] is to mute all channels xFloat32 factor = m_Coeffs[i] * m_MemBlock[0]; scalMpy(factor, inputs[i], outputs[i], static_cast(m_BlockLength)); } } else { xSInt32 numAudioIn = static_cast(m_NumAudioIn); for (xSInt32 i = 0; i < numAudioIn; i++) { scalMpy(m_Coeffs[i], inputs[i], outputs[i], static_cast(m_BlockLength)); } } } void CAwxAudioObjExt::calcGain(xSInt32 channelIndex, xFloat32 gainIndB) { xFloat32 maxGainIndB = getMaxGain(channelIndex); LIMIT(gainIndB, CONTROL_GAIN_MIN, maxGainIndB); m_Params[channelIndex * NUM_PARAMS_PER_CHANNEL] = gainIndB; xUInt32* mutePtr = reinterpret_cast<xUInt32*>(&m_Params[(channelIndex * NUM_PARAMS_PER_CHANNEL) + 1u]); m_Coeffs[channelIndex] = (0 == *mutePtr) ? powf(MAX_GAIN_DEFAULT_GAIN_dB, gainIndB * GAINDB_CONVERSION_FACTOR) : 0.f; } void CAwxAudioObjExt::tuneXTP(xSInt32 subBlock, xSInt32 offsetBytes, xSInt32 sizeBytes, xBool shouldAttemptRamp) { if(0 == subBlock) { xUInt32 channelu = static_cast(offsetBytes) >> 2u; xSInt32 channel = static_cast(channelu) / NUM_PARAMS_PER_CHANNEL; while (sizeBytes > 0) { calcGain(channel, m_Params[channel * NUM_PARAMS_PER_CHANNEL]); sizeBytes -= static_cast(NUM_PARAMS_PER_CHANNEL * sizeof(xFloat32)); channel++; } } else if(1 == subBlock) { // handle float array related here // values are available in m_MemBlock } else { } } xSInt32 CAwxAudioObjExt::controlSet(xSInt32 index, xFloat32 value) { if ((0 == index) && (static_cast(GAIN_WITH_CONTROL) == m_Mode)) { xSInt32 numAudioIn = static_cast(m_NumAudioIn); for (xSInt32 i = 0; i < numAudioIn; i++) { calcGain(i, value); } } return 0; } xUInt32 CAwxAudioObjExt::getSize() const { return sizeof(*this); }