Example #1
0
/* PSID metadata info is available here: 
   http://www.unusedino.de/ec64/technical/formats/sidplay.html */
bool get_sid_metadata(int fd, struct mp3entry* id3)
{    
    /* Use the trackname part of the id3 structure as a temporary buffer */
    unsigned char* buf = (unsigned char *)id3->path;    
    int read_bytes;
    char *p;
    

    if ((lseek(fd, 0, SEEK_SET) < 0) 
         || ((read_bytes = read(fd, buf, 0x80)) < 0x80))
    {
        return false;
    }
    
    if ((memcmp(buf, "PSID", 4) != 0))
    {
        return false;
    }

    p = id3->id3v2buf;

    /* Copy Title (assumed max 0x1f letters + 1 zero byte) */
    id3->title = p;
    buf[0x16+0x1f] = 0;
    p = iso_decode(&buf[0x16], p, 0, strlen(&buf[0x16])+1);

    /* Copy Artist (assumed max 0x1f letters + 1 zero byte) */
    id3->artist = p;
    buf[0x36+0x1f] = 0;
    p = iso_decode(&buf[0x36], p, 0, strlen(&buf[0x36])+1);

    /* Copy Year (assumed max 4 letters + 1 zero byte) */
    buf[0x56+0x4] = 0;
    id3->year = atoi(&buf[0x56]);

    /* Copy Album (assumed max 0x1f-0x05 letters + 1 zero byte) */
    id3->album = p;
    buf[0x56+0x1f] = 0;
    p = iso_decode(&buf[0x5b], p, 0, strlen(&buf[0x5b])+1);

    id3->bitrate = 706;
    id3->frequency = 44100;
    /* New idea as posted by Marco Alanen (ravon):
     * Set the songlength in seconds to the number of subsongs
     * so every second represents a subsong.
     * Users can then skip the current subsong by seeking
     *
     * Note: the number of songs is a 16bit value at 0xE, so this code only
     * uses the lower 8 bits of the counter.
    */
    id3->length = (buf[0xf]-1)*1000;
    id3->vbr = false;
    id3->filesize = filesize(fd);

    return true;
}
Example #2
0
static void decode2utf8(const unsigned char *src, unsigned char **dst,
                        int srcsize, int *dstsize, int codepage)
{
    unsigned char tmpbuf[srcsize * 3 + 1];
    unsigned char *p;
    int utf8size;

    if (codepage < NUM_CODEPAGES)
        p = iso_decode(src, tmpbuf, codepage, srcsize);
    else /* codepage == UCS2 */
        p = utf16BEdecode(src, tmpbuf, srcsize);

    *p = '\0';

    strlcpy(*dst, tmpbuf, *dstsize);
    utf8size = (p - tmpbuf) + 1;
    if (utf8size > *dstsize)
    {
        DEBUGF("metadata warning: data length: %d > contents store buffer size: %d\n",
                    utf8size, *dstsize);
        utf8size = *dstsize;
    }
    *dst     += utf8size;
    *dstsize -= utf8size;
}
Example #3
0
static int iso_skip_frame (codec_data_t *iso)
{
#if 0
  return (iso_decode(iso, ts, 0, NULL, buffer, buflen));
#else
  return 0;
#endif
}
Example #4
0
File: spc.c Project: IlVerz/rockbox
bool get_spc_metadata(int fd, struct mp3entry* id3)
{
    /* Use the trackname part of the id3 structure as a temporary buffer */
    unsigned char * buf = (unsigned char *)id3->path;
    char * p;
    
    unsigned long length;
    unsigned long fade;
    bool isbinary = true;
    int i;
    
    /* try to get the ID666 tag */
    if ((lseek(fd, 0x2e, SEEK_SET) < 0)
        || (read(fd, buf, 0xD2) < 0xD2))
    {
        DEBUGF("lseek or read failed\n");
        return false;
    }

    p = id3->id3v2buf;
    
    id3->title = p;
    buf[31] = 0;
    p = iso_decode(buf, p, 0, 32);
    buf += 32;

    id3->album = p;
    buf[31] = 0;
    p = iso_decode(buf, p, 0, 32);
    buf += 48;
    
    id3->comment = p;
    buf[31] = 0;
    p = iso_decode(buf, p, 0, 32);
    buf += 32;
    
    /* Date check */
    if(buf[2] == '/' && buf[5] == '/')
        isbinary = false;
    
    /* Reserved bytes check */
    if(buf[0xD2 - 0x2E - 112] >= '0' &&
       buf[0xD2 - 0x2E - 112] <= '9' &&
       buf[0xD3 - 0x2E - 112] == 0x00)
        isbinary = false;
    
    /* is length & fade only digits? */
    for (i=0;i<8 && ( 
        (buf[0xA9 - 0x2E - 112+i]>='0'&&buf[0xA9 - 0x2E - 112+i]<='9') ||
        buf[0xA9 - 0x2E - 112+i]=='\0');
        i++);
    if (i==8) isbinary = false;
    
    if(isbinary) {
        id3->year = buf[0] | (buf[1]<<8);
        buf += 11;
        
        length = (buf[0] | (buf[1]<<8) | (buf[2]<<16)) * 1000;
        buf += 3;
        
        fade = (buf[0] | (buf[1]<<8) | (buf[2]<<16) | (buf[3]<<24));
        buf += 4;
    } else {
        char tbuf[6];
        
        buf += 6;
        buf[4] = 0;
        id3->year = atoi(buf);
        buf += 5;
        
        memcpy(tbuf, buf, 3);
        tbuf[3] = 0;
        length = atoi(tbuf) * 1000;
        buf += 3;
        
        memcpy(tbuf, buf, 5);
        tbuf[5] = 0;
        fade = atoi(tbuf);
        buf += 5;
    }
    
    id3->artist = p;
    buf[31] = 0;
    iso_decode(buf, p, 0, 32);
    
    if (length==0) {
        length=3*60*1000; /* 3 minutes */
        fade=5*1000; /* 5 seconds */
    }
    
    id3->length = length+fade;

    id3->filesize = filesize(fd);
    id3->genre_string = id3_get_num_genre(36);

    return true;
}
Example #5
0
/* parse cuesheet "file" and store the information in "cue" */
bool parse_cuesheet(char *file, struct cuesheet *cue)
{
    char line[MAX_PATH];
    char *s;
    bool utf8 = false;

    int fd = open_utf8(file,O_RDONLY);
    if (fd < 0)
    {
        /* couln't open the file */
        return false;
    }
    if(lseek(fd, 0, SEEK_CUR) > 0)
        utf8 = true;

    /* Initialization */
    memset(cue, 0, sizeof(struct cuesheet));
    strcpy(cue->path, file);
    cue->curr_track = cue->tracks;

    while ( read_line(fd,line,MAX_PATH) && cue->track_count < MAX_TRACKS )
    {
        s = skip_whitespace(line);

        if (!strncmp(s, "TRACK", 5))
        {
            cue->track_count++;
        }
        else if (!strncmp(s, "INDEX 01", 8))
        {
            s = strchr(s,' ');
            s = skip_whitespace(s);
            s = strchr(s,' ');
            s = skip_whitespace(s);
            cue->tracks[cue->track_count-1].offset = 60*1000 * atoi(s);
            s = strchr(s,':') + 1;
            cue->tracks[cue->track_count-1].offset += 1000 * atoi(s);
            s = strchr(s,':') + 1;
            cue->tracks[cue->track_count-1].offset += 13 * atoi(s);
        }
        else if (!strncmp(s, "TITLE", 5)
                 || !strncmp(s, "PERFORMER", 9)
                 || !strncmp(s, "SONGWRITER", 10))
        {
            char *dest = NULL;
            char *string = get_string(s);
            if (!string)
                break;

            switch (*s)
            {
                case 'T': /* TITLE */
                    dest = (cue->track_count <= 0) ? cue->title :
                            cue->tracks[cue->track_count-1].title;
                    break;

                case 'P': /* PERFORMER */
                    dest = (cue->track_count <= 0) ? cue->performer :
                        cue->tracks[cue->track_count-1].performer;
                    break;

                case 'S': /* SONGWRITER */
                    dest = (cue->track_count <= 0) ? cue->songwriter :
                            cue->tracks[cue->track_count-1].songwriter;
                    break;
            }

            if (dest) 
            {
                if (!utf8)
                {
                    dest = iso_decode(string, dest, -1, MIN(strlen(string), MAX_NAME));
                    *dest = '\0';
                }
                else
                {
                    strlcpy(dest, string, MAX_NAME*3 + 1);
                }
            }    
        }
    }
    close(fd);

    /* If some songs don't have performer info, we copy the cuesheet performer */
    int i;
    for (i = 0; i < cue->track_count; i++)
    {
        if (*(cue->tracks[i].performer) == '\0')
            strlcpy(cue->tracks[i].performer, cue->performer, MAX_NAME*3);

        if (*(cue->tracks[i].songwriter) == '\0')
            strlcpy(cue->tracks[i].songwriter, cue->songwriter, MAX_NAME*3);
    }

    return true;
}
Example #6
0
int main(int argc, char **argv)
{
    int mini = 0;
    int i, j;
    unsigned char k;
    unsigned short uni;
    FILE *of;

    for (i = 1;i < argc;i++)
    {
        if (argv[i][0] == '-')
        {
            switch (argv[i][1])
            {
              case 'm':   /* create isomini.cp only */
                mini = 1;
                break;

              case 'h':   /* help */
              case '?':
                print_usage();
                exit(1);
                break;

              default:
                print_usage();
                exit(1);
                break;
            }
        }
    }

    for (i=0; i < MAX_TABLE_SIZE; i++)
        iso_table[i] = 0;

    if (mini) {
        of = fopen("isomini.cp", "wb");
        if (!of) return 1;

        for (i=1; i<6; i++) {

            for (j=0; j<128; j++) {
                k = (unsigned char)j + 128;
                uni = iso_decode(&k, mini_index[i], 1);
                writeshort(of, uni);
            }
        }
        fclose(of);
    }
    else {
        of = fopen("iso.cp", "wb");
        if (!of) return 1;

        for (i=1; i<9; i++) {

            for (j=0; j<128; j++) {
                k = (unsigned char)j + 128;
                uni = iso_decode(&k, i, 1);
                writeshort(of, uni);
            }
        }
        fclose(of);

        of = fopen("932.cp", "wb");
        if (!of) return 1;
        for (i=0; i < MAX_TABLE_SIZE; i++)
            writeshort(of, cp932_table[i]);
        fclose(of);

        of = fopen("936.cp", "wb");
        if (!of) return 1;
        for (i=0; i < MAX_TABLE_SIZE; i++)
            writeshort(of, cp936_table[i]);
        fclose(of);

        of = fopen("949.cp", "wb");
        if (!of) return 1;
        for (i=0; i < MAX_TABLE_SIZE; i++)
            writeshort(of, cp949_table[i]);
        fclose(of);

        of = fopen("950.cp", "wb");
        if (!of) return 1;
        for (i=0; i < MAX_TABLE_SIZE; i++)
            writeshort(of, cp950_table[i]);
        fclose(of);
    }

    return 0;
}
/* parse cuesheet "cue_file" and store the information in "cue" */
bool parse_cuesheet(struct cuesheet_file *cue_file, struct cuesheet *cue)
{
    char line[MAX_PATH];
    char *s;
    unsigned char char_enc = CHAR_ENC_ISO_8859_1;
    bool is_embedded = false;
    int line_len;
    int bytes_left = 0;
    int read_bytes = MAX_PATH;
    unsigned char utf16_buf[MAX_PATH];

    int fd = open(cue_file->path, O_RDONLY, 0644);
    if(fd < 0)
        return false;
    if (cue_file->pos > 0)
    {
        is_embedded = true;
        lseek(fd, cue_file->pos, SEEK_SET);
        bytes_left = cue_file->size;
        char_enc = cue_file->encoding;
    }

    /* Look for a Unicode BOM */
    unsigned char bom_read = 0;
    read(fd, line, BOM_UTF_8_SIZE);
    if(!memcmp(line, BOM_UTF_8, BOM_UTF_8_SIZE))
    {
        char_enc = CHAR_ENC_UTF_8;
        bom_read = BOM_UTF_8_SIZE;
    }
    else if(!memcmp(line, BOM_UTF_16_LE, BOM_UTF_16_SIZE))
    {
        char_enc = CHAR_ENC_UTF_16_LE;
        bom_read = BOM_UTF_16_SIZE;
    }
    else if(!memcmp(line, BOM_UTF_16_BE, BOM_UTF_16_SIZE))
    {
        char_enc = CHAR_ENC_UTF_16_BE;
        bom_read = BOM_UTF_16_SIZE;
    }
    if (bom_read < BOM_UTF_8_SIZE)
        lseek(fd, cue_file->pos + bom_read, SEEK_SET);
    if (is_embedded)
    {
        if (bom_read  > 0)
            bytes_left -= bom_read;
        if (read_bytes > bytes_left)
            read_bytes = bytes_left;
    }

    /* Initialization */
    memset(cue, 0, sizeof(struct cuesheet));
    strcpy(cue->path, cue_file->path);
    cue->curr_track = cue->tracks;

    while ((line_len = read_line(fd, line, read_bytes)) > 0
        && cue->track_count < MAX_TRACKS )
    {
        if (char_enc == CHAR_ENC_UTF_16_LE)
        {
            s = utf16LEdecode(line, utf16_buf, line_len);
            /* terminate the string at the newline */
            *s = '\0';
            strcpy(line, utf16_buf);
            /* chomp the trailing 0 after the newline */
            lseek(fd, 1, SEEK_CUR);
            line_len++;
        }
        else if (char_enc == CHAR_ENC_UTF_16_BE)
        {
            s = utf16BEdecode(line, utf16_buf, line_len);
            *s = '\0';
            strcpy(line, utf16_buf);
        }
        s = skip_whitespace(line);

        if (!strncmp(s, "TRACK", 5))
        {
            cue->track_count++;
        }
        else if (!strncmp(s, "INDEX 01", 8))
        {
            s = strchr(s,' ');
            s = skip_whitespace(s);
            s = strchr(s,' ');
            s = skip_whitespace(s);
            cue->tracks[cue->track_count-1].offset = 60*1000 * atoi(s);
            s = strchr(s,':') + 1;
            cue->tracks[cue->track_count-1].offset += 1000 * atoi(s);
            s = strchr(s,':') + 1;
            cue->tracks[cue->track_count-1].offset += 13 * atoi(s);
        }
        else if (!strncmp(s, "TITLE", 5)
                 || !strncmp(s, "PERFORMER", 9)
                 || !strncmp(s, "SONGWRITER", 10))
        {
            char *dest = NULL;
            char *string = get_string(s);
            if (!string)
                break;

            switch (*s)
            {
                case 'T': /* TITLE */
                    dest = (cue->track_count <= 0) ? cue->title :
                            cue->tracks[cue->track_count-1].title;
                    break;

                case 'P': /* PERFORMER */
                    dest = (cue->track_count <= 0) ? cue->performer :
                        cue->tracks[cue->track_count-1].performer;
                    break;

                case 'S': /* SONGWRITER */
                    dest = (cue->track_count <= 0) ? cue->songwriter :
                            cue->tracks[cue->track_count-1].songwriter;
                    break;
            }

            if (dest) 
            {
                if (char_enc == CHAR_ENC_ISO_8859_1)
                {
                    dest = iso_decode(string, dest, -1,
                        MIN(strlen(string), MAX_NAME));
                    *dest = '\0';
                }
                else
                {
                    strlcpy(dest, string, MAX_NAME*3 + 1);
                }
            }    
        }
        if (is_embedded)
        {
            bytes_left -= line_len;
            if (bytes_left <= 0)
                break;
            if (bytes_left < read_bytes)
                read_bytes = bytes_left;
        }
    }
    close(fd);

    /* If some songs don't have performer info, we copy the cuesheet performer */
    int i;
    for (i = 0; i < cue->track_count; i++)
    {
        if (*(cue->tracks[i].performer) == '\0')
            strlcpy(cue->tracks[i].performer, cue->performer, MAX_NAME*3);

        if (*(cue->tracks[i].songwriter) == '\0')
            strlcpy(cue->tracks[i].songwriter, cue->songwriter, MAX_NAME*3);
    }

    return true;
}