AWE Core OS 8.B.16 Documentation
LayoutControl.c

Examples.

Examples

/****************************************************************************
*
* LayoutControl
* -------------------------------
*
****************************************************************************
*
* Description: Pump a .wav file through a .awb layout. Set/get module variables with control API
*
* This example shows how to load an .awb from an file, and then
* how to get and set module variables with the Control Interface API.
* The example will stream an audio file called in_s32_stereo.raw
* and write the processed output to out_s32_stereo.raw
*
* This example meets all the conditions to achieve 0 blocks of
* latency in the AWE Core OS audio path. See the Latency section
* of the docs for more info.
*
* Copyright: (c) 2020 DSP Concepts, Inc. All rights reserved.
* 3235 Kifer Road
* Santa Clara, CA 95054-1527
*
*
***************************************************************************/
#include "AWECoreOS.h"
#include "ModuleList.h"
#include <errno.h>
#include <math.h>
#include <float.h>
#include <stdlib.h>
// Defines
#define true 1
#define false 0
// Passthrough layout releated includes
#include "passthrough_InitAWB.h"
#include "passthrough_ControlInterface.h"
const char inFilename[] = "../Audio/in_s32_stereo.raw"; // input audio file: stereo 32-bit fixed-point
const char outFilename[] = "../Audio/out_s32_stereo.raw"; // output audio file: stereo 32-bit fixed-point
const char awbFilename[] = "../Designs/passthrough.awb"; // Awb file that is used
// Input/output audio files and buffers
INT32 * inputBuffer, * outputBuffer;
FILE *fin;
FILE *fout;
// Declare an AWEOSInstance pointer.
AWEOSInstance *g_AWEOSInstance;
// Declare an AWEOSConfigParameters structure. The members of this structure determine the configuration of the AWEInstance members.
// For this example, it will be populated with defaults
static AWEOSConfigParameters configParams;
// Declare a module descriptor table. This module descriptor table includes the modules as defined in ModuleList.h (which we will ship)
static const void* moduleDescriptorTable[] =
{
LISTOFCLASSOBJECTS
};
UINT32 moduleDescriptorTableSize = sizeof(moduleDescriptorTable) / sizeof(moduleDescriptorTable[0]);
// Floating-point comparison function used for verification
// Inspired by: http://floating-point-gui.de/errors/comparison/
int isNearlyEqual(float a, float b, float epsilon)
{
float absA = fabsf(a);
float absB = fabsf(b);
float diff = fabsf(a - b);
if (a == b) { // to handle infinities
return 1;
} else if (a == 0 || b == 0 || diff < FLT_MIN) {
// a or b is zero or both are extremely close to it
// relative error is less meaningful here
return diff < (epsilon * FLT_MIN);
} else { // use relative error
if ((absA + absB) < FLT_MAX)
{
return diff / (absA + absB) < epsilon;
}
else
{
return diff / FLT_MAX < epsilon;
}
}
}
void destroyExample()
{
INT32 ret;
fclose(fin);
fclose(fout);
free(inputBuffer);
free(outputBuffer);
inputBuffer = NULL;
outputBuffer = NULL;
ret = aweOS_destroy(&g_AWEOSInstance);
if (ret != E_SUCCESS)
{
printf("aweOS_destroy returned error = %d (%s)\n", ret, aweOS_errorToString(ret));
}
}
int main()
{
//Call this function with an arg to the user declared AWEOSConfigParameters structure.
//This populates the configParams structure with DSPC defined default values.
aweOS_getParamDefaults(&configParams);
//Allocate a fastheapA
#define FASTHEAP_A_SIZE 420000
static UINT32 fastHeapA[FASTHEAP_A_SIZE];
configParams.pFastHeapA = fastHeapA;
configParams.fastHeapASize = FASTHEAP_A_SIZE;
//Allocate a fastheapB
#define FASTHEAP_B_SIZE 420000
static UINT32 fastHeapB[FASTHEAP_B_SIZE];
configParams.pFastHeapB = fastHeapB;
configParams.fastHeapBSize = FASTHEAP_B_SIZE;
//Allocate a slowheap
#define SLOWHEAP_SIZE 420000
static UINT32 slowHeap[SLOWHEAP_SIZE];
configParams.pSlowHeap = slowHeap;
configParams.slowHeapSize = SLOWHEAP_SIZE;
INT32 ret;
//Initialize the AWEOSInstance with the parameters that were previously set in the config structure
ret = aweOS_init(&g_AWEOSInstance, &configParams, moduleDescriptorTable, moduleDescriptorTableSize);
//Check if the aweOS_init succeeded. If it didn't then terminate the executable.
if (E_SUCCESS == ret)
{
printf("aweOS Initialised \n");
}
else
{
printf("aweOS init failed. exiting application with error = %d %s\n", ret, aweOS_errorToString(ret));
exit(1);
}
//Load the AWB from file
UINT32 position=0;
ret = aweOS_loadAWBFile(g_AWEOSInstance, awbFilename, &position);
if (E_SUCCESS == ret)
{
printf("Loaded layout loaded from file %s\n", awbFilename);
}
else
{
if (E_NOSUCHFILE == ret || E_CANTOPEN == ret)
{
printf("Layout %s load unsuccessful with Error = %d %s \n", awbFilename, ret, aweOS_errorToString(ret));
}
else
{
printf("Layout %s load unsuccessful in the positions %u with Error = %d %s \n", awbFilename, position, ret, aweOS_errorToString(ret));
}
exit(1);
}
//Check if the layout is valid
ret = aweOS_layoutIsValid(g_AWEOSInstance);
if (1 != ret)
{
printf("Error: Loaded layout is not valid: error = %d %s\n", ret, aweOS_errorToString(ret));
exit(1);
}
//Check if the Audio has started
ret = aweOS_audioIsStarted(g_AWEOSInstance);
if (1 != ret)
{
printf("Error: Audio not started: error = %d %s\n", ret, aweOS_errorToString(ret));
exit(1);
}
// Get the layout I/O configuration Input, Output and block size
// Input and output blocksizes are the same in all layouts
UINT32 layoutInChannels, layoutOutChannels, layoutBlockSize;
FLOAT32 SR;
ret = aweOS_layoutGetChannelCount(g_AWEOSInstance, &layoutInChannels, &layoutOutChannels);
if (E_SUCCESS != ret)
{
printf("Error: GetChannelCount failed: error = %d %s\n", ret, aweOS_errorToString(ret));
exit(1);
}
ret = aweOS_layoutGetBlockSize(g_AWEOSInstance, &layoutBlockSize);
if (E_SUCCESS != ret)
{
printf("Error: GetBlockSize failed: error = %d %s\n", ret, aweOS_errorToString(ret));
exit(1);
}
ret = aweOS_layoutGetSampleRate(g_AWEOSInstance, &SR);
if (E_SUCCESS != ret)
{
printf("Error: GetSampleRate failed: error = %d %s\n", ret, aweOS_errorToString(ret));
exit(1);
}
printf("Layout loaded with inputChannels=%u, outputChannels=%u, blockSize=%u, SR=%f\n", layoutInChannels, layoutOutChannels, layoutBlockSize, SR);
//Prepare the stereo input and output buffers
UINT32 inSize, outSize;
const INT32 inputChannels = 2;
const INT32 outputChannels = 2;
//The system is hardcoded for 2 channels.
//Prepare the stereo input and output buffers, and open files
inSize = inputChannels * layoutBlockSize;
outSize = outputChannels * layoutBlockSize;
inputBuffer = malloc(inSize * sizeof(INT32));
outputBuffer = malloc(outSize * sizeof(INT32));
fin = fopen(inFilename, "rb");
if (NULL == fin )
{
printf("Error opening input file %s\n", inFilename);
printf("Error %d \n", errno);
exit(1);
}
else
{
printf("Opening input file %s\n", inFilename);
}
fout = fopen(outFilename, "wb");
if (NULL == fout)
{
printf("Error opening input file %s\n", outFilename);
printf("Error %d \n", errno);
exit(1);
}
else
{
printf("Opening output file %s\n", outFilename);
}
//Set Scaler1 gain attributes
float scaler1Gain;
float scaler1TargetGain;
float meter1Values[AWE_Meter1_value_SIZE];
long count = 0;
int numSamplesRead = 0;
UINT32 classId;
//NOTE: All handle/ID/size macros passed into the aweOS_ctrl API's are found in the ControlInterface header file, "passthrough_ControlInterface.h"
//This header file was generated by Designer, alongside the corresponding .awb layout "passthrough_InitAWB.h".
//Check that the layout has the correct control modules in it
//Scaler module check
ret = aweOS_ctrlGetModuleClass(g_AWEOSInstance, AWE_Scaler1_gain_HANDLE, &classId);
if (E_SUCCESS == ret)
{
// Check that module assigned this object ID is of module class Scaler
if (AWE_Scaler1_classID != classId )
{
printf("Error: Scaler1 module not found in layout (%u)\n", AWE_Scaler1_classID );
exit(1);
}
}
else
{
printf("Error: aweOS_ctrlGetModuleClass with error = %d %s\n", ret,aweOS_errorToString(ret));
}
// Meter module check
ret = aweOS_ctrlGetModuleClass(g_AWEOSInstance, AWE_Meter1_value_HANDLE, &classId);
if (E_SUCCESS == ret)
{
// Check that module assigned this object ID is of module class Meter
if (AWE_Meter1_classID != classId)
{
printf("Error: Meter module not found in layout (%u)\n",AWE_Meter1_classID);
exit(1);
}
}
else
{
printf("Error: aweOS_ctrlGetModuleClass with error = %d %s\n", ret, aweOS_errorToString(ret));
}
ret = aweOS_ctrlGetValue(g_AWEOSInstance, AWE_Scaler1_gain_HANDLE, &scaler1Gain, 0, AWE_Scaler1_gain_SIZE);
if (E_SUCCESS == ret)
{
printf("\nGetValue: Default scaler1Gain = %f, error = %d\n", scaler1Gain, ret);
}
else
{
printf("Error: aweOS_ctrlGetValue with error = %d %s\n", ret, aweOS_errorToString(ret));
}
//Set the gain to -10 dB
scaler1Gain = -10.0;
ret = aweOS_ctrlSetValue(g_AWEOSInstance, AWE_Scaler1_gain_HANDLE, ( void *)&scaler1Gain, 0, AWE_Scaler1_gain_SIZE);
if (E_SUCCESS == ret)
{
printf("SetValue: scaler1Gain = %f, error = %d\n", scaler1Gain, ret);
}
else
{
printf("Error: aweOS_ctrlSetValue with error = %d %s\n", ret, aweOS_errorToString(ret));
}
ret = aweOS_ctrlGetValue(g_AWEOSInstance, AWE_Scaler1_gain_HANDLE, &scaler1Gain, 0, AWE_Scaler1_gain_SIZE);
if (E_SUCCESS == ret)
{
printf("GetValue: scaler1Gain = %f, error = %d\n", scaler1Gain, ret);
}
else
{
printf("Error: aweOS_ctrlGetValue with error = %d %s\n", ret, aweOS_errorToString(ret));
}
ret = aweOS_ctrlGetValue(g_AWEOSInstance, AWE_Scaler1_targetGain_HANDLE, &scaler1TargetGain, 0, AWE_Scaler1_targetGain_SIZE);
if (E_SUCCESS == ret)
{
printf("GetValue: scalerTarget1Gain = %f, error = %d\n", scaler1TargetGain, ret);
}
else
{
printf("Error: aweOS_ctrlGetValue with error = %d %s\n", ret, aweOS_errorToString(ret));
}
//Process the input data
printf("\nStarting to process [%s] into [%s]\n\n", inFilename, outFilename);
while ((numSamplesRead = fread(inputBuffer, sizeof(int), inSize, fin)) > 0)
{
INT32 i, j;
INT32 numOutFrames;
for (i = 0; i < inputChannels; i++)
{
ret = aweOS_audioImportSamples(g_AWEOSInstance, inputBuffer + i, inputChannels, i, Sample32bit);
if (ret != E_SUCCESS)
{
printf("Error: aweOS_audioImportSamples() failed: error = %d %s exiting application\n", ret, aweOS_errorToString(ret));
exit(1);
}
}
aweOS_audioPumpAll(g_AWEOSInstance);
for (i = 0; i < outputChannels; i++)
{
ret = aweOS_audioExportSamples(g_AWEOSInstance, outputBuffer + i, outputChannels, i, Sample32bit);
if (ret != E_SUCCESS)
{
printf("Error: aweOS_audioExportSamples() failed: error = %d %s exiting application\n", ret, aweOS_errorToString(ret));
exit(1);
}
}
count++;
// Print the Meter1 value every 1024 pump cycles
if (1024 == count)
{
count = 0;
ret = aweOS_ctrlGetValue(g_AWEOSInstance, AWE_Meter1_value_HANDLE, &meter1Values, 0, AWE_Meter1_value_SIZE);
if (E_SUCCESS == ret)
{
printf("GetValue: meter1Value = %f, error = %d\n", meter1Values[0], ret);
}
else
{
printf("Error: aweOS_ctrlGetValue with error = %d %s\n", ret, aweOS_errorToString(ret));
}
}
fwrite(outputBuffer, sizeof(int), outSize, fout);
//Perform inline verification
//Channel 1 is expected to be attenuated by -10 dB
//Channel 2 is expected to be passed through without modification
#define EPSILON 0.1f
numOutFrames = numSamplesRead / outputChannels;
for (j = 0; j < numOutFrames; j++)
{
float expectedValueChannel1 = powf(10.0, scaler1Gain / 20.0) * (float)inputBuffer[inputChannels * j];
float expectedValueChannel2 = (float)inputBuffer[inputChannels * j + 1];
if (isNearlyEqual(expectedValueChannel1, (float)outputBuffer[outputChannels * j], EPSILON) == 0)
{
printf("Verification error. Expected %f on channel 1 but got %f, sample %d\n", expectedValueChannel1,
(float)outputBuffer[outputChannels * j], j);
destroyExample();
exit(1);
}
if (isNearlyEqual(expectedValueChannel2, (float)outputBuffer[outputChannels * j + 1], EPSILON) == 0)
{
printf("Verification error. Expected %f on channel 2 but got %f\n, sample %d\n", expectedValueChannel2,
(float)outputBuffer[outputChannels * j + 1], j);
destroyExample();
exit(1);
}
}
// There is no latency introduced through this audio path
}
printf("\n");
ret = aweOS_ctrlGetValue(g_AWEOSInstance, AWE_Scaler1_gain_HANDLE, &scaler1Gain, 0, AWE_Scaler1_gain_SIZE);
if (E_SUCCESS == ret)
{
printf("GetValue: scaler1Gain = %f, error = %d\n", scaler1Gain, ret);
}
else
{
printf("Error: aweOS_ctrlGetValue with error = %d %s\n", ret, aweOS_errorToString(ret));
}
ret = aweOS_ctrlGetValue(g_AWEOSInstance, AWE_Scaler1_targetGain_HANDLE, &scaler1TargetGain, 0, AWE_Scaler1_targetGain_SIZE);
if (E_SUCCESS == ret)
{
printf("GetValue: scalerTarget1Gain = %f, error = %d\n", scaler1TargetGain, ret);
}
else
{
printf("Error: aweOS_ctrlGetValue with error = %d %s\n", ret, aweOS_errorToString(ret));
}
UINT32 avgCycles;
ret = aweOS_getAverageLayoutCycles(g_AWEOSInstance, 0, &avgCycles);
printf("Processed %ld audio frames -- average cycles per pump = %u\n", count, avgCycles);
//Clean up
destroyExample();
return 0;
}
The AWE Core OS API header file.
#define E_CANTOPEN
Can't open the specified file.
Definition: Errors.h:157
#define E_NOSUCHFILE
The specified file does not exist.
Definition: Errors.h:160
#define E_SUCCESS
OK result.
Definition: Errors.h:31
@ Sample32bit
Data is 32 bit PCM .
Definition: StandardDefs.h:231
void AWEOSInstance
The AWE Core OS Instance instance type.
Definition: AWECoreOS.h:103
INT32 aweOS_ctrlGetValue(const AWEOSInstance *pAWEOS, UINT32 handle, void *value, INT32 arrayOffset, UINT32 length)
Get a scalar or array value(s) of a module parameter by handle.
INT32 aweOS_ctrlGetModuleClass(const AWEOSInstance *pAWEOS, UINT32 handle, UINT32 *pClassID)
Get a module's object class from its handle.
INT32 aweOS_layoutGetSampleRate(const AWEOSInstance *pAWEOS, FLOAT32 *sampleRate)
Returns the sample rate of the loaded layout.
INT32 aweOS_audioExportSamples(AWEOSInstance *pAWEOS, void *outSamples, INT32 outStride, INT32 channel, SampleType outType)
Export samples to a user buffer from a specific channel of the AWEOSInstance's output pin.
INT32 aweOS_audioPumpAll(AWEOSInstance *pAWEOS)
Pump one fundamental block size of audio through the loaded layout and all of its sublayouts.
INT32 aweOS_audioIsStarted(const AWEOSInstance *pAWEOS)
Check if this instance has received an Audio Start command.
INT32 aweOS_init(AWEOSInstance **pAWEOS, const AWEOSConfigParameters *aweParams, const void *pModuleDescriptorTable, UINT32 moduleDescriptorTableSize)
Initialize the AWEOSInstance with the specified configuration parameters.
INT32 aweOS_layoutGetBlockSize(const AWEOSInstance *pAWEOS, UINT32 *blockSize)
Returns the block size of the loaded layout.
INT32 aweOS_layoutIsValid(const AWEOSInstance *pAWEOS)
Determines if a layout is loaded and valid.
INT32 aweOS_layoutGetChannelCount(const AWEOSInstance *pAWEOS, UINT32 *inCount, UINT32 *outCount)
Returns the number of input and output channels in the loaded layout.
INT32 aweOS_ctrlSetValue(const AWEOSInstance *pAWEOS, UINT32 handle, void *value, INT32 arrayOffset, UINT32 length)
Set a scalar or array value(s) of a module parameter by handle.
INT32 aweOS_destroy(AWEOSInstance **pAWEOS)
Destroys the AWEOSInstance and closes all associated threads.
const char * aweOS_errorToString(INT32 errorCode)
Convert an error code (INT32) to its corresponding error string.
INT32 aweOS_audioImportSamples(AWEOSInstance *pAWEOS, void *inSamples, INT32 inStride, INT32 channel, SampleType inType)
Import samples from an audio buffer to a specific channel of the AWEOSInstance's input pin.
INT32 aweOS_getParamDefaults(AWEOSConfigParameters *aweParams)
Populates an AWEOSConfigParameters structure with defaults.
INT32 aweOS_getAverageLayoutCycles(AWEOSInstance *pAWEOS, UINT32 idx, UINT32 *averageCycles)
Get the average cycles of a running layout, in units of cycles at profileSpeed.
INT32 aweOS_loadAWBFile(AWEOSInstance *pAWEOS, const char *binaryFile, UINT32 *pErrorOffset)
Executes packet commands from an AWB file on the filesystem.
AWEOSConfigParameters.
Definition: AWECoreOS.h:114
UINT32 fastHeapBSize
Size of fast heap B in 32-bit words.
Definition: AWECoreOS.h:120
UINT32 * pFastHeapA
Pointer to fast heap A.
Definition: AWECoreOS.h:116
UINT32 * pSlowHeap
Pointer to slow heap.
Definition: AWECoreOS.h:118
UINT32 slowHeapSize
Size of slow heap in 32-bit words.
Definition: AWECoreOS.h:121
UINT32 * pFastHeapB
Pointer to fast heap B.
Definition: AWECoreOS.h:117
UINT32 fastHeapASize
Size of fast heap A in 32-bit words.
Definition: AWECoreOS.h:119