#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 "TargetInfo.h"
const void* module_descriptor_table[] =
{
LISTOFCLASSOBJECTS
};
UINT32 awePacketBuffer[MAX_COMMAND_BUFFER_LEN];
UINT32 awePacketBufferReply[MAX_COMMAND_BUFFER_LEN];
UINT32 fastHeapA[FASTA_HEAP_SIZE];
UINT32 fastHeapB[FASTB_HEAP_SIZE];
UINT32 slowHeap[SLOW_HEAP_SIZE];
UINT32 audioInputBuffer[NUM_INPUT_CHANNELS * BASE_BLOCK_SIZE];
UINT32 audioOutputBuffer[NUM_OUTPUT_CHANNELS * BASE_BLOCK_SIZE];
pthread_t tuningThreadHandle;
pthread_t processThreadHandle;
pthread_t audioCallbackThreadHandle;
pthread_t audioPumpAllThreadHandle;
pthread_mutex_t pumpAllMutex, packetMutex;
pthread_cond_t pumpAllCond;
INT32 pumpAll = 0;
INT32 audioStarted = 0;
INT32 exitAudioCallbackThread = 0;
int sockfd, newsockfd;
int exitTuning = 0;
#define TUNING_PORT 15092
#define AUDIO_CALLBACK_PRIO 9
#define AUDIO_PUMP_PRIO 8
#define TUNING_THREAD_PRIO 7
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);
printf("Exiting LinuxApp\n");
exit(0);
}
}
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));
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(TUNING_PORT);
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", TUNING_PORT);
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 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)
{
pthread_mutex_lock(&pumpAllMutex);
while (pumpAll != 1) {
pthread_cond_wait(&pumpAllCond, &pumpAllMutex);
}
pthread_mutex_unlock(&pumpAllMutex);
{
pthread_mutex_lock(&packetMutex);
for (ix = 0; ix < NUM_THREADS; ix++)
{
if (pumpMask & (1U << ix))
{
}
}
if (ret > 0)
{
}
pthread_mutex_unlock(&packetMutex);
}
pthread_mutex_lock(&pumpAllMutex);
pumpAll = 0;
pthread_mutex_unlock(&pumpAllMutex);
}
return NULL;
}
void* audioCallbackSimulator(void * args)
{
struct timespec ts;
(void) args;
INT32 schedPolicy, ret;
struct sched_param schedParam;
ts.tv_sec = 0;
ts.tv_nsec = (long) ((float)1000000000L * ((float)BASE_BLOCK_SIZE / SAMPLE_RATE));
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)
{
pthread_mutex_lock(&pumpAllMutex);
pumpAll = 1;
pthread_cond_signal(&pumpAllCond);
pthread_mutex_unlock(&pumpAllMutex);
nanosleep(&ts, &ts);
}
return NULL;
}
{
(void) pAWE;
pthread_mutex_lock(&pumpAllMutex);
pumpAll = 0;
pthread_mutex_unlock(&pumpAllMutex);
exitAudioCallbackThread = 0;
pthread_create(&audioCallbackThreadHandle, NULL, audioCallbackSimulator, NULL);
audioStarted = 1;
printf("Audio Started\n");
return 0;
}
{
(void) pAWE;
if(audioCallbackThreadHandle)
{
pthread_mutex_lock(&pumpAllMutex);
pumpAll = 0;
pthread_mutex_unlock(&pumpAllMutex);
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.
pName = TARGET_NAME;
ret =
awe_initPin(&aweInputPin, NUM_INPUT_CHANNELS, NULL);
if (ret != 0)
{
printf("awe_initPin inputPin failed\n");
}
ret =
awe_initPin(&aweOutputPin, NUM_OUTPUT_CHANNELS, NULL);
if (ret != 0)
{
printf("awe_initPin outputPin failed\n");
}
if (ret != 0)
{
printf("awe_init instance 1 failed\n");
}
#ifndef PI
#define PI 3.141592653589793
#endif
for (i = 0; i < BASE_BLOCK_SIZE; i++)
{
for (j = 0; j < NUM_INPUT_CHANNELS; j++)
{
audioInputBuffer[i * NUM_INPUT_CHANNELS + j] =
float_to_fract32(sinf(2.f*PI*(j+1)*((
float)SAMPLE_RATE/BASE_BLOCK_SIZE) * (i / (
float)SAMPLE_RATE)));
}
}
}
int main( int argc, const char* argv[] )
{
(void) argc;
(void) argv;
if (signal(SIGINT, sig_handler) == SIG_ERR)
{
printf("Can't catch SIGINT (%d)\n", SIGINT);
}
InitializeAWEInstance();
pthread_mutex_init(&packetMutex, NULL);
pthread_mutex_init(&pumpAllMutex, NULL);
pthread_cond_init (&pumpAllCond, NULL);
pthread_create(&tuningThreadHandle, NULL, tuningPacketThread, NULL);
pthread_create(&audioPumpAllThreadHandle, NULL, aweuser_pumpAllAudio, NULL);
pthread_join(tuningThreadHandle, NULL);
pthread_join(audioPumpAllThreadHandle, NULL);
return 0;
}