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

📄 id3tag.c

📁 音频编码
💻 C
📖 第 1 页 / 共 2 页
字号:
    } while (c1 == c2);    return c1 - c2;}intid3tag_set_genre(lame_global_flags *gfp, const char *genre){    lame_internal_flags *gfc = gfp->internal_flags;    if (genre && *genre) {        char *str;        int num = strtol(genre, &str, 10);        /* is the input a string or a valid number? */        if (*str) {            int i;            for (i = 0; i < GENRE_NAME_COUNT; ++i) {                if (!local_strcasecmp(genre, genre_names[i])) {                    num = i;                    break;                }            }            if (i == GENRE_NAME_COUNT) {                return -1;            }        } else if ((num < 0) || (num >= GENRE_NAME_COUNT)) {            return -1;        }        gfc->tag_spec.genre = num;        gfc->tag_spec.flags |= CHANGED_FLAG;    }    return 0;}static unsigned char *set_4_byte_value(unsigned char *bytes, unsigned long value){    int index;    for (index = 3; index >= 0; --index) {        bytes[index] = value & 0xfful;        value >>= 8;    }    return bytes + 4;}#define FRAME_ID(a, b, c, d) \    ( ((unsigned long)(a) << 24) \    | ((unsigned long)(b) << 16) \    | ((unsigned long)(c) <<  8) \    | ((unsigned long)(d) <<  0) )#define TITLE_FRAME_ID FRAME_ID('T', 'I', 'T', '2')#define ARTIST_FRAME_ID FRAME_ID('T', 'P', 'E', '1')#define ALBUM_FRAME_ID FRAME_ID('T', 'A', 'L', 'B')#define YEAR_FRAME_ID FRAME_ID('T', 'Y', 'E', 'R')#define COMMENT_FRAME_ID FRAME_ID('C', 'O', 'M', 'M')#define TRACK_FRAME_ID FRAME_ID('T', 'R', 'C', 'K')#define GENRE_FRAME_ID FRAME_ID('T', 'C', 'O', 'N')#define ENCODER_FRAME_ID FRAME_ID('T', 'S', 'S', 'E')static unsigned char *set_frame(unsigned char *frame, unsigned long id, const char *text,    size_t length){    if (length) {        frame = set_4_byte_value(frame, id);        /* Set frame size = total size - header size.  Frame header and field         * bytes include 2-byte header flags, 1 encoding descriptor byte, and         * for comment frames: 3-byte language descriptor and 1 content         * descriptor byte */        frame = set_4_byte_value(frame, ((id == COMMENT_FRAME_ID) ? 5 : 1)                + length);        /* clear 2-byte header flags */        *frame++ = 0;        *frame++ = 0;        /* clear 1 encoding descriptor byte to indicate ISO-8859-1 format */        *frame++ = 0;        if (id == COMMENT_FRAME_ID) {            /* use id3lib-compatible bogus language descriptor */            *frame++ = 'X';            *frame++ = 'X';            *frame++ = 'X';            /* clear 1 byte to make content descriptor empty string */            *frame++ = 0;        }        while (length--) {            *frame++ = *text++;        }    }    return frame;}intid3tag_write_v2(lame_global_flags *gfp){    lame_internal_flags *gfc = gfp->internal_flags;    if ((gfc->tag_spec.flags & CHANGED_FLAG)            && !(gfc->tag_spec.flags & V1_ONLY_FLAG)) {        /* calculate length of four fields which may not fit in verion 1 tag */        size_t title_length = gfc->tag_spec.title            ? strlen(gfc->tag_spec.title) : 0;        size_t artist_length = gfc->tag_spec.artist            ? strlen(gfc->tag_spec.artist) : 0;        size_t album_length = gfc->tag_spec.album            ? strlen(gfc->tag_spec.album) : 0;        size_t comment_length = gfc->tag_spec.comment            ? strlen(gfc->tag_spec.comment) : 0;        /* write tag if explicitly requested or if fields overflow */        if ((gfc->tag_spec.flags & (ADD_V2_FLAG | V2_ONLY_FLAG))                || (title_length > 30)                || (artist_length > 30) || (album_length > 30)                || (comment_length > 30)                || (gfc->tag_spec.track && (comment_length > 28))) {            size_t tag_size;            char encoder[20];            size_t encoder_length;            char year[5];            size_t year_length;            char track[3];            size_t track_length;            char genre[6];            size_t genre_length;            unsigned char *tag;            unsigned char *p;            size_t adjusted_tag_size;            unsigned int index;            /* calulate size of tag starting with 10-byte tag header */            tag_size = 10;#if defined(__hpux) || defined(__svr4__) || defined(M_UNIX) || defined(_AIX)            encoder_length = sprintf(encoder,                            "LAME v%s", get_lame_short_version());#else#if defined(__sun__)            (void) sprintf(encoder, "LAME v%s", get_lame_short_version());            encoder_length = strlen(encoder);#else            encoder_length = snprintf(encoder, sizeof(encoder),                            "LAME v%s", get_lame_short_version());#endif#endif            tag_size += 11 + encoder_length;            if (title_length) {                /* add 10-byte frame header, 1 encoding descriptor byte ... */                tag_size += 11 + title_length;            }            if (artist_length) {                tag_size += 11 + artist_length;            }            if (album_length) {                tag_size += 11 + album_length;            }            if (gfc->tag_spec.year) {                year_length = sprintf(year, "%d", gfc->tag_spec.year);                tag_size += 11 + year_length;            } else {                year_length = 0;            }            if (comment_length) {                /* add 10-byte frame header, 1 encoding descriptor byte,                 * 3-byte language descriptor, 1 content descriptor byte ... */                tag_size += 15 + comment_length;            }            if (gfc->tag_spec.track) {                track_length = sprintf(track, "%d", gfc->tag_spec.track);                tag_size += 11 + track_length;            } else {                track_length = 0;            }            if (gfc->tag_spec.genre != GENRE_NUM_UNKNOWN) {                genre_length = sprintf(genre, "(%d)", gfc->tag_spec.genre);                tag_size += 11 + genre_length;            } else {                genre_length = 0;            }            if (gfc->tag_spec.flags & PAD_V2_FLAG) {                /* add 128 bytes of padding */                tag_size += 128;            }            tag = (unsigned char *)malloc(tag_size);            if (!tag) {                return -1;            }            p = tag;            /* set tag header starting with file identifier */            *p++ = 'I'; *p++ = 'D'; *p++ = '3';            /* set version number word */            *p++ = 3; *p++ = 0;            /* clear flags byte */            *p++ = 0;            /* calculate and set tag size = total size - header size */            adjusted_tag_size = tag_size - 10;            /* encode adjusted size into four bytes where most significant              * bit is clear in each byte, for 28-bit total */            *p++ = (adjusted_tag_size >> 21) & 0x7fu;            *p++ = (adjusted_tag_size >> 14) & 0x7fu;            *p++ = (adjusted_tag_size >> 7) & 0x7fu;            *p++ = adjusted_tag_size & 0x7fu;            /*             * NOTE: The remainder of the tag (frames and padding, if any)             * are not "unsynchronized" to prevent false MPEG audio headers             * from appearing in the bitstream.  Why?  Well, most players             * and utilities know how to skip the ID3 version 2 tag by now             * even if they don't read its contents, and it's actually             * very unlikely that such a false "sync" pattern would occur             * in just the simple text frames added here.             */            /* set each frame in tag */            p = set_frame(p, ENCODER_FRAME_ID, encoder, encoder_length);            p = set_frame(p, TITLE_FRAME_ID, gfc->tag_spec.title, title_length);            p = set_frame(p, ARTIST_FRAME_ID, gfc->tag_spec.artist,                    artist_length);            p = set_frame(p, ALBUM_FRAME_ID, gfc->tag_spec.album, album_length);            p = set_frame(p, YEAR_FRAME_ID, year, year_length);            p = set_frame(p, COMMENT_FRAME_ID, gfc->tag_spec.comment,                    comment_length);            p = set_frame(p, TRACK_FRAME_ID, track, track_length);            p = set_frame(p, GENRE_FRAME_ID, genre, genre_length);            /* clear any padding bytes */            memset(p, 0, tag_size - (p - tag));            /* write tag directly into bitstream at current position */            for (index = 0; index < tag_size; ++index) {                add_dummy_byte(gfp, tag[index]);            }            free(tag);            return tag_size;        }    }    return 0;}static unsigned char *set_text_field(unsigned char *field, const char *text, size_t size, int pad){    while (size--) {        if (text && *text) {            *field++ = *text++;        } else {            *field++ = pad;        }    }    return field;}intid3tag_write_v1(lame_global_flags *gfp){    lame_internal_flags *gfc = gfp->internal_flags;    if ((gfc->tag_spec.flags & CHANGED_FLAG)            && !(gfc->tag_spec.flags & V2_ONLY_FLAG)) {        unsigned char tag[128];        unsigned char *p = tag;        int pad = (gfc->tag_spec.flags & SPACE_V1_FLAG) ? ' ' : 0;        char year[5];        unsigned int index;        /* set tag identifier */        *p++ = 'T'; *p++ = 'A'; *p++ = 'G';        /* set each field in tag */        p = set_text_field(p, gfc->tag_spec.title, 30, pad);        p = set_text_field(p, gfc->tag_spec.artist, 30, pad);        p = set_text_field(p, gfc->tag_spec.album, 30, pad);        sprintf(year, "%d", gfc->tag_spec.year);        p = set_text_field(p, gfc->tag_spec.year ? year : NULL, 4, pad);        /* limit comment field to 28 bytes if a track is specified */        p = set_text_field(p, gfc->tag_spec.comment, gfc->tag_spec.track                ? 28 : 30, pad);        if (gfc->tag_spec.track) {            /* clear the next byte to indicate a version 1.1 tag */            *p++ = 0;            *p++ = gfc->tag_spec.track;        }        *p++ = gfc->tag_spec.genre;        /* write tag directly into bitstream at current position */        for (index = 0; index < 128; ++index) {            add_dummy_byte(gfp, tag[index]);        }        return 128;    }    return 0;}

⌨️ 快捷键说明

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