Main.c++ 5.61 KB
/******************************************************************************
 *
 *    Main function for AudioEditor
 *
 *****************************************************************************/
#include <stdio.h>     
#include <sys/types.h>
#include <sys/prctl.h>
#include <sys/dir.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/procfs.h> 
#include <limits.h> 
#include <paths.h>
#include <unistd.h>
#include <assert.h>
#include <signal.h>

#include <Xm/Xm.h>

#include "AudioApp.h"
#include "EditMgr.h"
#include "MidiMain.h"
#include "AssetMgr.h"
#include "FileMgr.h"
#include "U64Dev.h"
#include "CnfgMgr.h"
#include "Mgrs.h"

static int IsAppRunning(char *appname);
void myMainProc(void);

AssetMgr   *theAssetMgr;
FileMgr    *theFileMgr;
EditMgr    *theEditMgr;
U64Device  *theU64Dev;

AudioConfig  audCnfg;
int          midiPID;
int          mainPID;
int          parentPID;
int          parentDie = 0;

int         myArgc;
char        **myArgv;

int         verbose;
char         *bankFileName = 0;


void mySigHandler(int signo)
{
    kill(midiPID,SIGKILL);
    kill(mainPID,SIGKILL); 
    parentDie = 1;
}

void main(int argc, char **argv)
{
    int          c;
    CnfgMgr      *cnfgmgr;
    char         *cFileName = "AudioEditor.cnfg";
    AssetPair    *bankfAssets;
    int          numBnkfs;

    myArgc = argc;
    myArgv = argv;

    struct sigaction sigAct;

    /* Check to see if there is another copy of AudioEditor already running */
    if(IsAppRunning(argv[0]))
    {
        fprintf(stderr,"%s is already running, will exit\n",argv[0]);
        exit(-1);
    }

    while ((c = getopt(argc, argv, "vb:c:")) != EOF)
    {
        switch (c) 
        {
            case 'v':
                verbose = TRUE;
                break;
            case 'c':
                cFileName = optarg;
                break;
            case 'b':
                bankFileName = optarg;
                break;
            case '?':
                fprintf(stderr,"Usage [-v] [-b] [filename...] [-c] [filename...]\n");
		fprintf(stderr,"-v verbose\n-b bankfile without extensions\n-c configuration file\n");
                exit(0);
                break;
        }
    }



    /* Set up the signal handling */
    sigAct.sa_handler = (void(*)(...))mySigHandler;
    sigemptyset(&sigAct.sa_mask);
    sigAct.sa_flags = 0;

    if(sigaction(SIGCHLD,&sigAct,NULL) < 0)
    {
        perror("Unable to install signal handler SIGCHLD");
        exit(-1);
    }
    if(sigaction(SIGINT,&sigAct,NULL) < 0)
    {
        perror("Unable to install signal handler SIGINT");
        exit(-1);
    }
    if(sigaction(SIGTERM,&sigAct,NULL) < 0)
    {
        perror("Unable to install signal handler SIGTERM");
        exit(-1);
    }
    if(sigaction(SIGQUIT,&sigAct,NULL) < 0)
    {
        perror("Unable to install signal handler SIGQUIT");
        exit(-1);
    }

    /* create top level objects */
    theEditMgr = new EditMgr(myArgc, myArgv);
    assert(theEditMgr);

    theAssetMgr = new AssetMgr;
    assert(theAssetMgr);
    
    theFileMgr = new FileMgr;
    assert(theFileMgr);

    cnfgmgr = new CnfgMgr;
    assert(cnfgmgr);

    theU64Dev = new U64Device;
    assert(theU64Dev);

    /* initialization cnfgmgr and U64Device*/
    if(cnfgmgr->SetAudConfig(&audCnfg,cFileName) != 0)
    {
	fprintf(stderr,"Failure initializing resources\n");
	exit(-1);
    }

    theU64Dev->InitDevice(&audCnfg);

    if(theFileMgr->ReadBank(bankFileName) == FILE_OK)
    {
	theU64Dev->UpdateSmplMem(0);
	theU64Dev->UpdateAssets(0);
    }
    
    bankfAssets = theAssetMgr->ListBankFiles(&numBnkfs);
    if(bankfAssets)
    {
	theU64Dev->StartDevice((AEBankFile*)bankfAssets[0].asset,0);
	free(bankfAssets);
    }
    else
	printf("No bank file specified, did not start audio running on Ultra64\n");

    /*do the sprocing */
    parentPID = getpid();

    mainPID = sproc(myMainProc, PR_SALL, NULL);
    if(mainPID < 0)
    {
	fprintf(stderr, "%s: Unable to start main thread, will exit\n",argv[0]);
	exit(-1);
    }

    midiPID = sproc(midiMain, PR_SALL, NULL);
    if(midiPID < 0)
    {
	fprintf(stderr, "%s: Unable to start midi thread, will exit\n",argv[0]);
	exit(-1);
    }

    while(!parentDie)
	sleep(0x7FFFFFF);

    if(theU64Dev)
    {
	delete theU64Dev;
	theU64Dev = 0;
    }

}

void myMainProc()
{

    theEditMgr->startApp();
}


static int IsAppRunning(char *appname)
{
    DIR             *dirp;      /* Directory pointer */
    struct direct   *dp;        /* Directory entry */
    char            pbuf[PATH_MAX]; /* Buffer for procfs file name */
    int             pfd;        /* Process file descriptor */
    prpsinfo_t      psinfo;     /* Process information */
    int             found = 0;  /* Flag indicating that we found a match */
    pid_t           mypid;      /* My Process ID */

    /* Open the process info directory */
    if ((dirp = opendir(_PATH_PROCFSPI)) == NULL)
        return -1;

    mypid = getpid();

    /* Iterate through all of the files in the directory */
    while ((dp = readdir(dirp)) != NULL && !found)
    {
        /* We don't care about ourselves */
        if (mypid == atoi(dp->d_name))
            continue;

        /* Open the actual process file */
        strcpy(pbuf, _PATH_PROCFSPI);
        strcat(pbuf, dp->d_name);
        if ((pfd = open(pbuf, O_RDONLY)) < 0)
            continue;

        /* Try and retrieve the process info */
        if (ioctl(pfd, PIOCPSINFO, &psinfo) == -1)
        {
            close(pfd);
            continue;
        }

        close(pfd);

        if (strcmp(appname, psinfo.pr_fname) == 0)
            found = psinfo.pr_pid;
    }

    closedir(dirp);
    return found;
}