Harman Logo
AUDIOWORX
  • Home
  • Documentation
  • Videos
  • Release Notes
  • Login
Harman Logo
AUDIOWORX
  • Home
  • Documentation
  • Videos
  • Release Notes
  • Login
Harman Logo
AUDIOWORX
  • Home
  • Documentation
  • Videos
  • Release Notes
  • Login
  • Getting Started
  • User Guides
  • Developer Guides

Table of Content

  • 20

Audio Object Developer Guide

  1. Purpose of this Document
  2. Overview
    1. Audio Object Workflow
    2. Audio Object Class
  3. Audio Object Configuration
    1. Design Time Configuration
      1. Metadata
    2. Advanced Design Time Configuration
      1. Audio Object Memory
  4. Basic Features and APIs
  5. Advanced Features and APIs
    1. Switch Processing State
    2. Debug and Monitoring
    3. Background Method
  6. Audio object Examples
    1. Example 1 - AwxAudioObjExt.cpp
    2. Example 2 - AwxAudioObjExtToolbox.cpp
    3. Example 3 - AwxAudioObjExtMemRecs.cpp
    4. Example 4 - AwxAudioObjExt.h
    5. Example 5 - AwxAudioObjExtToolbox.h
    6. Example 6 - AwxAudioObjExtMemRecs.h
  7. General Guidelines
  8. Adding External AO into AudioworX Package
  9. Building External Audio Object

Starter Kit Developer Guide

  1. Overview
  2. Setting Up the Developer Environment
  3. SKUtility Developer Options
  4. Build AWX External Object
  5. Running Debug Session

xAF Integration User Guide

  1. Support on xAF Integration

Troubleshooting

  1. GTT GUI Issues
  2. AmpSRV2
  3. Installation
  • Audio Object Developer Guide
  • Example 1 - AwxAudioObjExt.cpp

6.1.Example 1 - AwxAudioObjExt.cpp

/*!
*   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);
}

« Audio object ExamplesExample 2 - AwxAudioObjExtToolbox.cpp »
Suggest Edit
  • Careers
  • Contact
  • Sitemap
  • News

© 2025 HARMAN International. All Rights Reserved. Privacy Policy | Cookies | Terms of Use

If you are using a screen reader and are having problems using this website, please call (800) 645-7484 for assistance.