AWE Core OS 8.B.20 Documentation
Libtester.c

Examples.

Examples

/****************************************************************************
*
* Libtester
* -------------------------------
*
****************************************************************************
*
* Description: AWECoreOS Library Test App
* The sample application 'Libtester' is intended to show basic usage of AWECoreOS.
* An AWECoreOS Instance is configured and initialized, and processing can be done by specifying
* input files, or with simulated real-time audio on Linux. Run the app with no options for usage.
* Includes an ethernet/TCPIP tuning interface to connect to AWE Server on port 15002 or
* user defined port (15002 - 15098).
*
* Copyright: (c) 2020 DSP Concepts, Inc. All rights reserved.
* 3235 Kifer Road
* Santa Clara, CA 95054-1527
*
*
***************************************************************************/
#include "AWECoreOS.h"
#include "ModuleList.h"
#include "AWECoreUtils.h"
#include <stdlib.h>
#include <errno.h>
#include <math.h>
#include <float.h>
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>
#include <sched.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <semaphore.h>
// Defines
#define true 1
#define false 0
#define FASTHEAP_A_SIZE 4200000
#define FASTHEAP_B_SIZE 4200000
#define SLOWHEAP_SIZE 4200000
// Global heaps (dynamically allocated based on the size argument
UINT32 *fastHeapA;
UINT32 *fastHeapB;
UINT32 *slowHeap;
UINT32 heapSizeFastA = FASTHEAP_A_SIZE;
UINT32 heapSizeFastB = FASTHEAP_B_SIZE;
UINT32 heapSizeSlow = SLOWHEAP_SIZE;
// Global thread handles and mutexes
pthread_t audioCallbackThreadHandle;
pthread_mutex_t audioThreadMutex;
pthread_cond_t audioThreadCond;
sem_t pumpSem;
// Global variables
INT32 audioStarted = 0;
INT32 exitAudioCallbackThread = 0;
INT32 pumpActive = 0;
static UINT32 quiet = false;
// Static counter to count the number of audio frames processes(in terms of fundamental block size)
static unsigned long long count = 0;
// USed to mask out warning, so that aweOS_audioPumpAll() prints the errors only once in the loop per run.
// ErrMask gets reset in the aweOSuser_audioStop()
static UINT32 ErrMask = false;
// Input/output audio files and buffers
INT32 *inputBuffer, *outputBuffer;
UINT8 *inputBuffer1, *outputBuffer1;
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]);
void sig_handler(int signo)
{
if (!quiet)
{
printf("Exiting Libtester\n");
}
exit(0);
}
void copyright()
{
AWEOSVersionInfo_t versionInfo;
aweOS_getVersion(&versionInfo);
printf("%s\nAWE Core OS Libtester Copyright (c) DSP Concepts 2013-2022\n", versionInfo.textVer);
}
static void usage(const char *program)
{
printf(
"Usage: %s [args]\n"
" -load:<file> AWB file to load\n"
" -in:<file> input file to process\n"
" -out:<file> output file\n"
" -sr:sampling_rate value in Hz, default 48KHz\n"
" -pf:profile_frequency value in Hz, default 10MHz\n"
" -cf:cpu_frequency value in Hz, default 1GHz\n"
" -profStatus set profiling status (0 - disable, 1 - enable, 2 - enable module level only, 3 - enable top level only)\n"
" -bsize:N default 32, Audio block size for the system\n"
" -inchans:N default 2, number of input channels\n"
" -outchans:N default 2, number of output channels\n"
" -wait default disabled, sets up the integrated socket interface and waits for the designer to connect\n"
" -tport default 15002, port number for socket interface. User can choose between 15002 - 15098\n"
" -tlog enable tuning packet logging\n"
" -quiet works in quiet mode, displays only necessary messages\n"
" -hsizefasta:N fast A heap size in words, default %d\n"
" -hsizefastb:N fast B heap size in words, default %d\n"
" -hsizeslow:N slow heap size in words, default %d\n"
"This program exercises the AWECoreOS library.\n",
program,FASTHEAP_A_SIZE,FASTHEAP_B_SIZE,SLOWHEAP_SIZE);
exit(0);
}
void usrLogging(AWEOSInstance* pAWEOS, INT32 level, UINT32 type, void* payload, INT32 payloadSizeInBytes)
{
// Simple logging function always writes payload to stdout
struct timeval ts;
char timeCh[25];
// Get current time for log
gettimeofday(&ts, NULL);
snprintf(timeCh, 25, "%ld.%03ld: ", ts.tv_sec, ts.tv_usec / 1000);
if (payloadSizeInBytes > 0)
{
printf("%s%s\n", timeCh, (char *)payload);
}
}
INT32 usrEventRegister(AWEOSInstance* pAWEOS, INT32 eventType, UINT32 moduleObjId, INT32 payloadSizeInBytes, void** userHandle)
{
// This function does nothing, but it could use the eventHandle->userHandle struct
// to open a file to write events, or whatever else is needed
printf("Got an event registration callback for objectId %u, eventType %d. Size of event payloads will be %d bytes\n",
moduleObjId, eventType, payloadSizeInBytes);
// Allcoate some dummy stuff to the userHandle(TODO)
return E_SUCCESS;
}
INT32 usrEventDeregister(AWEOSInstance* pAWEOS, INT32 eventType, UINT32 moduleObjId, void** userHandle)
{
// This function would normally free any memory allocated by the register function
printf("Got an event deregistration callback for objectId %u\n", moduleObjId);
// (TODO) free dummy stuff
return E_SUCCESS;
}
INT32 usrEventTrigger(AWEOSInstance* pAWEOS, INT32 eventType, UINT32 moduleObjId, void* payload, INT32 payloadSizeInBytes, void* userHandle)
{
// This function gets called when an event is triggered by an Event Module in the layout.
// Normally the BSP would react to specific eventTypes and objectIds in specific
// ways (e.g. pass wakeword detection on to another system),
// but here we are just printing the details of the event, assuming the payload is ASCII characters
// if eventType is 10. Also one specific objectId case is handled
struct timeval ts;
char timeCh[25];
// Get current time for log
gettimeofday(&ts, NULL);
snprintf(timeCh, 25, "%ld.%03ld: ", ts.tv_sec, ts.tv_usec / 1000);
if (eventType == 10)
{
printf("%sGot an event trigger callback for objectId %u\n ascii payload: %s\n", timeCh, moduleObjId, (char *)payload);
}
else if (moduleObjId == 31111 && payloadSizeInBytes == 2 * sizeof(FLOAT32))
{
// Just an example of handling for a specific objectId event (RMS overflow)
printf("%sGot a RMS overflow event: objectId %u, RMS = %f, threshold = %f\n", timeCh, moduleObjId, ((FLOAT32*)payload)[0], ((FLOAT32*)payload)[1]);
}
else
{
printf("%sGot an event trigger callback for objectId %u, eventType %d\n", timeCh, moduleObjId, eventType);
}
return E_SUCCESS;
}
void* audioCallbackSimulator(void * args)
{
// Simple real-time audio simulator. Would be ALSA, PortAudio, etc callback
// Will not achieve exact realtime interrupts
struct timespec ts;
struct timespec ts_tmp;
long time_nsec;
long long accumulated_time1;
long long accumulated_time2;
long long overshoot = 0.0;
(void) args;
pthread_mutex_lock(&audioThreadMutex);
audioStarted = 1;
pthread_cond_signal(&audioThreadCond);
pthread_mutex_unlock(&audioThreadMutex);
// Calculate sleep time for fundamental blocksize
time_nsec = (long) ((float)1000000000L * ((float)configParams.fundamentalBlockSize / configParams.sampleRate));
ts.tv_sec = 0;
ts_tmp.tv_sec = 0;
ts_tmp.tv_nsec = 0;
// Set this thread to run at real time priority
int max_priority = sched_get_priority_max(SCHED_FIFO);
struct sched_param audio_sched_param = {0};
pthread_t currentHandle = pthread_self();
int target_priority = max_priority - 2;
audio_sched_param.sched_priority = target_priority;
pthread_setschedparam(currentHandle, SCHED_FIFO, &audio_sched_param);
int policy;
pthread_getschedparam(currentHandle, &policy, &audio_sched_param);
if ((SCHED_FIFO != policy) ||
(audio_sched_param.sched_priority != target_priority))
{
printf("Warning: Failed to increase priority of audio simulation thread to %d\nTry running as root\n", target_priority);
}
while (!exitAudioCallbackThread)
{
// Check if the previous pump is active (overflow detection)
// Workaround for the AWECore overflow detection failure
if (!pumpActive)
{
// Kick off the audio thread
sem_post(&pumpSem);
// Might need to post more than once due to clock resolution
while (overshoot > time_nsec)
{
overshoot -= time_nsec;
sem_post(&pumpSem);
}
}
else
{
overshoot = 0.0;
}
ts.tv_nsec = time_nsec;
clock_gettime(CLOCK_MONOTONIC, &ts_tmp);
accumulated_time1 = ((long long)ts_tmp.tv_sec*1000000000) + ts_tmp.tv_nsec + time_nsec;
while(1)
{
clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
clock_gettime(CLOCK_MONOTONIC, &ts_tmp);
accumulated_time2 = ((long long)ts_tmp.tv_sec*1000000000) + ts_tmp.tv_nsec;
if (accumulated_time2 >= accumulated_time1)
{
overshoot += (accumulated_time2 - accumulated_time1);
break;
}
else
{
ts.tv_nsec = (long)(accumulated_time1 - accumulated_time2);
}
}
}
return NULL;
}
void destroyExample()
{
INT32 ret;
ret = aweOS_destroy(&g_AWEOSInstance);
if (E_SUCCESS != ret)
{
printf("aweOS_destroy: failed with the error = %d %s\n", ret, aweOS_errorToString(ret));
}
ret = aweOS_wavFileClose(fin);
if (E_SUCCESS != ret)
{
printf("aweOS_wavFileClose: failed with the error = %d %s\n", ret, aweOS_errorToString(ret));
}
ret = aweOS_wavFileClose(fout);
if (E_SUCCESS != ret)
{
printf("aweOS_wavFileClose: failed with the error = %d %s\n", ret, aweOS_errorToString(ret));
}
free(inputBuffer);
free(outputBuffer);
free(fastHeapA);
free(fastHeapB);
free(slowHeap);
inputBuffer = NULL;
outputBuffer = NULL;
fastHeapA = NULL;
fastHeapB = NULL;
slowHeap = NULL;
}
INT32 aweOSuser_audioStart(AWEOSInstance *pAWEOS)
{
INT32 ret;
UINT32 layoutInChannels, layoutOutChannels, blockSize;
FLOAT32 sampleRate;
// Audio start callback. Can be used to start audio stream from audio framework.
// Could be ALSA, Pulse, Jack, Portaudio, etc.
ret = aweOS_layoutGetChannelCount(pAWEOS, &layoutInChannels, &layoutOutChannels);
if (E_SUCCESS != ret)
{
printf("Failed to get layout channel counts: ret = %d: %s\n", ret, aweOS_errorToString(ret));
}
ret = aweOS_layoutGetBlockSize(pAWEOS, &blockSize);
if (E_SUCCESS != ret)
{
printf("Failed to get layout block size: ret = %d: %s\n", ret, aweOS_errorToString(ret));
}
ret = aweOS_layoutGetSampleRate(pAWEOS, &sampleRate);
if (E_SUCCESS != ret)
{
printf("Failed to get layout sample rate: ret = %d: %s\n", ret, aweOS_errorToString(ret));
}
printf("Loaded layout with inChans = %u, outChans = %u, blockSize = %u, sampleRate = %f\n", layoutInChannels, layoutOutChannels, blockSize, sampleRate);
// Kick off real-time audio simulation thread
exitAudioCallbackThread = 0;
ret = pthread_create(&audioCallbackThreadHandle, NULL, audioCallbackSimulator, NULL);
if (0 != ret)
{
printf("Error creating audio callback simulator! ret = %d\n", ret);
return 0;
}
// Reset the count to 0, at the start of audio processing
count = 0;
// Wait for thread to have been created
pthread_mutex_lock(&audioThreadMutex);
while (1 != audioStarted)
{
pthread_cond_wait(&audioThreadCond, &audioThreadMutex);
}
pthread_mutex_unlock(&audioThreadMutex);
if (!quiet)
{
printf("\n\nAudio Started\n");
}
return 0;
}
INT32 aweOSuser_audioStop(AWEOSInstance *pAWEOS)
{
// Audio stop callback. Can be used to clean up audio stream.
if (audioStarted)
{
INT32 ret;
exitAudioCallbackThread = 1;
ret = pthread_join(audioCallbackThreadHandle, NULL);
if (0 != ret)
{
printf("Failed to join audio simulator thread: ret = %d\n", ret);
}
audioStarted = 0;
ErrMask = false;
if (!quiet)
{
UINT32 avgCycles;
ret = aweOS_getAverageLayoutCycles(pAWEOS, 0, &avgCycles);
if (E_SUCCESS != ret)
{
printf("Failed to get average cycles: ret = %d: %s\n", ret, aweOS_errorToString(ret));
}
printf("\nAudio Stopped\n");
printf("Processed %llu audio frames with I/O block size of %u -- average cycles: %f\n", count, configParams.fundamentalBlockSize,
(avgCycles >> 8) * (configParams.coreSpeed / configParams.profileSpeed));
}
}
return 0;
}
int main(int argc, char **argv)
{
// Setup signal handler
if (signal(SIGINT, sig_handler) == SIG_ERR)
{
printf("Can't catch SIGINT (%d)\n", SIGINT);
}
//Print the DSPC copyright
copyright();
//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);
//Tuning port id set to default 15002
INT32 tuningPort = 15002;
const char *awbpath = NULL;
const char *infile = NULL;
const char *outfile = NULL;
UINT32 profileStatus = 1;
UINT32 waitFlag = false;
UINT32 tlog = false;
//local variables buffer sizes
UINT32 layoutInChannels, layoutOutChannels, layoutBlockSize;
FLOAT32 layoutSampleRate = 0;
UINT32 inSize, outSize;
UINT32 i,j;
INT32 ret;
// Check if the argc == 1, meaing that there are not input parameters supplied with the program.
// Print the usage information, to help the user.
if (1 == argc)
{
usage(argv[0]);
}
else
{
printf("\nEntered parameters\n");
for (i = 1; i < argc; i++)
{
const char *arg = argv[i];
if (0 == strncmp(arg, "-profStatus:", 12))
{
profileStatus = atoi(arg + 12);
printf("profStatus: %u\n", profileStatus);
}
else if (0 == strncmp(arg, "-bsize:", 7))
{
configParams.fundamentalBlockSize = atoi(arg + 7);
printf("-bsize: %u\n",configParams.fundamentalBlockSize);
}
else if (0 == strncmp(arg, "-inchans:", 9))
{
configParams.inChannels = atoi(arg + 9);
printf("-inchans: %u\n",configParams.inChannels);
}
else if (0 == strncmp(arg, "-outchans:", 10))
{
configParams.outChannels = atoi(arg + 10);
printf("-outchans: %u\n",configParams.outChannels);
}
else if(0 == strncmp(arg, "-sr:", 4))
{
configParams.sampleRate = (float)atof(arg + 4);
printf("-sr: %f\n",configParams.sampleRate);
}
else if (0 == strncmp(arg, "-cf:", 4))
{
configParams.coreSpeed = (float)atof(arg + 4);
printf("-cf: %f\n",configParams.coreSpeed);
}
else if (0 == strncmp(arg, "-pf:", 4))
{
configParams.profileSpeed = (float)atof(arg + 4);
printf("-pf: %f\n",configParams.profileSpeed);
}
else if (0 == strncmp(arg, "-load:", 6))
{
awbpath = arg + 6;
printf("-load: %s\n",awbpath);
}
else if (0 == strncmp(arg, "-in:", 4))
{
infile = arg + 4;
printf("-in: %s\n",infile);
}
else if (0 == strncmp(arg, "-out:", 5))
{
outfile = arg + 5;
printf("-out: %s\n",outfile);
}
else if (0 == strncmp(arg, "-wait", 5))
{
waitFlag = true;
printf("-wait: %u\n",waitFlag);
}
else if (0 == strncmp(arg, "-tport:", 7))
{
tuningPort = atoi(arg + 7);
printf("-tport: %d\n",tuningPort);
}
else if (0 == strncmp(arg, "-tlog", 5))
{
tlog = true;
printf("-tlog: %u\n",tlog);
}
else if (0 == strncmp(arg, "-hsizefasta:", 12))
{
heapSizeFastA = atoi(arg + 12);
printf("-hsizefasta: %u\n",heapSizeFastA);
}
else if (0 == strncmp(arg, "-hsizefastb:", 12))
{
heapSizeFastB = atoi(arg + 12);
printf("-hsizefastb: %u\n",heapSizeFastB);
}
else if (0 == strncmp(arg, "-hsizeslow:", 11))
{
heapSizeSlow = atoi(arg + 11);
printf("-hsizeslow: %u\n",heapSizeSlow);
}
else if (0 == strncmp(arg, "-quiet", 6))
{
quiet = true;
printf("-quiet: %u\n",quiet);
}
else
{
printf("main: unknown option '%s'\n", arg);
}
}
}
// Error Conditions that need to checked
// Error1 not in "wait for ever" mode. Input and output files are required to be specified
if (!waitFlag )
{
if ((!awbpath) || (!outfile) || (!infile))
{
printf("Please rerun with the missing file arguments defined\n");
printf(" -load: %s\n", awbpath ? awbpath : "Missing");
printf(" -in: %s\n", infile ? infile : "Missing");
printf(" -out: %s\n", outfile ? outfile : "Missing");
exit(1);
}
}
if (!quiet)
{
printf("\naweOS initialised with the following parameters\n");
printf("Name: %s\n",configParams.pName);
printf("-cf: %f Hz\n",configParams.coreSpeed);
printf("-pf: %f Hz\n",configParams.profileSpeed);
printf("num of Threads:%u\n",configParams.numThreads);
printf("-sr: %f Hz\n",configParams.sampleRate);
printf("-bsize: %u\n",configParams.fundamentalBlockSize);
printf("-inchans: %u\n",configParams.inChannels);
printf("-outchans: %u\n",configParams.outChannels);
printf("-tport: %d\n",tuningPort);
printf("-hsizefasta: %u\n",heapSizeFastA);
printf("-hsizefastb: %u\n",heapSizeFastB);
printf("-hsizeslow: %u\n",heapSizeSlow);
if (profileStatus)
{
printf("-profStatus: Profiling is enabled\n");
}
else
{
printf("-profStatus: Profiling is disabled\n");
}
if (waitFlag)
{
printf("-wait: Set up the intergrated tuning interface and wait for the designer to connect\n");
}
else
{
printf("-wait: No tuning interface. Process the audio i/o files and the supplied design\n");
}
if (tlog)
{
printf("-tlog: Tuning log is enabled\n");
}
else
{
printf("-tlog: Tuning log is disabled\n");
}
printf("The following i/o files are used\n");
printf("-load: %s\n",awbpath ? awbpath : "undefined");
printf("-in: %s\n",infile ? infile : "undefined");
printf("-out: %s\n",outfile ? outfile : "undefined");
}
// Larger packet buffer size can improve tuning interface speed
configParams.packetBufferSize = 4105;
//Allocate a fastheapA
fastHeapA = malloc(heapSizeFastA * sizeof(UINT32));
configParams.pFastHeapA = fastHeapA;
configParams.fastHeapASize = heapSizeFastA;
//Allocate a fastheapB
fastHeapB = malloc(heapSizeFastB * sizeof(UINT32));
configParams.pFastHeapB = fastHeapB;
configParams.fastHeapBSize = heapSizeFastB;
//Allocate a slowheap
slowHeap = malloc(heapSizeSlow * sizeof(UINT32));
configParams.pSlowHeap = slowHeap;
configParams.slowHeapSize = heapSizeSlow;
printf("\n\n");
if (true == waitFlag)
{
configParams.cbAudioStart = aweOSuser_audioStart;
configParams.cbAudioStop = aweOSuser_audioStop;
pthread_mutex_init(&audioThreadMutex, NULL);
pthread_cond_init (&audioThreadCond, NULL);
sem_init(&pumpSem, 0, 0);
}
//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)
{
if (!quiet)
printf("aweOS Initialised\n\n");
}
else
{
printf("aweOS init failed. exiting application with error = %d %s\n",ret, aweOS_errorToString(ret));
exit(1);
}
// After the AWEOSInstance is init. set the profiling status
ret = aweOS_setProfilingStatus(g_AWEOSInstance, profileStatus);
if (E_SUCCESS == ret)
{
if (!quiet)
{
printf("aweOS profiling is disabled\n");
}
}
else
{
printf("aweOS_setProfilingStatus: profiling status set failed. exiting application with error = %d %s\n",ret, aweOS_errorToString(ret));
exit(1);
}
// Register logging callback for framework log messages
aweOS_registerLoggingCallback(g_AWEOSInstance, usrLogging, AWE_LOG_LEVEL_DEBUG, AWE_LOG_ALL_TYPE_MASK);
if (ret)
{
if (!quiet)
{
printf("Failed to register logging callback, ret = %d %s\n", ret, aweOS_errorToString(ret));
}
}
// Register event callbacks that can be triggered by Event Modules in the layout
ret = aweOS_registerEventCallbacks(g_AWEOSInstance, usrEventTrigger, usrEventRegister, usrEventDeregister);
if (ret)
{
if (!quiet)
{
printf("Failed to register event callbacks, ret = %d %s\n", ret, aweOS_errorToString(ret));
}
}
if (tlog)
{
ret = aweOS_tuningLoggingEnable(g_AWEOSInstance, NULL, NULL, TUNING_LOG_INFO);
if (E_SUCCESS == ret)
{
if (!quiet)
{
printf("aweOS integrated tuning interface logging enabled, with the mode set to TUNING_LOG_INFO\n");
}
}
else
{
printf("aweOS_tuningLoggingEnable: failed with the error = %d %s\n",ret, aweOS_errorToString(ret));
}
}
if ( NULL != awbpath )
{
UINT32 position;
fin = fopen(awbpath, "rb");
if (NULL == fin )
{
printf("Error opening input file %s\n", awbpath);
printf("Error string: %s \nPlease check the path\n", strerror(errno));
exit(1);
}
//Load the AWB from the file
ret = aweOS_loadAWBFile(g_AWEOSInstance,awbpath, &position);
if (E_SUCCESS == ret)
{
if (!quiet)
{
printf("The layout %s loaded with parameters\n", awbpath);
}
}
else
{
printf("The layout %s download unsuccessful in the positions %u with Error = %d \n", awbpath, position, ret);
exit(1);
}
// Get the layout I/O configuration Input, Output and block size
ret = aweOS_layoutGetChannelCount(g_AWEOSInstance, &layoutInChannels, &layoutOutChannels);
if (E_SUCCESS != ret)
{
printf("Error: aweOS_layoutGetChannelCount failed: error = %d %s\n", ret, aweOS_errorToString(ret));
exit(1);
}
ret = aweOS_layoutGetBlockSize(g_AWEOSInstance, &layoutBlockSize);
if (E_SUCCESS != ret)
{
printf("Error: aweOS_layoutGetBlockSize failed: error = %d %s\n", ret, aweOS_errorToString(ret));
exit(1);
}
ret = aweOS_layoutGetSampleRate(g_AWEOSInstance, &layoutSampleRate);
if (E_SUCCESS != ret)
{
printf("Error: aweOS_layoutGetSampleRate failed: error = %d %s\n", ret, aweOS_errorToString(ret));
exit(1);
}
if (!quiet)
{
printf("sr: %f\ninchans: %u\noutchans: %u\nbsize: %u\n\n", layoutSampleRate, layoutInChannels, layoutOutChannels, layoutBlockSize);
}
//Check if the layout is valid
ret = aweOS_layoutIsValid(g_AWEOSInstance);
if (1 != ret)
{
printf("Error: Loaded layout is not valid: error = %d\n", ret);
exit(1);
}
//Check if the Audio has stated
ret = aweOS_audioIsStarted(g_AWEOSInstance);
if (1 != ret)
{
printf("Error: Audio not started: error = %d\n", ret);
exit(1);
}
}
if (true == waitFlag)
{
//Prepare the stereo input and output buffers for the waitFlag == true condition
// The I/O buffers are allocated based on the target info / configParams
inSize = configParams.inChannels * configParams.fundamentalBlockSize;
outSize = configParams.outChannels * configParams.fundamentalBlockSize;
inputBuffer = malloc(inSize * sizeof(INT32));
outputBuffer = malloc(outSize * sizeof(INT32));
#ifndef PI
#define PI 3.141592653589793
#endif
// Fill audio input buffers with sin waves scaled by -12 dB
for (i = 0; i < configParams.fundamentalBlockSize; i++)
{
for (j = 0; j < configParams.inChannels; j++)
{
inputBuffer[i * configParams.inChannels + j] = float_to_fract32(sinf(2.f*PI*(j+1)*(configParams.sampleRate/configParams.fundamentalBlockSize) * (i / configParams.sampleRate))) >> 2;
}
}
//Open the aweOS integrated tuning interface. Note that this cannot be called before a succesful initialization. If called without succesful init, will fail/
ret = aweOS_tuningSocketOpen(&g_AWEOSInstance, tuningPort, 1);
if (E_SUCCESS != ret)
{
printf("Failed to open aweOS integrated tuning interface on Port number: %d with the error = %d %s \n", tuningPort, ret,aweOS_errorToString(ret));
}
else
{
if (!quiet)
{
printf("aweOS integrated tuning interface is open on Port number: %d\n", tuningPort);
}
}
// Set this thread to run at real time priority
int max_priority = sched_get_priority_max(SCHED_FIFO);
struct sched_param audio_sched_param = {0};
pthread_t currentHandle = pthread_self();
int target_priority = max_priority - 3; // let the audio simulator run at a higher priority
audio_sched_param.sched_priority = target_priority;
pthread_setschedparam(currentHandle, SCHED_FIFO, &audio_sched_param);
int policy;
pthread_getschedparam(currentHandle, &policy, &audio_sched_param);
if ((SCHED_FIFO != policy) ||
(audio_sched_param.sched_priority != target_priority))
{
printf("Warning: Failed to increase priority of audio thread to %d\nTry running as root\n", target_priority);
}
while (1)
{
// Wait for signal to run thread
sem_wait(&pumpSem);
// Set the pumpActive global flag
pumpActive = 1;
if (aweOS_audioIsStarted(g_AWEOSInstance) && aweOS_layoutIsValid(g_AWEOSInstance))
{
for (i = 0; i < configParams.inChannels ; i++)
{
// Import new samples
ret = aweOS_audioImportSamples(g_AWEOSInstance, &inputBuffer[i], configParams.inChannels, i, Sample32bit);
if (E_SUCCESS != ret)
{
printf("Error: aweOS_audioImportSamples() failed: error = %d %s \n", ret, aweOS_errorToString(ret));
}
}
ret = aweOS_audioPumpAll(g_AWEOSInstance);
if (E_SUCCESS != ret)
{
if (ErrMask == 0)
{
printf("Warning: aweOS_audioPumpAll(): %d %s \n", ret, aweOS_errorToString(ret));
ErrMask = true;
}
}
for (i = 0; i < configParams.outChannels ; i++)
{
// Export samples
ret = aweOS_audioExportSamples(g_AWEOSInstance, &outputBuffer[i], configParams.outChannels, i, Sample32bit);
if (E_SUCCESS != ret)
{
printf("Error: aweOS_audioExportSamples() failed: error = %d %s \n", ret, aweOS_errorToString(ret));
}
}
count++;
}
// Clear the pumpActive global flag
pumpActive = 0;
}
return 0;
}
else // if (true != waitFlag)
{
// In the option, the input .wav file is process and out put is coppied into a output .wav file
// Input channels sample rate and sample size are derived from the input .wav file
// Output channels are derived from the layout.
INT32 numSamplesRead = 0;
UINT32 wfNumChannels=0 , wfSampleSize =0, wfNumSamples = 0, outSampleSize = 0;
FLOAT32 wfSampleRate=0;
SampleType wfsampleType, outsampleType;
UINT32 chOffset=0;
ret = aweOS_wavFileOpen(infile, &wfSampleRate, &wfNumChannels, &wfSampleSize, &wfNumSamples, &fin);
if (E_SUCCESS != ret)
{
printf("Error opening input file %s return with error: %d %s\n", infile, ret, aweOS_errorToString(ret));
exit(1);
}
else
{
if (!quiet)
{
printf("Opening input file %s with paramerters\n", infile);
printf("sr: %f \nchannels: %u \nsampleWidth: %u \nTotalSamples: %u\n\n", wfSampleRate, wfNumChannels ,wfSampleSize, wfNumSamples);
}
}
//Check for some paramters incomming from the i/o wave file againt the layout parameters
if (wfSampleRate != layoutSampleRate)
{
printf("Warning: Mismatch in sampleRate \nInput file %s sr: %f and Layout %s sr: %f\n",infile, wfSampleRate, awbpath, layoutSampleRate);
}
if (wfNumChannels != layoutInChannels)
{
printf("Warning: Mismatch in number of input channels \nInput file %s inchans: %u and Layout %s inchans: %u\n",infile, wfNumChannels, awbpath, layoutInChannels );
}
if (4 == wfSampleSize)
{
wfsampleType = Sample32bit;
}
else if (2 == wfSampleSize)
{
wfsampleType = Sample16bit;
}
else
{
printf("Error processing input file %s unspported sample type: %u\n", infile, wfSampleSize);
printf("Currently only 2 bytes and 4 bytes sample sizes supported\n");
exit(1);
}
// These outsampleType and outSampleSize are used to create the .wav output. export samples etc
outsampleType = wfsampleType;
outSampleSize = wfSampleSize;
// Create the output file with the following parameters
// number of channels = Layout output channels
// sample rate = input file sample rate (input .wav)
// sample size = input sample size (input .wav)
ret = aweOS_wavFileCreate(outfile, wfSampleRate, layoutOutChannels, outSampleSize, &fout);
if (E_SUCCESS != ret)
{
printf("\nError creating the output file %s return with error: %d %s\n", outfile, ret , aweOS_errorToString(ret));
exit(1);
}
else
{
if (!quiet)
{
printf("\nCreating the output file %s with paramerters\n", outfile);
printf("sr: %f (from input .wav)\nchannels: %u (from layout)\nsampleWidth: %u (from input .wav)\n", wfSampleRate, layoutOutChannels, outSampleSize);
}
}
//Prepare the stereo input and output buffers for the waitFlag != true condition
//The I/O buffers are allocated based on size of data coming from the the input .wav file and layout
// inputbuffer : based of the no of incoming channels from the input .wav file
// outpubuffer : based on the the no of output channels in the layout
inSize = wfNumChannels * configParams.fundamentalBlockSize;
outSize = layoutOutChannels * configParams.fundamentalBlockSize;
inputBuffer1 = malloc(inSize * wfSampleSize);
outputBuffer1 = malloc(outSize * outSampleSize);
//Process the input data
if (!quiet)
{
printf("\nStarting to process [%s] into [%s]\n\n", infile, outfile);
}
while ((numSamplesRead = aweOS_wavFileRead(fin, inputBuffer1, inSize, wfSampleSize)) > 0)
{
if (aweOS_audioIsStarted(g_AWEOSInstance) && aweOS_layoutIsValid(g_AWEOSInstance))
{
for (i = 0, chOffset = 0; i < wfNumChannels; i++, chOffset += wfSampleSize)
{
if (Sample32bit == wfsampleType)
{
ret = aweOS_audioImportSamples(g_AWEOSInstance, (INT32 *)(inputBuffer1 + chOffset), wfNumChannels, i, wfsampleType);
}
else // Sample16bit
{
ret = aweOS_audioImportSamples(g_AWEOSInstance, (INT16 *)(inputBuffer1 + chOffset), wfNumChannels, i, wfsampleType);
}
if (E_SUCCESS != ret)
{
printf("Error: aweOS_audioImportSamples() failed: error = %d %s exiting application\n", ret, aweOS_errorToString(ret));
exit(1);
}
}
ret = aweOS_audioPumpAll(g_AWEOSInstance);
if (E_SUCCESS != ret)
{
if (ErrMask == false)
{
printf("Warning: aweOS_audioPumpAll(): %d %s \n", ret, aweOS_errorToString(ret));
ErrMask = true;
}
}
for (i = 0, chOffset = 0; i < layoutOutChannels; i++, chOffset += outSampleSize)
{
if (Sample32bit == outsampleType)
{
ret = aweOS_audioExportSamples(g_AWEOSInstance, (INT32 *)(outputBuffer1 + chOffset), layoutOutChannels, i, outsampleType);
}
else // Sample16bit
{
ret = aweOS_audioExportSamples(g_AWEOSInstance, (INT16 *)(outputBuffer1 + chOffset), layoutOutChannels, i, outsampleType);
}
if (E_SUCCESS != ret)
{
printf("Error: aweOS_audioExportSamples() failed: error = %d %s exiting application\n", ret, aweOS_errorToString(ret));
exit(1);
}
}
count++;
ret = aweOS_wavFileWrite(fout, outputBuffer1, outSize, outSampleSize);
}
}// end of while
printf("\n");
printf("Processed Audio Frames: %llu (block size %u)copied it to output file: %s\n", count, configParams.fundamentalBlockSize, outfile);
//Clean up
destroyExample();
} // end of if (true != waitFlag)
return 0;
} // end of main ()
The AWE Core OS API header file.
The AWECore Helper Functions File.
INT32 float_to_fract32(FLOAT32 x)
Convert audio data from floating point to Fract32 sample by sample.
#define E_SUCCESS
OK result.
Definition: Errors.h:31
enum _SampleType SampleType
Type of data for I/O.
@ Sample32bit
Data is 32 bit PCM .
Definition: StandardDefs.h:231
@ Sample16bit
Data is 16 bit PCM.
Definition: StandardDefs.h:222
#define TUNING_LOG_INFO
AWE Core OS internal tuning interface logging verbosity level: medium – log errors and header info fr...
Definition: AWECoreOS.h:54
void AWEOSInstance
The AWE Core OS Instance instance type.
Definition: AWECoreOS.h:106
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_wavFileCreate(const char *file, FLOAT32 sampleRate, UINT32 numChannels, UINT32 sampleSize, FILE **fp)
Create a .wav file and populate the header with the passed in arguments.
INT32 aweOS_tuningLoggingEnable(AWEOSInstance *pAWEOS, char *path, char *baseName, UINT32 verbosity)
Enable logging of the tuning packets sent and received by the AWEOSInstance.
INT32 aweOS_layoutGetBlockSize(const AWEOSInstance *pAWEOS, UINT32 *blockSize)
Returns the block size of the loaded layout.
INT32 aweOS_wavFileRead(FILE *fp, void *samples, UINT32 numSamples, UINT32 sampleSize)
Read audio data from .wav file opened using aweOS_wavFileOpen.
INT32 aweOS_registerLoggingCallback(AWEOSInstance *pAWEOS, cbAweOSLogging_t cbAweOSLogging, INT32 logLevel, UINT32 logTypeMask)
Register the logging callback with required logging level and logging type mask.
INT32 aweOS_layoutIsValid(const AWEOSInstance *pAWEOS)
Determines if a layout is loaded and valid.
INT32 aweOS_wavFileWrite(FILE *fp, void *samples, UINT32 numSamples, UINT32 sampleSize)
Write audio data to .wav file created using aweOS_wavFileCreate.
INT32 aweOS_layoutGetChannelCount(const AWEOSInstance *pAWEOS, UINT32 *inCount, UINT32 *outCount)
Returns the number of input and output channels in the loaded layout.
void aweOS_getVersion(AWEOSVersionInfo_t *versionInfo)
Get the version information of the AWE Core OS library.
INT32 aweOS_tuningSocketOpen(AWEOSInstance **pAWEOS, INT32 portNo, UINT32 numInstances)
Initialize and open an integrated TCP/IP tuning interface socket.
INT32 aweOS_registerEventCallbacks(AWEOSInstance *pAWEOS, cbAweOSEventTrigger_t cbAweOSEventTrigger, cbAweOSEventRegister_t cbAweOSEventRegister, cbAweOSEventDeregister_t cbAweOSEventDeregister)
Register the event callbacks used by the Event Module.
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_setProfilingStatus(AWEOSInstance *pAWEOS, UINT32 status)
Enable or disable the profiling ability of the AWE Core OS Instance.
INT32 aweOS_wavFileOpen(const char *file, FLOAT32 *sampleRate, UINT32 *numChannels, UINT32 *sampleSize, UINT32 *numSamples, FILE **fp)
Open a .wav file and populate the user arguments with the header information in the file.
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_wavFileClose(FILE *fp)
Close the.wav file opened using aweOS_wavFileOpen or aweOS_wavFileCreate.
INT32 aweOS_loadAWBFile(AWEOSInstance *pAWEOS, const char *binaryFile, UINT32 *pErrorOffset)
Executes packet commands from an AWB file on the filesystem.
Versioning structure returned by aweOS_getVersion.
Definition: AWECoreOS.h:93
const char * textVer
String of form: "AWECoreOS Version 8.A.1.1 -- Build Number 1234".
Definition: AWECoreOS.h:100
AWEOSConfigParameters.
Definition: AWECoreOS.h:117
float profileSpeed
Application profiling speed in Hz.
Definition: AWECoreOS.h:132
UINT32 fastHeapBSize
Size of fast heap B in 32-bit words.
Definition: AWECoreOS.h:123
const char * pName
Name of target.
Definition: AWECoreOS.h:133
float coreSpeed
Processor clock speed in Hz.
Definition: AWECoreOS.h:131
UINT32 * pFastHeapA
Pointer to fast heap A.
Definition: AWECoreOS.h:119
UINT32 numThreads
Maximum number of supported sublayouts.
Definition: AWECoreOS.h:134
UINT32 fundamentalBlockSize
Fundamental block size of audio driver.
Definition: AWECoreOS.h:136
UINT32 * pSlowHeap
Pointer to slow heap.
Definition: AWECoreOS.h:121
UINT32 outChannels
Number of output channels of audio device.
Definition: AWECoreOS.h:138
UINT32 packetBufferSize
Size of packet buffers.
Definition: AWECoreOS.h:129
UINT32 slowHeapSize
Size of slow heap in 32-bit words.
Definition: AWECoreOS.h:124
INT32(* cbAudioStop)(AWEOSInstance *pAWEOS)
Pointer to user created callback function for audio stop commands.
Definition: AWECoreOS.h:126
UINT32 * pFastHeapB
Pointer to fast heap B.
Definition: AWECoreOS.h:120
UINT32 fastHeapASize
Size of fast heap A in 32-bit words.
Definition: AWECoreOS.h:122
float sampleRate
Sample rate of audio device.
Definition: AWECoreOS.h:135
UINT32 inChannels
Number of input channels of audio device.
Definition: AWECoreOS.h:137
INT32(* cbAudioStart)(AWEOSInstance *pAWEOS)
Pointer to user created callback function for audio start commands.
Definition: AWECoreOS.h:125