#include "ModuleList.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 <time.h>
#define true 1
#define false 0
pthread_t audioCallbackThreadHandle;
pthread_mutex_t pumpAllMutex;
pthread_cond_t pumpAllCond;
pthread_mutex_t audioThreadMutex;
pthread_cond_t audioThreadCond;
INT32 pumpAll = 0;
INT32 audioStarted = 0;
INT32 exitAudioCallbackThread = 0;
static UINT32 quiet = false;
static unsigned long long count = 0;
static UINT32 ErrMask = false;
INT32 *inputBuffer, *outputBuffer;
UINT8 *inputBuffer1, *outputBuffer1;
FILE *fin;
FILE *fout;
static const void* moduleDescriptorTable[] =
{
LISTOFCLASSOBJECTS
};
UINT32 moduleDescriptorTableSize = sizeof(moduleDescriptorTable) / sizeof(moduleDescriptorTable[0]);
void copyright()
{
printf(
"%s\nAWE Libtester Copyright (c) DSP Concepts 2013-2020\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"
" -profDisable disable system profiling\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"
"This program exercises the AWECoreEX library.\n",
program);
exit(0);
}
void* audioCallbackSimulator(void * args)
{
struct timespec ts;
(void) args;
pthread_mutex_lock(&audioThreadMutex);
audioStarted = 1;
pthread_cond_signal(&audioThreadCond);
pthread_mutex_unlock(&audioThreadMutex);
ts.tv_sec = 0;
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)
{
pthread_mutex_lock(&pumpAllMutex);
pumpAll = 1;
pthread_cond_signal(&pumpAllCond);
pthread_mutex_unlock(&pumpAllMutex);
nanosleep(&ts, NULL);
}
return NULL;
}
void destroyExample()
{
INT32 ret;
{
}
{
}
{
}
free(inputBuffer);
free(outputBuffer);
inputBuffer = NULL;
outputBuffer = NULL;
}
{
INT32 ret;
UINT32 layoutInChannels, layoutOutChannels, blockSize;
FLOAT32 sampleRate;
pthread_mutex_lock(&pumpAllMutex);
pumpAll = 0;
pthread_mutex_unlock(&pumpAllMutex);
{
}
{
}
{
}
printf("Loaded layout with inChans = %d, outChans = %d, blockSize = %d, sampleRate = %f\n", layoutInChannels, layoutOutChannels, blockSize, sampleRate);
exitAudioCallbackThread = 0;
ret = pthread_create(&audioCallbackThreadHandle, NULL, audioCallbackSimulator, NULL);
if (0 != ret)
{
printf("Error creating audio callback simulator! ret = %d\n", ret);
return 0;
}
count = 0;
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;
}
{
if (audioStarted)
{
INT32 ret;
pthread_mutex_lock(&pumpAllMutex);
pumpAll = 0;
pthread_mutex_unlock(&pumpAllMutex);
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;
{
}
printf("\nAudio Stopped\n");
printf(
"Processed %llu audio frames with I/O block size of %d -- average cycles: %f\n", count, configParams.
fundamentalBlockSize,
}
}
return 0;
}
int main(int argc, char **argv)
{
copyright();
#define FASTHEAP_A_SIZE 4200000
static UINT32 fastHeapA[FASTHEAP_A_SIZE];
#define FASTHEAP_B_SIZE 4200000
static UINT32 fastHeapB[FASTHEAP_B_SIZE];
#define SLOWHEAP_SIZE 4200000
static UINT32 slowHeap[SLOWHEAP_SIZE];
INT32 tuningPort = 15002;
const char *awbpath = NULL;
const char *infile = NULL;
const char *outfile = NULL;
UINT32 profileEn = true;
UINT32 waitFlag = false;
UINT32 tlog = false;
UINT32 layoutInChannels, layoutOutChannels, layoutBlockSize;
FLOAT32 layoutSampleRate = 0;
UINT32 inSize, outSize;
UINT32 i,j;
INT32 ret;
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, "-profDisable", 12))
{
profileEn = false;
printf("profDisable:%d\n",!profileEn);
}
else if (0 == strncmp(arg, "-bsize:", 7))
{
}
else if (0 == strncmp(arg, "-inchans:", 9))
{
}
else if (0 == strncmp(arg, "-outchans:", 10))
{
}
else if(0 == strncmp(arg, "-sr:", 4))
{
}
else if (0 == strncmp(arg, "-cf:", 4))
{
configParams.
coreSpeed = (float)atof(arg + 4);
}
else if (0 == strncmp(arg, "-pf:", 4))
{
}
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: %d\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: %d\n",tlog);
}
else if (0 == strncmp(arg, "-quiet", 6))
{
quiet = true;
printf("-quiet: %d\n",quiet);
}
else
{
printf("main: unknown option '%s'\n", arg);
}
}
}
if (!waitFlag )
{ if ((!awbpath) || (!outfile) || (!infile))
{
printf("Please rerun with the missing Files\n");
printf("-load: %s\n",awbpath);
printf("-in: %s\n",infile);
printf("-out: %s\n",outfile);
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(
"num of Threads:%d\n",configParams.
numThreads);
printf("-tport: %d\n",tuningPort);
if (profileEn)
{
printf("-profDisable: Profiling is enabled\n");
}
else
{
printf("-profDisable: 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);
printf("-in: %s\n",infile);
printf("-out: %s\n",outfile);
}
printf("\n\n");
if (true == waitFlag)
{
pthread_mutex_init(&pumpAllMutex, NULL);
pthread_cond_init (&pumpAllCond, NULL);
pthread_mutex_init(&audioThreadMutex, NULL);
pthread_cond_init (&audioThreadCond, NULL);
}
ret =
aweOS_init(&g_AWEOSInstance, &configParams, moduleDescriptorTable, moduleDescriptorTableSize);
{
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);
}
if (!profileEn)
{
{
if (!quiet)
{
printf("aweOS profiling is disabled\n");
}
}
else
{
printf(
"aweOS_setProfilingStatus: profiling disable failed. exiting application with error = %d %s\n",ret,
aweOS_errorToString(ret));
exit(1);
}
}
if (tlog)
{
{
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);
}
{
if (!quiet)
{
printf("The layout %s loaded with parameters\n", awbpath);
}
}
else
{
printf("The layout %s download unsuccessful in the positions %d with Error = %d %s \n", awbpath, position, ret, strerror(ret));
exit(1);
}
{
printf(
"Error: aweOS_layoutGetChannelCount failed: error = %d %s\n", ret,
aweOS_errorToString(ret));
exit(1);
}
{
printf(
"Error: aweOS_layoutGetBlockSize failed: error = %d %s\n", ret,
aweOS_errorToString(ret));
exit(1);
}
{
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);
}
if (1 != ret)
{
printf("Error: Loaded layout is not valid: error = %d\n", ret);
exit(1);
}
if (1 != ret)
{
printf("Error: Audio not started: error = %d\n", ret);
exit(1);
}
}
if (true == waitFlag)
{
inputBuffer = malloc(inSize * sizeof(INT32));
outputBuffer = malloc(outSize * sizeof(INT32));
#ifndef PI
#define PI 3.141592653589793
#endif
{
{
}
}
{
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);
}
}
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;
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)
{
pthread_mutex_lock(&pumpAllMutex);
while (1 != pumpAll)
{
pthread_cond_wait(&pumpAllCond, &pumpAllMutex);
}
pthread_mutex_unlock(&pumpAllMutex);
{
{
{
printf(
"Error: aweOS_audioImportSamples() failed: error = %d %s \n", ret,
aweOS_errorToString(ret));
}
}
{
if (ErrMask == 0)
{
ErrMask = true;
}
}
{
{
printf(
"Error: aweOS_audioExportSamples() failed: error = %d %s \n", ret,
aweOS_errorToString(ret));
}
}
count++;
}
pthread_mutex_lock(&pumpAllMutex);
pumpAll = 0;
pthread_mutex_unlock(&pumpAllMutex);
}
return 0;
}
else
{
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);
{
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: %d \nsampleWidth: %d \nTotalSamples: %d\n\n", wfSampleRate, wfNumChannels ,wfSampleSize, wfNumSamples);
}
}
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: %d and Layout %s inchans: %d\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: %d\n", infile, wfSampleSize);
printf("Currently only 2 bytes and 4 bytes sample sizes supported\n");
exit(1);
}
outsampleType = wfsampleType;
outSampleSize = wfSampleSize;
{
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: %d (from layout)\nsampleWidth: %d (from input .wav)\n", wfSampleRate, layoutOutChannels, outSampleSize);
}
}
inputBuffer1 = malloc(inSize * wfSampleSize);
outputBuffer1 = malloc(outSize * outSampleSize);
if (!quiet)
{
printf("\nStarting to process [%s] into [%s]\n\n", infile, outfile);
}
while ((numSamplesRead =
aweOS_wavFileRead(fin, inputBuffer1, inSize, wfSampleSize)) > 0)
{
{
for (i = 0, chOffset = 0; i < wfNumChannels; i++, chOffset += wfSampleSize)
{
if (Sample32bit == wfsampleType)
{
}
else
{
}
{
printf(
"Error: aweOS_audioImportSamples() failed: error = %d %s exiting application\n", ret,
aweOS_errorToString(ret));
exit(1);
}
}
{
if (ErrMask == false)
{
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
{
ret =
aweOS_audioExportSamples(g_AWEOSInstance, (INT16 *)(outputBuffer1 + chOffset), layoutOutChannels, i, outsampleType);
}
{
printf(
"Error: aweOS_audioExportSamples() failed: error = %d %s exiting application\n", ret,
aweOS_errorToString(ret));
exit(1);
}
}
count++;
}
}
printf("\n");
printf(
"Processed Audio Frames: %llu (block size %d)copied it to output file: %s\n", count, configParams.
fundamentalBlockSize, outfile);
destroyExample();
}
return 0;
}