⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 playmix.cpp

📁 大量的汇编程序源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
   dspout(dspcmdDMADAC);       /* program dsp for dma mode dac */
   dspout(count & 0xFF);       /* block size low byte */
   dspout(count >> 8);         /* high byte */
#endif
}



void SetMixer(void)
/* Resets the Sound Blaster card and sets the volume levels in the SB-PRO
 * mixer chip.
 */
{

   unsigned int val;

   outp(dspaddrReset,1);       /* reset DSP */
   delay(1);
   outp(dspaddrReset,0);
   dspin(&val);
   if (val!=dspReady)
      printf("SBPRO not ready.");

   outp(mixeraddr,MICVOL);
   outp(mixerdata,0);          /* turn mic vol off */
   outp(mixeraddr,VOCVOL);
   outp(mixerdata,0xFF);       /* both chans up */
   outp(mixeraddr,MASTERVOL);
   outp(mixerdata,0xFF);       /* master up */
   dspout(0xD1);               /* turn speaker on*/
}



void interrupt OutputDMAend(...)
/* This is the playback interrupt service routine.  It acknowledges the
 * interrupt, reprograms the sound blaster card and the DMA controller for
 * another buffer transfer, and sends and End Of Interrupt to the interrupt
 * controller.
 */
{
   inp(dspaddrDataAvail);  /* acknowledge interrupt */

   BusyBuf ^= 1;  /* toggle BusyBuf because other buffer is now busy */
#ifdef AUTOINIT
   /* no re-programming necessary. */
#else
   if (BusyBuf) {
      SetupOutputDMA(page1,offset1,count,outtc);
   } else {
      SetupOutputDMA(page0,offset0,count,outtc);
   }
#endif

   outp(PICMODE,PICEOI);    /* end of interrupt */
}




void FillBuffer(void)
/* Fills the buffer specified to BufToFill with data from the VOC file. */
{
   unsigned char *ptr;
   unsigned int i;

   if (BufToFill)
      ptr=buf1;
   else ptr=buf0;

   for (i=0; i<BUFSIZE; i++)
      *ptr++ = (v1.GetSample() + v2.GetSample()) >> 1;

   BufToFill ^= 1;  /* toggle so BufToFill specifies other one */
}



void PrintShiftStat(void)
{
   gotoxy(1,14);
   printf("File 2 pitch shifting: %3s",v2pitchshift ? "ON":"OFF");
}


void NewShift(int skip)
{
   v2.SetShiftAmount(skip);
   gotoxy(1,15);
   printf("skip amount: %7u\r",skip);
}


void SetFile1Repeat(boolean repeat)
{
   v1.SetRepeat(v1repeat=repeat);
   gotoxy(1,11);
   printf("File 1 repeat: %3s",v1repeat ? "ON" : "OFF");
}


void SetFile2Repeat(boolean repeat)
{
   v2.SetRepeat(v2repeat=repeat);
   gotoxy(1,12);
   printf("File 2 repeat: %3s",v2repeat ? "ON" : "OFF");
}


void SetupScreen(void)
{
   clrscr();
   printf("VOC file mixing and pitch shift sample program.\n\n");
   printf("File 1: %s\n",filename1);
   printf("File 2: %s\n\n",filename2);
   printf("F1 - Toggle file 1 repeat             F3 - Reset file 1\n");
   printf("F2 - Toggle file 2 repeat             F4 - Reset file 2\n");
   printf("SPACE - Toggle file 2 pitch shift     L/R arrows - shift pitch\n");
   printf("ESC to quit.\n\n");
}


void appendvoc(char *fname)
/* Appends the .voc extension to a filename, if necessary. */
{
   char drive[MAXDRIVE], dir[MAXDIR], name[MAXFILE], ext[MAXEXT];

   fnsplit(fname, drive, dir, name, ext);  /* split fname into components */

   if (strlen(ext)==0)                     /* if there's no extension */
      strcpy(ext,".voc");                  /* add .voc */

   fnmerge(fname, drive, dir, name, ext);  /* recombine components */
}



void main(int argc, char *argv[])
{
   int i,c,err;
   void interrupt (*IRQsave)(...);
   unsigned long physaddr,endaddr;
   unsigned int masksave;
   boolean done=false;

   SegToPhys(buf0,BUFSIZE,&physaddr,&endaddr);
   if (BUFSIZE > PhysToPage(physaddr,endaddr,&page0,&offset0)) {
      printf("Page error.\n");
      exit(1);
      /* If this happens, you should dynamically allocate memory instead,
       * and don't use any blocks of memory that fail the above test.
       */
   }

   SegToPhys(buf1,BUFSIZE,&physaddr,&endaddr);
   if (BUFSIZE > PhysToPage(physaddr,endaddr,&page1,&offset1)) {
      printf("page error\n");
      exit(1);
      /* See comment above. */
   }

   clrscr();
   if (argc > 1)
      strcpy(filename1, argv[1]);
   else {
      printf("\n.voc file 1 name: ");
      scanf("%s",filename1);
   }
   appendvoc(filename1);

   if (argc > 2)
      strcpy(filename2, argv[2]);
   else {
      printf(".voc file 2 name: ");
      scanf("%s",filename2);
   }
   appendvoc(filename2);

   if (0 != (err=v1.open(filename1))) {
      printf("Error %d opening %s\n",err,filename1);
      exit(1);
   }

   if (0 != (err=v2.open(filename2))) {
      printf("Error %d opening %s\n",err,filename2);
      exit(1);
   }


   v2.SetPitchShift(v2pitchshift);

   SetupScreen();
   PrintShiftStat();
   SetFile1Repeat(true);
   SetFile2Repeat(true);


   for (i=0; i<BUFSIZE; i++) {
      buf0[i]=0;    /* Clear the buffers.  Not necessary, but good idea */
      buf1[i]=0;    /* in case something goes wrong. */
   }


   SetMixer();

   IRQsave=getvect(IRQ);              /* save the old interrupt vector */
   setvect(IRQ,OutputDMAend);         /* point to new ISR */

   BufToFill=0;
   FillBuffer();                      /* fill buffer 0 */
   BusyBuf=0;                         /* buffer 0 will start playing soon */

   masksave=inp(PICMASK);                 /* save mask to restore later */
   outp(PICMASK,(masksave & ~IRQmask));   /* enable interrupt */

#ifdef AUTOINIT
   SetupOutputDMA(page0,offset0,2*BUFSIZE,outtc); /* this will start buf0 playing */
#else
   SetupOutputDMA(page0,offset0,count,outtc);     /* this will start buf0 playing */
#endif

   do {
      while (!done && BufToFill==BusyBuf) {
         /* mainly wait until it's OK to refill BusyBuf, but check keyboard
          * in the mean time */
         if (kbhit()) {
            c=getch();
            switch (c) {
               case 0:
                  c=getch();
                  switch (c) {
                     case LEFTKEY:
                        v2skip += 1;
                        NewShift(v2skip);
                        break;
                     case RIGHTKEY:
                        if (v2skip>1)  /* don't let go to zero */
                           v2skip -= 1;
                        NewShift(v2skip);
                        break;
                     case F1KEY:
                        SetFile1Repeat((boolean)!v1repeat);
                        break;
                     case F2KEY:
                        SetFile2Repeat((boolean)!v2repeat);
                        break;
                     case F3KEY:
                        v1.ResetVOC();
                        break;
                     case F4KEY:
                        v2.ResetVOC();
                        break;
                  }
                  break;
               case SPACEKEY:
                  v2pitchshift= (boolean) !v2pitchshift;
                  v2.SetPitchShift(v2pitchshift);
                  PrintShiftStat();
                  break;
               case ESC:
                  done=true;
                  break;
            }
         }
      }
      FillBuffer();  /* refill the next buffer */
   } while (!done);


#ifdef AUTOINIT
   dspout(dspcmdHaltAuto);        /* stop auto-init DMA transfer */
#else
   dspout(dspcmdHaltDMA);         /* stop DMA transfer */
#endif


   outp(PICMASK, masksave);       /* restore interrupt mask */

   setvect(IRQ,IRQsave);          /* restore old vector */
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -