Search This Blog

Thursday, 14 July 2011

WAV file player in C

WAV file player in C

/****************************************************************
 WARNING: You need a HUGE memory model to run this.
****************************************************************/

//Include files
#include "ALLOC.H"
#include "DOS.H"
#include "CONIO.H"
#include "STDIO.H"


void main()
{
 char *name;
 printf("
 Enter the file name...:");
 scanf("%s",name);


 playwav(name,1.0);

}


void playwav(char wavefile[14],float delaytime);
struct WaveData {
  unsigned int SoundLength, Frequency;
  char *Sample;
};


struct HeaderType {
  long         RIFF;      //RIFF header
  char         NI1 [18];  //not important

  unsigned int Channels;  //channels 1 = mono; 2 = stereo
  long         Frequency; //sample frequency
  char         NI2 [6];   //not important
  char         BitRes;    //bit resolution 8/16 bit
  char         NI3 [12];  //not important
} Header;





struct WaveData Voice;         //Pointer to wave file


unsigned int    Base;          //Sound Blaster base address


char            WaveFile [25]; //File name for the wave file to be played


/****************************************************************
Checks to see if a Sound Blaster exists at a given address, returns true if Sound Blaster found, false if not.
****************************************************************/

int ResetDSP(unsigned int Test)
{
  //Reset the DSP
  outportb (Test + 0x6, 1);
  delay(10);
  outportb (Test + 0x6, 0);
  delay(10);
  //Check if (reset was succesfull
  if ((inportb(Test + 0xE) & 0x80 == 0x80) && (inportb(Test + 0xA) ==
0xAA))
  {
    //DSP was found
    Base = Test;
    return (1);
  }
  else
    //No DSP was found
    return (0);
}

/****************************************************************
Send a byte to the DSP (Digital Signal Processor) on the Sound Blaster
****************************************************************/

void WriteDSP(unsigned char Value)
{
  //Wait for the DSP to be ready to accept data
  while ((inportb(Base + 0xC) & 0x80) == 0x80);
  //Send byte

  outportb (Base + 0xC, Value);
}


/****************************************************************
Plays a part of the memory
****************************************************************/

void PlayBack (struct WaveData *Wave)
{
  long          LinearAddress;
  unsigned int  Page, OffSet;
  unsigned char TimeConstant;


  TimeConstant = (65536 - (256000000 / Wave->Frequency)) >> 8;
  WriteDSP(0x40);                  //DSP-command 40h - Set sample
frequency
  WriteDSP(TimeConstant);          //Write time constant


  //Convert pointer to linear address
  LinearAddress = FP_SEG (Wave->Sample);
  LinearAddress = (LinearAddress << 4) + FP_OFF (Wave->Sample);
  Page = LinearAddress >> 16;      //Calculate page
  OffSet = LinearAddress & 0xFFFF; //Calculate offset in the page

  /****************
      Note - this procedure only works with DMA channel 1
  ****************/

  outportb (0x0A, 5);              //Mask DMA channel 1
  outportb (0x0C, 0);              //Clear byte pointer
  outportb (0x0B, 0x49);           //Set mode

  /****************
      The mode consists of the following:
      0x49 = binary 01 00 10 01
                    |  |  |  |
                    |  |  |  +- DMA channel 01
                    |  |  +---- Read operation (the DSP reads from memory)
                    |  +------- Single cycle mode
                    +---------- Block mode
  ****************/


  outportb (0x02, OffSet & 0x100); //Write the offset to the DMA controller
  outportb (0x02, OffSet >> 8);


  outportb (0x83, Page);           //Write the page to the DMA controller


  outportb (0x03, Wave->SoundLength & 0x100);
  outportb (0x03, Wave->SoundLength >> 8);


  outportb (0x0A, 1);              //Unmask DMA channel



  WriteDSP(0x14);                  // DSP-command 14h - Single cycle
playback
  WriteDSP(Wave->SoundLength & 0xFF);
  WriteDSP(Wave->SoundLength >> 8);
}


/**************************************************************
Loads a wave file into memory. This procedure expects a _very_ standard wave header. It doesn't perform much error checking.
**************************************************************/

int LoadVoice (struct WaveData *Voice, char *FileName)
{
  FILE *WAVFile;


  //If it can't be opened...
  WAVFile = fopen(FileName, "rb");
  if (WAVFile == NULL) {
    //..display error message


    return (0);
  }


  //Return length of file for sound length minus 48 bytes for .WAV header
  fseek(WAVFile, 0L, SEEK_END);
  Voice->SoundLength = ftell (WAVFile) - 48;
  fseek(WAVFile, 0L, SEEK_SET);


  //Check RIFF header
  if (Voice->SoundLength > 32000) {




    if (Voice->SoundLength > 64000) {


      Voice->SoundLength = 64000;
    }
  }
  free(Voice->Sample);
  Voice->Sample = (char *)malloc(Voice->SoundLength); //Assign memory
  if (!Voice->Sample) {

    return (0);
  }


  //Load the sample data
  fread(&Header, 46, 1, WAVFile);


  //Check RIFF header
  if (Header.RIFF != 0x46464952) {
    printf ("Not a wave file
");
    return (0);
  }


  //Check channels
  if (Header.Channels != 1) {
    printf ("Not a mono wave file
");
    return (0);
  }


  //Check bit resolution
  if (Header.BitRes != 8) {
    printf ("Not an 8-bit wave file
");
    return (0);
  }


  Voice->Frequency = Header.Frequency;


  //Load the sample data
  fread(Voice->Sample, Voice->SoundLength + 2, 1, WAVFile);


  fclose (WAVFile); //Close the file


  return (1);
}


void playwav (char wavefile[14], float delaytime  )
{
  delaytime=1.0;
  if (ResetDSP (0x220)) {
    //at 220h
    printf ("");
  } else {
    if (ResetDSP (0x240)) {

      //at 240h
      printf ("");
    } else {
      //or none at all
      printf ("");
      return;
    }
  }




  //Load wave file
  if (LoadVoice (&Voice, wavefile)) {


    //Start playback
    PlayBack (&Voice);


    delay(delaytime*1000);


    //Stops DMA-transfer
    WriteDSP (0xD0);
  }
}

Read more: http://cmagical.blogspot.com/2011/03/wav-file-player-in-c.html#ixzz1S6BOnfaA 
Under Creative Commons License: Attribution Non-Commercial No Derivatives
Related Posts Plugin for WordPress, Blogger...