# Include <stdio. h> # include <stdlib. h> # include <unistd. h> # include <sys/STAT. h> # include <sys/Mman. h> # include <sys/Soundcard. h> # include <sys/IOCTL. h> # include <sys/fcntl. h> # include <sys/types. h> # include "mad. H "struct buffer {unsigned char const * start; unsigned long length ;}; static int SFD;/* sound device descriptor */static int decode (unsigned char const *, unsigned long); int main (INT argc, Char * argv []) {struct Stat; void * OFDM; char const * file; int FD; file = argv [1]; FD = open (file, o_rdonly ); if (SFD = open ("/dev/DSP", o_wronly) <0) {printf ("can not open device !!! /N "); return 5;} IOCTL (SFD, sndctl_dsp_sync, 0);/* This sentence can be left blank */If (fstat (FD, & Stat) =-1 | stat. st_size = 0) return 2; OFDM = MMAP (0, stat. st_size, prot_read, map_shared, FD, 0); If (OFDM = map_failed) return 3; decode (OFDM, stat. st_size); If (munmap (OFDM, stat. st_size) =-1) return 4; IOCTL (SFD, sndctl_dsp_reset, 0); close (SFD); Return 0;} static Enum mad_flow input (void * data, struct mad_stream * Stream) {struct buffer * buffer = data; If (! Buffer-> length) return mad_flow_stop; mad_stream_buffer (stream, buffer-> Start, buffer-> length); buffer-> length = 0; return mad_flow_continue ;} /* This section is the PCM audio after processing the sample */static inline signed int Scale (mad_fixed_t sample) {sample + = (1l <(mad_f_fracbits-16 )); if (sample> = mad_f_one) Sample = mad_f_one-1; else if (sample <-mad_f_one) Sample =-mad_f_one; return sample> (mad_f_fracbits + 1-16 );} static Enum mad_flow output (void * data, struct mad_header const * Header, struct mad_pcm * PCM) {unsigned int nchannels, nsamples, N; mad_fixed_t const * left_ch, * right_ch; unsigned char output [6912], * outputptr; int FMT, wrote, speed; nchannels = PCM-> channels; n = nsamples = PCM-> length; left_ch = PCM-> samples [0]; right_ch = PCM-> samples [1]; FMt = afmt_s16_le; speed = PCM-> samplerate * 2; /* the playback speed is twice the sampling rate */IOCTL (SFD, sndctl_dsp_speed, & (speed); IOCTL (SFD, sndctl_dsp_setfmt, & FMT); IOCTL (SFD, sndctl_dsp_channels, & (PCM-> channels); outputptr = output; while (nsamples --) {signed int sample; sample = Scale (* left_ch ++); * (outputptr ++) = sample> 0; * (outputptr ++) = sample> 8; If (nchannels = 2) {sample = Scale (* right_ch ++ ); * (outputptr ++) = sample> 0; * (outputptr ++) = sample> 8 ;}} N * = 4; /* The data length is 4 times of PCM audio sampling */outputptr = output; while (n) {wrote = write (SFD, outputptr, n); outputptr + = wrote; n-= wrote;} outputptr = output; return mad_flow_continue;} static Enum mad_flow error (void * data, struct mad_stream * stream, struct mad_frame * frame) {return mad_flow_continue ;} static int decode (unsigned char const * Start, unsigned long length) {struct buffer; struct mad_decoder decoder; int result; buffer. start = start; buffer. length = length; mad_decoder_init (& decoder, & buffer, input, 0, 0, output, error, 0); mad_decoder_options (& decoder, 0); Result = mad_decoder_run (& decoder, mad_decoder_mode_sync); mad_decoder_finish (& decoder); return result ;}