Examples.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <signal.h>
#include <netinet/in.h>
#include <pthread.h>
#include <math.h>
#include <time.h>
#include <sys/time.h>
#include <semaphore.h>
#include "TargetInfo.h"
typedef struct ConfigParameters
{
float coreSpeed;
float profileSpeed;
float sampleRate;
UINT32 fundamentalBlockSize;
UINT32 inChannels;
UINT32 outChannels;
UINT32 profileStatus;
INT32 tuningPort;
} ConfigParameters;
static ConfigParameters configParams;
INT32 *audioInputBuffer = NULL;
INT32 *audioOutputBuffer = NULL;
static BOOL quiet = FALSE;
static IOPinDescriptor aweInputPin;
static IOPinDescriptor aweOutputPin;
const void* module_descriptor_table[] =
{
LISTOFCLASSOBJECTS
};
UINT32 awePacketBuffer[MAX_COMMAND_BUFFER_LEN];
UINT32 awePacketBufferReply[MAX_COMMAND_BUFFER_LEN];
UINT32 *fastHeapA;
UINT32 *fastHeapB;
UINT32 *slowHeap;
UINT32 heapSizeFastA = FASTA_HEAP_SIZE_LINUX;
UINT32 heapSizeFastB = FASTB_HEAP_SIZE_LINUX;
UINT32 heapSizeSlow = SLOW_HEAP_SIZE_LINUX;
pthread_t tuningThreadHandle;
pthread_t processThreadHandle;
pthread_t audioCallbackThreadHandle;
pthread_t audioPumpAllThreadHandle;
pthread_mutex_t packetMutex;
sem_t pumpSem;
INT32 audioStarted = 0;
INT32 exitAudioCallbackThread = 0;
int sockfd, newsockfd;
int exitTuning = 0;
INT32 pumpActive = 0;
INT32 eventRegisterCnt = 0;
#define AUDIO_CALLBACK_PRIO 9
#define AUDIO_PUMP_PRIO 8
#define TUNING_THREAD_PRIO 7
static void usage(const char *program)
{
printf(
"Usage: %s [args]\n"
" -load:<file> AWB file to load\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:N set profiling status (0 - disable, 1 - enable(default), 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"
" -tport:N default 15002, port number for socket interface. User can choose between 15002 - 15098\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"
" -quiet works in quiet mode, displays only necessary messages\n"
"This program exercises the AWECore library.\n",
program, FASTA_HEAP_SIZE_LINUX, FASTB_HEAP_SIZE_LINUX, SLOW_HEAP_SIZE_LINUX);
exit(0);
}
void destroyApp(void)
{
free(audioInputBuffer);
free(audioOutputBuffer);
free(fastHeapA);
free(fastHeapB);
free(slowHeap);
audioInputBuffer = NULL;
audioOutputBuffer = NULL;
fastHeapA = NULL;
fastHeapB = NULL;
slowHeap = NULL;
}
void error(const char *msg)
{
perror(msg);
exit(1);
}
void sig_handler(int signo)
{
if (signo == SIGINT)
{
exitTuning = 1;
shutdown(newsockfd, SHUT_RDWR);
close(newsockfd);
shutdown(sockfd, SHUT_RDWR);
close(sockfd);
pthread_join(tuningThreadHandle, NULL);
destroyApp();
}
printf("Exiting LinuxApp\n");
exit(0);
}
void usrLogging(
AWEInstance* pAWE, INT32 level, UINT32 type,
void* payload, INT32 payloadSizeInBytes)
{
struct timeval ts;
char timeCh[25];
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(
AWEInstance* pAWE, INT32 eventType, UINT32 moduleObjId, INT32 payloadSizeInBytes,
void** userHandle)
{
printf("Got an event registration callback for objectId %u, eventType %d. Size of event payloads will be %d bytes\n",
moduleObjId, eventType, payloadSizeInBytes);
}
INT32 usrEventDeregister(
AWEInstance* pAWE, INT32 eventType, UINT32 moduleObjId,
void** userHandle)
{
printf("Got an event deregistration callback for objectId %u\n", moduleObjId);
}
INT32 usrEventTrigger(
AWEInstance* pAWE, INT32 eventType, UINT32 moduleObjId,
void* payload, INT32 payloadSizeInBytes,
void* userHandle)
{
struct timeval ts;
char timeCh[25];
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))
{
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);
}
}
void* tuningPacketThread(void* arg)
{
(void) arg;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
INT32 schedPolicy, ret;
struct sched_param schedParam;
int socketOption;
pthread_t currentHandle = pthread_self();
schedParam.sched_priority = TUNING_THREAD_PRIO;
schedPolicy = SCHED_FIFO;
ret = pthread_setschedparam(currentHandle, schedPolicy, &schedParam);
if (ret != 0)
{
printf("Failed to increase priority of tuning thread with error: %s \nTry running with sudo\n", strerror(ret));
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
error("ERROR opening socket");
}
socketOption = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &socketOption, sizeof(socketOption));
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(configParams.tuningPort);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
{
error("ERROR on binding");
}
while (!exitTuning)
{
listen(sockfd,5);
printf("Listening for connection on port %d\n", configParams.tuningPort);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0)
{
error("ERROR on accept");
}
printf( "Found connection!\n");
while(1)
{
unsigned int plen;
ssize_t readBytes, n;
if (readBytes == 0)
{
break;
}
else if (readBytes < 0)
{
error("ERROR reading from socket");
}
while (readBytes < plen)
{
n = read(newsockfd,&((
char*)aweInstance.
pPacketBuffer)[readBytes], MAX_COMMAND_BUFFER_LEN *
sizeof(aweInstance.
pPacketBuffer[0]));
if (n == 0)
{
break;
}
else if (n < 0)
{
error("ERROR reading from socket");
}
else
{
readBytes += n;
}
}
pthread_mutex_lock(&packetMutex);
pthread_mutex_unlock(&packetMutex);
if (n < plen)
{
error("ERROR writing to socket");
}
}
}
return NULL;
}
void* aweuser_pumpAllAudio(void * args)
{
(void) args;
INT32 pumpMask;
INT32 ix;
INT32 i;
INT32 schedPolicy, ret;
struct sched_param schedParam;
pthread_t currentHandle = pthread_self();
schedParam.sched_priority = AUDIO_PUMP_PRIO;
schedPolicy = SCHED_FIFO;
ret = pthread_setschedparam(currentHandle, schedPolicy, &schedParam);
if (ret != 0)
{
printf("Failed to increase priority of audio pump thread to real time with error: %s \nTry running with sudo\n", strerror(ret));
}
printf("Starting pump all thread\n");
while (1)
{
sem_wait(&pumpSem);
pumpActive = 1;
{
for (i = 0; i < configParams.inChannels ; i++)
{
}
pthread_mutex_lock(&packetMutex);
for (ix = 0; ix < NUM_THREADS; ix++)
{
if (pumpMask & (1U << ix))
{
}
}
if (ret > 0)
{
}
for (i = 0; i < configParams.outChannels ; i++)
{
}
pthread_mutex_unlock(&packetMutex);
}
pumpActive = 0;
}
return NULL;
}
void* audioCallbackSimulator(void * args)
{
struct timespec ts;
struct timespec ts_tmp;
long time_nsec;
long long accumulated_time;
long long target_time;
long long overshoot = 0.0;
(void) args;
INT32 schedPolicy, ret;
struct sched_param schedParam;
ts.tv_sec = 0;
time_nsec = (long) ((float)1000000000L * ((float)configParams.fundamentalBlockSize / configParams.sampleRate));
ts.tv_sec = 0;
ts_tmp.tv_sec = 0;
ts_tmp.tv_nsec = 0;
pthread_t currentHandle = pthread_self();
schedParam.sched_priority = AUDIO_CALLBACK_PRIO;
schedPolicy = SCHED_FIFO;
ret = pthread_setschedparam(currentHandle, schedPolicy, &schedParam);
if (ret != 0)
{
printf("Failed to increase priority of audio callback thread with error: %s \nTry running with sudo\n", strerror(ret));
}
while (!exitAudioCallbackThread)
{
if (!pumpActive)
{
sem_post(&pumpSem);
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);
target_time = ((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_time = ((long long)ts_tmp.tv_sec*1000000000) + ts_tmp.tv_nsec;
if (accumulated_time >= target_time)
{
overshoot += (accumulated_time - target_time);
break;
}
else
{
ts.tv_nsec = (long)(target_time - accumulated_time);
}
}
}
return NULL;
}
{
(void) pAWE;
exitAudioCallbackThread = 0;
pthread_create(&audioCallbackThreadHandle, NULL, audioCallbackSimulator, NULL);
audioStarted = 1;
printf("Audio Started\n");
return 0;
}
{
(void) pAWE;
if(audioCallbackThreadHandle)
{
exitAudioCallbackThread = 1;
pthread_join(audioCallbackThreadHandle, NULL);
if (audioStarted)
{
printf("Audio Stopped\n");
audioStarted = 0;
}
}
return 0;
}
void InitializeAWEInstance()
{
int ret = 0;
int i, j;
UINT32 module_descriptor_table_size;
module_descriptor_table_size = sizeof(module_descriptor_table) / sizeof(module_descriptor_table[0]);
aweInstance.
numModules = module_descriptor_table_size;
aweInstance.
coreSpeed = configParams.coreSpeed;
aweInstance.
pName = TARGET_NAME;
ret =
awe_initPin(&aweInputPin, configParams.inChannels, NULL);
if (ret != 0)
{
printf("awe_initPin inputPin failed\n");
}
ret =
awe_initPin(&aweOutputPin, configParams.outChannels, NULL);
if (ret != 0)
{
printf("awe_initPin outputPin failed\n");
}
if (ret != 0)
{
printf("awe_init instance 1 failed\n");
}
if (ret != 0)
{
printf("awe_setProfilingStatus failed with error code: %d\n", ret);
}
if (ret != 0)
{
printf("awe_registerLoggingCallback failed with error code: %d\n", ret);
}
if (ret != 0)
{
printf("awe_registerEventCallbacks failed with error code: %d\n", ret);
}
#ifndef PI
#define PI 3.141592653589793
#endif
for (i = 0; i < configParams.fundamentalBlockSize; i++)
{
for (j = 0; j < configParams.inChannels; j++)
{
audioInputBuffer[i * configParams.inChannels + j] =
float_to_fract32(sinf(2.f*PI*(j+1)*((
float)configParams.sampleRate/configParams.fundamentalBlockSize) * (i / (
float)configParams.sampleRate)));
}
}
}
int main( int argc, const char* argv[] )
{
INT32 i;
UINT32 inSize, outSize;
const char *awbpath = NULL;
INT32 ret;
configParams.fundamentalBlockSize = BASE_BLOCK_SIZE;
configParams.sampleRate = SAMPLE_RATE;
configParams.inChannels = NUM_INPUT_CHANNELS;
configParams.outChannels = NUM_OUTPUT_CHANNELS;
configParams.coreSpeed = CORE_SPEED;
configParams.profileSpeed = PROFILE_SPEED;
configParams.profileStatus = 1;
configParams.tuningPort = 15002;
for (i = 1; i < argc; i++)
{
const char *arg = argv[i];
if (0 == strncmp(arg, "-profStatus:", 12))
{
configParams.profileStatus = atoi(arg + 12);
printf("profStatus:%u\n",configParams.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, "-tport:", 7))
{
configParams.tuningPort = atoi(arg + 7);
printf("-tport: %d\n",configParams.tuningPort);
}
else if (0 == strncmp(arg, "-quiet", 6))
{
quiet = TRUE;
printf("-quiet: %d\n",quiet);
}
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, "-load:", 6))
{
awbpath = arg + 6;
printf("-load: %s\n",awbpath);
}
else
{
usage(argv[0]);
}
}
if (!quiet)
{
{
printf("\nAWECore version %u.%c.%u.%u.%c (build %u) initialized with the following parameters\n\n",
}
else
{
printf("\nAWECore version %u.%c.%u.%u (build %u) initialized with the following parameters\n\n",
}
printf("-cf: %f Hz\n",configParams.coreSpeed);
printf("-pf: %f Hz\n",configParams.profileSpeed);
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",configParams.tuningPort);
printf("-hsizefasta: %u\n",heapSizeFastA);
printf("-hsizefastb: %u\n",heapSizeFastB);
printf("-hsizeslow: %u\n",heapSizeSlow);
printf("-load: %s\n",awbpath ? awbpath : "undefined");
if (configParams.profileStatus)
{
printf("-profStatus: Profiling is enabled\n");
}
else
{
printf("-profStatus: Profiling is disabled\n");
}
}
if (signal(SIGINT, sig_handler) == SIG_ERR)
{
printf("Can't catch SIGINT (%d)\n", SIGINT);
}
inSize = configParams.inChannels * configParams.fundamentalBlockSize;
outSize = configParams.outChannels * configParams.fundamentalBlockSize;
audioInputBuffer = malloc(inSize * sizeof(INT32));
audioOutputBuffer = malloc(outSize * sizeof(INT32));
fastHeapA = malloc(heapSizeFastA * sizeof(UINT32));
fastHeapB = malloc(heapSizeFastB * sizeof(UINT32));
slowHeap = malloc(heapSizeSlow * sizeof(UINT32));
InitializeAWEInstance();
if ( NULL != awbpath )
{
FILE *fin;
UINT32 position;
fin = fopen(awbpath, "rb");
if (NULL == fin )
{
printf("Error opening input file %s\n", awbpath);
printf("Please check the path\n");
exit(1);
}
{
printf("The layout %s loaded successfully\n", awbpath);
}
else
{
printf("The layout %s download unsuccessful in the positions %u with Error = %d \n", awbpath, position, ret);
exit(1);
}
}
pthread_mutex_init(&packetMutex, NULL);
sem_init(&pumpSem, 0, 0);
pthread_create(&tuningThreadHandle, NULL, tuningPacketThread, NULL);
pthread_create(&audioPumpAllThreadHandle, NULL, aweuser_pumpAllAudio, NULL);
pthread_join(tuningThreadHandle, NULL);
pthread_join(audioPumpAllThreadHandle, NULL);
return 0;
}
The AWECore 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 PACKET_LENGTH_WORDS(x)
This will determine the length of a packet in words.
Definition: AWECoreUtils.h:40
#define PACKET_LENGTH_BYTES(x)
This will determine the length of a packet in bytes.
Definition: AWECoreUtils.h:43
INT32 awe_initPin(IOPinDescriptor *pPin, UINT32 channels, const char *name)
Initialize an input or output pin.
INT32 awe_deferredSetCall(AWEInstance *pAWE)
Perform deferred awe set on a module.
INT32 awe_registerEventCallbacks(AWEInstance *pAWE, cbAweEventTrigger_t cbAweEventTrigger, cbAweEventRegister_t cbAweEventRegister, cbAweEventDeregister_t cbAweEventDeregister)
Register the event callbacks used by the Event Module.
INT32 awe_getBuildVersionInfo(AWEBuildVersionInfo_t *pBuildVersionInfo)
Get the AWECore build number and version information.
INT32 awe_audioPump(AWEInstance *pAWE, UINT32 layoutIndex)
Audio pump function.
INT32 awe_registerLoggingCallback(AWEInstance *pAWE, cbAweLogging_t cbAweLogging, INT32 logLevel, UINT32 logTypeMask)
Register the logging callback with required logging level and logging type mask.
INT32 awe_audioImportSamples(const AWEInstance *pAWE, const void *inSamples, INT32 inStride, INT32 channel, SampleType inType)
Import samples from a user buffer to a channel.
INT32 awe_layoutIsValid(const AWEInstance *pAWE)
Determines if a layout is loaded and valid.
INT32 awe_audioExportSamples(const AWEInstance *pAWE, void *outSamples, INT32 outStride, INT32 channel, SampleType outType)
Export samples to a user buffer from a channel.
INT32 awe_audioGetPumpMask(AWEInstance *pAWE)
Test if AWE is ready to run.
INT32 awe_setProfilingStatus(AWEInstance *pAWE, UINT32 status)
Enable or disable the profiling ability of the AWE Core.
INT32 awe_packetProcess(AWEInstance *pAWE)
Process an AWEInstance's newly received tuning packet.
INT32 awe_loadAWBfromFile(AWEInstance *pAWE, const char *binaryFile, UINT32 *pPos)
Load an AWB file from stdio.
INT32 awe_init(AWEInstance *pAWE)
Initialize the instance.
INT32 awe_audioIsStarted(const AWEInstance *pAWE)
Check if this instance is running.
#define E_SUCCESS
OK result.
Definition: Errors.h:31
A list of all AWE Server Commands.
@ Sample32bit
Data is 32 bit PCM .
Definition: StandardDefs.h:231
The AWE instance.
Definition: AWEInstance.h:82
IOPinDescriptor * pInputPin
A BSP author must define/allocate an input pin in their BSP and assign it to this member NOTE: AudioW...
Definition: AWEInstance.h:146
const char * pName
The name of the AWE Instance that will be displayed in Server.
Definition: AWEInstance.h:215
float profileSpeed
Profiling clock speed in Hz.
Definition: AWEInstance.h:207
UINT32 * pReplyBuffer
Reply buffer pointer.
Definition: AWEInstance.h:189
UINT32 * pFastHeapB
The second fast heap, B .
Definition: AWEInstance.h:94
UINT32 numThreads
Number of threads supported for multithreaded systems(1-4).
Definition: AWEInstance.h:219
IOPinDescriptor * pOutputPin
A BSP author must define/allocate an output pin in their BSP and assign it to this member NOTE: Audio...
Definition: AWEInstance.h:152
UINT32 * pPacketBuffer
The Packet buffer pointer.
Definition: AWEInstance.h:180
INT32(* cbAudioStart)(struct _AWEInstance *PAWE)
OPTIONAL This callback is invoked when a layout is run or when a StartAudio command is sent.
Definition: AWEInstance.h:116
INT32(* cbAudioStop)(struct _AWEInstance *pAWE)
OPTIONAL.
Definition: AWEInstance.h:122
UINT32 slowHeapSize
The slow heap size.
Definition: AWEInstance.h:108
UINT32 fundamentalBlockSize
Base frame size of this instance.
Definition: AWEInstance.h:226
UINT32 * pSlowHeap
The slow heap.
Definition: AWEInstance.h:97
float sampleRate
Default sample rate of this instance.
Definition: AWEInstance.h:222
UINT32 packetBufferSize
Packet buffer size.
Definition: AWEInstance.h:196
UINT32 fastHeapBSize
The fast heap B size.
Definition: AWEInstance.h:105
AWEFlashFSInstance * pFlashFileSystem
DSPC Flash file system instance.
Definition: AWEInstance.h:231
float coreSpeed
A BSP author will set this to the speed of the CPU they are integrating into.
Definition: AWEInstance.h:204
UINT32 numModules
Number of modules in module table.
Definition: AWEInstance.h:162
const ModClassModule ** pModuleDescriptorTable
Pointer to module table.
Definition: AWEInstance.h:170
UINT32 fastHeapASize
The fast heap A size in 32-bit words.
Definition: AWEInstance.h:102
UINT32 * pFastHeapA
Fast heap A.
Definition: AWEInstance.h:91
Build versioning structure returned by awe_getBuildVersionInfo.
Definition: AWEInstance.h:260
UINT32 buildNumber
Library build number.
Definition: AWEInstance.h:266
UINT32 minorVer
Minor API version.
Definition: AWEInstance.h:263
char hotFixVer
Hot fix version, if the build is a hot fix release.
Definition: AWEInstance.h:265
char majorVer
Major API version (single letter)
Definition: AWEInstance.h:262
UINT32 procVer
Processor specific version.
Definition: AWEInstance.h:264
UINT32 tuningVer
Tuning version.
Definition: AWEInstance.h:261