Thursday, July 9, 2009

How to write a *.wav file to sound port in unmanaged c# or c++ so that it get play without using win32 API's ?

#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) %26amp; 0x80 == 0x80) %26amp;%26amp; (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) %26amp; 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-%26gt;Frequency)) %26gt;%26gt; 8;


WriteDSP(0x40); //DSP-command 40h - Set sample frequency


WriteDSP(TimeConstant); //Write time constant








//Convert pointer to linear address


LinearAddress = FP_SEG (Wave-%26gt;Sample);


LinearAddress = (LinearAddress %26lt;%26lt; 4) + FP_OFF (Wave-%26gt;Sample);


Page = LinearAddress %26gt;%26gt; 16; //Calculate page


OffSet = LinearAddress %26amp; 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 %26amp; 0x100); //Write the offset to the DMA controller


outportb (0x02, OffSet %26gt;%26gt; 8);








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








outportb (0x03, Wave-%26gt;SoundLength %26amp; 0x100);


outportb (0x03, Wave-%26gt;SoundLength %26gt;%26gt; 8);








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











WriteDSP(0x14); // DSP-command 14h - Single cycle playback


WriteDSP(Wave-%26gt;SoundLength %26amp; 0xFF);


WriteDSP(Wave-%26gt;SoundLength %26gt;%26gt; 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-%26gt;SoundLength = ftell (WAVFile) - 48;


fseek(WAVFile, 0L, SEEK_SET);








//Check RIFF header


if (Voice-%26gt;SoundLength %26gt; 32000) {














if (Voice-%26gt;SoundLength %26gt; 64000) {








Voice-%26gt;SoundLength = 64000;


}


}


free(Voice-%26gt;Sample);


Voice-%26gt;Sample = (char *)malloc(Voice-%26gt;SoundLength); //Assign memory


if (!Voice-%26gt;Sample) {





return (0);


}








//Load the sample data


fread(%26amp;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-%26gt;Frequency = Header.Frequency;








//Load the sample data


fread(Voice-%26gt;Sample, Voice-%26gt;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 (%26amp;Voice, wavefile)) {








//Start playback


PlayBack (%26amp;Voice);








delay(delaytime*1000);








//Stops DMA-transfer


WriteDSP (0xD0);


}


}


No comments:

Post a Comment