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

📄 mp3data.c

📁 编译后直接运行的MP3播放器全部C语言源代码 一个包含FAT文件系统、系统引导 Boot、FLASH Driver等内容的
💻 C
📖 第 1 页 / 共 2 页
字号:
    memset(info, 0, sizeof(struct mp3info));    if(!mp3headerinfo(info, header))        return -2;    /* OK, we have found a frame. Let's see if it has a Xing header */    if(read(fd, frame, info->frame_size-4) < 0)        return -3;    /* calculate position of VBR header */    if ( info->version == MPEG_VERSION1 ) {        if (info->channel_mode == 3) /* mono */            vbrheader = frame + 17;        else            vbrheader = frame + 32;    }    else {        if (info->channel_mode == 3) /* mono */            vbrheader = frame + 9;        else            vbrheader = frame + 17;    }    if (vbrheader[0] == 'X' &&        vbrheader[1] == 'i' &&        vbrheader[2] == 'n' &&        vbrheader[3] == 'g')    {        int i = 8; /* Where to start parsing info */        DEBUGF("Xing header\n");        /* Remember where in the file the Xing header is */        info->vbr_header_pos = lseek(fd, 0, SEEK_CUR) - info->frame_size;                /* We want to skip the Xing frame when playing the stream */        bytecount += info->frame_size;                /* Now get the next frame to find out the real info about           the mp3 stream */        header = find_next_frame(fd, &tmp, 0x20000, 0);        if(header == 0)            return -4;        if(!mp3headerinfo(info, header))            return -5;        /* Yes, it is a VBR file */        info->is_vbr = true;        info->is_xing_vbr = true;                if(vbrheader[7] & VBR_FRAMES_FLAG) /* Is the frame count there? */        {            info->frame_count = BYTES2INT(vbrheader[i], vbrheader[i+1],                                          vbrheader[i+2], vbrheader[i+3]);            info->file_time = info->frame_count * info->frame_time;            i += 4;        }        if(vbrheader[7] & VBR_BYTES_FLAG) /* Is byte count there? */        {            info->byte_count = BYTES2INT(vbrheader[i], vbrheader[i+1],                                         vbrheader[i+2], vbrheader[i+3]);            i += 4;        }        if(info->file_time && info->byte_count)            info->bitrate = info->byte_count * 8 / info->file_time;        else            info->bitrate = 0;                if(vbrheader[7] & VBR_TOC_FLAG) /* Is table-of-contents there? */        {            memcpy( info->toc, vbrheader+i, 100 );        }    }    if (vbrheader[0] == 'V' &&        vbrheader[1] == 'B' &&        vbrheader[2] == 'R' &&        vbrheader[3] == 'I')    {        DEBUGF("VBRI header\n");        /* We want to skip the VBRI frame when playing the stream */        bytecount += info->frame_size;                /* Now get the next frame to find out the real info about           the mp3 stream */        header = find_next_frame(fd, &bytecount, 0x20000, 0);        if(header == 0)            return -6;                if(!mp3headerinfo(info, header))            return -7;        DEBUGF("%04x: %04x %04x ", 0, header >> 16, header & 0xffff);        for(i = 4;i < (int)sizeof(frame)-4;i+=2) {            if(i % 16 == 0) {                DEBUGF("\n%04x: ", i-4);            }            DEBUGF("%04x ", (frame[i-4] << 8) | frame[i-4+1]);        }        DEBUGF("\n");                /* Yes, it is a FhG VBR file */        info->is_vbr = true;        info->is_vbri_vbr = true;        info->has_toc = false; /* We don't parse the TOC (yet) */        info->byte_count = BYTES2INT(vbrheader[10], vbrheader[11],                                     vbrheader[12], vbrheader[13]);        info->frame_count = BYTES2INT(vbrheader[14], vbrheader[15],                                      vbrheader[16], vbrheader[17]);         info->file_time = info->frame_count * info->frame_time;        info->bitrate = info->byte_count * 8 / info->file_time;        /* We don't parse the TOC, since we don't yet know how to (FIXME) */        num_offsets = BYTES2INT(0, 0, vbrheader[18], vbrheader[19]);        frames_per_entry = BYTES2INT(0, 0, vbrheader[24], vbrheader[25]);        DEBUGF("Frame size (%dkpbs): %d bytes (0x%x)\n",               info->bitrate, info->frame_size, info->frame_size);        DEBUGF("Frame count: %x\n", info->frame_count);        DEBUGF("Byte count: %x\n", info->byte_count);        DEBUGF("Offsets: %d\n", num_offsets);        DEBUGF("Frames/entry: %d\n", frames_per_entry);        offset = 0;        for(i = 0;i < num_offsets;i++)        {           j = BYTES2INT(0, 0, vbrheader[26+i*2], vbrheader[27+i*2]);           offset += j;           DEBUGF("%03d: %x (%x)\n", i, offset - bytecount, j);        }    }    /* Is it a LAME Info frame? */    if (vbrheader[0] == 'I' &&        vbrheader[1] == 'n' &&        vbrheader[2] == 'f' &&        vbrheader[3] == 'o')    {        /* Make sure we skip this frame in playback */        bytecount += info->frame_size;    }    return bytecount;}static void int2bytes(unsigned char *buf, int val){    buf[0] = (val >> 24) & 0xff;    buf[1] = (val >> 16) & 0xff;    buf[2] = (val >> 8) & 0xff;    buf[3] = val & 0xff;}int count_mp3_frames(int fd, int startpos, int filesize,                     void (*progressfunc)(int)){    unsigned long header = 0;    struct mp3info info;    int num_frames;    int bytes;    int cnt;    int progress_chunk = filesize / 50; /* Max is 50%, in 1% increments */    int progress_cnt = 0;    bool is_vbr = false;    int last_bitrate = 0;    int header_template = 0;    if(lseek(fd, startpos, SEEK_SET) < 0)        return -1;    buf_init();    /* Find out the total number of frames */    num_frames = 0;    cnt = 0;        while((header = buf_find_next_frame(fd, &bytes, -1, header_template))) {        mp3headerinfo(&info, header);        if(!header_template)            header_template = header;                /* See if this really is a VBR file */        if(last_bitrate && info.bitrate != last_bitrate)        {            is_vbr = true;        }        last_bitrate = info.bitrate;                buf_seek(fd, info.frame_size-4);        num_frames++;        if(progressfunc)        {            cnt += bytes + info.frame_size;            if(cnt > progress_chunk)            {                progress_cnt++;                progressfunc(progress_cnt);                cnt = 0;            }        }    }    DEBUGF("Total number of frames: %d\n", num_frames);    if(is_vbr)        return num_frames;    else    {        DEBUGF("Not a VBR file\n");        return 0;    }}static const char cooltext[] = "Rockbox - rocks your box";int create_xing_header(int fd, int startpos, int filesize,                       unsigned char *buf, int num_frames,                       unsigned long header_template,                       void (*progressfunc)(int), bool generate_toc){    unsigned long header = 0;    struct mp3info info;    int pos, last_pos;    int i, j;    int bytes;    unsigned int filepos;    int x;    int index;    unsigned char toc[100];    unsigned long xing_header_template = 0;    DEBUGF("create_xing_header()\n");    if(header_template)        xing_header_template = header_template;        if(generate_toc)    {        lseek(fd, startpos, SEEK_SET);        buf_init();            /* Generate filepos table */        last_pos = 0;        filepos = 0;        header = 0;        x = 0;        for(i = 0;i < 100;i++) {            /* Calculate the absolute frame number for this seek point */            pos = i * num_frames / 100;                        /* Advance from the last seek point to this one */            for(j = 0;j < pos - last_pos;j++)            {                header = buf_find_next_frame(fd, &bytes, -1, header_template);                filepos += bytes;                mp3headerinfo(&info, header);                buf_seek(fd, info.frame_size-4);                filepos += info.frame_size;                if(!header_template)                    header_template = header;            }            /* Save a header for later use if header_template is empty.               We only save one header, and we want to save one in the               middle of the stream, just in case the first and the last               headers are corrupt. */            if(!xing_header_template && i == 1)                xing_header_template = header;                        if(progressfunc)            {                progressfunc(50 + i/2);            }                        /* Fill in the TOC entry */            /* each toc is a single byte indicating how many 256ths of the             * way through the file, is that percent of the way through the             * song. the easy method, filepos*256/filesize, chokes when             * the upper 8 bits of the file position are nonzero              * (i.e. files over 16mb in size).             */            if (filepos > 0xFFFFFF)            {                /* instead of multiplying filepos by 256, we divide                 * filesize by 256.                 */                toc[i] = filepos / (filesize >> 8);            }            else            {                toc[i] = filepos * 256 / filesize;            }                        DEBUGF("Pos %d: %d  relpos: %d  filepos: %x tocentry: %x\n",                   i, pos, pos-last_pos, filepos, toc[i]);                        last_pos = pos;        }    }    /* Clear the frame */    memset(buf, 0, 1500);    /* Use the template header and create a new one */    mp3headerinfo(&info, xing_header_template);    /* calculate position of VBR header */    if ( info.version == MPEG_VERSION1 ) {        if (info.channel_mode == 3) /* mono */            index = 21;        else            index = 36;    }    else {        if (info.channel_mode == 3) /* mono */            index = 13;        else            index = 21;    }    /* We ignore the Protection bit even if the rest of the stream is       protected. (fixme?) */    header = xing_header_template & ~(BITRATE_MASK | PROTECTION_MASK);    header |= 8 << 12; /* This gives us plenty of space, at least 192 bytes */    /* Write the header to the buffer */    int2bytes(buf, header);        /* Now get the length of the newly created frame */    mp3headerinfo(&info, header);    /* Create the Xing data */    buf[index] = 'X';    buf[index+1] = 'i';    buf[index+2] = 'n';    buf[index+3] = 'g';    int2bytes(&buf[index+4], ((num_frames?VBR_FRAMES_FLAG:0) |                              (filesize?VBR_BYTES_FLAG:0) |                              (generate_toc?VBR_TOC_FLAG:0)));    index = index+8;    if(num_frames)    {        int2bytes(&buf[index], num_frames);        index += 4;    }    if(filesize)    {        int2bytes(&buf[index], filesize - startpos);        index += 4;    }    /* Copy the TOC */    memcpy(buf + index, toc, 100);    /* And some extra cool info */    memcpy(buf + index + 100, cooltext, sizeof(cooltext));#ifdef DEBUG    for(i = 0;i < info.frame_size;i++)    {        if(i && !(i % 16))            DEBUGF("\n");        DEBUGF("%02x ", buf[i]);    }#endif        return info.frame_size;}

⌨️ 快捷键说明

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