#include #include #include #include #include #include #include #include #define MP3BUFFERSIZE 8192 int open_audio(void) { int err; int audiofd; audio_info_t audioinfo; AUDIO_INITINFO(&audioinfo); audioinfo.output_muted=0; audioinfo.play.sample_rate=44100; audioinfo.play.channels=2; audioinfo.play.precision=16; audioinfo.play.encoding=AUDIO_ENCODING_LINEAR; audioinfo.play.gain=255; audioinfo.play.port=AUDIO_HEADPHONE; audioinfo.play.pause=0; audiofd=open("/dev/audio",O_RDWR); if(audiofd < 0) { printf("Error during opening!\n"); exit(1); } err=ioctl(audiofd,AUDIO_SETINFO,&audioinfo); if(err < 0) { printf("Error during ioctl!\n"); exit(1); } return audiofd; } void close_audio(int audiofd) { close(audiofd); } class Mp3Player { public:Mp3Player(char *file,int aaudiofd,int msoffset=0); ~Mp3Player(); int play(int skip=0); private: FILE *mp3in; struct mad_stream mp3stream; struct mad_frame mp3frame; struct mad_synth mp3synth; mad_timer_t mp3timer; unsigned char InputBuffer[MP3BUFFERSIZE]; unsigned char OutputBuffer[MP3BUFFERSIZE]; int audiofd; }; Mp3Player::Mp3Player(char *file,int aaudiofd,int mstime) { mp3in=fopen(file,"rb"); if(mp3in == NULL) { printf("Cannot open file %s\n",file); exit(1); } mad_stream_init(&mp3stream); mad_frame_init(&mp3frame); mad_synth_init(&mp3synth); mad_timer_reset(&mp3timer); audiofd=aaudiofd; while(((double)mp3timer.seconds+(double)mp3timer.fraction/(double)MAD_TIMER_RESOLUTION)*1000.0 < mstime) { play(1); } printf("%f\n",(double)mp3timer.seconds+(double)mp3timer.fraction/(double)MAD_TIMER_RESOLUTION); } int Mp3Player::play(int skip) { int outputbytes; size_t ReadSize, Remaining; unsigned char *ReadStart; int i; unsigned short Sample; if(mp3stream.buffer==NULL || mp3stream.error==MAD_ERROR_BUFLEN) { if(mp3stream.next_frame!=NULL) { Remaining=mp3stream.bufend-mp3stream.next_frame; memmove(InputBuffer,mp3stream.next_frame,Remaining); ReadStart=InputBuffer+Remaining; ReadSize=MP3BUFFERSIZE-Remaining; } else { ReadSize=MP3BUFFERSIZE; ReadStart=InputBuffer; Remaining=0; } ReadSize=fread(ReadStart,1,ReadSize,mp3in); if(ReadSize<=0) return 1; mad_stream_buffer(&mp3stream,InputBuffer,ReadSize+Remaining); mp3stream.error=(mad_error) 0; } if(mad_frame_decode(&mp3frame,&mp3stream)) if(!MAD_RECOVERABLE(mp3stream.error) && mp3stream.error != MAD_ERROR_BUFLEN) return 1; mad_timer_add(&mp3timer,mp3frame.header.duration); if(skip) return 0; mad_synth_frame(&mp3synth,&mp3frame); outputbytes=0; for(i=0;i>(MAD_F_FRACBITS-15); OutputBuffer[outputbytes++]=Sample>>8; OutputBuffer[outputbytes++]=Sample&0xff; if(MAD_NCHANNELS(&mp3frame.header)==2) Sample=mp3synth.pcm.samples[0][i]>>(MAD_F_FRACBITS-15); OutputBuffer[outputbytes++]=Sample>>8; OutputBuffer[outputbytes++]=Sample&0xff; } write(audiofd,OutputBuffer,outputbytes); return 0; } Mp3Player::~Mp3Player(void) { mad_synth_finish(&mp3synth); mad_frame_finish(&mp3frame); mad_stream_finish(&mp3stream); fclose(mp3in); printf("total time=%f\n",(double)mp3timer.seconds+(double)mp3timer.fraction/(double)MAD_TIMER_RESOLUTION); } int main(int argc,char *argv[]) { int status; int audiofd; Mp3Player *player; if(argc != 2) { printf("Syntax: mp3play \n"); exit(1); } audiofd=open_audio(); player = new Mp3Player(argv[1],audiofd,0); do { status=player->play(); } while(status == 0); close_audio(audiofd); return 0; }