void player_get_song_info(struct fat_fileentry *file){ uint8_t buffer[56]; uint8_t xingoffset,i; uint32_t headersize=0; /* Look for ID3 tag */ fat_readfile(file,buffer,10); if(strncmp((char*)buffer,"ID3",3)==0){ //Save ID3 header size (4 unsynch. bytes, big-endian) = 28bytes headersize=buffer[9]; headersize|=((uint16_t)buffer[8]<<7); headersize|=((uint32_t)buffer[7]<<14); headersize|=((uint32_t)buffer[6]<<21); } /* Jump to first header */ fat_seek(file,file->pointer+headersize); fat_readfile(file,buffer,56); /* Fill some song information */ currentsong.mpeg=(buffer[1]>>3) & 0x3; if(currentsong.mpeg==MPEG_1){ i=0; }else{ i=1; } currentsong.layer=(3-((buffer[1]>>1) & 0x3)); currentsong.channel=buffer[3]>>6; currentsong.samples_per_sec=pgm_read_word(&samples_per_sec[currentsong.mpeg][((buffer[2]>>2)&0x3)]); currentsong.samples_per_frame=pgm_read_word(&samples_per_frame[i][currentsong.layer]); /* Determine XING offset */ if(currentsong.mpeg==MPEG_1 && currentsong.channel!=CHAN_MONO){ xingoffset=36; }else if(currentsong.mpeg==MPEG_2 && currentsong.channel==CHAN_MONO){ xingoffset=13; }else{ xingoffset=21; } /* Check if XING header exists */ if(strncmp((char*)&buffer[xingoffset], "Xing",4)==0 || strncmp((char*)&buffer[xingoffset], "Info",4)==0){ //Store the number of frames currentsong.frames=buffer[xingoffset+11]; currentsong.frames|=(uint16_t)buffer[xingoffset+10]<<8; currentsong.frames|=(uint32_t)buffer[xingoffset+9]<<16; currentsong.frames|=(uint32_t)buffer[xingoffset+8]<<24; //Store song length (in seconds) //TODO -> A fix for that :S? Inline fails...! //This commented line does not work //currentsong.length=(currentsong.frames*currentsong.samples_per_frame)/currentsong.samples_per_sec; //The following code works fine: currentsong.length=currentsong.frames; currentsong.length*=currentsong.samples_per_frame; currentsong.length/=currentsong.samples_per_sec; //Calculate song bitrate in kbps (average) currentsong.bitrate=(uint16_t)((file->size-(headersize+10))/currentsong.length)/125; }else{ //TODO -> Handle VBRI headers //Bitrate will be considered constant by now if XING header does not exist currentsong.bitrate=pgm_read_word(&bitrates[i][currentsong.layer][buffer[2]>>4]); currentsong.length=(file->size-(headersize+10))/(currentsong.bitrate*125); } //Restore file pointer to start. fat_seek(file, 0); }