This design idea: first open a normal WAV audio file, from the 44 bytes in front of the defined file header, remove the file header definition message, placed in a file header structure. Then open the ALSA audio driver, from the file header structure to remove the sampling accuracy, the number of channels, sampling frequency three important parameters, using the ALSA audio-driven API set parameters, finally open the WAV file, locate the data area, the audio data is written to the audio drive, start playing, when the write is complete, Exits the Write loop.
Note: This design requires a ALSA Libasound-dev library, which requires a connection-lasound when compiling the link.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <alsa/asoundlib.h>
struct Wav_header
{
Char rld[4]; RiffSign Symbol
int Rlen;
Char wld[4]; //format type (wave)
Char fld[4]; "FMT"
int Flen; sizeof (wave format Matex)
Short wFormatTag; //encoding Format
Short wchannels; //Number of channels
int nsamplespersec; //Sampling Frequency
int Navgbitspersample;//waveFile Sample Size
Short wblockalign;//Block Alignment
Short wbitspersample; WAVEFile Sample Size
Char dld[4]; "Data"
int wsamplelength; //the size of the audio data
Wav_header;
int Set_pcm_play (FILE *fp);
int main (int argc,char *argv[])
{
if (argc!=2)
{
printf ("Usage:wav-player+wav file name\n");
exit (1);
}
int nread;
file *FP;
fp=fopen (argv[1], "RB");
if (fp==null)
{
perror ("Open File failed:\n");
exit (1);
}
nread=fread (&wav_header,1,sizeof (Wav_header), FP);
printf ("nread=%d\n", nread);
//printf ("RIFF&NBSP; logo%s\n ", Wav_header.rld);
printf ("File size Rlen:%d\n ", Wav_header.rlen);
printf ("wld=%s\n", wav_header.wld);
printf ("fld=%s\n", WAV_HEADER.FLD);
printf ("flen=%d\n", Wav_header.flen);
printf ("wformattag=%d\n", Wav_header.wformattag);
printf ("Number of channels:%d\n ", wav_header.wchannels);
printf ("Sample frequency:%d\n ", wav_header.nsamplespersec);
printf ("navgbitspersample=%d\n", wav_header.navgbitspersample);
printf ("wblockalign=%d\n", wav_header.wblockalign);
printf ("Number of bits sampled:%d\n ", wav_header.wbitspersample);
printf ("data=%s\n", WAV_HEADER.DLD);
printf ("wsamplelength=%d\n", wav_header.wsamplelength);
Set_pcm_play (FP);
return 0;
}
int Set_pcm_play (FILE *fp)
{
int RC;
int ret;
int size;
Snd_pcm_t* handle; PCI Device handle
snd_pcm_hw_params_t* params;//hardware information and PCM stream configuration
unsigned int val;
int dir=0;
snd_pcm_uframes_t frames;
Char *buffer;
int channels=wav_header.wchannels;
int frequency=wav_header.nsamplespersec;
int bit=wav_header.wbitspersample;
int datablock=wav_header.wblockalign;
unsigned char ch[100]; //the header information used to store WAV files
Rc=snd_pcm_open (&handle, "Default", Snd_pcm_stream_playback, 0);
if (rc<0)
{
Perror ("\nopen PCM device failed:");
Exit (1);
}
Snd_pcm_hw_params_alloca (¶ms); //assigning the params structure body
if (rc<0)
{
Perror ("\nsnd_pcm_hw_params_alloca:");
Exit (1);
}
Rc=snd_pcm_hw_params_any (handle, params);//InitializeParams
if (rc<0)
{
Perror ("\nsnd_pcm_hw_params_any:");
Exit (1);
}
Rc=snd_pcm_hw_params_set_access (handle, params, snd_pcm_access_rw_interleaved); Initializing access rights
if (rc<0)
{
Perror ("\nsed_pcm_hw_set_access:");
Exit (1);
}
//number of sample bits
Switch (BIT/8)
{
Case 1:snd_pcm_hw_params_set_format (handle, params, snd_pcm_format_u8);
break;
Case 2:snd_pcm_hw_params_set_format (handle, params, snd_pcm_format_s16_le);
break;
Case 3:snd_pcm_hw_params_set_format (handle, params, snd_pcm_format_s24_le);
break;
}
Rc=snd_pcm_hw_params_set_channels (handle, params, channels); //set channel, 1 for mono > channel, 2 for stereo
if (rc<0)
{
Perror ("\nsnd_pcm_hw_params_set_channels:");
Exit (1);
}
val = frequency;
Rc=snd_pcm_hw_params_set_rate_near (handle, params, &val, &dir); //Settings > Frequency
if (rc<0)
{
Perror ("\nsnd_pcm_hw_params_set_rate_near:");
Exit (1);
}
rc = Snd_pcm_hw_params (handle, params);
if (rc<0)
{
Perror ("\nsnd_pcm_hw_params:");
Exit (1);
}
Rc=snd_pcm_hw_params_get_period_size (params, &frames, &dir); /*Get Cycle
length*/
if (rc<0)
{
Perror ("\nsnd_pcm_hw_params_get_period_size:");
Exit (1);
}
Size = frames * DATABLOCK; /*4 represents fast data length*/
Buffer = (char*) malloc (size);
Fseek (Fp,58,seek_set); Locate the song to the data area
while (1)
{
memset (buffer,0,sizeof (buffer));
RET = fread (buffer, 1, size, FP);
if (ret = = 0)
{
printf ("Song write End\ n ");
Break
}
else if (ret! = size)
{
}
Write audio data to PCM devices
while (ret = Snd_pcm_writei (handle, buffer, frames) <0)
{
Usleep (2000);
if (ret = =-epipe)
{
/* Epipe means underrun */
fprintf (stderr, "underrun occurred\n");
Complete the hardware parameter settings to make the device ready.
Snd_pcm_prepare (handle);
}
else if (Ret < 0)
{
fprintf (stderr,
"Error from Writei:%s\n",
Snd_strerror (ret));
}
}
}
Snd_pcm_drain (handle);
Snd_pcm_close (handle);
Free (buffer);
return 0;
}
WAV file parsing and playback program based on Linux ALSA audio driver Dongfang