Ejemplo n.º 1
0
char * getTagString(struct id3_tag *tag, const char *frameName) {
	struct id3_frame *frame;
	union id3_field *field;
	int i;
	const id3_ucs4_t *unicode;
	char *ret;
	
	frame = id3_tag_findframe(tag,frameName,0);
	if(!frame) {
		fprintf(stdout,"No frame\n");
		return NULL;
	}
	for(i=0;;i++) {
		field = id3_frame_field(frame,i);
		if(!field) {
			break;
		}
		if(id3_field_type(field) == ID3_FIELD_TYPE_STRINGLIST) {
			unicode = id3_field_getstrings(field,0);
			if(unicode) {
				id3_utf8_t *str;
				str = id3_ucs4_utf8duplicate(unicode);
				ret = (char *) str;
			}
			
		}
	}
	
	return ret;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
id3_ucs4_list_t *metadata_getstrings(const struct id3_tag* tag, const char* id, enum id3_field_textencoding* encoding)
{
  int nstrings, j;
  union id3_field const *field;
  struct id3_frame const *frame;
  id3_ucs4_list_t *list;

  frame = id3_tag_findframe(tag, id, 0);
  if (frame == 0)
	  return 0;

  *encoding = id3_field_gettextencoding(id3_frame_field(frame, 0));

  field = id3_frame_field(frame, 1);
  if (field == 0)
    return 0;

  nstrings = id3_field_getnstrings(field);

  list = 0;
  if (nstrings)
  {
    list = (id3_ucs4_list_t*)malloc(sizeof(*list));
    if (list)
      list->strings = (const id3_ucs4_t**)malloc(nstrings * sizeof(*list->strings));
  }
  if (list && list->strings)
  {
    list->nstrings = nstrings;
    for (j = 0; j < list->nstrings; ++j)
      list->strings[j] = id3_field_getstrings(field, j);
  }
  return list;
}
Ejemplo n.º 4
0
const id3_ucs4_t* metadata_getstring(const struct id3_tag* tag, const char* id, enum id3_field_textencoding* encoding)
{
  int nstrings, j;
  char const *name;
  id3_ucs4_t const *ucs4;
  union id3_field const *field;
  struct id3_frame const *frame;

  frame = id3_tag_findframe(tag, id, 0);
  if (frame == 0)
	  return id3_ucs4_empty;

  *encoding = id3_field_gettextencoding(id3_frame_field(frame, 0));

  field = id3_frame_field(frame, 1);
  if (field == 0)
    return id3_ucs4_empty;

  nstrings = id3_field_getnstrings(field);

  ucs4 = id3_ucs4_empty;

  for (j = 0; j < nstrings; ++j)
  {
    ucs4 = id3_field_getstrings(field, j);
    if (ucs4 && *ucs4)
      break;
  }

  return ucs4;
}
Ejemplo n.º 5
0
/*
 * NAME:	v1->render()
 * DESCRIPTION:	render an ID3v1 (or ID3v1.1) tag
 */
static
id3_length_t v1_render(struct id3_tag const *tag, id3_byte_t *buffer)
{
  struct id3_frame *frame;
  unsigned int number, i;

  if (buffer == 0)
    return 128;

  id3_render_immediate(&buffer, "TAG", 3);

  v1_renderstr(tag, ID3_FRAME_TITLE,   &buffer, 30);
  v1_renderstr(tag, ID3_FRAME_ARTIST,  &buffer, 30);
  v1_renderstr(tag, ID3_FRAME_ALBUM,   &buffer, 30);
  v1_renderstr(tag, ID3_FRAME_YEAR,    &buffer,  4);
  v1_renderstr(tag, ID3_FRAME_COMMENT, &buffer, 30);

  frame = id3_tag_findframe(tag, ID3_FRAME_TRACK, 0);
  if (frame) {
    number = id3_ucs4_getnumber(id3_field_getstrings(&frame->fields[1], 0));
    if (number & 0xff) {
      buffer[-2] = 0;
      buffer[-1] = number;
    }
  }

  frame = id3_tag_findframe(tag, ID3_FRAME_GENRE, 0);
  number = frame ?
    id3_ucs4_getnumber(id3_field_getstrings(&frame->fields[1], 0)) : 0xff;
  id3_render_int(&buffer, number, 1);

  /* make sure the tag is not empty */

  buffer -= 128;
  for (i = 3; i < 127; ++i) {
    if (buffer[i] != ' ')
      break;
  }

  return (i == 127 && buffer[127] == 0xff) ? 0 : 128;
}
Ejemplo n.º 6
0
static char *get_tag (struct id3_tag *tag, const char *what)
{
	struct id3_frame *frame;
	union id3_field *field;
	const id3_ucs4_t *ucs4;
	char *comm = NULL;

	frame = id3_tag_findframe (tag, what, 0);
	if (frame && (field = &frame->fields[1])) {
		ucs4 = id3_field_getstrings (field, 0);
		if (ucs4)
			comm = (char *)id3_ucs4_utf8duplicate (ucs4);
	}

	return comm;
}
Ejemplo n.º 7
0
QString mpgDecoder::getID3String( id3_tag* idtag, const char* field_frame )
{
    QString str;
    id3_frame* frame = id3_tag_findframe( idtag, field_frame, 0 );
    if(frame)
    {
        id3_field* field = id3_frame_field(frame, 1);
        if(field)
        {
            const id3_ucs4_t* id3_string = id3_field_getstrings(field, 0);
            if(id3_string)
                str = (char*)id3_ucs4_utf8duplicate(id3_string);
        }
    }
    return str;
}
Ejemplo n.º 8
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);
	}
}
Ejemplo n.º 9
0
static
void v1_renderstr(struct id3_tag const *tag, char const *frameid,
		  id3_byte_t **buffer, id3_length_t length)
{
  struct id3_frame *frame;
  id3_ucs4_t const *string;

  frame = id3_tag_findframe(tag, frameid, 0);
  if (frame == 0)
    string = id3_ucs4_empty;
  else {
    if (strcmp(frameid, ID3_FRAME_COMMENT) == 0)
      string = id3_field_getfullstring(&frame->fields[3]);
    else
      string = id3_field_getstrings(&frame->fields[1], 0);
  }

  id3_render_paddedstring(buffer, string, length);
}
Ejemplo n.º 10
0
static char *get_tag (struct id3_tag *tag, const char *what)
{
	struct id3_frame *frame;
	union id3_field *field;
	const id3_ucs4_t *ucs4;
	char *comm = NULL;

	frame = id3_tag_findframe (tag, what, 0);
	if (frame && (field = &frame->fields[1])) {
		ucs4 = id3_field_getstrings (field, 0);
		if (ucs4) {
			/* Workaround for ID3 tags v1/v1.1 where the encoding
			 * is latin1. */
            union id3_field *encoding_field = &frame->fields[0];
			if ((id3_tag_options(tag, 0, 0) & ID3_TAG_OPTION_ID3V1) 
                    || ((options_get_int ("EnforceTagsEncoding") && 
                            (id3_field_gettextencoding((encoding_field)) 
                             == ID3_FIELD_TEXTENCODING_ISO_8859_1))))
            {
				char *t;

				comm = (char *)id3_ucs4_latin1duplicate (ucs4);

#ifdef HAVE_RCC
				if (options_get_int("UseRCC"))
					comm = do_rcc (comm);
				else {
#endif /* HAVE_RCC */
					t = comm;
					comm = id3v1_fix (comm);
					free (t);
#ifdef HAVE_RCC
				}
#endif /* HAVE_RCC */
			}
			else
				comm = (char *)id3_ucs4_utf8duplicate (ucs4);
		}
	}

	return comm;
}
Ejemplo n.º 11
0
wchar_t* GetMP3Tag(const id3_tag* tag, const char* name)
{
	wchar_t* content = NULL;
	id3_frame* frame = id3_tag_findframe(tag, name, 0);
	if (frame != NULL)
	{
		id3_field* field = id3_frame_field(frame, 0);
		id3_field_textencoding encoding = id3_field_gettextencoding(field);
		field = id3_frame_field(frame, 1);

		switch (id3_field_type(field))
		{
		case ID3_FIELD_TYPE_STRING:
			content = GetMP3Text(encoding, field, id3_field_getstring(field));
			break;

		case ID3_FIELD_TYPE_STRINGFULL:						
			content = GetMP3Text(encoding, field, id3_field_getfullstring(field));
			break;

		case ID3_FIELD_TYPE_STRINGLIST:
			{				
				DWORD dataLength = 0, bufferLength = 0;
				unsigned int n = id3_field_getnstrings(field);
				for (unsigned int i = 0; i < n; i++)
				{
					wchar_t* p = GetMP3Text(encoding, field, id3_field_getstrings(field, i));
					if (p == NULL)
						continue;

					AppendBuffer((char**)&content, dataLength, bufferLength, (const char*)p, wcslen(p) * 2 + 1);
					SAFE_DELETE_ARRAY(p);
				}
			}
			break;
		}
	}

	return content;
}
Ejemplo n.º 12
0
wxString GetID3FieldStr(struct id3_tag *tp, const char *name)
{
   struct id3_frame *frame;

   frame = id3_tag_findframe(tp, name, 0);
   if (frame) {
      const id3_ucs4_t *ustr;

      if (strcmp(name, ID3_FRAME_COMMENT) == 0)
	 ustr = id3_field_getfullstring(&frame->fields[3]);
      else
	 ustr = id3_field_getstrings(&frame->fields[1], 0);

      if (ustr) {
	 char *str = (char *)id3_ucs4_utf8duplicate(ustr);
	 wxString s = UTF8CTOWX(str);
	 free(str);
	 return s;
      }
   }

   return wxT("");
}
Ejemplo n.º 13
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;

}
Ejemplo n.º 14
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);
}
Ejemplo n.º 15
0
static int
_get_dsftags(char *file, struct song_metadata *psong)
{
	struct id3_tag *pid3tag;
	struct id3_frame *pid3frame;
	int err;
	int index;
	int used;
	unsigned char *utf8_text;
	int genre = WINAMP_GENRE_UNKNOWN;
	int have_utf8;
	int have_text;
	id3_ucs4_t const *native_text;
	char *tmp;
	int got_numeric_genre;
	id3_byte_t const *image;
	id3_length_t image_size = 0;
	
	FILE *fp;
	struct id3header *pid3;
	uint32_t len;
	unsigned char hdr[28] = {0};
	uint64_t total_size = 0;
	uint64_t pointer_to_metadata_chunk = 0;
	uint64_t metadata_chunk_size = 0;
	unsigned char *id3tagbuf = NULL;

	//DEBUG DPRINTF(E_DEBUG,L_SCANNER,"Getting DSF file info\n");

	if((fp = fopen(file, "rb")) == NULL)
	{
		DPRINTF(E_WARN, L_SCANNER, "Could not create file handle\n");
		return -1;
	}

	len = 28;
	if(!(len = fread(hdr, len, 1,fp)))
	{
		DPRINTF(E_WARN, L_SCANNER, "Could not read DSD Chunk from %s\n", file);
		fclose(fp);
		return -1;
	}

	if(strncmp((char*)hdr, "DSD ", 4))
	{
		DPRINTF(E_WARN, L_SCANNER, "Invalid DSD Chunk header in %s\n", file);
		fclose(fp);
		return -1;
	}

	total_size = GET_DSF_INT64(hdr + 12);
	pointer_to_metadata_chunk = GET_DSF_INT64(hdr + 20);
	
	//DEBUG DPRINTF(E_DEBUG, L_SCANNER, "%llu\n", total_size);
	//DEBUG DPRINTF(E_DEBUG, L_SCANNER, "%llu\n", pointer_to_metadata_chunk);
	//DEBUG DPRINTF(E_DEBUG, L_SCANNER, "%llu\n", metadata_chunk_size);

	//check invalid metadata
	if(total_size == 0)
	{
		fclose(fp);
		DPRINTF(E_INFO, L_SCANNER, "Invalid TotalDataSize in %s\n", file);
		return 0;
	}

	if(pointer_to_metadata_chunk == 0)
	{
		fclose(fp);
		DPRINTF(E_INFO, L_SCANNER, "Metadata doesn't exist %s\n", file);
		return 0;
	}

	if(total_size > pointer_to_metadata_chunk)
	{
		metadata_chunk_size = total_size - pointer_to_metadata_chunk;
	}
	else
	{
		fclose(fp);
		DPRINTF(E_INFO, L_SCANNER, "Invalid PointerToMetadata in %s\n", file);
		return 0;
	}

	fseeko(fp, pointer_to_metadata_chunk,SEEK_SET);

	id3tagbuf = (unsigned char *)malloc(sizeof(unsigned char)*metadata_chunk_size);
	if(id3tagbuf == NULL)
	{
		fclose(fp);
		DPRINTF(E_WARN, L_SCANNER, "Out of memory.Big MetadataSize in %s\n",file);
		return -1;
	}
	memset(id3tagbuf, 0,sizeof(unsigned char)*metadata_chunk_size);
	
	if(!(len = fread(id3tagbuf,metadata_chunk_size,1,fp)))
	{
		fclose(fp);
		free(id3tagbuf);
		DPRINTF(E_WARN, L_SCANNER, "Could not read Metadata Chunk from %s\n", file);
		return -1;
	}
	
	pid3tag = id3_tag_parse(id3tagbuf,metadata_chunk_size);
	
	if(!pid3tag)
	{
		free(id3tagbuf);
		err = errno;
		errno = err;
		DPRINTF(E_WARN, L_SCANNER, "Cannot get ID3 tag for %s\n", file);
		return -1;
	}

	pid3 = (struct id3header*)id3tagbuf;

	if(strncmp((char*)pid3->id, "ID3", 3) == 0)
	{
		char tagversion[16];

		/* found an ID3 header... */
		snprintf(tagversion, sizeof(tagversion), "ID3v2.%d.%d",
			 pid3->version[0], pid3->version[1]);
		psong->tagversion = strdup(tagversion);
	}
	pid3 = NULL;
	
	index = 0;
	while((pid3frame = id3_tag_findframe(pid3tag, "", index)))
	{
		used = 0;
		utf8_text = NULL;
		native_text = NULL;
		have_utf8 = 0;
		have_text = 0;

		if(!strcmp(pid3frame->id, "YTCP"))   /* for id3v2.2 */
		{
			psong->compilation = 1;
			DPRINTF(E_DEBUG, L_SCANNER, "Compilation: %d [%s]\n", psong->compilation, basename(file));
		}
		else if(!strcmp(pid3frame->id, "APIC") && !image_size)
		{
			if( (strcmp((char*)id3_field_getlatin1(&pid3frame->fields[1]), "image/jpeg") == 0) ||
			    (strcmp((char*)id3_field_getlatin1(&pid3frame->fields[1]), "image/jpg") == 0) ||
			    (strcmp((char*)id3_field_getlatin1(&pid3frame->fields[1]), "jpeg") == 0) )
			{
				image = id3_field_getbinarydata(&pid3frame->fields[4], &image_size);
				if( image_size )
				{
					psong->image = malloc(image_size);
					memcpy(psong->image, image, image_size);
					psong->image_size = image_size;
					//DEBUG DPRINTF(E_DEBUG, L_SCANNER, "Found thumbnail: %d\n", psong->image_size);
				}
			}
		}

		if(((pid3frame->id[0] == 'T') || (strcmp(pid3frame->id, "COMM") == 0)) &&
		   (id3_field_getnstrings(&pid3frame->fields[1])))
			have_text = 1;

		if(have_text)
		{
			native_text = id3_field_getstrings(&pid3frame->fields[1], 0);

			if(native_text)
			{
				have_utf8 = 1;
				if(lang_index >= 0)
					utf8_text = _get_utf8_text(native_text); // through iconv
				else
					utf8_text = (unsigned char*)id3_ucs4_utf8duplicate(native_text);

				if(!strcmp(pid3frame->id, "TIT2"))
				{
					used = 1;
					psong->title = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TPE1"))
				{
					used = 1;
					psong->contributor[ROLE_ARTIST] = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TALB"))
				{
					used = 1;
					psong->album = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TCOM"))
				{
					used = 1;
					psong->contributor[ROLE_COMPOSER] = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TIT1"))
				{
					used = 1;
					psong->grouping = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TPE2"))
				{
					used = 1;
					psong->contributor[ROLE_BAND] = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TPE3"))
				{
					used = 1;
					psong->contributor[ROLE_CONDUCTOR] = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TCON"))
				{
					used = 1;
					psong->genre = (char*)utf8_text;
					got_numeric_genre = 0;
					if(psong->genre)
					{
						if(!strlen(psong->genre))
						{
							genre = WINAMP_GENRE_UNKNOWN;
							got_numeric_genre = 1;
						}
						else if(isdigit(psong->genre[0]))
						{
							genre = atoi(psong->genre);
							got_numeric_genre = 1;
						}
						else if((psong->genre[0] == '(') && (isdigit(psong->genre[1])))
						{
							genre = atoi((char*)&psong->genre[1]);
							got_numeric_genre = 1;
						}

						if(got_numeric_genre)
						{
							if((genre < 0) || (genre > WINAMP_GENRE_UNKNOWN))
								genre = WINAMP_GENRE_UNKNOWN;
							free(psong->genre);
							psong->genre = strdup(winamp_genre[genre]);
						}
					}
				}
				else if(!strcmp(pid3frame->id, "COMM"))
				{
					used = 1;
					psong->comment = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TPOS"))
				{
					tmp = (char*)utf8_text;
					strsep(&tmp, "/");
					if(tmp)
					{
						psong->total_discs = atoi(tmp);
					}
					psong->disc = atoi((char*)utf8_text);
				}
				else if(!strcmp(pid3frame->id, "TRCK"))
				{
					tmp = (char*)utf8_text;
					strsep(&tmp, "/");
					if(tmp)
					{
						psong->total_tracks = atoi(tmp);
					}
					psong->track = atoi((char*)utf8_text);
				}
				else if(!strcmp(pid3frame->id, "TDRC"))
				{
					psong->year = atoi((char*)utf8_text);
				}
				else if(!strcmp(pid3frame->id, "TLEN"))
				{
					psong->song_length = atoi((char*)utf8_text);
				}
				else if(!strcmp(pid3frame->id, "TBPM"))
				{
					psong->bpm = atoi((char*)utf8_text);
				}
				else if(!strcmp(pid3frame->id, "TCMP"))
				{
					psong->compilation = (char)atoi((char*)utf8_text);
				}
			}
		}

		// check if text tag
		if((!used) && (have_utf8) && (utf8_text))
			free(utf8_text);

		// v2 COMM
		if((!strcmp(pid3frame->id, "COMM")) && (pid3frame->nfields == 4))
		{
			native_text = id3_field_getstring(&pid3frame->fields[2]);
			if(native_text)
			{
				utf8_text = (unsigned char*)id3_ucs4_utf8duplicate(native_text);
				if((utf8_text) && (strncasecmp((char*)utf8_text, "iTun", 4) != 0))
				{
					// read comment
					free(utf8_text);

					native_text = id3_field_getfullstring(&pid3frame->fields[3]);
					if(native_text)
					{
						utf8_text = (unsigned char*)id3_ucs4_utf8duplicate(native_text);
						if(utf8_text)
						{
							free(psong->comment);
							psong->comment = (char*)utf8_text;
						}
					}
				}
				else
				{
					free(utf8_text);
				}
			}
		}

		index++;
	}

	id3_tag_delete(pid3tag);
	free(id3tagbuf);
	fclose(fp);
	//DPRINTF(E_DEBUG, L_SCANNER, "Got id3tag successfully for file=%s\n", file);
	return 0;
}
Ejemplo n.º 16
0
void MP3ImportFileHandle::ImportID3(Tags *tags)
{
#ifdef USE_LIBID3TAG 
   struct id3_file *fp = id3_file_open(OSFILENAME(mFilename), ID3_FILE_MODE_READONLY);
   if (!fp) {
      return;
   }

   struct id3_tag *tp = id3_file_tag(fp);
   if (!tp) {
      id3_file_close(fp);
      return;
   }

   tags->Clear();
   tags->SetID3V2( tp->options & ID3_TAG_OPTION_ID3V1 ? false : true );

   // Loop through all frames
   for (int i = 0; i < (int) tp->nframes; i++) {
      struct id3_frame *frame = tp->frames[i];

      // printf("ID: %08x '%4s'\n", (int) *(int *)frame->id, frame->id);
      // printf("Desc: %s\n", frame->description);
      // printf("Num fields: %d\n", frame->nfields);

      // for (int j = 0; j < (int) frame->nfields; j++) {
      //    printf("field %d type %d\n", j, frame->fields[j].type );
      //    if (frame->fields[j].type == ID3_FIELD_TYPE_STRINGLIST) {
      //       printf("num strings %d\n", frame->fields[j].stringlist.nstrings);
      //    }
      // }

      wxString n, v;

      // Determine the tag name
      if (strcmp(frame->id, ID3_FRAME_TITLE) == 0) {
         n = TAG_TITLE;
      }
      else if (strcmp(frame->id, ID3_FRAME_ARTIST) == 0) {
         n = TAG_ARTIST;
      }
      else if (strcmp(frame->id, ID3_FRAME_ALBUM) == 0) {
         n = TAG_ALBUM;
      }
      else if (strcmp(frame->id, ID3_FRAME_TRACK) == 0) {
         n = TAG_TRACK;
      }
      else if (strcmp(frame->id, "TYER") == 0) {
         n = TAG_YEAR;
      }
      else if (strcmp(frame->id, ID3_FRAME_YEAR) == 0) {
         n = TAG_YEAR;
      }
      else if (strcmp(frame->id, ID3_FRAME_COMMENT) == 0) {
         n = TAG_COMMENTS;
      }
      else if (strcmp(frame->id, ID3_FRAME_GENRE) == 0) {
         n = TAG_GENRE;
      }
   else {
         // Use frame description as default tag name.  The descriptions
         // may include several "meanings" separated by "/" characters, so
         // we just use the first meaning
         n = UTF8CTOWX(frame->description).BeforeFirst(wxT('/'));
      }

      const id3_ucs4_t *ustr = NULL;

      if (n == TAG_COMMENTS) {
         ustr = id3_field_getfullstring(&frame->fields[3]);
      }
      else if (frame->nfields == 3) {
         ustr = id3_field_getstring(&frame->fields[1]);
         if (ustr) {
            char *str = (char *)id3_ucs4_utf8duplicate(ustr);
            n = UTF8CTOWX(str);
            free(str);
         }

         ustr = id3_field_getstring(&frame->fields[2]);
      }
      else if (frame->nfields >= 2) {
         ustr = id3_field_getstrings(&frame->fields[1], 0);
      }

      if (ustr) {
         char *str = (char *)id3_ucs4_utf8duplicate(ustr);
         v = UTF8CTOWX(str);
         free(str);
      }

      if (!n.IsEmpty() && !v.IsEmpty()) {
         tags->SetTag(n, v);
   }
}

   // Convert v1 genre to name
   if (tags->HasTag(TAG_GENRE)) {
      long g = -1;
      if (tags->GetTag(TAG_GENRE).ToLong(&g)) {
         tags->SetTag(TAG_GENRE, tags->GetGenre(g));
   }
}

   id3_file_close(fp);
#endif // ifdef USE_LIBID3TAG 
}
Ejemplo n.º 17
0
Archivo: id3read.c Proyecto: 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;
}
Ejemplo n.º 18
0
void MP3ImportFileHandle::ImportID3(Tags *tags)
{
#ifdef USE_LIBID3TAG
   wxFile f;   // will be closed when it goes out of scope
   struct id3_file *fp = NULL;

   if (f.Open(mFilename)) {
      // Use id3_file_fdopen() instead of id3_file_open since wxWidgets can open a
      // file with a Unicode name and id3_file_open() can't (under Windows).
      fp = id3_file_fdopen(f.fd(), ID3_FILE_MODE_READONLY);
   }

   if (!fp) {
      return;
   }

   // The file descriptor is now owned by "fp", so we must tell "f" to forget
   // about it.
   f.Detach();

   struct id3_tag *tp = id3_file_tag(fp);
   if (!tp) {
      id3_file_close(fp);
      return;
   }

   tags->Clear();

   // Loop through all frames
   bool have_year = false;
   for (int i = 0; i < (int) tp->nframes; i++) {
      struct id3_frame *frame = tp->frames[i];

      // printf("ID: %08x '%4s'\n", (int) *(int *)frame->id, frame->id);
      // printf("Desc: %s\n", frame->description);
      // printf("Num fields: %d\n", frame->nfields);

      // for (int j = 0; j < (int) frame->nfields; j++) {
      //    printf("field %d type %d\n", j, frame->fields[j].type );
      //    if (frame->fields[j].type == ID3_FIELD_TYPE_STRINGLIST) {
      //       printf("num strings %d\n", frame->fields[j].stringlist.nstrings);
      //    }
      // }

      wxString n, v;

      // Determine the tag name
      if (strcmp(frame->id, ID3_FRAME_TITLE) == 0) {
         n = TAG_TITLE;
      }
      else if (strcmp(frame->id, ID3_FRAME_ARTIST) == 0) {
         n = TAG_ARTIST;
      }
      else if (strcmp(frame->id, ID3_FRAME_ALBUM) == 0) {
         n = TAG_ALBUM;
      }
      else if (strcmp(frame->id, ID3_FRAME_TRACK) == 0) {
         n = TAG_TRACK;
      }
      else if (strcmp(frame->id, ID3_FRAME_YEAR) == 0) {
         // LLL:  When libid3tag encounters the "TYER" tag, it converts it to a
         //       "ZOBS" (obsolete) tag and adds a "TDRC" tag at the end of the
         //       list of tags using the first 4 characters of the "TYER" tag.
         //       Since we write both the "TDRC" and "TYER" tags, the "TDRC" tag
         //       will always be encountered first in the list.  We want use it
         //       since the converted "TYER" tag may have been truncated.
         if (have_year) {
            continue;
         }
         n = TAG_YEAR;
         have_year = true;
      }
      else if (strcmp(frame->id, ID3_FRAME_COMMENT) == 0) {
         n = TAG_COMMENTS;
      }
      else if (strcmp(frame->id, ID3_FRAME_GENRE) == 0) {
         n = TAG_GENRE;
      }
   else {
         // Use frame description as default tag name.  The descriptions
         // may include several "meanings" separated by "/" characters, so
         // we just use the first meaning
         n = UTF8CTOWX(frame->description).BeforeFirst(wxT('/'));
      }

      const id3_ucs4_t *ustr = NULL;

      if (n == TAG_COMMENTS) {
         ustr = id3_field_getfullstring(&frame->fields[3]);
      }
      else if (frame->nfields == 3) {
         ustr = id3_field_getstring(&frame->fields[1]);
         if (ustr) {
            char *str = (char *)id3_ucs4_utf8duplicate(ustr);
            n = UTF8CTOWX(str);
            free(str);
         }

         ustr = id3_field_getstring(&frame->fields[2]);
      }
      else if (frame->nfields >= 2) {
         ustr = id3_field_getstrings(&frame->fields[1], 0);
      }

      if (ustr) {
         char *str = (char *)id3_ucs4_utf8duplicate(ustr);
         v = UTF8CTOWX(str);
         free(str);
      }

      if (!n.IsEmpty() && !v.IsEmpty()) {
         tags->SetTag(n, v);
   }
}

   // Convert v1 genre to name
   if (tags->HasTag(TAG_GENRE)) {
      long g = -1;
      if (tags->GetTag(TAG_GENRE).ToLong(&g)) {
         tags->SetTag(TAG_GENRE, tags->GetGenre(g));
   }
}

   id3_file_close(fp);
#endif // ifdef USE_LIBID3TAG
}
Ejemplo n.º 19
0
int scan_mp3_get_mp3tags(char *file, MP3FILE *pmp3) {
    struct id3_file *pid3file;
    struct id3_tag *pid3tag;
    struct id3_frame *pid3frame;
    int err;
    int index;
    int used;
    char *utf8_text;
    int genre=WINAMP_GENRE_UNKNOWN;
    int have_utf8;
    int have_text;
    id3_ucs4_t const *native_text;
    char *tmp;
    int got_numeric_genre;
    int rating;
    char *conversion_codepage;

    pid3file=id3_file_open(file,ID3_FILE_MODE_READONLY);
    if(!pid3file) {
        DPRINTF(E_WARN,L_SCAN,"Cannot open %s\n",file);
        return FALSE;
    }

    pid3tag=id3_file_tag(pid3file);

    if(!pid3tag) {
        err=errno;
        id3_file_close(pid3file);
        errno=err;
        DPRINTF(E_WARN,L_SCAN,"Cannot get ID3 tag for %s\n",file);
        return FALSE;
    }

    DPRINTF(E_SPAM,L_SCAN,"Starting mp3 tag scan\n");

    conversion_codepage = conf_alloc_string("scanning","mp3_tag_codepage",
                                            "ISO-8859-1");

    index=0;
    while((pid3frame=id3_tag_findframe(pid3tag,"",index))) {
        used=0;
        utf8_text=NULL;
        native_text=NULL;
        have_utf8=0;
        have_text=0;

        DPRINTF(E_SPAM,L_SCAN,"Found tag %s\n",pid3frame->id);

        if(!strcmp(pid3frame->id,"YTCP")) { /* for id3v2.2 */
            pmp3->compilation = 1;
            DPRINTF(E_DBG,L_SCAN,"Compilation: %d\n", pmp3->compilation);
        }

        if(((pid3frame->id[0] == 'T')||(strcmp(pid3frame->id,"COMM")==0)) &&
           (id3_field_getnstrings(&pid3frame->fields[1])))
            have_text=1;

        if(have_text) {
            native_text=id3_field_getstrings(&pid3frame->fields[1],0);

            if(native_text) {
                have_utf8=1;


                utf8_text = (char*)id3_ucs4_utf8duplicate(native_text);
                if(utf8_text)
                    mem_register(utf8_text,0);

                if(id3_field_gettextencoding(&pid3frame->fields[1]) ==
                   ID3_FIELD_TEXTENCODING_ISO_8859_1) {
#ifdef HAVE_ICONV
                    /* this is kinda cheesy, but ucs4* == char* for 8859-1 */
                    free(utf8_text);
                    utf8_text =
                        (char*)util_xtoutf8_alloc((unsigned char*)native_text,
                                                  strlen((char*)native_text),
                                                  conversion_codepage);
#endif
                }



                if(!strcmp(pid3frame->id,"TIT2")) { /* Title */
                    used=1;
                    pmp3->title = utf8_text;
                    DPRINTF(E_DBG,L_SCAN," Title: %s\n",utf8_text);
                } else if(!strcmp(pid3frame->id,"TPE1")) {
                    used=1;
                    pmp3->artist = utf8_text;
                    DPRINTF(E_DBG,L_SCAN," Artist: %s\n",utf8_text);
                } else if(!strcmp(pid3frame->id,"TALB")) {
                    used=1;
                    pmp3->album = utf8_text;
                    DPRINTF(E_DBG,L_SCAN," Album: %s\n",utf8_text);
                } else if(!strcmp(pid3frame->id,"TCOM")) {
                    used=1;
                    pmp3->composer = utf8_text;
                    DPRINTF(E_DBG,L_SCAN," Composer: %s\n",utf8_text);
                } else if(!strcmp(pid3frame->id,"TIT1")) {
                    used=1;
                    pmp3->grouping = utf8_text;
                    DPRINTF(E_DBG,L_SCAN," Grouping: %s\n",utf8_text);
                } else if(!strcmp(pid3frame->id,"TPE2")) {
                    used=1;
                    pmp3->orchestra = utf8_text;
                    DPRINTF(E_DBG,L_SCAN," Orchestra: %s\n",utf8_text);
                } else if(!strcmp(pid3frame->id,"TPE3")) {
                    used=1;
                    pmp3->conductor = utf8_text;
                    DPRINTF(E_DBG,L_SCAN," Conductor: %s\n",utf8_text);
                } else if(!strcmp(pid3frame->id,"TCON")) {
                    used=1;
                    pmp3->genre = utf8_text;
                    got_numeric_genre=0;
                    DPRINTF(E_DBG,L_SCAN," Genre: %s\n",utf8_text);
                    if(pmp3->genre) {
                        if(!strlen(pmp3->genre)) {
                            genre=WINAMP_GENRE_UNKNOWN;
                            got_numeric_genre=1;
                        } else if (scan_mp3_is_numeric(pmp3->genre)) {
                            genre=atoi(pmp3->genre);
                            got_numeric_genre=1;
                        } else if ((pmp3->genre[0] == '(') && (isdigit(pmp3->genre[1]))) {
                            genre=atoi((char*)&pmp3->genre[1]);
                            got_numeric_genre=1;
                        }

                        if(got_numeric_genre) {
                            if((genre < 0) || (genre > WINAMP_GENRE_UNKNOWN))
                                genre=WINAMP_GENRE_UNKNOWN;
                            free(pmp3->genre);
                            pmp3->genre=strdup(scan_winamp_genre[genre]);
                        }
                    }
                } else if(!strcmp(pid3frame->id,"COMM")) {
                    used=1;
                    pmp3->comment = utf8_text;
                    DPRINTF(E_DBG,L_SCAN," Comment: %s\n",pmp3->comment);
                } else if(!strcmp(pid3frame->id,"TPOS")) {
                    tmp=utf8_text;
                    strsep(&tmp,"/");
                    if(tmp) {
                        pmp3->total_discs=atoi(tmp);
                    }
                    pmp3->disc=atoi(utf8_text);
                    DPRINTF(E_DBG,L_SCAN," Disc %d of %d\n",pmp3->disc,pmp3->total_discs);
                } else if(!strcmp(pid3frame->id,"TRCK")) {
                    tmp=utf8_text;
                    strsep(&tmp,"/");
                    if(tmp) {
                        pmp3->total_tracks=atoi(tmp);
                    }
                    pmp3->track=atoi(utf8_text);
                    DPRINTF(E_DBG,L_SCAN," Track %d of %d\n",pmp3->track,pmp3->total_tracks);
                } else if(!strcmp(pid3frame->id,"TDRC")) {
                    pmp3->year = atoi(utf8_text);
                    DPRINTF(E_DBG,L_SCAN," Year: %d\n",pmp3->year);
                } else if(!strcmp(pid3frame->id,"TLEN")) {
                    pmp3->song_length = atoi(utf8_text); /* now in ms */
                    DPRINTF(E_DBG,L_SCAN," Length: %d\n", pmp3->song_length);
                } else if(!strcmp(pid3frame->id,"TBPM")) {
                    pmp3->bpm = atoi(utf8_text);
                    DPRINTF(E_DBG,L_SCAN,"BPM: %d\n", pmp3->bpm);
                } else if(!strcmp(pid3frame->id,"TCMP")) { /* for id3v2.3 */
                    pmp3->compilation = (char)atoi(utf8_text);
                    DPRINTF(E_DBG,L_SCAN,"Compilation: %d\n", pmp3->compilation);
                }
            }
        }

        /* can check for non-text tags here */
        if((!used) && (have_utf8) && (utf8_text))
            free(utf8_text);

        if((!strcmp(pid3frame->id,"POPM")) && (pid3frame->nfields == 3)) {
            rating = id3_field_getint(&pid3frame->fields[1]);
            if(rating >= 0x01)
                pmp3->rating = 20;
            if(rating >= 0x40)
                pmp3->rating = 40;
            if(rating >= 0x80)
                pmp3->rating = 60;
            if(rating >= 0xC4)
                pmp3->rating = 80;
            if(rating >= 0xFF)
                pmp3->rating = 100;
        }


        /* v2 COMM tags are a bit different than v1 */
        if((!strcmp(pid3frame->id,"COMM")) && (pid3frame->nfields == 4)) {
            /* Make sure it isn't a application-specific comment...
             * This currently includes the following:
             *
             * iTunes_CDDB_IDs
             * iTunNORM
             *
             * If other apps stuff crap into comment fields, then we'll ignore them
             * here.
             */
            native_text=id3_field_getstring(&pid3frame->fields[2]);
            if(native_text) {
                utf8_text=(char*)id3_ucs4_utf8duplicate(native_text);
                if(utf8_text)
                    mem_register(utf8_text,0);

                if((utf8_text) && (strncasecmp(utf8_text,"iTun",4) != 0)) {
                    /* it's a real comment */
                    if(utf8_text)
                        free(utf8_text);

                    native_text=id3_field_getfullstring(&pid3frame->fields[3]);
                    if(native_text) {
                        if(pmp3->comment)
                            free(pmp3->comment);
                        utf8_text=(char*)id3_ucs4_utf8duplicate(native_text);
                        if(utf8_text) {
                            mem_register(utf8_text,0);
                            pmp3->comment=utf8_text;
                        }
                    }
                } else {
                    if(utf8_text)
                        free(utf8_text);
                }
            }
        }

        index++;
    }

    free(conversion_codepage);
    id3_file_close(pid3file);
    DPRINTF(E_DBG,L_SCAN,"Got id3 tag successfully\n");
    return TRUE;
}
Ejemplo n.º 20
0
/*****************************************************************************
 * ParseID3Tag : parse an id3tag into the info structures
 *****************************************************************************/
static void ParseID3Tag( demux_meta_t *p_demux_meta, const uint8_t *p_data, int i_size )
{
    struct id3_tag   *p_id3_tag;
    struct id3_frame *p_frame;
    vlc_meta_t       *p_meta;
    int i;

    p_id3_tag = id3_tag_parse( p_data, i_size );
    if( !p_id3_tag )
        return;

    if( !p_demux_meta->p_meta )
        p_demux_meta->p_meta = vlc_meta_New();
    p_meta = p_demux_meta->p_meta;

#define ID_IS( a ) (!strcmp(  p_frame->id, a ))
#define DESCR_IS( a) strstr( (char*)p_frame->description, a )
#define GET_STRING(frame,fidx) id3_ucs4_latin1duplicate( id3_field_getstring( &(frame)->fields[fidx] ) )

    /* */
    for( i = 0; (p_frame = id3_tag_findframe( p_id3_tag, "UFID", i )) != NULL; i++ )
    {
        const char *psz_owner = id3_field_getlatin1( &p_frame->fields[0] );

        if( !strncmp( psz_owner, "http://musicbrainz.org", 22 ) )
        {
            id3_byte_t const * p_ufid;
            id3_length_t i_ufidlen;

            p_ufid = id3_field_getbinarydata( &p_frame->fields[1], &i_ufidlen );
            char *psz_ufid = strndup( p_ufid, i_ufidlen );

            vlc_meta_SetTrackID( p_meta, psz_ufid );
            free( psz_ufid );
        }
    }

    /* User defined text (TXXX) */
    for( i = 0; (p_frame = id3_tag_findframe( p_id3_tag, "TXXX", i )) != NULL; i++ )
    {
        /* 3 fields: 'encoding', 'description', 'value' */
        char *psz_name = GET_STRING( p_frame, 1 );
        char *psz_value = GET_STRING( p_frame, 2 );

        vlc_meta_AddExtra( p_meta, psz_name, psz_value );
#if 0
        if( !strncmp( psz_name, "MusicBrainz Artist Id", 21 ) )
            vlc_meta_SetArtistID( p_meta, psz_value );
        if( !strncmp( psz_desc, "MusicBrainz Album Id", 20 ) )
            vlc_meta_SetAlbumID( p_meta, psz_value );
#endif
        free( psz_name );
        free( psz_value );
    }

    /* Relative volume adjustment */
    for( i = 0; (p_frame = id3_tag_findframe( p_id3_tag, "RVA2", i )) != NULL; i++ )
    {
        /* 2 fields: 'latin1', 'binary' */
        const char *psz_type = id3_field_getlatin1( &p_frame->fields[0] );
        if( !strcasecmp( psz_type, "track" ) || !strcasecmp( psz_type, "album" ) ||
            !strcasecmp( psz_type, "normalize" ) )
        {
            id3_byte_t const * p_data;
            id3_length_t i_data;

            p_data = id3_field_getbinarydata( &p_frame->fields[1], &i_data );
            while( i_data >= 4 )
            {
                const unsigned int i_peak_size = p_data[3];
                const float f_temp = GetWBE( &p_data[1] );
                const float f_gain = f_temp / 512.0;
                char psz_value[32];

                if( i_data < i_peak_size + 4 )
                    break;
                /* only master volume */
                if( p_data[0] == 0x01 )
                {
                    snprintf( psz_value, sizeof(psz_value), "%f", f_gain );
                    if( !strcasecmp( psz_type, "album" ) )
                        vlc_meta_AddExtra( p_meta, "REPLAYGAIN_ALBUM_GAIN", psz_value );
                    else
                        vlc_meta_AddExtra( p_meta, "REPLAYGAIN_TRACK_GAIN", psz_value );
                    /* XXX I have no idea what peak unit is ... */
                }
                i_data -= 4+i_peak_size;
            }
        }
    }

    /* TODO 'RGAD' if it is used somewhere */

    /* T--- Text informations */
    for( i = 0; (p_frame = id3_tag_findframe( p_id3_tag, "T", i )) != NULL; i++ )
    {
        unsigned i_strings;
 
        /* Special case TXXX is not the same beast */
        if( ID_IS( "TXXX" ) )
            continue;

        i_strings = id3_field_getnstrings( &p_frame->fields[1] );
        while( i_strings > 0 )
        {
            char *psz_temp = id3_ucs4_utf8duplicate(
                id3_field_getstrings( &p_frame->fields[1], --i_strings ) );

            if( ID_IS( ID3_FRAME_GENRE ) )
            {
                char *psz_endptr;
                int i_genre = strtol( psz_temp, &psz_endptr, 10 );

                if( psz_temp != psz_endptr &&
                    i_genre >= 0 && i_genre < NUM_GENRES )
                {
                    vlc_meta_SetGenre( p_meta, ppsz_genres[atoi(psz_temp)]);
                }
                else
                {
                    /* Unknown genre */
                    vlc_meta_SetGenre( p_meta,psz_temp );
                }
            }
            else if( ID_IS( ID3_FRAME_TITLE ) )
            {
                vlc_meta_SetTitle( p_meta, psz_temp );
            }
            else if( ID_IS( ID3_FRAME_ARTIST ) )
            {
                vlc_meta_SetArtist( p_meta, psz_temp );
            }
            else if( ID_IS( ID3_FRAME_YEAR ) )
            {
                vlc_meta_SetDate( p_meta, psz_temp );
            }
            else if( ID_IS( ID3_FRAME_COMMENT ) )
            {
                vlc_meta_SetDescription( p_meta, psz_temp );
            }
            else if( DESCR_IS( "Copyright" ) )
            {
                vlc_meta_SetCopyright( p_meta, psz_temp );
            }
            else if( DESCR_IS( "Publisher" ) )
            {
                vlc_meta_SetPublisher( p_meta, psz_temp );
            }
            else if( DESCR_IS( "Track number/position in set" ) )
            {
                vlc_meta_SetTrackNum( p_meta, psz_temp );
            }
            else if( DESCR_IS( "Album/movie/show title" ) )
            {
                vlc_meta_SetAlbum( p_meta, psz_temp );
            }
            else if( DESCR_IS( "Encoded by" ) )
            {
                vlc_meta_SetEncodedBy( p_meta, psz_temp );
            }
            else if( ID_IS ( "APIC" ) )
            {
                msg_Dbg( p_demux_meta, "** Has APIC **" );
            }
            else if( p_frame->description )
            {
                /* Unhandled meta */
                vlc_meta_AddExtra( p_meta, (char*)p_frame->description, psz_temp );
            }
            free( psz_temp );
        }
    }
    id3_tag_delete( p_id3_tag );
#undef GET_STRING
#undef DESCR_IS
#undef ID_IS
}
Ejemplo n.º 21
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;

}
Ejemplo n.º 22
0
void Tags::ImportID3(wxString fileName)
{
#ifdef USE_LIBID3TAG 

   struct id3_file *fp = id3_file_open(OSFILENAME(fileName),
                                          ID3_FILE_MODE_READONLY);
   if (!fp) return;

   struct id3_tag *tp = id3_file_tag(fp);
   if (!tp) return;

   mTitle = GetID3FieldStr(tp, ID3_FRAME_TITLE);
   mArtist = GetID3FieldStr(tp, ID3_FRAME_ARTIST);
   mAlbum = GetID3FieldStr(tp, ID3_FRAME_ALBUM);   
   mYear = GetID3FieldStr(tp, ID3_FRAME_YEAR);
   mComments = GetID3FieldStr(tp, ID3_FRAME_COMMENT);

   long l;
   wxString s;
   if ((s = GetID3FieldStr(tp, ID3_FRAME_TRACK)).ToLong(&l))
      mTrackNum = l;

   mID3V2 = ( tp->options & ID3_TAG_OPTION_ID3V1 ) ? false : true;
   
   s = GetID3FieldStr(tp, ID3_FRAME_GENRE);

   if( mID3V2 ) {
      int numGenres = GetNumGenres();
      for(int i=0; i<numGenres; i++)
         if (0 == s.CmpNoCase(GetGenreNum(i)))
            mGenre = i;
   }
   else {
      if( s.ToLong( &l ) )
         mGenre = l;
   }

   // Loop through all remaining frames
   int i;
   for(i=0; i<(int)tp->nframes; i++) {
      struct id3_frame *frame = tp->frames[i];

      //printf("ID: %08x '%4s'\n", (int) *(int *)frame->id, frame->id);
      //printf("Desc: %s\n", frame->description);
      //printf("Num fields: %d\n", frame->nfields);
      
      if (!strcmp(frame->id, ID3_FRAME_TITLE) ||
          !strcmp(frame->id, ID3_FRAME_ARTIST) ||
          !strcmp(frame->id, ID3_FRAME_ALBUM) ||
          !strcmp(frame->id, ID3_FRAME_YEAR) ||
          !strcmp(frame->id, ID3_FRAME_COMMENT) ||
          !strcmp(frame->id, ID3_FRAME_GENRE) ||
          !strcmp(frame->id, ID3_FRAME_TRACK)) {
         continue;
      }

      const id3_ucs4_t *ustr;

      if (frame->nfields>=2) {
         ustr = id3_field_getstrings(&frame->fields[1], 0);
         if (ustr) {
            wxString name = UTF8CTOWX(frame->description);
            
            char *str = (char *)id3_ucs4_utf8duplicate(ustr);
            wxString value = UTF8CTOWX(str);
            free(str);
            
            mExtraNames.Add(name);
            mExtraValues.Add(value);
         }
      }

      if (frame->nfields==3) {
         wxString name, value;

         ustr = id3_field_getstring(&frame->fields[2]);
         if (ustr) {
            char *str = (char *)id3_ucs4_utf8duplicate(ustr);
            value = UTF8CTOWX(str);
            free(str);
         }

         ustr = id3_field_getstring(&frame->fields[1]);
         if (ustr) {
            char *str = (char *)id3_ucs4_utf8duplicate(ustr);
            name = UTF8CTOWX(str);
            free(str);
         }

         mExtraNames.Add(name);
         mExtraValues.Add(value);
      }

   }

   id3_file_close(fp);
#endif // ifdef USE_LIBID3TAG 
}
Ejemplo n.º 23
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);
    }
  }
}
Ejemplo n.º 24
0
/*
 * NAME:	v1->render()
 * DESCRIPTION:	render an ID3v1 (or ID3v1.1) tag
 */
static
id3_length_t v1_render(struct id3_tag const *tag, id3_byte_t *buffer)
{
  id3_byte_t data[128], *ptr;
  struct id3_frame *frame;
  unsigned int i;
  int genre = -1;

  ptr = data;

  id3_render_immediate(&ptr, "TAG", 3);

  v1_renderstr(tag, ID3_FRAME_TITLE,   &ptr, 30);
  v1_renderstr(tag, ID3_FRAME_ARTIST,  &ptr, 30);
  v1_renderstr(tag, ID3_FRAME_ALBUM,   &ptr, 30);
  v1_renderstr(tag, ID3_FRAME_YEAR,    &ptr,  4);
  v1_renderstr(tag, ID3_FRAME_COMMENT, &ptr, 30);

  /* ID3v1.1 track number */

  frame = id3_tag_findframe(tag, ID3_FRAME_TRACK, 0);
  if (frame) {
    unsigned int track;

    track = id3_ucs4_getnumber(id3_field_getstrings(&frame->fields[1], 0));
    if (track > 0 && track <= 0xff) {
      ptr[-2] = 0;
      ptr[-1] = track;
    }
  }

  /* ID3v1 genre number */

  frame = id3_tag_findframe(tag, ID3_FRAME_GENRE, 0);
  if (frame) {
    unsigned int nstrings;

    nstrings = id3_field_getnstrings(&frame->fields[1]);

    for (i = 0; i < nstrings; ++i) {
      genre = id3_genre_number(id3_field_getstrings(&frame->fields[1], i));
      if (genre != -1)
	break;
    }

    if (i == nstrings && nstrings > 0)
      genre = ID3_GENRE_OTHER;
  }

  id3_render_int(&ptr, genre, 1);

  /* make sure the tag is not empty */

  if (genre == -1) {
    for (i = 3; i < 127; ++i) {
      if (data[i] != ' ')
	break;
    }

    if (i == 127)
      return 0;
  }

  if (buffer)
    memcpy(buffer, data, 128);

  return 128;
}
Ejemplo n.º 25
0
static int
_get_mp3tags(char *file, struct song_metadata *psong)
{
	struct id3_file *pid3file;
	struct id3_tag *pid3tag;
	struct id3_frame *pid3frame;
	int err;
	int index;
	int used;
	unsigned char *utf8_text;
	int genre = WINAMP_GENRE_UNKNOWN;
	int have_utf8;
	int have_text;
	id3_ucs4_t const *native_text;
	char *tmp;
	int got_numeric_genre;
	id3_byte_t const *image;
	id3_length_t image_size = 0;

	pid3file = id3_file_open(file, ID3_FILE_MODE_READONLY);
	if(!pid3file)
	{
		DPRINTF(E_ERROR, L_SCANNER, "Cannot open %s\n", file);
		return -1;
	}

	pid3tag = id3_file_tag(pid3file);

	if(!pid3tag)
	{
		err = errno;
		id3_file_close(pid3file);
		errno = err;
		DPRINTF(E_WARN, L_SCANNER, "Cannot get ID3 tag for %s\n", file);
		return -1;
	}

	index = 0;
	while((pid3frame = id3_tag_findframe(pid3tag, "", index)))
	{
		used = 0;
		utf8_text = NULL;
		native_text = NULL;
		have_utf8 = 0;
		have_text = 0;

		if(!strcmp(pid3frame->id, "YTCP"))   /* for id3v2.2 */
		{
			psong->compilation = 1;
			DPRINTF(E_DEBUG, L_SCANNER, "Compilation: %d [%s]\n", psong->compilation, basename(file));
		}
		else if(!strcmp(pid3frame->id, "APIC") && !image_size)
		{
			if( (strcmp((char*)id3_field_getlatin1(&pid3frame->fields[1]), "image/jpeg") == 0) ||
			    (strcmp((char*)id3_field_getlatin1(&pid3frame->fields[1]), "image/jpg") == 0) ||
			    (strcmp((char*)id3_field_getlatin1(&pid3frame->fields[1]), "jpeg") == 0)
#if HAVE_LIBPNG
			    || (strcmp((char*)id3_field_getlatin1(&pid3frame->fields[1]), "image/png") == 0) ||
				(strcmp((char*)id3_field_getlatin1(&pid3frame->fields[1]), "png") == 0)
#endif
			)
			{
				image = id3_field_getbinarydata(&pid3frame->fields[4], &image_size);
				if( image_size )
				{
					psong->image = malloc(image_size);
					memcpy(psong->image, image, image_size);
					psong->image_size = image_size;
					//DEBUG DPRINTF(E_DEBUG, L_SCANNER, "Found thumbnail: %d\n", psong->image_size);
				}
			}
		}

		if(((pid3frame->id[0] == 'T') || (strcmp(pid3frame->id, "COMM") == 0)) &&
		   (id3_field_getnstrings(&pid3frame->fields[1])))
			have_text = 1;

		if(have_text)
		{
			native_text = id3_field_getstrings(&pid3frame->fields[1], 0);

			if(native_text)
			{
				have_utf8 = 1;
				if(lang_index >= 0)
					utf8_text = _get_utf8_text(native_text); // through iconv
				else
					utf8_text = (unsigned char*)id3_ucs4_utf8duplicate(native_text);

				if(!strcmp(pid3frame->id, "TIT2"))
				{
					used = 1;
					psong->title = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TPE1"))
				{
					used = 1;
					psong->contributor[ROLE_ARTIST] = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TALB"))
				{
					used = 1;
					psong->album = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TCOM"))
				{
					used = 1;
					psong->contributor[ROLE_COMPOSER] = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TIT1"))
				{
					used = 1;
					psong->grouping = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TPE2"))
				{
					used = 1;
					psong->contributor[ROLE_BAND] = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TPE3"))
				{
					used = 1;
					psong->contributor[ROLE_CONDUCTOR] = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TCON"))
				{
					used = 1;
					psong->genre = (char*)utf8_text;
					got_numeric_genre = 0;
					if(psong->genre)
					{
						if(!strlen(psong->genre))
						{
							genre = WINAMP_GENRE_UNKNOWN;
							got_numeric_genre = 1;
						}
						else if(isdigit(psong->genre[0]))
						{
							genre = atoi(psong->genre);
							got_numeric_genre = 1;
						}
						else if((psong->genre[0] == '(') && (isdigit(psong->genre[1])))
						{
							genre = atoi((char*)&psong->genre[1]);
							got_numeric_genre = 1;
						}

						if(got_numeric_genre)
						{
							if((genre < 0) || (genre > WINAMP_GENRE_UNKNOWN))
								genre = WINAMP_GENRE_UNKNOWN;
							free(psong->genre);
							psong->genre = strdup(winamp_genre[genre]);
						}
					}
				}
				else if(!strcmp(pid3frame->id, "COMM"))
				{
					used = 1;
					psong->comment = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TPOS"))
				{
					tmp = (char*)utf8_text;
					strsep(&tmp, "/");
					if(tmp)
					{
						psong->total_discs = atoi(tmp);
					}
					psong->disc = atoi((char*)utf8_text);
				}
				else if(!strcmp(pid3frame->id, "TRCK"))
				{
					tmp = (char*)utf8_text;
					strsep(&tmp, "/");
					if(tmp)
					{
						psong->total_tracks = atoi(tmp);
					}
					psong->track = atoi((char*)utf8_text);
				}
				else if(!strcmp(pid3frame->id, "TDRC"))
				{
					psong->year = atoi((char*)utf8_text);
				}
				else if(!strcmp(pid3frame->id, "TLEN"))
				{
					psong->song_length = atoi((char*)utf8_text);
				}
				else if(!strcmp(pid3frame->id, "TBPM"))
				{
					psong->bpm = atoi((char*)utf8_text);
				}
				else if(!strcmp(pid3frame->id, "TCMP"))
				{
					psong->compilation = (char)atoi((char*)utf8_text);
				}
			}
		}

		// check if text tag
		if((!used) && (have_utf8) && (utf8_text))
			free(utf8_text);

		// v2 COMM
		if((!strcmp(pid3frame->id, "COMM")) && (pid3frame->nfields == 4))
		{
			native_text = id3_field_getstring(&pid3frame->fields[2]);
			if(native_text)
			{
				utf8_text = (unsigned char*)id3_ucs4_utf8duplicate(native_text);
				if((utf8_text) && (strncasecmp((char*)utf8_text, "iTun", 4) != 0))
				{
					// read comment
					free(utf8_text);

					native_text = id3_field_getfullstring(&pid3frame->fields[3]);
					if(native_text)
					{
						utf8_text = (unsigned char*)id3_ucs4_utf8duplicate(native_text);
						if(utf8_text)
						{
							free(psong->comment);
							psong->comment = (char*)utf8_text;
						}
					}
				}
				else
				{
					free(utf8_text);
				}
			}
		}

		index++;
	}

	id3_file_close(pid3file);
	//DEBUG DPRINTF(E_INFO, L_SCANNER, "Got id3 tag successfully for file=%s\n", file);
	return 0;
}
Ejemplo n.º 26
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);
}
Ejemplo n.º 27
0
Archivo: tag_id3.c Proyecto: azuwis/mpd
static void
getID3Info(struct id3_tag *tag, const char *id, int type, struct tag *mpdTag)
{
	struct id3_frame const *frame;
	id3_ucs4_t const *ucs4;
	id3_utf8_t *utf8;
	union id3_field const *field;
	unsigned int nstrings, i;
	enum id3_field_textencoding id3_encoding = 0xff;

	frame = id3_tag_findframe(tag, id, 0);
	/* Check frame */
	if (!frame)
	{
		return;
	}
	/* Check fields in frame */
	if(frame->nfields == 0)
	{
		g_debug("Frame has no fields");
		return;
	}

	/* Starting with T is a stringlist */
	if (id[0] == 'T')
	{
		/* This one contains 2 fields:
		 * 1st: Text encoding
		 * 2: Stringlist
		 * Shamefully this isn't the RL case.
		 * But I am going to enforce it anyway. 
		 */
		if(frame->nfields != 2) 
		{
			g_debug("Invalid number '%i' of fields for TXX frame",
				frame->nfields);
			return;
		}
		field = &frame->fields[0];
		/**
		 * First field is encoding field.
		 * This is ignored by mpd.
		 */
		if(field->type != ID3_FIELD_TYPE_TEXTENCODING)
		{
			g_debug("Expected encoding, found: %i",
				field->type);
		} else
                        id3_encoding = field->number.value;
		/* Process remaining fields, should be only one */
		field = &frame->fields[1];
		/* Encoding field */
		if(field->type == ID3_FIELD_TYPE_STRINGLIST) {
			/* 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)
					continue;
				utf8 = processID3FieldString(isId3v1(tag),ucs4, type, id3_encoding);
				if(!utf8)
					continue;

				tag_add_item(mpdTag, type, (char *)utf8);
				g_free(utf8);
			}
		}
		else {
			g_warning("Field type not processed: %i",
				  (int)id3_field_gettextencoding(field));
		}
	}
	/* A comment frame */
	else if(!strcmp(ID3_FRAME_COMMENT, id))
	{
		/* A comment frame is different... */
	/* 1st: encoding
         * 2nd: Language
         * 3rd: String
         * 4th: FullString.
         * The 'value' we want is in the 4th field
         */
		if(frame->nfields == 4)
		{
			/* for now I only read the 4th field, with the fullstring */
			field = &frame->fields[3];
			if(field->type == ID3_FIELD_TYPE_STRINGFULL)
			{
				ucs4 = id3_field_getfullstring(field);
				if(ucs4)
				{
					utf8 = processID3FieldString(isId3v1(tag),ucs4, type, id3_encoding);
					if(utf8)
					{
						tag_add_item(mpdTag, type, (char *)utf8);
						g_free(utf8);
					}
				}
			}
			else
			{
				g_debug("4th field in comment frame differs from expected, got '%i': ignoring",
					field->type);
			}
		}
		else
		{
			g_debug("Invalid 'comments' tag, got '%i' fields instead of 4",
				frame->nfields);
		}
	}
	/* Unsupported */
	else
		g_debug("Unsupported tag type requrested");
}