⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mp3data.c

📁 编译后直接运行的MP3播放器全部C语言源代码 一个包含FAT文件系统、系统引导 Boot、FLASH Driver等内容的
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************** *             __________               __   ___. *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  / *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  < *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \ *                     \/            \/     \/    \/            \/ * $Id: mp3data.c,v 1.21 2004/01/13 14:06:18 linusnielsen Exp $ * * Copyright (C) 2002 by Daniel Stenberg * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************//* * Parts of this code has been stolen from the Ample project and was written * by David H鋜deman. It has since been extended and enhanced pretty much by * all sorts of friendly Rockbox people. * * A nice reference for MPEG header info: * http://rockbox.haxx.se/docs/mpeghdr.html * */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stdbool.h>#include "debug.h"#include "mp3data.h"#include "file.h"#include "buffer.h"#define DEBUG_VERBOSE#define BYTES2INT(b1,b2,b3,b4) (((b1 & 0xFF) << (3*8)) | \                                ((b2 & 0xFF) << (2*8)) | \                                ((b3 & 0xFF) << (1*8)) | \                                ((b4 & 0xFF) << (0*8)))#define SYNC_MASK (0x7ff << 21)#define VERSION_MASK (3 << 19)#define LAYER_MASK (3 << 17)#define PROTECTION_MASK (1 << 16)#define BITRATE_MASK (0xf << 12)#define SAMPLERATE_MASK (3 << 10)#define PADDING_MASK (1 << 9)#define PRIVATE_MASK (1 << 8)#define CHANNELMODE_MASK (3 << 6)#define MODE_EXT_MASK (3 << 4)#define COPYRIGHT_MASK (1 << 3)#define ORIGINAL_MASK (1 << 2)#define EMPHASIS_MASK 3/* Table of bitrates for MP3 files, all values in kilo. * Indexed by version, layer and value of bit 15-12 in header. */const int bitrate_table[2][3][16] ={    {        {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0},        {0,32,48,56, 64,80, 96, 112,128,160,192,224,256,320,384,0},        {0,32,40,48, 56,64, 80, 96, 112,128,160,192,224,256,320,0}    },    {        {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,0},        {0, 8,16,24,32,40,48, 56, 64, 80, 96,112,128,144,160,0},        {0, 8,16,24,32,40,48, 56, 64, 80, 96,112,128,144,160,0}    }};/* Table of samples per frame for MP3 files. * Indexed by layer. Multiplied with 1000. */const int bs[3] = {384000, 1152000, 1152000};/* Table of sample frequency for MP3 files. * Indexed by version and layer. */const int freqtab[][4] ={    {11025, 12000, 8000, 0},  /* MPEG version 2.5 */    {44100, 48000, 32000, 0}, /* MPEG Version 1 */    {22050, 24000, 16000, 0}, /* MPEG version 2 */};/* check if 'head' is a valid mp3 frame header */static bool is_mp3frameheader(unsigned long head){    if ((head & SYNC_MASK) != (unsigned long)SYNC_MASK) /* bad sync? */        return false;    if ((head & VERSION_MASK) == (1 << 19)) /* bad version? */        return false;    if (!(head & LAYER_MASK)) /* no layer? */        return false;    if ((head & BITRATE_MASK) == BITRATE_MASK) /* bad bitrate? */        return false;    if (!(head & BITRATE_MASK)) /* no bitrate? */        return false;    if ((head & SAMPLERATE_MASK) == SAMPLERATE_MASK) /* bad sample rate? */        return false;    if (((head >> 19) & 1) == 1 &&        ((head >> 17) & 3) == 3 &&        ((head >> 16) & 1) == 1)        return false;    if ((head & 0xffff0000) == 0xfffe0000)        return false;        return true;}static bool mp3headerinfo(struct mp3info *info, unsigned long header){    int bittable = 0;    int bitindex;    int freqindex;        /* MPEG Audio Version */    switch(header & VERSION_MASK) {    case 0:        /* MPEG version 2.5 is not an official standard */        info->version = MPEG_VERSION2_5;        bittable = MPEG_VERSION2 - 1; /* use the V2 bit rate table */        break;            case (1 << 19):        return false;            case (2 << 19):        /* MPEG version 2 (ISO/IEC 13818-3) */        info->version = MPEG_VERSION2;        bittable = MPEG_VERSION2 - 1;        break;            case (3 << 19):        /* MPEG version 1 (ISO/IEC 11172-3) */        info->version = MPEG_VERSION1;        bittable = MPEG_VERSION1 - 1;        break;    }    switch(header & LAYER_MASK) {    case 0:        return false;    case (1 << 17):        info->layer = 2;        break;    case (2 << 17):        info->layer = 1;        break;    case (3 << 17):        info->layer = 0;        break;    }    info->protection = (header & PROTECTION_MASK)?true:false;        /* Bitrate */    bitindex = (header & 0xf000) >> 12;    info->bitrate = bitrate_table[bittable][info->layer][bitindex];    if(info->bitrate == 0)        return false;        /* Sampling frequency */    freqindex = (header & 0x0C00) >> 10;    info->frequency = freqtab[info->version][freqindex];    if(info->frequency == 0)        return false;    info->padding = (header & 0x0200)?1:0;        /* Calculate number of bytes, calculation depends on layer */    switch(info->layer) {    case 0:        info->frame_size = info->bitrate * 48000;        info->frame_size /=            freqtab[info->version][freqindex] << bittable;        break;    case 1:    case 2:        info->frame_size = info->bitrate * 144000;        info->frame_size /=            freqtab[info->version][freqindex] << bittable;        break;    default:        info->frame_size = 1;    }        info->frame_size += info->padding;    /* Calculate time per frame */    info->frame_time = bs[info->layer] /        (freqtab[info->version][freqindex] << bittable);    info->channel_mode = (header & 0xc0) >> 6;    info->mode_extension = (header & 0x30) >> 4;    info->emphasis = header & 3;#ifdef DEBUG_VERBOSE    DEBUGF( "Header: %08x, Ver %d, lay %d, bitr %d, freq %d, "            "chmode %d, mode_ext %d, emph %d, bytes: %d time: %d\n",            header, info->version, info->layer, info->bitrate, info->frequency,            info->channel_mode, info->mode_extension,            info->emphasis, info->frame_size, info->frame_time);#endif    return true;}static unsigned long __find_next_frame(int fd, int *offset, int max_offset, unsigned long last_header, int(*getfunc)(int fd, unsigned char *c)){    unsigned long header=0;    unsigned char tmp;    int i;    int pos = 0;    /* We remember the last header we found, to use as a template to see if       the header we find has the same frequency, layer etc */    last_header &= 0xffff0c00;        /* Fill up header with first 24 bits */    for(i = 0; i < 3; i++) {        header <<= 8;        if(!getfunc(fd, &tmp))            return 0;        header |= tmp;        pos++;    }    do {        header <<= 8;        if(!getfunc(fd, &tmp))            return 0;        header |= tmp;        pos++;        if(max_offset > 0 && pos > max_offset)            return 0;    } while(!is_mp3frameheader(header) ||            (last_header?((header & 0xffff0c00) != last_header):false));    *offset = pos - 4;#if defined(DEBUG) || defined(SIMULATOR)    if(*offset)        DEBUGF("Warning: skipping %d bytes of garbage\n", *offset);#endif        return header;}static int fileread(int fd, unsigned char *c){    return read(fd, c, 1);}unsigned long find_next_frame(int fd, int *offset, int max_offset, unsigned long last_header){    return __find_next_frame(fd, offset, max_offset, last_header, fileread);}static int fnf_read_index;static int fnf_buf_len;static int buf_getbyte(int fd, unsigned char *c){    if(fnf_read_index < fnf_buf_len)    {        *c = mp3buf[fnf_read_index++];        return 1;    }    else    {        fnf_buf_len = read(fd, mp3buf, mp3end - mp3buf);        if(fnf_buf_len < 0)            return -1;        fnf_read_index = 0;        if(fnf_buf_len > 0)        {            *c = mp3buf[fnf_read_index++];            return 1;        }        else            return 0;    }    return 0;}static int buf_seek(int fd, int len){    fnf_read_index += len;    if(fnf_read_index > fnf_buf_len)    {        len = fnf_read_index - fnf_buf_len;                fnf_buf_len = read(fd, mp3buf, mp3end - mp3buf);        if(fnf_buf_len < 0)            return -1;        fnf_read_index = 0;        fnf_read_index += len;    }        if(fnf_read_index > fnf_buf_len)    {        return -1;    }    else        return 0;}static void buf_init(void){    fnf_buf_len = 0;    fnf_read_index = 0;}unsigned long buf_find_next_frame(int fd, int *offset, int max_offset,                                  unsigned long last_header){    return __find_next_frame(fd, offset, max_offset, last_header, buf_getbyte);}static int mp3buflen;static int mem_pos;static int mem_cnt;static int mem_maxlen;static int mem_getbyte(int dummy, unsigned char *c){    dummy = dummy;        *c = mp3buf[mem_pos++];    if(mem_pos >= mp3buflen)        mem_pos = 0;    if(mem_cnt++ >= mem_maxlen)        return 0;    else        return 1;}unsigned long mem_find_next_frame(int startpos, int *offset, int max_offset,                                  unsigned long last_header){    mp3buflen = mp3end - mp3buf;    mem_pos = startpos;    mem_cnt = 0;    mem_maxlen = max_offset;    return __find_next_frame(0, offset, max_offset, last_header, mem_getbyte);}int get_mp3file_info(int fd, struct mp3info *info){    unsigned char frame[1800];    unsigned char *vbrheader;    unsigned long header;    int bytecount;    int num_offsets;    int frames_per_entry;    int i;    int offset;    int j;    int tmp;    header = find_next_frame(fd, &bytecount, 0x20000, 0);    /* Quit if we haven't found a valid header within 128K */    if(header == 0)        return -1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -