1. Compile libmad
1. Download the compressed package to your local computer and decompress it.
Tar-xvzf libmad-0.15.1b.tar.gz.-C ./
2. Go to the source code folder and configure
Compile a configuration file to facilitate <modification and compilation>. The file content is as follows:
. /Configure cc = arm-Linux-GCC -- Host = arm-Linux -- Build = i686-pc-linux-gnu -- enable-FPM = arm -- enable-shared -- disable-debugging -- prefix =/home/Tang /WiFi-music/mplayer/libmad-0.15.1b_install
Run configuration and record information
3. Make compilation and recording information
Tips
Modify makefile and delete "-- Fforce-Mem"
4. Make install installation and record information
Tips
The Library and file to be called are libmad. so mad. h.
2. Write Program code
1. You can play the code in WAV and MP3 formats.
<Play-wav-or-mp3.c>
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <linux/types.h>#include <fcntl.h>#include <sys/types.h>#include <semaphore.h>#include <sys/stat.h> #include <string.h>#include <errno.h>#include <linux/soundcard.h>#include <termio.h>#include <getopt.h>#include <time.h>#include <strings.h>#include <signal.h>#include "wav.h"#include "mad.h"#include <sys/mman.h>#define SND_OUT_BUF_SIZE0x2000struct buffer { unsigned char const *start; unsigned long length;};int fd_sound;int n;int vol_val;int i=0;staticenum 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;}static signed int scale(mad_fixed_t sample){ /* round */ sample += (1L << (MAD_F_FRACBITS - 16)); /* clip */ if (sample >= MAD_F_ONE) sample = MAD_F_ONE - 1; else if (sample < -MAD_F_ONE) sample = -MAD_F_ONE; /* quantize */ return sample >> (MAD_F_FRACBITS + 1 - 16);}staticenum mad_flow output(void *data, struct mad_header const *header, struct mad_pcm *pcm){ unsigned short nchannels ,nsamples; unsigned int nsamplerate; unsigned char ldata,rdata; unsigned char outputbuf[8196],*outputptr; int write_num; mad_fixed_t const *left_ch, *right_ch; /* pcm->samplerate contains the sampling frequency */ nchannels = pcm->channels; nsamplerate = pcm->samplerate; n=nsamples = pcm->length; left_ch = pcm->samples[0]; right_ch = pcm->samples[1]; if(i==0){int bits_set=16;ioctl(fd_sound, SNDCTL_DSP_SYNC, &nsamplerate);ioctl(fd_sound, SOUND_PCM_WRITE_RATE, &nsamplerate);ioctl(fd_sound, SNDCTL_DSP_SETFMT, &bits_set);ioctl(fd_sound, SOUND_PCM_WRITE_CHANNELS, &nchannels);ioctl(fd_sound, SOUND_MIXER_WRITE_VOLUME, &vol_val);}i++; outputptr=outputbuf; while (nsamples--) { signed int sample; /* output sample(s) in 16-bit signed little-endian PCM */sample = scale(*left_ch++);ldata = (sample >> 0);rdata = (sample >> 8);//printf("ssss\n");*(outputptr++)=ldata;*(outputptr++)=rdata;//printf("buflen%d\n",strlen(outputbuf[i]));if (nchannels == 2) {sample = scale(*right_ch++);ldata = (sample >> 0);rdata = (sample >> 8);*(outputptr++)=ldata;*(outputptr++)=rdata;} }n*=4;outputptr=outputbuf;while(n){write_num=write(fd_sound,outputptr,n);outputptr+=write_num;n-=write_num; //printf("n:%d\n",n);}outputptr=outputbuf; return MAD_FLOW_CONTINUE;}staticenum mad_flow error(void *data, struct mad_stream *stream, struct mad_frame *frame){ struct buffer *buffer = data; fprintf(stderr, "decoding error 0x%04x (%s) at byte offset %u\n", stream->error, mad_stream_errorstr(stream), stream->this_frame - buffer->start); /* return MAD_FLOW_BREAK here to stop decoding (and propagate an error) */ return MAD_FLOW_CONTINUE;}static int decode(unsigned char const *start, unsigned long length){ struct buffer buffer; struct mad_decoder decoder; int result; /* initialize our private message structure */ buffer.start = start; buffer.length = length; /* configure input, output, and error functions */ mad_decoder_init(&decoder, &buffer, input, 0 /* header */, 0 /* filter */, output, error, 0 /* message */); /* start decoding */ result = mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC); /* release the decoder */ mad_decoder_finish(&decoder); return result;}int main(int argc, char **argv){if(argc < 3){printf("argc error\n");return -1;}int rate_set, bits_set, ch_set,fd_file_path=0,DataLen;char file_path[256]={0};int *psound_data_buf=NULL;struct stat stat;void *fdm;//ch_set=2;//bits_set=16;//rate_set=44100;if(sscanf(argv[1], "%s", &file_path)!= 1 ||sscanf(argv[2], "%d", &vol_val)!= 1){printf("argv error\n");return -1;}if(vol_val<0)vol_val=26;if(strcmp(&file_path[strlen(file_path)-4],".wav")!=0 && strcmp(&file_path[strlen(file_path)-4],".mp3")!=0){printf("file is not wav or mp3 farmat\n");return -1;}while((fd_sound = open("/dev/dsp",O_WRONLY)) == -1) { printf("Can not open /dev/dsp\n"); return -1; }fd_file_path = open(file_path,O_RDONLY);if(fd_file_path == -1){printf("fd_file_path open file error");goto exit;}if(strcmp(&file_path[strlen(file_path)-4],".wav")==0){wav_struct FileWav;psound_data_buf=(int *)malloc(SND_OUT_BUF_SIZE);if(psound_data_buf == NULL)goto exit;memset(&FileWav,0,sizeof(FileWav));if((DataLen = read(fd_file_path, &FileWav, sizeof(FileWav)))>0){if((strncmp(FileWav.rif_info.riff,RIFF_FIELD,strlen(RIFF_FIELD)) == 0)&&(strncmp(FileWav.rif_info.wave,WAVE_FIELD,strlen(WAVE_FIELD)) == 0)){rate_set=FileWav.fmt_info.sample_rate;ch_set=FileWav.fmt_info.channel_nb;bits_set=FileWav.fmt_info.bits_per_sample;}else{printf("wav head error\n");goto exit;}}else{goto exit;}//printf("sample:%d,channel:%d,bits:%d,vol_val:%d\n", rate_set,ch_set,bits_set,vol_val);ioctl(fd_sound, SNDCTL_DSP_SYNC, &rate_set);ioctl(fd_sound, SOUND_PCM_WRITE_RATE, &rate_set);ioctl(fd_sound, SNDCTL_DSP_SETFMT, &bits_set);ioctl(fd_sound, SOUND_PCM_WRITE_CHANNELS, &ch_set);ioctl(fd_sound, SOUND_MIXER_WRITE_VOLUME, &vol_val);while((DataLen=read(fd_file_path, psound_data_buf ,SND_OUT_BUF_SIZE))>0)write(fd_sound, psound_data_buf, DataLen);free(psound_data_buf);}/*mp3 play*/else if(strcmp(&file_path[strlen(file_path)-4],".mp3")==0){if(fstat(fd_file_path,&stat)==-1||stat.st_size==0)goto exit;fdm=mmap(0,stat.st_size,PROT_READ,MAP_SHARED,fd_file_path,0);if(fdm==MAP_FAILED)goto exit;decode(fdm,stat.st_size);}exit:if(munmap(fdm,stat.st_size)==-1){printf("munmap error\n");}if(fd_file_path>0){close(fd_file_path);fd_file_path=0;}if(fd_sound>0){close(fd_sound);fd_sound=0;}return 0;}
<WAV. h>
#ifndef _WAV_H_#define _WAV_H_/*_____ I N C L U D E S ____________________________________________________*//*_____ M A C R O S ________________________________________________________*/#define WAV_HEADER_SIZE sizeof(wav_struct)/* RIFF info */#define RIFF_FIELD "RIFF"#define WAVE_FIELD "WAVE"/* FMT info */#define FMT_FIELD "FMT "#define FMT_LENGTH ((unsigned long)(16)) /* data start beg of sector *//* wave format */#define PCM_FMT ((unsigned short)0x0100)/* channel number */#define MONO ((unsigned short)0x0100)#define STEREO ((unsigned short)0x0200)/* bytes per sample */#define ONE_BYTE ((unsigned short)0x0100)#define TWO_BYTE ((unsigned short)0x0200)/* bits per sample */#define EIGHT_BIT ((unsigned short)0x0800)#define SIXTEEN_BIT ((unsigned short)0x1000)/* DATA info */#define DATA_FIELD 'data'/*_____ D E F I N I T I O N ________________________________________________*//* WAV Format Structure */typedef struct{ /* RIFF info */ char riff[4]; unsigned long pack_length; char wave[4];} riff_struct;typedef struct{ /* FMT info */ char fmt[4]; unsigned long fmt_length; unsigned short wav_format; unsigned short channel_nb; unsigned long sample_rate; unsigned long bytes_per_second; unsigned short bytes_per_sample; unsigned short bits_per_sample;} fmt_struct;typedef struct{ /* DATA info */ char dat[4]; unsigned long data_length;} data_struct;typedef struct{ riff_struct rif_info; fmt_struct fmt_info; data_struct dat_info;} wav_struct;/*_____ D E C L A R A T I O N ______________________________________________*/#endif /* _WAV_H_ */
Dynamically compile arm-None-Linux-gnueabi-GCC play-wav-or-mp3.c-O play-wav-or-mp3-LMAD-L ./
Run./play-wav-or-mp3 xxx.mp3/WAV 70
Argc [1] indicates playing a song, And argc [2] indicates the volume.