/* ** ustring getFrame(const char *frameID) ** ** Return frame text by frameID. Frame ID is a four character string defined to uniquely ** identify a frame. Details see http://www.id3.org ** */ ustring CMP3ID3::getFrame(const char *frameID){ if ( m_pID3Tag == NULL || m_pID3File == NULL ) return ustring((unsigned char *)""); ustring str = ustring((unsigned char *)""); //Search for given frame by frame id struct id3_frame *pFrame = id3_tag_findframe(m_pID3Tag,frameID,0); if ( pFrame == NULL ) return ustring((unsigned char *)""); union id3_field field = pFrame->fields[1]; id3_ucs4_t const *pTemp = id3_field_getstrings(&field,0); if ( !strcmp(frameID,"TCON") ){ //If the frameID is TCON, we then retreive genre name using id3_genre_name id3_ucs4_t const *pGenre = id3_genre_name(pTemp); pTemp = pGenre; } id3_latin1_t *pStrLatinl; if ( pTemp != NULL ){ pStrLatinl = id3_ucs4_latin1duplicate(pTemp); str = pStrLatinl; delete pStrLatinl; } return str; }
wxString GetGenreNum(int i) { #ifdef USE_LIBID3TAG id3_latin1_t i_latin1[50]; id3_ucs4_t *i_ucs4; const id3_ucs4_t *genre_ucs4; sprintf((char *)i_latin1, "%d", i); i_ucs4 = (id3_ucs4_t *)malloc((id3_latin1_length(i_latin1) + 1) * sizeof(*i_ucs4)); if (i_ucs4) { id3_latin1_decode(i_latin1, i_ucs4); genre_ucs4 = id3_genre_name(i_ucs4); char *genre_char = (char *)id3_ucs4_utf8duplicate(genre_ucs4); wxString genreStr = UTF8CTOWX(genre_char); free(genre_char); free(i_ucs4); return genreStr; } #endif // ifdef USE_LIBID3TAG return wxT(""); }
/** * Import a "Text information frame" (ID3v2.4.0 section 4.2). It * contains 2 fields: * * - encoding * - string list */ static void tag_id3_import_text(struct tag *dest, struct id3_tag *tag, const char *id, enum tag_type type) { struct id3_frame const *frame; id3_ucs4_t const *ucs4; id3_utf8_t *utf8; union id3_field const *field; unsigned int nstrings, i; frame = id3_tag_findframe(tag, id, 0); if (frame == NULL || frame->nfields != 2) return; /* check the encoding field */ field = id3_frame_field(frame, 0); if (field == NULL || field->type != ID3_FIELD_TYPE_TEXTENCODING) return; /* process the value(s) */ field = id3_frame_field(frame, 1); if (field == NULL || field->type != ID3_FIELD_TYPE_STRINGLIST) return; /* Get the number of strings available */ nstrings = id3_field_getnstrings(field); for (i = 0; i < nstrings; i++) { ucs4 = id3_field_getstrings(field, i); if (ucs4 == NULL) continue; if (type == TAG_GENRE) ucs4 = id3_genre_name(ucs4); utf8 = import_id3_string(tag_is_id3v1(tag), ucs4); if (utf8 == NULL) continue; tag_add_item(dest, type, (char *)utf8); g_free(utf8); } }
/* This will try to convert a string to utf-8, */ static id3_utf8_t * processID3FieldString (int is_id3v1, const id3_ucs4_t *ucs4, int type, enum id3_field_textencoding id3_encoding) { id3_utf8_t *utf8, *utf8_stripped; id3_utf8_t *isostr; const char *encoding; if (type == TAG_ITEM_GENRE) ucs4 = id3_genre_name(ucs4); /* use encoding field here? */ if ((encoding = config_get_string(CONF_ID3V1_ENCODING, NULL)) != NULL) { if(!is_id3v1 && (id3_encoding == ID3_FIELD_TEXTENCODING_UTF_16 || id3_encoding == ID3_FIELD_TEXTENCODING_UTF_8)) isostr = id3_ucs4_utf8duplicate(ucs4); else isostr = (id3_utf8_t*)id3_ucs4_latin1duplicate(ucs4); if (G_UNLIKELY(!isostr)) { return NULL; } if(id3_encoding == 0xff || id3_encoding == ID3_FIELD_TEXTENCODING_ISO_8859_1) { utf8 = (id3_utf8_t *) g_convert_with_fallback((const char*)isostr, -1, "utf-8", encoding, NULL, NULL, NULL, NULL); } else utf8 = (id3_utf8_t *) g_strdup((const char*)isostr); if (utf8 == NULL) { g_debug("Unable to convert %s string to UTF-8: '%s'", encoding, isostr); g_free(isostr); return NULL; } g_free(isostr); } else { utf8 = id3_ucs4_utf8duplicate(ucs4); if (G_UNLIKELY(!utf8)) { return NULL; } } utf8_stripped = (id3_utf8_t *)g_strdup(g_strstrip((gchar *)utf8)); g_free(utf8); return utf8_stripped; }
/* stolen from mpg321 * * Convenience for retrieving already formatted id3 data * what parameter is one of * ID3_FRAME_TITLE * ID3_FRAME_ARTIST * ID3_FRAME_ALBUM * ID3_FRAME_YEAR * ID3_FRAME_COMMENT * ID3_FRAME_GENRE */ string LibMadWrapper::id3_get_tag(struct id3_tag const *tag, char const *what) { struct id3_frame const *frame = NULL; union id3_field const *field = NULL; int nstrings; int avail; int j; int tocopy; int len; char printable[1024]; id3_ucs4_t const *ucs4 = NULL; id3_latin1_t *latin1 = NULL; memset(printable, '\0', 1024); avail = 1024; if (strcmp(what, ID3_FRAME_COMMENT) == 0) { /*There may be sth wrong. I did not fully understand how to use libid3tag for retrieving comments */ j = 0; frame = id3_tag_findframe(tag, ID3_FRAME_COMMENT, j++); if (!frame) { return ""; } ucs4 = id3_field_getfullstring(&frame->fields[3]); if (!ucs4) { return ""; } latin1 = id3_ucs4_latin1duplicate(ucs4); if (!latin1 || strlen(reinterpret_cast<char *>(latin1)) == 0) { return ""; } len = strlen(reinterpret_cast<char *>(latin1)); if (avail > len) { tocopy = len; } else { tocopy = 0; } if (!tocopy) { return ""; } avail -= tocopy; strncat(printable, reinterpret_cast<char *>(latin1), tocopy); free(latin1); } else { frame = id3_tag_findframe(tag, what, 0); if (!frame) { return ""; } field = &frame->fields[1]; nstrings = id3_field_getnstrings(field); for (j = 0; j < nstrings; ++j) { ucs4 = id3_field_getstrings(field, j); if (!ucs4) { return ""; } if (strcmp(what, ID3_FRAME_GENRE) == 0) { ucs4 = id3_genre_name(ucs4); } latin1 = id3_ucs4_latin1duplicate(ucs4); if (!latin1) { break; } len = strlen(reinterpret_cast<char *>(latin1)); if (avail > len) { tocopy = len; } else { tocopy = 0; } if (!tocopy) { break; } avail -= tocopy; strncat(printable, reinterpret_cast<char *>(latin1), tocopy); free(latin1); } } return string(printable); }
/* Convenience for retrieving already formatted id3 data * what parameter is one of * ID3_FRAME_TITLE * ID3_FRAME_ARTIST * ID3_FRAME_ALBUM * ID3_FRAME_YEAR * ID3_FRAME_COMMENT * ID3_FRAME_GENRE * It allocates a new string. Free it later. * NULL if no tag or error. */ char *id3_get_tag (struct id3_tag const *tag, char const *what, unsigned int maxlen) { struct id3_frame const *frame = NULL; union id3_field const *field = NULL; int nstrings; int avail; int j; int tocopy; int len; char printable [1024]; char *retval = NULL; id3_ucs4_t const *ucs4 = NULL; id3_latin1_t *latin1 = NULL; memset (printable, '\0', 1024); avail = 1024; if (strcmp (what, ID3_FRAME_COMMENT) == 0) { /*There may be sth wrong. I did not fully understand how to use libid3tag for retrieving comments */ j=0; frame = id3_tag_findframe(tag, ID3_FRAME_COMMENT, j++); if (!frame) return (NULL); ucs4 = id3_field_getfullstring (&frame->fields[3]); if (!ucs4) return (NULL); latin1 = id3_ucs4_latin1duplicate (ucs4); if (!latin1 || strlen(latin1) == 0) return (NULL); len = strlen(latin1); if (avail > len) tocopy = len; else tocopy = 0; if (!tocopy) return (NULL); avail-=tocopy; strncat (printable, latin1, tocopy); free (latin1); } else { frame = id3_tag_findframe (tag, what, 0); if (!frame) return (NULL); field = &frame->fields[1]; nstrings = id3_field_getnstrings(field); for (j=0; j<nstrings; ++j) { ucs4 = id3_field_getstrings(field, j); if (!ucs4) return (NULL); if (strcmp (what, ID3_FRAME_GENRE) == 0) ucs4 = id3_genre_name(ucs4); latin1 = id3_ucs4_latin1duplicate(ucs4); if (!latin1) break; len = strlen(latin1); if (avail > len) tocopy = len; else tocopy = 0; if (!tocopy) break; avail-=tocopy; strncat (printable, latin1, tocopy); free (latin1); } } retval = malloc (maxlen + 1); if (!retval) return (NULL); strncpy (retval, printable, maxlen); retval[maxlen] = '\0'; len = strlen(printable); if (maxlen > len) { memset (retval + len, ' ', maxlen - len); } return (retval); }
int mp3_get_tag (Private * h, char *path, struct SongDBEntry *e) { FILE *fd; mp3Private *mp3_priv = (mp3Private *) h; int length = 0; long size = 0; char *empty = strdup (""); char *title = NULL, *artist = NULL, *album = NULL; char *comment = NULL, *year = NULL, *genre = NULL; if( h == NULL || path == NULL || e ==NULL) return ERROR_INVALID_ARG; { struct id3_file *id3file; struct id3_tag *id3tag; id3_ucs4_t *ucs4; id3_latin1_t *latin1; struct id3_frame *frame; id3file = id3_file_open ( path, ID3_FILE_MODE_READONLY); if (id3file == NULL) { ERROR("get_tag: Error opening file: %s", strerror (errno)); return -1; } id3tag = id3_file_tag (id3file); frame = id3_tag_findframe (id3tag, ID3_FRAME_TITLE, 0); if (frame != NULL) { ucs4 = (id3_ucs4_t *) id3_field_getstrings ((union id3_field const *) &frame->fields[1], 0); if (ucs4 != NULL) { latin1 = id3_ucs4_latin1duplicate (ucs4); if (latin1 != NULL) { title = strdup (latin1); } } } frame = id3_tag_findframe (id3tag, ID3_FRAME_ARTIST, 0); if (frame != NULL) { ucs4 = (id3_ucs4_t *) id3_field_getstrings (&frame->fields[1], 0); if (ucs4 != NULL) { latin1 = id3_ucs4_latin1duplicate (ucs4); if (latin1 != NULL) { artist = strdup (latin1); } } } frame = id3_tag_findframe ((struct id3_tag const *) id3tag, ID3_FRAME_ALBUM, 0); if (frame != NULL) { ucs4 = (id3_ucs4_t *) id3_field_getstrings (&frame->fields[1], 0); if (ucs4 != NULL) { latin1 = id3_ucs4_latin1duplicate (ucs4); if (latin1 != NULL) { album = strdup (latin1); } } } frame = id3_tag_findframe ((struct id3_tag const *) id3tag, ID3_FRAME_COMMENT, 0); if (frame != NULL) { ucs4 = (id3_ucs4_t *) id3_field_getstrings (&frame->fields[1], 0); if (ucs4 != NULL) { latin1 = id3_ucs4_latin1duplicate (ucs4); if (latin1 != NULL) { comment = strdup (latin1); } } } frame = id3_tag_findframe ((struct id3_tag const *) id3tag, ID3_FRAME_YEAR, 0); if (frame != NULL) { ucs4 = (id3_ucs4_t *) id3_field_getstrings (&frame->fields[1], 0); if (ucs4 != NULL) { latin1 = id3_ucs4_latin1duplicate (ucs4); if (latin1 != NULL) { year = strdup (latin1); } } } frame = id3_tag_findframe ((struct id3_tag const *) id3tag, ID3_FRAME_GENRE, 0); if (frame != NULL) { ucs4 = (id3_ucs4_t *) id3_field_getstrings (&frame->fields[1], 0); if (ucs4 != NULL) { ucs4 = (id3_ucs4_t *) id3_genre_name (ucs4); if (ucs4 != NULL) { latin1 = id3_ucs4_latin1duplicate (ucs4); if (latin1 != NULL) { genre = strdup (latin1); } } } } id3_file_close (id3file); } e->title = title; e->artist = artist; e->album = album; e->comment = comment; e->year = year; e->genre = genre; /* length calculation stuff */ { struct mad_header header; struct xing xing; if( e->AddInfo == NULL ) { e->AddInfo = malloc( sizeof(struct SongAddInfo) ); if( e->AddInfo == NULL) return ERROR_NO_MEMORY; memset( e->AddInfo, 0, sizeof( struct SongAddInfo )); } fd = fopen ( path, "rb"); if (fd == NULL) { ERROR("get_tag: Error opening file %s:%s", path, strerror (errno)); return ERROR_OPEN_ERROR; } fseek(fd,0,SEEK_END); size=ftell(fd); fseek(fd,0,SEEK_SET); e->filesize = size; if (scan_header (fd, &header, &xing) == -1) { fclose (fd); // printf ("get_tag: Error Reading File\n"); return ERROR_READ_SEEK_ERROR; } switch( header.layer ) { case MAD_LAYER_I: e->AddInfo->type = str_mpeg1_l1; break; case MAD_LAYER_II: e->AddInfo->type = str_mpeg1_l2; break; case MAD_LAYER_III: if( header.flags & MAD_FLAG_MPEG_2_5_EXT ) e->AddInfo->type = str_mpeg25_l3; else e->AddInfo->type = str_mpeg1_l3; break; default: e->AddInfo->type = NULL; break; } e->AddInfo->n_ch = MAD_NCHANNELS(&header); e->AddInfo->SampleRate = header.samplerate; e->AddInfo->bitrate = header.bitrate; e->AddInfo->err_protection = ((header.flags & MAD_FLAG_PROTECTION) >0); e->AddInfo->copyright = ((header.flags & MAD_FLAG_COPYRIGHT) >0); e->AddInfo->original = ((header.flags & MAD_FLAG_ORIGINAL) >0); fseek (fd, 0, SEEK_SET); // bitrate = 0; if (xing.flags & XING_FRAMES) { mad_timer_t timer; timer = header.duration; mad_timer_multiply (&timer, xing.frames); length = mad_timer_count (timer, MAD_UNITS_MILLISECONDS); /* if (xing.flags & XING_BYTES) bitrate = xing.bytes * 8 / length; */ // printf ("XING header w/ XING_FRAMES found. length = %d\n", length); } else { if (!cfg->lengthcalc) length = (size * 8 / (header.bitrate / 1000)); /* est. */ else { fseek (fd, 0, SEEK_SET); scan_file (fd, &length, NULL); } } e->time = length; mp3_priv->length = length; } fclose (fd); mp3_priv->size = size; mp3_priv->position = 0; return 1; }
/* * NAME: show_id3() * DESCRIPTION: display an ID3 tag */ static void show_id3(playa_info_t * info3, struct id3_tag const *tag) { unsigned int i; struct id3_frame const *frame; id3_ucs4_t const *ucs4; id3_latin1_t *latin1; /* $$$ Care of order in mp3dc.h */ struct { char const *id; char const *name; } const info[] = { {ID3_FRAME_ARTIST, N_("Artist")}, {ID3_FRAME_ALBUM, N_("Album")}, {ID3_FRAME_TRACK, N_("Track")}, {ID3_FRAME_TITLE, N_("Title")}, {ID3_FRAME_YEAR, N_("Year")}, {ID3_FRAME_GENRE, N_("Genre")}, }; /* text information */ for (i = 0; i < sizeof(info) / sizeof(info[0]); ++i) { union id3_field const *field; unsigned int nstrings, namelen, j; char const *name; frame = id3_tag_findframe(tag, info[i].id, 0); if (frame == 0) continue; field = &frame->fields[1]; nstrings = id3_field_getnstrings(field); name = info[i].name; namelen = name ? strlen(name) : 0; // assert(namelen < sizeof(spaces)); for (j = 0; j < nstrings; ++j) { ucs4 = id3_field_getstrings(field, j); assert(ucs4); if (strcmp(info[i].id, ID3_FRAME_GENRE) == 0) ucs4 = id3_genre_name(ucs4); latin1 = id3_ucs4_latin1duplicate(ucs4); if (latin1 == 0) return; if (j == 0 && name) { info3->info[PLAYA_INFO_ARTIST+i].s = latin1; } else { free (latin1); } } } /* comments */ i = 0; while ((frame = id3_tag_findframe(tag, ID3_FRAME_COMMENT, i++))) { id3_latin1_t *ptr; ucs4 = id3_field_getstring(&frame->fields[2]); assert(ucs4); if (*ucs4) continue; ucs4 = id3_field_getfullstring(&frame->fields[3]); assert(ucs4); latin1 = id3_ucs4_latin1duplicate(ucs4); if (latin1 == 0) break; { int c; ptr = latin1; while (c=*ptr, c) { if (c < ' ' || c>127) *ptr = ' '; ptr++; } } if (strlen(latin1) > 0) { info3->info[PLAYA_INFO_COMMENTS].s = latin1; break; /* One comment only ! */ } else { free (latin1); } } }
static gchar * getFrameText (struct id3_tag *tag, char *frame_name) { const id3_ucs4_t *string; struct id3_frame *frame; union id3_field *field; gchar *utf8 = NULL; enum id3_field_textencoding encoding = ID3_FIELD_TEXTENCODING_ISO_8859_1; frame = id3_tag_findframe (tag, frame_name, 0); if (!frame) return NULL; /* Find the encoding used for the field */ field = id3_frame_field (frame, 0); //printf ("field: %p\n", field); if (field && (id3_field_type (field) == ID3_FIELD_TYPE_TEXTENCODING)) { encoding = field->number.value; //printf ("encoding: %d\n", encoding); } if (strcmp (frame_name, ID3_FRAME_COMMENT) == 0) field = id3_frame_field (frame, 3); else field = id3_frame_field (frame, 1); //printf ("field: %p\n", field); if (!field) return NULL; if (strcmp (frame_name, ID3_FRAME_COMMENT) == 0) string = id3_field_getfullstring (field); else string = id3_field_getstrings (field, 0); // g_debug("string: %s\n", string); if (!string) return NULL; if (strcmp (frame_name, ID3_FRAME_GENRE) == 0) string = id3_genre_name (string); if (encoding == ID3_FIELD_TEXTENCODING_ISO_8859_1) { /* ISO_8859_1 is just a "marker" -- most people just drop whatever coding system they are using into it, so we use charset_to_utf8() to convert to utf8 */ id3_latin1_t *raw = id3_ucs4_latin1duplicate (string); utf8 = (gchar *) charset_to_utf8 (raw); g_free (raw); } else { /* Standard unicode is being used -- we won't have to worry about charsets then. */ // g_debug("This frame is a Unicode frame!\n"); utf8 = (gchar *) id3_ucs4_utf8duplicate (string); } // g_debug("Found tag: %s, value: %s\n", frame_name, utf8); return utf8; }
JNIEXPORT jstring JNICALL Java_com_ssb_droidsound_utils_ID3Tag_getStringInfo(JNIEnv *env, jobject obj, jint what) { struct id3_file *id3file = (struct id3_file*)env->GetLongField(obj, refField); struct id3_tag *tag = (struct id3_tag*)env->GetLongField(obj, tagRefField); __android_log_print(ANDROID_LOG_VERBOSE, "ID3Tag", "Get String Info %p %p", id3file, tag); if(!tag && id3file) tag = id3_file_tag(id3file); if(!tag) return 0; const id3_ucs4_t *title = NULL; struct id3_frame *frame = NULL; __android_log_print(ANDROID_LOG_VERBOSE, "ID3Tag", "id3tag %p", tag); switch(what) { case INFO_TITLE: frame = id3_tag_findframe(tag, ID3_FRAME_TITLE, 0); break; case INFO_AUTHOR: frame = id3_tag_findframe(tag, ID3_FRAME_ARTIST, 0); break; case INFO_COPYRIGHT: frame = id3_tag_findframe(tag, ID3_FRAME_YEAR, 0); break; case ID3INFO_GENRE: frame = id3_tag_findframe(tag, ID3_FRAME_GENRE, 0); if(frame) { title = id3_field_getstrings(&frame->fields[1], 0); title = id3_genre_name(title); } break; case ID3INFO_ALBUM: frame = id3_tag_findframe(tag, ID3_FRAME_ALBUM, 0); break; case ID3INFO_TRACK: frame = id3_tag_findframe(tag, ID3_FRAME_TRACK, 0); break; case ID3INFO_COMMENT: frame = id3_tag_findframe(tag, ID3_FRAME_COMMENT, 0); if(frame) { __android_log_print(ANDROID_LOG_VERBOSE, "ID3Tag", "COMMENT %d fields", frame->nfields); if(frame->nfields >= 4) title = id3_field_getfullstring(&frame->fields[3]); } break; } if(frame) { __android_log_print(ANDROID_LOG_VERBOSE, "ID3Tag", "frame %p %d", frame, what); if(title == NULL) title = id3_field_getstrings(&frame->fields[1], 0); if(title) { __android_log_print(ANDROID_LOG_VERBOSE, "ID3Tag", "title %p", title); id3_utf8_t *titleu8 = id3_ucs4_utf8duplicate(title); jstring j = env->NewStringUTF((const char *)titleu8); return j; } } return NULL; }