Example 2 – AwxAudioObjExtToolbox.cpp

/*!
*   \file      AwxAudioObjExtToolbox.cpp
*   \brief     AwxAudioObjExt Toolbox Source file
*   \details   Implements the AwxAudioObjExt signal design API
*   \details   Project    Extendable Audio Framework
*   \copyright Harman/Becker Automotive Systems GmbH
*   
       2020
*   
       All rights reserved
*   \author    xAF Team
*/

/*!
*   xaf mandataory includes to handle the toolbox related data
*/
#include "AwxAudioObjExtToolbox.h"
#include "XafXmlHelper.h"
#include "AudioObjectProperties.h"
#include "AwxAudioObjExt.h"
#include "XafMacros.h"
#include "AudioObject.h"



// the revision number may be different for specific targets
#define MIN_REQUIRED_XAF_VERSION            (RELEASE_U)
// mode specific defines
#define AUDIO_IN_OUT_MIN                    (1)
#define AUDIO_IN_OUT_MAX                    (255)
#define EST_MEMORY_CONSUMPTION_NA           (0)         // memory consuption not available/measured
#define EST_CPU_LOAD_CONSUMPTION_NA         (0.f) // cpu load not available/measured
#define CONTROL_GAIN_MAX                   (30.0f)
#define CONTROL_GAIN_MIN                   (-128.0f)
#define CONTROL_GAIN_IN_LABEL              "Gain"
#define MAX_CONFIG_MIN_GAIN_dB              (-12.0f)
#define MAX_CONFIG_MAX_GAIN_dB              (30.0f)
#define MAX_GAIN_DEFAULT_GAIN_dB            (10.0f)

CAwxAudioObjExtToolbox::CAwxAudioObjExtToolbox()
{
}

CAwxAudioObjExtToolbox::~CAwxAudioObjExtToolbox()
{
}

static CAudioObjectToolbox::additionalSfdVarDescription theVar;
const CAwxAudioObjExtToolbox::additionalSfdVarDescription* CAwxAudioObjExtToolbox::getAdditionalSfdVarsDescription(xUInt32 index)

{
    CAudioObjectToolbox::additionalSfdVarDescription* ptr = &theVar;
    static CAudioObjectToolbox::MinMaxDefault addVar1 = { MAX_CONFIG_MIN_GAIN_dB ,MAX_CONFIG_MAX_GAIN_dB ,MAX_GAIN_DEFAULT_GAIN_dB }; //Min,max,default values for additional config variable
    static CAudioObjectToolbox::MinMaxDefault addVar2 = { 0, 1, 0 }; //Min,max,default values
    
    static CAudioObjectToolbox::addVarsSize m_AddtionalVarSize1[NUM_DIMENSION_VAR] =
    {
        // size, label, start index, increment
        {1, "Max Gain per channel(dB)", 0, 1}
    };
    static CAudioObjectToolbox::addVarsSize m_AddtionalVarSize2[NUM_DIMENSION_VAR] =
    {
        // size, label, start index, increment
        {1, "Disable: 0\nEnable  : 1", 0, 1}
    };

     if (index == 0)
     {
       theVar.mP_Label = "Max Gain per channel";
       theVar.m_DataType = xAF_FLOAT_32;
       theVar.mP_RangeSet = &addVar1;
       theVar.m_Dimension = 1;
       theVar.m_DataOrder = xAF_NONE;
       //size varies according to the number of channels
       m_AddtionalVarSize1[0].m_Size = static_cast(m_NumAudioIn);
       theVar.mP_MaddVarsSize = m_AddtionalVarSize1;
     }
     else if (index == 1)
     {
         theVar.mP_Label = "Abstracted Tuning Memory";
         theVar.m_DataType = xAF_UCHAR;
         theVar.mP_RangeSet = &addVar2;
         theVar.m_Dimension = 1;
         theVar.m_DataOrder = xAF_NONE;
         theVar.mP_MaddVarsSize = m_AddtionalVarSize2;
     }
     else
     {
         /* Invalid index. Return NULL */
         ptr = NULL;
     }
     return ptr;
}


const CAudioObjectToolbox::tObjectDescription* CAwxAudioObjExtToolbox::getObjectDescription()
{
    static const CAudioObjectToolbox::tObjectDescription descriptions =
    {
        1, 1, 0, 0, "AwxAudioObjExt", "Simple Object to start with for 3rd party/external objects integration", "External", AWX_EXT_NUM_ADD_VARS, AWX_EXT_NUM_MODES
    };
    return &descriptions;
}


const CAudioObjectToolbox::tModeDescription* CAwxAudioObjExtToolbox::getModeDescription(xUInt32 mode)
{
    static const CAudioObjectToolbox::tModeDescription modeDescription[AWX_EXT_NUM_MODES] =
    {
        {"Gain", "No control input", 0, 0, "", CFG_NCHANNEL},
        {"GainWithControl", "One gain control input pin gets added", 0, 0, "", CFG_NCHANNEL},
    };
    return (mode < (sizeof(modeDescription) / sizeof(tModeDescription))) ? &modeDescription[mode] : static_cast<tModeDescription*>(NULL);
}


xAF_Error CAwxAudioObjExtToolbox::getObjectIo(ioObjectConfigOutput* configOut)
{
    if (static_cast(GAIN_WITH_CONTROL) == m_Mode)
    {
        configOut->numControlIn = 1;
        configOut->numControlOut = 0;
    }
    else 
    {
        configOut->numControlIn = 0;
        configOut->numControlOut = 0;
    }

    return xAF_SUCCESS;
}


xUInt32 CAwxAudioObjExtToolbox::getXmlObjectTemplate(tTuningInfo* info, xInt8* buffer, xUInt32 maxLen)
{
    initiateNewBufferWrite(buffer, maxLen);
    
    // add your tuning parameters here in order to show up in the tuning tool
    // the number of params specified here, depends on the number to be tuned in GTT
    // in this example we are exposing the tuning parameters as arrays split into 2 subblocks

    //template 1
    xSInt32 numAudioIn = static_cast(m_NumAudioIn);
    xSInt32 blockID = info->Global_Object_Count; // uniq to this instance
    xUInt32 id = 0;

    for (xSInt32 i = 0; i < numAudioIn; i++)
    {
        //Max value for each channel to show up shall be specified by this function
        xFloat32 gainval = getMaxGain(i);
        xAFOpenLongXMLTag("Object");
        string templateName = string("").append("AwxAudioObjExtTuneTemplate").append(xAFIntToString(i + 1)).append(xAFIntToString(blockID));
        xAFAddFieldToXMLTag("Key", templateName.c_str());
        xAFEndLongXMLTag();
        xAFWriteQuickXmlTag("ExplorerIcon", "Object");
        xAFWriteXmlTag("StateVariables", XML_OPEN);
        xAFWriteStateVariable("Gain",                   // name                
            id,                                         // id
            NULL,                                       // control law
            "dB",                                       // unit type
            DataTypes[xAF_FLOAT],                       // data type
            -128.0,                                     // min
            gainval,                                    // max
            0.0,                                        // default
            0u,                                         // offset
            NULL,                                       // encode value
            NULL,                                       // decode value
            DataTypeConverters[xAF_FLOAT],              // bit converter
            false                                       // disable streaming
        );
        id++;

        xAFWriteStateVariable("Mute",                    // name                
            id,                                          // id
            NULL,                                        // control law
            NULL,                                        // unit type
            DataTypes[xAF_UINT],                         // data type
            0.0,                                         // min
            1.0,                                         // max
            0.0,                                         // default
            4u,                                          // offset
            NULL,                                        // encode value
            NULL,                                        // decode value
            DataTypeConverters[xAF_UINT],                // bit converter
            false                                        // disable streaming
        );
        id++;

        xAFWriteXmlTag("StateVariables", XML_CLOSE);
        xAFWriteXmlTag("Object", XML_CLOSE);

    }

    //template 2
    //It shall be shown up in the State Variable Explorer if through additional configuration "Abstracted Tuning Memory" is set to 1 or enabled.
    if (static_cast(ENABLE_BLOCK) == m_EnMemory)
    {
        xAFOpenLongXMLTag("Object");
        xAFAddFieldToXMLTag("Key", "AwxAudioObjExtArrayTemplate");
        xAFEndLongXMLTag();
        xAFWriteQuickXmlTag("ExplorerIcon", "Object");
        xAFWriteXmlTag("StateVariables", XML_OPEN);
        xAFWriteStateVariableBuffer(/* name = */ "FloatArray",
            /* id = */ id,
            /* type = */ FLOATARRAY_SV,
            /* size = */ FLOAT_ARRAY_SIZE,
            /* streamIdx = */ id,
            /* minVal = */ -1000.0,
            /* maxVal = */ 1000.0,
            /* defaultVal = */ 0.0,
            /* offset = */ 0,
            /* isStreamable = */ false);
        
        xAFWriteXmlTag("StateVariables", XML_CLOSE);
        xAFWriteXmlTag("Object", XML_CLOSE);
    }
    return finishWritingToBuffer();
}


xUInt32 CAwxAudioObjExtToolbox::getXmlFileInfo(tTuningInfo* info, xInt8* buffer, xUInt32 maxLen)
{
    initiateNewBufferWrite(buffer, maxLen);
    xUInt32 hiqnetInc = 0u;
    xUInt8  subBlock = 0u;
    xSInt32 blockID = info->Global_Object_Count; // uniq to this instance

    xAFWriteObject(info->Name, static_cast(info->Global_Object_Count), hiqnetInc, static_cast(info->HiQNetVal), 0);

    xAFWriteXmlTag("Objects", XML_OPEN);
    xSInt32 numAudioIn = static_cast(m_NumAudioIn); // m_NumAudioIn == m_NumAudioOut
    
    xAFWriteXmlObjectContainer("Gains", hiqnetInc, subBlock, PARAM_CATEGORY);
    xAFWriteXmlTag("Objects", XML_OPEN);
    for(xSInt32 i = 0; i < numAudioIn; i++)
    {        
        string templateName = string("").append("AwxAudioObjExtTuneTemplate").append(xAFIntToString(i+1)).append(xAFIntToString(blockID));
        xAFWriteXmlObjectTemplateInstance(templateName.c_str(), string("Ch").append(xAFIntToString(i+1)).c_str(), i * 8, 1 + i); 
        // 8 is related here to the internal memory layout where a "state/tuning" is related to a block of N-bytes and withing this needs to be offset
        hiqnetInc++;
    }
    xAFWriteXmlTag("Objects", XML_CLOSE);
    xAFWriteXmlTag("Object", XML_CLOSE); //gains

    if (static_cast(ENABLE_BLOCK) == m_EnMemory)
    {        
        xAFWriteXmlObjectBlockOffset("AwxAudioObjExtArrayTemplate", "FloatArrayMemory", subBlock, static_cast(info->HiQNetVal), hiqnetInc, PARAM_CATEGORY);
        hiqnetInc++;
    }
    xAFWriteXmlTag("Objects", XML_CLOSE);

    xAFWriteXmlTag("Object", XML_CLOSE);

    return finishWritingToBuffer();
}


void CAwxAudioObjExtToolbox::createStaticMetadata()
{
    m_StaticMetadata.minReqXafVersion = static_cast(MIN_REQUIRED_XAF_VERSION);

    setAudioObjectVersion(AWXAUDIOOBJEXT_VERSION_MAJOR, AWXAUDIOOBJEXT_VERSION_MINOR, AWXAUDIOOBJEXT_VERSION_REVISION);
    setTuningVersion     (AWXAUDIOOBJEXT_TUNING_VERSION_MAJOR, AWXAUDIOOBJEXT_TUNING_VERSION_MINOR);

    m_StaticMetadata.supDataFormats.push_back(xAF_DATATYPE_FLOAT);

    //creation/release date
    setCreationDate(2022, 8, 4);

    //Simple AO supports in-place computation
    m_StaticMetadata.inPlaceComputationEnabled = true;
    //This flag allows to set whether the object dynamically updates its additional vars based on input params
    m_StaticMetadata.isAddVarUpdateRequired = true;
}

void CAwxAudioObjExtToolbox::createDynamicMetadata(ioObjectConfigInput& configIn, ioObjectConfigOutput& configOut)
{
    metaDataControlDescription ctrlDesc;
    // define audio in metadata
    m_DynamicMetadata.audioIn.Min = AUDIO_IN_OUT_MIN;
    m_DynamicMetadata.audioIn.Max = AUDIO_IN_OUT_MAX;

    // define audio out metadata
    m_DynamicMetadata.audioOut.Min = AUDIO_IN_OUT_MIN;
    m_DynamicMetadata.audioOut.Max = AUDIO_IN_OUT_MAX;

    switch (configIn.mode)
    {
        case static_cast(GAIN_WITH_CONTROL) :
        // define control in min, max and label values for the control pin
            
        ctrlDesc.Min = CONTROL_GAIN_MIN;
        ctrlDesc.Max = CONTROL_GAIN_MAX;
        ctrlDesc.Label = CONTROL_GAIN_IN_LABEL;
        m_DynamicMetadata.controlIn.push_back(ctrlDesc);
        break;

        default:
        break;
    }

    m_DynamicMetadata.estMemory = EST_MEMORY_CONSUMPTION_NA;
    m_DynamicMetadata.estMIPS = EST_CPU_LOAD_CONSUMPTION_NA;
}

_________________

Rate this post!