示例#1
0
LRESULT CMainDlg::OnSave(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	char fileName[MAX_PATH];
	memset(fileName, 0, sizeof(fileName));
	OPENFILENAME ofn;
	memset(&ofn, 0, sizeof(ofn));
	ofn.lStructSize = sizeof(ofn);
	ofn.hwndOwner = m_hWnd;
	ofn.lpstrFilter = "Sound Files(*.wav)\0*.wav\0All Files(*.*)\0*.*\0";
	ofn.nFilterIndex = 1;
	ofn.lpstrFile = fileName;
	ofn.lpstrDefExt = ".wav";
	ofn.nMaxFile = MAX_PATH;
	ofn.Flags = OFN_OVERWRITEPROMPT;
	
	if (GetSaveFileName (&ofn))
	{
		WaveFile wvf;
		wvf.OpenWaveFile(fileName, 2);
		InitGen();
		long totalSamples = (long) ((durTotal * synthParams.sampleRate) + 0.5);
		long atkSamples = (long) (durAtkSus * synthParams.sampleRate);
		long n;
		for (n = 0; n < atkSamples; n++)
			wvf.Output1(Generate());
		NoteOff();
		while (n++ < totalSamples)
			wvf.Output1(Generate());
		for (n = 0; n < 440; n++)
			wvf.Output1(0);
		wvf.CloseWaveFile();
	}
	return 0;
}
/***** MAIN BLOCK *****/
int main(void)
{
    InitGen(); DrawBoard(); side = LIGHT; xside = DARK; computerside = DARK;

    do
    {
        if (side == computerside) ComputerThink();
        else if (GetHumanMove()) break;
        side = xside; xside = 1-xside;
    }
    while (!UpdateNewMove());
}
示例#3
0
/* main: */
int main(int argc, char *argv[])
{
   char *s;
   char fname[MAXSTRLEN];

   InitShell(argc, argv, hmgetool_version, hmgetool_vc_id);
   InitMem();
   InitMath();
   InitSigP();
   InitWave();
   InitLabel();
   InitModel();
   InitTrain();
   InitParm();
   InitUtil();
   InitFB();
   InitGen();
   InitAdapt(&xfInfo, NULL);
   InitMTrain();

   /* process argument */
   if (NumArgs() == 0)
      ReportUsage();
   CreateHeap(&hmmStack, "Model Stack", MSTAK, 1, 1.0, 80000, 4000000);
   CreateHeap(&orighmmStack, "Model Stack", MSTAK, 1, 1.0, 80000, 4000000);
   CreateHeap(&accStack, "Acc Stack", MSTAK, 1, 1.0, 80000, 400000);
   CreateHeap(&genStack, "Gen Stack", MSTAK, 1, 1.0, 80000, 400000);
   CreateHeap(&mgeStack, "MGE Train Stack", MSTAK, 1, 1.0, 80000, 400000);

   SetConfParms();
   CreateHMMSet(&hset, &hmmStack, TRUE);
   CreateHMMSet(&orighset, &orighmmStack, TRUE);

   statInfo = (MTStatInfo *) New(&gstack, sizeof(MTStatInfo));
   memset(statInfo, 0, sizeof(MTStatInfo));

   genInfo = (GenInfo *) New(&genStack, sizeof(GenInfo));
   memset(genInfo, 0, sizeof(GenInfo));
   genInfo->hset = &hset;
   genInfo->genMem = &genStack;

   mtInfo = (MgeTrnInfo *) New(&mgeStack, sizeof(MgeTrnInfo));
   memset(mtInfo, 0, sizeof(MgeTrnInfo));
   mtInfo->genInfo = genInfo;
   mtInfo->statInfo = statInfo;
   mtInfo->hset = &hset;
   mtInfo->orighset = &orighset;
   mtInfo->mgeMem = &mgeStack;

   while (NextArg() == SWITCHARG) {
      s = GetSwtArg();
      if (strlen(s) != 1)
         HError(6601, "HMgeTool: Bad switch %s; must be single letter", s);
      switch (s[0]) {
      case 'a':
         nMaxBAIter = GetChkedInt(1, 1000, s);
         nMaxBALen = GetChkedInt(1, 1000, s);
         break;
      case 'b':
         mtInfo->bBoundAdj = TRUE;
         nBAEndIter = GetChkedInt(0, 1000, s);
         nBoundAdjWin = GetChkedInt(1, 1000, s);
         break;
      case 'c':
         outProcData = TRUE;
         break;
      case 'd':
         if (NextArg() != STRINGARG)
            HError(6601, "HMgeTool: HMM definition directory expected");
         hmmDir = GetStrArg();
         break;
      case 'e':
         mtInfo->bStepLimit = TRUE;
         break;
      case 'f':
         frameRate = (HTime) GetChkedFlt(0.0, 10000000.0, s);
         break;
      case 'g':
         mtInfo->bMVar = TRUE;
         break;
      case 'i':
         startIter = GetChkedInt(0, 1000, s);
         endIter = GetChkedInt(startIter, 1000, s);
         break;
      case 'j':
         funcType = GetChkedInt(0, 2, s);
         mtInfo->funcType = funcType;
         break;
      case 'l':
         if (NextArg() != STRINGARG)
            HError(6601, "HMgeTool: Label file output directory expected");
         outLabDir = GetStrArg();
         break;
      case 'o':
         if (NextArg() != STRINGARG)
            HError(6601, "HMgeTool: HMM file extension expected");
         outExt = GetStrArg();
         break;
      case 'p':
         A_STEP = GetChkedFlt(0.0, 10000000.0, s);
         B_STEP = GetChkedFlt(0.0, 10000000.0, s);
         break;
      case 'r':
         mtInfo->bOrigHmmRef = TRUE;
         if (NextArg() != STRINGARG)
            HError(6601, "HMgeTool: HMM macro file name expected");
         s = GetStrArg();
         AddMMF(&orighset, s);
         break;
      case 's':                /* updating scale file */
         scalefn = GetStrArg();
         break;
      case 'u':
         SetuFlags();
         break;
      case 'v':
         MSDthresh = GetChkedFlt(0.0, 1.0, s);
         break;
      case 'w':
         fGVDistWght = GetChkedFlt(0.0, 1000.0, s);
         break;
      case 'x':
         if (NextArg() != STRINGARG)
            HError(6601, "HMgeTool: HMM file extension expected");
         hmmExt = GetStrArg();
         break;
      case 'B':
         inBinary = TRUE;
         break;
      case 'G':
         mtInfo->nGainStreamIndex = GetChkedInt(1, SMAX, s);
         mtInfo->nGainDimIndex = GetChkedInt(1, 1000, s);
         if (NextArg() == FLOATARG || NextArg() == INTARG)
            mtInfo->fGainWghtComp = GetChkedFlt(-10000.0, 1000000.0, s);
         break;
      case 'H':
         if (NextArg() != STRINGARG)
            HError(6601, "HMgeTool: HMM macro file name expected");
         mmfFn = GetStrArg();
         AddMMF(&hset, mmfFn);
         break;
      case 'I':
         if (NextArg() != STRINGARG)
            HError(6601, "HMgeTool: MLF file name expected");
         LoadMasterFile(GetStrArg());
         break;
      case 'J':                /* regression class and tree */
         if (NextArg() != STRINGARG)
            HError(6601, "HMgeTool: HMM regression class/tree file name expected");
         s = GetStrArg();
         AddMMF(&hset, s);
         AddMMF(&orighset, s);
         break;
      case 'K':
         if (NextArg() != STRINGARG)
            HError(6601, "HMgeTool: HMM transform file name expected");
         xformfn = GetStrArg();
         break;
      case 'L':
         if (NextArg() != STRINGARG)
            HError(6601, "HMgeTool: Label file directory expected");
         labDir = GetStrArg();
         break;
      case 'M':
         if (NextArg() != STRINGARG)
            HError(6601, "HMgeTool: Output macro file directory expected");
         outDir = GetStrArg();
         break;
      case 'T':
         trace = GetChkedInt(0, 0100000, s);
         break;
      case 'X':
         if (NextArg() != STRINGARG)
            HError(2319, "HMGenS: Label file extension expected");
         labExt = GetStrArg();
         break;
      default:
         HError(6601, "HMgeTool: Unknown switch %s", s);
      }
   }

   if (NextArg() != STRINGARG)
      HError(6601, "HMgeTool: file name of model list expected");
   hmmListFn = GetStrArg();
   Initialise();

   if (funcType == MGE_EVAL) {
      PerformMgeEval();
   } else if (funcType == MGE_TRAIN) {
      PerformMgeTrain();
      if (endIter > 0 && bMgeUpdate) {
         /* output HMM files */
         ConvDiagC(&hset, TRUE);
         SaveHMMSet(&hset, outDir, outExt, NULL, inBinary);
      }
   } else if (funcType == MGE_ADAPT) {
      PerformMgeAdapt();
      if (endIter > 0 && bMgeUpdate) {
         MakeFN(xformfn, outDir, NULL, fname);
         SaveOneXForm(&hset, hset.curXForm, fname, FALSE);
      }
   }

   ResetHeap(&hmmStack);
   ResetHeap(&orighmmStack);
   ResetHeap(&accStack);
   ResetHeap(&genStack);
   ResetHeap(&mgeStack);

   return 0;
}
示例#4
0
int main(){
int listen_sock;
int server_len, client_len;
struct sockaddr_in server_address;
struct sockaddr_in client_address;

listen_sock = socket(AF_INET, SOCK_STREAM, 0);
if (listen_sock == -1)
 {
    printf("khong tao duoc socket\n");
    return 0;
 }
 printf("Tao socket thanh cong\n");

server_address.sin_family = AF_INET;
inet_aton("127.0.0.1",&server_address.sin_addr);
server_address.sin_port = htons(5500);
server_len = sizeof(server_address);

if(bind(listen_sock, (struct sockaddr *)&server_address,server_len)<0)
{
	printf("bind failed.\n");
    return 0;
}
printf("bind done\n");
int check = listen(listen_sock, 10);
if (check == -1)
 {
 printf("error");
 return 0;
 }
printf("waiting connect ...\n");
while(1) {

client_len = sizeof(client_address);
conn_sock = accept(listen_sock,(struct sockaddr *)&client_address, &client_len);
if(conn_sock==-1){
	printf("error connect\n");
	return 0;
}else{
	printf("Accept new connection\n");
}
if(fork() == 0){
	close(listen_sock);
    //thiet lap truyen nhan giu lieu lien tuc
	int sentBytes,revedBytes,i;
    time_t start;
    struct tm * timeinfo;
    char name[30];
    char pass[16];
    struct userinfo acc1;
    char s[2]="|";
    char *token;
    int flag;
    char str_flag[3];
    char filename[]="data.txt";
    int stop = 0;
    FILE *f;
    FILE *result;
    int login;
    while((revedBytes = recv(conn_sock,buff,1024,0)) >= 0){
        buff[revedBytes]='\0';
        token = strtok(buff, s);
        strcpy(str_flag,token);
        flag=atoi(str_flag);
        //nhan va kiem tra co bao
        switch(flag){
            case 0:
                //kiem tra dang nhap neu dang nhap thang cong tra ve buff[0] = 5 
                //neu khong dung tra ve buff[0]=4 va buff[1] la ma loi
                printf("Dang nhap\n");
                token =strtok(NULL,s);
                strcpy(name,token);
                token=strtok(NULL,s);
                strcpy(pass,token);
                login = checklogin(name,pass);
                if(login==1){
                result =fopen(name,"w");
                buff[0] = 5;
                sentBytes = send(conn_sock,buff,1024,0);
                }else{
                    buff[0] = 4;
                    buff[1] = login;
                    sentBytes = send(conn_sock,buff,1024,0);
                }
            break;
            case 1: 
                token =strtok(NULL,s);
                strcpy(name,token);
                token=strtok(NULL,s);
                strcpy(pass,token);
                if(findAcc(name)==1){
                    buff[0] = 4;
                    buff[1] = 1;
                    buff[2] = '\0';
                    sentBytes = send(conn_sock,buff,1024,0);
                    break;
                }
                f =fopen(filename,"a");
                fprintf(f, "%s\t%s\n",name,pass );
                fclose(f);
                buff[0] = 5;
                buff[1] = '\0';
                sentBytes = send(conn_sock,buff,1024,0);
            break;
            case 2:
                side = 1 ;xside = 0;
                time (&start );
                timeinfo = localtime ( &start );
                fprintf(result,"IP address is: %s\n", inet_ntoa(client_address.sin_addr));
                fprintf (result,"time start :%s\n", asctime (timeinfo) );
                InitGen();
                while(1){
                    if(side == computerside){
                        ComputerThink();
                        printf("%d may choi\n",side);
                        fprintf(result,"%s-%s\n",indexChar(newmove.from),indexChar(newmove.dest));
                        UpdateNewMove();
                        buff[0] = 3;
                        buff[1] = newmove.from;
                        buff[2] = newmove.dest;
                        buff[3] = check_thua();stop = buff[3];
                        buff[4] = '\0';
                        send(conn_sock,buff,1024,0);
                        if(stop == 1)  break;
                    }
                    else 
                        if(GetHumanMove(0,1)==0){
                        fprintf(result,"%s-%s\t",indexChar(newmove.from),indexChar(newmove.dest));
                        UpdateNewMove();
                        printf("%d nguoi choi\n",side);                     
                        buff[0] = 3;
                        buff[1] = 1;
                        buff[2] = 0;
                        buff[3] = check_thang(); stop = buff[3];
                        buff[4] = '\0';
                        send(conn_sock,buff,1024,0);
                        //tra ve neu di thanh cong
                        if(stop == 1) break;
                    };
                    side = xside; xside = 1-xside;
                    printf("%d-%d-%d\n",side,newmove.from,newmove.dest);
            	}
            printf("Dung choi\n");
            time (&start );
            timeinfo = localtime ( &start );
            fprintf (result,"time end :%s\n", asctime (timeinfo));
            fclose(result);
            result = fopen(name,"r");
            while(!feof(result)){
                if (fgets(buff,81,result) != NULL ){
                sentBytes=send(conn_sock,buff,1024,0);
                }
            }
            buff[0] = 'Q';
            buff[1] = '\0';
            sentBytes=send(conn_sock,buff,1024,0);
            break;
            default:
            break;
        	    
        }
    }
    close(conn_sock);
    exit(0);
}
signal(SIGCHLD,sig_chld);
close(conn_sock);
}
return 1;
}
示例#5
0
int main(int argc, char *argv[])
{
   char *s;
   char *labfn;
   int numUtt;

   void Initialise(void);
   void DoGeneration(char *labfn);

   if (InitShell(argc, argv, hmgens_version, hmgens_vc_id) < SUCCESS)
      HError(2300, "HMGenS: InitShell failed");
   InitMem();
   InitMath();
   InitSigP();
   InitWave();
   InitLabel();
   InitModel();
   if (InitParm() < SUCCESS)
      HError(2300, "HMGenS: InitParm failed");
   InitUtil();
   InitFB();
   InitAdapt(&xfInfo_hmm, &xfInfo_dur);
   InitMap();
   InitGen();

   if (NumArgs() == 0)
      ReportUsage();

   CreateHeap(&genStack, "genStore", MSTAK, 1, 1.0, 80000, 400000);
   CreateHeap(&uttStack, "uttStore", MSTAK, 1, 0.5, 100, 1000);
   CreateHeap(&fbInfoStack, "FBInfoStore", MSTAK, 1, 0.5, 100, 1000);
   CreateHeap(&hmmStack, "HmmStore", MSTAK, 1, 1.0, 50000, 500000);
   CreateHeap(&dmStack, "dmStore", MSTAK, 1, 1.0, 50000, 500000);
   SetConfParms();
   CreateHMMSet(&hmset, &hmmStack, TRUE);
   CreateHMMSet(&dmset, &dmStack, TRUE);

   utt = (UttInfo *) New(&uttStack, sizeof(UttInfo));
   genInfo = (GenInfo *) New(&genStack, sizeof(GenInfo));
   fbInfo = (FBInfo *) New(&fbInfoStack, sizeof(FBInfo));

   while (NextArg() == SWITCHARG) {
      s = GetSwtArg();
      if (strlen(s) != 1)
         HError(9919, "HMGenS: Bad switch %s; must be single letter", s);
      switch (s[0]) {
      case 'a':
         xfInfo_hmm.useInXForm = TRUE;
         break;
      case 'b':
         xfInfo_dur.useInXForm = TRUE;
         break;
      case 'c':
         if (NextArg() != INTARG)
            HError(2119, "HMGenS: Parameter generation algorithm type value expected");
         type = (ParmGenType) GetChkedInt(CHOLESKY, FB, s);
         break;
      case 'd':
         if (NextArg() != STRINGARG)
            HError(2319, "HMGenS: HMM definition directory expected");
         hmmDir = GetStrArg();
         break;
      case 'e':
         useAlign = TRUE;
         break;
      case 'f':
         frameRate = (HTime) GetChkedFlt(0.0, 10000000.0, s);
         break;
      case 'g':
         minFrwdP = GetChkedFlt(0.0, 1000.0, s);
         break;
      case 'h':
         if (NextArg() != STRINGARG)
            HError(1, "Speaker name pattern expected");
         xfInfo_hmm.inSpkrPat = xfInfo_dur.inSpkrPat = GetStrArg();
         if (NextArg() == STRINGARG)
            xfInfo_hmm.paSpkrPat = xfInfo_dur.paSpkrPat = GetStrArg();
         if (NextArg() != SWITCHARG)
            HError(2319, "HMGenS: cannot have -h as the last option");
         break;
      case 'm':
         modelAlign = TRUE;
         break;
      case 'n':
         if (NextArg() != STRINGARG)
            HError(2319, "HMGenS: duration model definition directory expected");
         dmDir = GetStrArg();
         break;
      case 'p':
         outPdf = TRUE;
         break;
      case 'r':
         if (NextArg() != FLOATARG)
            HError(2119, "HMGenS: Speaking rate value (float) expected");
         speakRate = GetChkedFlt(0.0, 3.0, s);
         break;
      case 's':
         stateAlign = TRUE;
         break;
      case 't':
         pruneInit = GetChkedFlt(0.0, 1.0E20, s);
         if (NextArg() == FLOATARG || NextArg() == INTARG) {
            pruneInc = GetChkedFlt(0.0, 1.0E20, s);
            pruneLim = GetChkedFlt(0.0, 1.0E20, s);
         } else {
            pruneInc = 0.0;
            pruneLim = pruneInit;
         }
         break;
      case 'v':
         MSDthresh = GetChkedFlt(0.0, 1.0, s);
         break;
      case 'x':
         if (NextArg() != STRINGARG)
            HError(2319, "HMGenS: HMM file extension expected");
         hmmExt = GetStrArg();
         break;
      case 'y':
         if (NextArg() != STRINGARG)
            HError(2319, "HMGenS: duration model file extension expected");
         dmExt = GetStrArg();
         break;
      case 'B':
         inBinary = TRUE;
         break;
      case 'E':
         if (NextArg() != STRINGARG)
            HError(2319, "HMGenS: parent transform directory expected");
         xfInfo_hmm.usePaXForm = TRUE;
         xfInfo_hmm.paXFormDir = GetStrArg();
         if (NextArg() == STRINGARG)
            xfInfo_hmm.paXFormExt = GetStrArg();
         if (NextArg() != SWITCHARG)
            HError(2319, "HMGenS: cannot have -E as the last option");
         break;
      case 'G':
         if (NextArg() != STRINGARG)
            HError(2119, "HMGenS: Label File format expected");
         if ((lff = Str2Format(GetStrArg())) == ALIEN)
            HError(-2189, "HMGenS: Warning ALIEN Label file format set");
         break;
      case 'H':
         if (NextArg() != STRINGARG)
            HError(3219, "HMGenS: HMM MMF File name expected");
         AddMMF(&hmset, GetStrArg());
         break;
      case 'I':
         if (NextArg() != STRINGARG)
            HError(2319, "HMGenS: MLF file name expected");
         LoadMasterFile(GetStrArg());
         break;
      case 'J':
         if (NextArg() != STRINGARG)
            HError(2319, "HMGenS: input transform directory expected");
         AddInXFormDir(&hmset, GetStrArg());
         if (NextArg() == STRINGARG)
            xfInfo_hmm.inXFormExt = GetStrArg();
         if (NextArg() != SWITCHARG)
            HError(2319, "HMGenS: cannot have -J as the last option");
         break;
      case 'L':
         if (NextArg() != STRINGARG)
            HError(2319, "HMGenS: Label file directory expected");
         labDir = GetStrArg();
         break;
      case 'M':
         if (NextArg() != STRINGARG)
            HError(2319, "HMGenS: Output macro file directory expected");
         genDir = GetStrArg();
         break;
      case 'N':
         if (NextArg() != STRINGARG)
            HError(3219, "HMGenS: Duration MMF File name expected");
         AddMMF(&dmset, GetStrArg());
         break;
      case 'T':
         if (NextArg() != INTARG)
            HError(2119, "HMGenS: Trace value expected");
         trace = GetChkedInt(0, 0002, s);
         break;
      case 'W':
         if (NextArg() != STRINGARG)
            HError(2319, "HMGenS: parent duration transform directory expected");
         xfInfo_dur.usePaXForm = TRUE;
         xfInfo_dur.paXFormDir = GetStrArg();
         if (NextArg() == STRINGARG)
            xfInfo_dur.paXFormExt = GetStrArg();
         if (NextArg() != SWITCHARG)
            HError(2319, "HMGenS: cannot have -W as the last option");
         break;
      case 'X':
         if (NextArg() != STRINGARG)
            HError(2319, "HMGenS: Label file extension expected");
         labExt = GetStrArg();
         break;
      case 'Y':
         if (NextArg() != STRINGARG)
            HError(2319, "HMGenS: input duration transform directory expected");
         AddInXFormDir(&dmset, GetStrArg());
         if (NextArg() == STRINGARG) {
            if (xfInfo_dur.inXFormExt == NULL)
               xfInfo_dur.inXFormExt = GetStrArg();
            else
               HError(2319, "MGenS: only one input duration transform extension may be specified");
         }
         if (NextArg() != SWITCHARG)
            HError(2319, "HMGenS: cannot have -Y as the last option");
         break;
      default:
         HError(9919, "HMGenS: Unknown switch %s", s);
      }
   }
   if (NextArg() != STRINGARG)
      HError(2319, "HMGenS: file name of vocabulary list expected");

   Initialise();
   InitUttInfo(utt, FALSE);
   numUtt = 1;

   if (trace & T_TOP)
      SetTraceGen();

   /* generate parameter sequences */
   do {
      if (NextArg() != STRINGARG)
         HError(2319, "HMGenS: data file name expected");
      labfn = GetStrArg();

      /* track speakers */
      if (UpdateSpkrStats(&hmset, &xfInfo_hmm, labfn)) {
         if (!xfInfo_hmm.useInXForm)
            xfInfo_hmm.inXForm = NULL;
      }
      if (UpdateSpkrStats(&dmset, &xfInfo_dur, labfn)) {
         if (!xfInfo_dur.useInXForm)
            xfInfo_dur.inXForm = NULL;
         else
            ResetDMMPreComps(&dmset);
      }

      fbInfo->xfinfo_hmm = &xfInfo_hmm;
      fbInfo->xfinfo_dur = &xfInfo_dur;
      fbInfo->inXForm_hmm = xfInfo_hmm.inXForm;
      fbInfo->inXForm_dur = xfInfo_dur.inXForm;
      fbInfo->al_inXForm_hmm = xfInfo_hmm.al_inXForm;
      fbInfo->al_inXForm_dur = xfInfo_dur.al_inXForm;
      fbInfo->paXForm_hmm = xfInfo_hmm.paXForm;
      fbInfo->paXForm_dur = xfInfo_dur.paXForm;

      /* generate parameters */
      DoGeneration(labfn);
      numUtt++;
   } while (NumArgs() > 0);

   if (trace & T_TOP) {
      printf("Generation complete - average log prob per frame = %e (%d frames)\n", totalPr / totalT, totalT);
   }

   /* Reset stacks */
   Dispose(&fbInfoStack, fbInfo);
   Dispose(&genStack, genInfo);
   Dispose(&uttStack, utt);
   ResetHeap(&fbInfoStack);
   ResetHeap(&uttStack);
   ResetHeap(&genStack);
   ResetHeap(&dmStack);
   ResetHeap(&hmmStack);

   /* Reset modules */
   ResetGen();
   ResetAdapt(&xfInfo_hmm, &xfInfo_dur);
   ResetFB();
   ResetUtil();
   ResetParm();
   ResetModel();
   ResetLabel();
   ResetWave();
   ResetSigP();
   ResetMath();
   ResetMem();
   ResetShell();

   Exit(0);
   return (0);                  /* never reached -- make compiler happy */
}
示例#6
0
int CMainDlg::PlayFM(int loop)
{
	WAVEFORMATEX wf;
	wf.wFormatTag = WAVE_FORMAT_PCM;
	wf.nChannels = 1;
    wf.nSamplesPerSec = synthParams.isampleRate;
    wf.nAvgBytesPerSec = wf.nSamplesPerSec * 2;
	wf.nBlockAlign = 2; 
    wf.wBitsPerSample = 16;
	wf.cbSize = 0;

	StopPlaying();

	InitGen();

	DWORD atkSusSamples = (DWORD) (durAtkSus * synthParams.sampleRate);
	DWORD totalSamples = (DWORD) (durTotal * synthParams.sampleRate);
	// add room for silence at end to minimize "click" when player turns off.
	DWORD bufSize = totalSamples + (DWORD) (0.1 * synthParams.sampleRate);
	SampleValue *samples;

#ifdef USE_DIRECTSOUND
	HRESULT hr;
	if (dirSndObj == NULL)
	{
		hr = DirectSoundCreate(NULL, &dirSndObj, NULL);
		if (hr == S_OK)
		{
			hr = dirSndObj->SetCooperativeLevel(m_hWnd, DSSCL_NORMAL);
			if (hr != S_OK)
			{
				dirSndObj->Release();
				dirSndObj = NULL;
				MessageBox("Cannot open direct sound output", "Error", MB_OK|MB_ICONSTOP);
				return -1;
			}
		}
	}
	void *pAudio1 = NULL;
	void *pAudio2 = NULL;
	DWORD dwAudio1 = 0;
	DWORD dwAudio2 = 0;

	DSBUFFERDESC dsbd;
	dsbd.dwSize = sizeof(dsbd);
	dsbd.dwFlags = 0; 
	dsbd.dwBufferBytes = bufSize * 2;
	dsbd.dwReserved = 0; 
	dsbd.lpwfxFormat = &wf;
	
	hr = dirSndObj->CreateSoundBuffer(&dsbd, &dirSndBuf, NULL);
	if (hr != S_OK)
		return -1;
	hr = dirSndBuf->Lock(0, bufSize, &pAudio1, &dwAudio1, NULL, NULL, DSBLOCK_ENTIREBUFFER);
	if (hr != S_OK)
	{
		MessageBox("Cannot create direct sound buffer", "Error", MB_OK|MB_ICONSTOP);
		return -1;
	}
	samples = (SampleValue *) pAudio1;
#else
	MMRESULT res; 
	if (woHandle == NULL)
	{
		res = waveOutOpen(&woHandle, WAVE_MAPPER, &wf, (DWORD) m_hWnd, 0, CALLBACK_WINDOW);
		if (res != MMSYSERR_NOERROR)
		{
			MessageBox("Cannot open wave output", "Error", MB_OK|MB_ICONSTOP);
			return -1;
		}
	}

	memset(&wh, 0, sizeof(wh));
	wh.dwBufferLength = bufSize * sizeof(SampleValue);
	wh.lpData = (LPSTR) malloc(wh.dwBufferLength);
	if (wh.lpData == NULL)
	{
		MessageBox("Cannot create wave out buffer", "Error", MB_OK|MB_ICONSTOP);
		return -1;
	}

	res = waveOutPrepareHeader(woHandle, &wh, sizeof(wh));
	samples = (SampleValue *) wh.lpData;
#endif

	DWORD n = 0; 
	while (n++ < atkSusSamples)
		*samples++ = (SampleValue) (Generate() * synthParams.sampleScale);
	NoteOff();
	while (!gen1EG.IsFinished() && n++ < bufSize)
		*samples++ = (SampleValue) (Generate() * synthParams.sampleScale);
	while (n++ < bufSize)
		*samples++ = 0;

#ifdef USE_DIRECTSOUND
	dirSndBuf->Unlock(pAudio1, dwAudio1, pAudio2, dwAudio2);
	dirSndBuf->Play(0, 0, loop ? DSBPLAY_LOOPING : 0);
	if (!loop)
		idTimer = SetTimer(1, (UINT) (durTotal * 1000.0) + 500);
#else
	if (loop)
	{
		wh.dwFlags |= WHDR_BEGINLOOP | WHDR_ENDLOOP;
		wh.dwLoops = 100;
	}
	waveOutWrite(woHandle, &wh, sizeof(wh));
#endif

	return 0;
}