Example #1
0
/*
** 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;
}
Example #2
0
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("");
}
Example #3
0
/**
 * 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);
	}
}
Example #4
0
File: tag_id3.c Project: azuwis/mpd
/* 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;
}
Example #5
0
/* 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);
}
Example #6
0
/* 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);
}
Example #7
0
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;

}
Example #8
0
/*
 * 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);
    }
  }
}
Example #9
0
File: id3read.c Project: cjd/mtpfs
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;
}
Example #10
0
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;

}