void cFCODatabaseFileIter::SeekToGenre(cGenre::Genre genreId)
{
    for( SeekBegin(); ! Done(); Next() )
    {
        if( GetGenre() == genreId )
            return;
    }
}
Ejemplo n.º 2
0
/* Sets a specified field of the given tag. */
void ID3V1_TAG::SetField(ID3V1_TAG_COMP type, const char* source, int charset)
{
  if (!source) // cannot remove components of ID3V1 tags
    source = "";
  char encoded[32];

  switch( type )
  {
    case ID3V1_TITLE:
      ch_convert( CH_CP_NONE, source, charset, encoded, sizeof( encoded ), 0);
      spacecopy( title, encoded, sizeof title );
      break;

    case ID3V1_ARTIST:
      ch_convert( CH_CP_NONE, source, charset, encoded, sizeof( encoded ), 0);
      spacecopy( artist, encoded, sizeof artist );
      break;

    case ID3V1_ALBUM:
      ch_convert( CH_CP_NONE, source, charset, encoded, sizeof( encoded ), 0);
      spacecopy( album, encoded, sizeof album );
      break;

    case ID3V1_YEAR:
      ch_convert( CH_CP_NONE, source, charset, encoded, sizeof( encoded ), 0);
      spacecopy( year, encoded, sizeof year );
      break;

    case ID3V1_COMMENT:
      ch_convert( CH_CP_NONE, source, charset, encoded, sizeof( encoded ), 0);
      spacecopy( comment, encoded, sizeof comment );
      break;

    case ID3V1_TRACK:
      empty = 0;
      track = atol( source );
      break;

    case ID3V1_GENRE:
    { int i;
      size_t l;
      if (*source == 0)
        genre = 0xFF;
      else if (sscanf(source, "#%i%n", &i, &l) == 1 && l == strlen(source))
        genre = i;
      else
        genre = (unsigned char)GetGenre(source);
      break;
    }
  }
}
Ejemplo n.º 3
0
/*
	GetIcyData()
*/
void CIcy::GetIcyData(ICYDATA* pIcyData)
{
	memset(pIcyData,'\0',sizeof(ICYDATA));
	if(m_nResponse==ICY_CODE_OK)
	{
		strcpyn(pIcyData->station,GetStationName(),ICY_MAX_STATION+1);
		strcpyn(pIcyData->genre,GetGenre(),ICY_MAX_GENRE+1);
		strcpyn(pIcyData->url,GetUrl(),ICY_MAX_URL+1);
		strcpyn(pIcyData->contenttype,GetContentType(),ICY_MAX_CONTENT+1);
		pIcyData->metaint = GetMetaInterval();
		pIcyData->bitrate = GetBitRate();
		strcpyn(pIcyData->notice,GetNotice(),ICY_MAX_NOTICE+1);
		strcpyn(pIcyData->noticeinfo,GetNoticeInfo(),ICY_MAX_NOTICE+1);
		pIcyData->code = m_nResponse;
	}
}
Ejemplo n.º 4
0
int CGenreTable::SearchGenre( CUString strSearch ) const
{
	int i;

	strSearch.TrimLeft();
	strSearch.TrimRight();

	for ( i = 0 ; i < (int)v_Entries.size(); i++ )
	{
		if ( 0 == strSearch.CompareNoCase( GetGenre( i ) ) )
		{
			return i;
		}
	}
	return -1;
}
Ejemplo n.º 5
0
CUString CGenreTable::GetID3V1GenreString( int nID3TagIdx ) const
{
	int i;
	CUString strRet;

	for ( i = 0 ; i < (int)v_Entries.size(); i++ )
	{
		if ( nID3TagIdx == GetID3V1ID( i ) )
		{
			return GetGenre( i );
		}
	}

	strRet = g_language.GetString( IDS_UNKNOWN );

	return strRet;
}
Ejemplo n.º 6
0
int CGenreTable::AddEntry( INT nID3V1ID, const CUString& strGenre, const CUString& strCDDBGenre, bool bCanBeModified  )
{
	bool	bAdd = true;
	int		i = 0;

	GENRETABLEENTRY newEntry;

	newEntry.nID3V1ID = nID3V1ID;
	newEntry.strGenre = strGenre;
	newEntry.bCanBeModified = bCanBeModified;
	newEntry.strCDDBGenre = strCDDBGenre;

	newEntry.strGenre.TrimLeft();
	newEntry.strGenre.TrimRight();

	newEntry.strCDDBGenre.TrimLeft();
	newEntry.strCDDBGenre.TrimRight();

	// check if entry is already in this list
	for ( i = 0 ; i < (int)v_Entries.size(); i++ )
	{
		if ( GetID3V1ID( i )  == nID3V1ID  && 
			( 0 == strGenre.CompareNoCase( GetGenre( i ) ) ) )
		{
			bAdd = false;
		}
	}

	if ( true == bAdd )
	{
		v_Entries.push_back( newEntry );
//		Sort();
	}


	return v_Entries.size();
}
Ejemplo n.º 7
0
bool FLACMetadata::WriteMetadata(CFErrorRef *error)
{
	UInt8 buf [PATH_MAX];
	if(!CFURLGetFileSystemRepresentation(mURL, false, buf, PATH_MAX))
		return false;
	
	FLAC__Metadata_Chain *chain = FLAC__metadata_chain_new();
	
	// ENOMEM sux
	if(NULL == chain)
		return false;
	
	if(!FLAC__metadata_chain_read(chain, reinterpret_cast<const char *>(buf))) {
		
		// Attempt to provide a descriptive error message
		if(NULL != error) {
			CFMutableDictionaryRef errorDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 
																			   32,
																			   &kCFTypeDictionaryKeyCallBacks,
																			   &kCFTypeDictionaryValueCallBacks);
			
			switch(FLAC__metadata_chain_status(chain)) {
				case FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE:
				{
					CFStringRef displayName = CreateDisplayNameForURL(mURL);
					CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, 
																	   NULL, 
																	   CFCopyLocalizedString(CFSTR("The file “%@” is not a valid FLAC file."), ""), 
																	   displayName);
					
					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedDescriptionKey, 
										 errorString);
					
					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedFailureReasonKey, 
										 CFCopyLocalizedString(CFSTR("Not a FLAC file"), ""));
					
					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedRecoverySuggestionKey, 
										 CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), ""));
					
					CFRelease(errorString), errorString = NULL;
					CFRelease(displayName), displayName = NULL;
					
					break;
				}
					
					
				case FLAC__METADATA_CHAIN_STATUS_BAD_METADATA:
				{
					CFStringRef displayName = CreateDisplayNameForURL(mURL);
					CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, 
																	   NULL, 
																	   CFCopyLocalizedString(CFSTR("The file “%@” is not a valid FLAC file."), ""), 
																	   displayName);
					
					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedDescriptionKey, 
										 errorString);
					
					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedFailureReasonKey, 
										 CFCopyLocalizedString(CFSTR("Not a FLAC file"), ""));
					
					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedRecoverySuggestionKey, 
										 CFCopyLocalizedString(CFSTR("The file contains bad metadata."), ""));
					
					CFRelease(errorString), errorString = NULL;
					CFRelease(displayName), displayName = NULL;
					
					break;
				}
					
				default:
				{
					CFStringRef displayName = CreateDisplayNameForURL(mURL);
					CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, 
																	   NULL, 
																	   CFCopyLocalizedString(CFSTR("The file “%@” is not a valid FLAC file."), ""), 
																	   displayName);
					
					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedDescriptionKey, 
										 errorString);
					
					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedFailureReasonKey, 
										 CFCopyLocalizedString(CFSTR("Not a FLAC file"), ""));
					
					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedRecoverySuggestionKey, 
										 CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), ""));
					
					CFRelease(errorString), errorString = NULL;
					CFRelease(displayName), displayName = NULL;
					
					break;
				}
			}
			
			*error = CFErrorCreate(kCFAllocatorDefault, 
								   AudioMetadataErrorDomain, 
								   AudioMetadataFileFormatNotRecognizedError, 
								   errorDictionary);
			
			CFRelease(errorDictionary), errorDictionary = NULL;
		}
		
		FLAC__metadata_chain_delete(chain), chain = NULL;
		
		return false;
	}
	
	FLAC__metadata_chain_sort_padding(chain);
	
	FLAC__Metadata_Iterator *iterator = FLAC__metadata_iterator_new();
	
	if(NULL == iterator) {
		FLAC__metadata_chain_delete(chain), chain = NULL;

		return false;
	}
	
	FLAC__metadata_iterator_init(iterator, chain);
	
	// Seek to the vorbis comment block if it exists
	while(FLAC__METADATA_TYPE_VORBIS_COMMENT != FLAC__metadata_iterator_get_block_type(iterator)) {
		if(!FLAC__metadata_iterator_next(iterator))
			break; // Already at end
	}
	
	FLAC__StreamMetadata *block = NULL;
	
	// If there isn't a vorbis comment block add one
	if(FLAC__METADATA_TYPE_VORBIS_COMMENT != FLAC__metadata_iterator_get_block_type(iterator)) {
		
		// The padding block will be the last block if it exists; add the comment block before it
		if(FLAC__METADATA_TYPE_PADDING == FLAC__metadata_iterator_get_block_type(iterator))
			FLAC__metadata_iterator_prev(iterator);
		
		block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT);
		
		if(NULL == block) {
			FLAC__metadata_chain_delete(chain), chain = NULL;
			FLAC__metadata_iterator_delete(iterator), iterator = NULL;

			return false;
		}
		
		// Add our metadata
		if(!FLAC__metadata_iterator_insert_block_after(iterator, block)) {
			if(NULL != error) {
				CFMutableDictionaryRef errorDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 
																				   32,
																				   &kCFTypeDictionaryKeyCallBacks,
																				   &kCFTypeDictionaryValueCallBacks);

				CFStringRef displayName = CreateDisplayNameForURL(mURL);
				CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, 
																   NULL, 
																   CFCopyLocalizedString(CFSTR("The file “%@” is not a valid FLAC file."), ""), 
																   displayName);
				
				CFDictionarySetValue(errorDictionary, 
									 kCFErrorLocalizedDescriptionKey, 
									 errorString);
				
				CFDictionarySetValue(errorDictionary, 
									 kCFErrorLocalizedFailureReasonKey, 
									 CFCopyLocalizedString(CFSTR("Unable to write metadata"), ""));
				
				CFDictionarySetValue(errorDictionary, 
									 kCFErrorLocalizedRecoverySuggestionKey, 
									 CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), ""));
				
				CFRelease(errorString), errorString = NULL;
				CFRelease(displayName), displayName = NULL;

				*error = CFErrorCreate(kCFAllocatorDefault, 
									   AudioMetadataErrorDomain, 
									   AudioMetadataInputOutputError, 
									   errorDictionary);
				
				CFRelease(errorDictionary), errorDictionary = NULL;				
			}
			
			FLAC__metadata_chain_delete(chain), chain = NULL;
			FLAC__metadata_iterator_delete(iterator), iterator = NULL;
			
			return false;
		}
	}
	else
		block = FLAC__metadata_iterator_get_block(iterator);
	
	// Standard tags
	SetVorbisComment(block, "ALBUM", GetAlbumTitle());
	SetVorbisComment(block, "ARTIST", GetArtist());
	SetVorbisComment(block, "ALBUMARTIST", GetAlbumArtist());
	SetVorbisComment(block, "COMPOSER", GetComposer());
	SetVorbisComment(block, "GENRE", GetGenre());
	SetVorbisComment(block, "DATE", GetReleaseDate());
	SetVorbisComment(block, "DESCRIPTION", GetComment());
	SetVorbisComment(block, "TITLE", GetTitle());
	SetVorbisCommentNumber(block, "TRACKNUMBER", GetTrackNumber());
	SetVorbisCommentNumber(block, "TRACKTOTAL", GetTrackTotal());
	SetVorbisCommentBoolean(block, "COMPILATION", GetCompilation());
	SetVorbisCommentNumber(block, "DISCNUMBER", GetDiscNumber());
	SetVorbisCommentNumber(block, "DISCTOTAL", GetDiscTotal());
	SetVorbisComment(block, "ISRC", GetISRC());
	SetVorbisComment(block, "MCN", GetMCN());

	// Additional metadata
	CFDictionaryRef additionalMetadata = GetAdditionalMetadata();
	if(NULL != additionalMetadata) {
		CFIndex count = CFDictionaryGetCount(additionalMetadata);
		
		const void * keys [count];
		const void * values [count];
		
		CFDictionaryGetKeysAndValues(additionalMetadata, 
									 reinterpret_cast<const void **>(keys), 
									 reinterpret_cast<const void **>(values));
		
		for(CFIndex i = 0; i < count; ++i) {
			CFIndex keySize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(reinterpret_cast<CFStringRef>(keys[i])), kCFStringEncodingASCII);
			char key [keySize + 1];
			       
			if(!CFStringGetCString(reinterpret_cast<CFStringRef>(keys[i]), key, keySize + 1, kCFStringEncodingASCII)) {
				log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger("org.sbooth.AudioEngine.AudioMetadata.FLAC");
				LOG4CXX_WARN(logger, "CFStringGetCString() failed");
				continue;
			}
			
			SetVorbisComment(block, key, reinterpret_cast<CFStringRef>(values[i]));
		}
	}
	
	// ReplayGain info
	SetVorbisCommentDouble(block, "REPLAYGAIN_REFERENCE_LOUDNESS", GetReplayGainReferenceLoudness(), CFSTR("%2.1f dB"));
	SetVorbisCommentDouble(block, "REPLAYGAIN_TRACK_GAIN", GetReplayGainReferenceLoudness(), CFSTR("%+2.2f dB"));
	SetVorbisCommentDouble(block, "REPLAYGAIN_TRACK_PEAK", GetReplayGainTrackGain(), CFSTR("%1.8f"));
	SetVorbisCommentDouble(block, "REPLAYGAIN_ALBUM_GAIN", GetReplayGainAlbumGain(), CFSTR("%+2.2f dB"));
	SetVorbisCommentDouble(block, "REPLAYGAIN_ALBUM_PEAK", GetReplayGainAlbumPeak(), CFSTR("%1.8f"));
	
	// Write the new metadata to the file
	if(!FLAC__metadata_chain_write(chain, true, false)) {
		if(NULL != error) {
			CFMutableDictionaryRef errorDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 
																			   32,
																			   &kCFTypeDictionaryKeyCallBacks,
																			   &kCFTypeDictionaryValueCallBacks);

			CFStringRef displayName = CreateDisplayNameForURL(mURL);
			CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, 
															   NULL, 
															   CFCopyLocalizedString(CFSTR("The file “%@” is not a valid FLAC file."), ""), 
															   displayName);
			
			CFDictionarySetValue(errorDictionary, 
								 kCFErrorLocalizedDescriptionKey, 
								 errorString);
			
			CFDictionarySetValue(errorDictionary, 
								 kCFErrorLocalizedFailureReasonKey, 
								 CFCopyLocalizedString(CFSTR("Unable to write metadata"), ""));
			
			CFDictionarySetValue(errorDictionary, 
								 kCFErrorLocalizedRecoverySuggestionKey, 
								 CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), ""));
			
			CFRelease(errorString), errorString = NULL;
			CFRelease(displayName), displayName = NULL;
			
			*error = CFErrorCreate(kCFAllocatorDefault, 
								   AudioMetadataErrorDomain, 
								   AudioMetadataInputOutputError, 
								   errorDictionary);
			
			CFRelease(errorDictionary), errorDictionary = NULL;				
		}
		
		FLAC__metadata_chain_delete(chain), chain = NULL;
		FLAC__metadata_iterator_delete(iterator), iterator = NULL;
		
		return false;
	}
	
	FLAC__metadata_chain_delete(chain), chain = NULL;
	FLAC__metadata_iterator_delete(iterator), iterator = NULL;
	
	MergeChangedMetadataIntoMetadata();
	
	return true;
}
Ejemplo n.º 8
0
void FillID3List(HWND hwndDlg, HWND hwndList, char *filename)
{
    ID3Tag *tag;
    ID3Frame *frame;
    ID3Field *field;
    ID3_FrameID eFrameID;
    char info[1024];
    int numFrames;
    int i;
    int iItem = 0;


    if ((tag = ID3Tag_New()) != NULL)
    {
        ID3Tag_Link(tag, filename);

        numFrames = ID3Tag_NumFrames(tag);

        for (i = 0; i < numFrames; i++)
        {
            iItem++;

            frame = ID3Tag_GetFrameNum(tag, i);
            eFrameID = ID3Frame_GetID(frame);

            switch (eFrameID)
            {
            case ID3FID_ALBUM:            case ID3FID_BPM:
            case ID3FID_COMPOSER:         case ID3FID_CONTENTTYPE:
            case ID3FID_COPYRIGHT:        case ID3FID_DATE:
            case ID3FID_PLAYLISTDELAY:    case ID3FID_ENCODEDBY:
            case ID3FID_LYRICIST:         case ID3FID_FILETYPE:
            case ID3FID_TIME:             case ID3FID_CONTENTGROUP:
            case ID3FID_TITLE:            case ID3FID_SUBTITLE:
            case ID3FID_INITIALKEY:       case ID3FID_LANGUAGE:
            case ID3FID_SONGLEN:          case ID3FID_MEDIATYPE:
            case ID3FID_ORIGALBUM:        case ID3FID_ORIGFILENAME:
            case ID3FID_ORIGLYRICIST:     case ID3FID_ORIGARTIST:
            case ID3FID_ORIGYEAR:         case ID3FID_FILEOWNER:
            case ID3FID_LEADARTIST:       case ID3FID_BAND:
            case ID3FID_CONDUCTOR:        case ID3FID_MIXARTIST:
            case ID3FID_PARTINSET:        case ID3FID_PUBLISHER:
            case ID3FID_TRACKNUM:         case ID3FID_RECORDINGDATES:
            case ID3FID_NETRADIOSTATION:  case ID3FID_NETRADIOOWNER:
            case ID3FID_SIZE:             case ID3FID_ISRC:
            case ID3FID_ENCODERSETTINGS:  case ID3FID_YEAR:
            {
                LV_ITEM lvi;
                ID3ITEM *pItem = LocalAlloc(LPTR, sizeof(ID3ITEM));

                /* Initialize LV_ITEM members that are common to all items. */
                lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
                lvi.state = 0;
                lvi.stateMask = 0;
                lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
                lvi.iImage = 0;
                lvi.iItem = iItem;
                lvi.iSubItem = 0;

                pItem->frameId = eFrameID;
                pItem->aCols[0] = GetFrameDesc(eFrameID);

                field = ID3Frame_GetField(frame, ID3FN_TEXT);
                ID3Field_GetASCII(field, info, 1024, 1);
                if (eFrameID == ID3FID_CONTENTTYPE)
                    pItem->aCols[1] = GetGenre(info);
                else
                    pItem->aCols[1] = DupString(info);

                lvi.lParam = (LPARAM)pItem;    /* item data */

                /* Add the item. */
                ListView_InsertItem(hwndList, &lvi);

                break;
            }
            case ID3FID_USERTEXT:
            case ID3FID_COMMENT: /* Can also contain an extra language field (but not used now) */
            case ID3FID_UNSYNCEDLYRICS: /* Can also contain an extra language field (but not used now) */
            {
                LV_ITEM lvi;
                ID3ITEM *pItem = LocalAlloc(LPTR, sizeof(ID3ITEM));

                /* Initialize LV_ITEM members that are common to all items. */
                lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
                lvi.state = 0;
                lvi.stateMask = 0;
                lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
                lvi.iImage = 0;
                lvi.iItem = iItem;
                lvi.iSubItem = 0;

                pItem->frameId = eFrameID;

                field = ID3Frame_GetField(frame, ID3FN_DESCRIPTION);
                ID3Field_GetASCII(field, info, 1024, 1);
                pItem->aCols[0] = DupString(info);

                field = ID3Frame_GetField(frame, ID3FN_TEXT);
                ID3Field_GetASCII(field, info, 1024, 1);
                pItem->aCols[1] = DupString(info);

                lvi.lParam = (LPARAM)pItem;    /* item data */

                /* Add the item. */
                ListView_InsertItem(hwndList, &lvi);

                break;
            }
            case ID3FID_WWWAUDIOFILE:       case ID3FID_WWWARTIST:
            case ID3FID_WWWAUDIOSOURCE:     case ID3FID_WWWCOMMERCIALINFO:
            case ID3FID_WWWCOPYRIGHT:       case ID3FID_WWWPUBLISHER:
            case ID3FID_WWWPAYMENT:         case ID3FID_WWWRADIOPAGE:
            {
                LV_ITEM lvi;
                ID3ITEM *pItem = LocalAlloc(LPTR, sizeof(ID3ITEM));

                /* Initialize LV_ITEM members that are common to all items. */
                lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
                lvi.state = 0;
                lvi.stateMask = 0;
                lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
                lvi.iImage = 0;
                lvi.iItem = iItem;
                lvi.iSubItem = 0;

                pItem->frameId = eFrameID;

                pItem->aCols[0] = GetFrameDesc(eFrameID);

                field = ID3Frame_GetField(frame, ID3FN_URL);
                ID3Field_GetASCII(field, info, 1024, 1);
                pItem->aCols[1] = DupString(info);

                lvi.lParam = (LPARAM)pItem;    /* item data */

                /* Add the item. */
                ListView_InsertItem(hwndList, &lvi);

                break;
            }
            case ID3FID_WWWUSER:
            {
                LV_ITEM lvi;
                ID3ITEM *pItem = LocalAlloc(LPTR, sizeof(ID3ITEM));

                /* Initialize LV_ITEM members that are common to all items. */
                lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
                lvi.state = 0;
                lvi.stateMask = 0;
                lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
                lvi.iImage = 0;
                lvi.iItem = iItem;
                lvi.iSubItem = 0;

                pItem->frameId = eFrameID;

                field = ID3Frame_GetField(frame, ID3FN_DESCRIPTION);
                ID3Field_GetASCII(field, info, 1024, 1);
                pItem->aCols[0] = DupString(info);

                field = ID3Frame_GetField(frame, ID3FN_URL);
                ID3Field_GetASCII(field, info, 1024, 1);
                pItem->aCols[1] = DupString(info);

                lvi.lParam = (LPARAM)pItem;    /* item data */

                /* Add the item. */
                ListView_InsertItem(hwndList, &lvi);

                break;
            }
            default:
                break;
            }
        }
        ID3Tag_Delete(tag);
    }
}
Ejemplo n.º 9
0
/* Get the title from the file */
void GetID3FileTitle(char *filename, char *title, char *format)
{
    ID3Tag *tag;
    ID3Frame *frame;
    ID3Field *field;
    char buffer[255];
    int some_info = 0;
    char *in = format;
    char *out = title;
    char *bound = out + (MAX_PATH - 10 - 1);


    if ((tag = ID3Tag_New()) != NULL)
    {
        ID3Tag_Link(tag, filename);

        while (*in && out < bound)
        {
            switch (*in) {
            case '%':
                ++in;
                break;

            default:
                *out++ = *in++;
                continue;
            }

            /* handle % escape sequence */
            switch (*in++) {
            case '0':
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_TRACKNUM)) != NULL) {
                    int size;
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
                    lstrcpy(out, buffer); out += size;
                    some_info = 1;
                }
                break;
            case '1':
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_LEADARTIST)) != NULL) {
                    int size;
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
                    lstrcpy(out, buffer); out += size;
                    some_info = 1;
                }
                break;
            case '2':
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_TITLE)) != NULL) {
                    int size;
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
                    lstrcpy(out, buffer); out += size;
                    some_info = 1;
                }
                break;
            case '3':
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_ALBUM)) != NULL) {
                    int size;
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
                    lstrcpy(out, buffer); out += size;
                    some_info = 1;
                }
                break;
            case '4':
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_YEAR)) != NULL) {
                    int size;
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
                    lstrcpy(out, buffer); out += size;
                    some_info = 1;
                }
                break;
            case '5':
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_COMMENT)) != NULL) {
                    int size;
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
                    lstrcpy(out, buffer); out += size;
                    some_info = 1;
                }
                break;
            case '6':
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_CONTENTTYPE)) != NULL) {
                    int size; char *tmp;
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
                    tmp = GetGenre(buffer);
                    lstrcpy(out, tmp); out += size;
                    some_info = 1;
                }
                break;
            case '7':
            {
                char *p=filename+lstrlen(filename);
                int len = 0;
                while (*p != '\\' && p >= filename) { p--; len++; }
                lstrcpy(out, ++p); out += len;
                some_info = 1;
                break;
            }
            }
        }

        ID3Tag_Delete(tag);
    }

    if (!some_info)
    {
        char *p=filename+lstrlen(filename);
        while (*p != '\\' && p >= filename) p--;
        lstrcpy(title,++p);
    }
}
Ejemplo n.º 10
0
bool MP4Metadata::WriteMetadata(CFErrorRef *error)
{
	UInt8 buf [PATH_MAX];
	if(!CFURLGetFileSystemRepresentation(mURL, false, buf, PATH_MAX))
		return false;
	
	// Open the file for modification
	MP4FileHandle file = MP4Modify(reinterpret_cast<const char *>(buf));
	if(MP4_INVALID_FILE_HANDLE == file) {
		if(error) {
			CFMutableDictionaryRef errorDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 
																			   32,
																			   &kCFTypeDictionaryKeyCallBacks,
																			   &kCFTypeDictionaryValueCallBacks);
			
			CFStringRef displayName = CreateDisplayNameForURL(mURL);
			CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, 
															   NULL, 
															   CFCopyLocalizedString(CFSTR("The file “%@” is not a valid MPEG-4 file."), ""), 
															   displayName);
			
			CFDictionarySetValue(errorDictionary, 
								 kCFErrorLocalizedDescriptionKey, 
								 errorString);
			
			CFDictionarySetValue(errorDictionary, 
								 kCFErrorLocalizedFailureReasonKey, 
								 CFCopyLocalizedString(CFSTR("Not an MPEG file"), ""));
			
			CFDictionarySetValue(errorDictionary, 
								 kCFErrorLocalizedRecoverySuggestionKey, 
								 CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), ""));
			
			CFRelease(errorString), errorString = NULL;
			CFRelease(displayName), displayName = NULL;
			
			*error = CFErrorCreate(kCFAllocatorDefault, 
								   AudioMetadataErrorDomain, 
								   AudioMetadataInputOutputError, 
								   errorDictionary);
			
			CFRelease(errorDictionary), errorDictionary = NULL;				
		}
		
		return false;
	}
	
	// Read the tags
	const MP4Tags *tags = MP4TagsAlloc();

	if(NULL == tags) {
		MP4Close(file), file = NULL;
		
		if(error)
			*error = CFErrorCreate(kCFAllocatorDefault, kCFErrorDomainPOSIX, ENOMEM, NULL);
	
		return false;
	}
	
	MP4TagsFetch(tags, file);
	
	// Album Title
	CFStringRef str = GetAlbumTitle();

	if(str) {
		CFIndex cStringSize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8);
		char cString [cStringSize + 1];
		
		if(!CFStringGetCString(str, cString, cStringSize + 1, kCFStringEncodingUTF8)) {
			log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger("org.sbooth.AudioEngine.AudioMetadata.MP4");
			LOG4CXX_WARN(logger, "CFStringGetCString() failed");
			return false;			
		}
		
		MP4TagsSetAlbum(tags, cString);
	}
	else
		MP4TagsSetAlbum(tags, NULL);

	// Artist
	str = GetArtist();
	
	if(str) {
		CFIndex cStringSize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8);
		char cString [cStringSize + 1];
		
		if(!CFStringGetCString(str, cString, cStringSize + 1, kCFStringEncodingUTF8)) {
			log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger("org.sbooth.AudioEngine.AudioMetadata.MP4");
			LOG4CXX_WARN(logger, "CFStringGetCString() failed");
			return false;			
		}
		
		MP4TagsSetArtist(tags, cString);
	}
	else
		MP4TagsSetArtist(tags, NULL);
	
	// Album Artist
	str = GetAlbumArtist();
	
	if(str) {
		CFIndex cStringSize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8);
		char cString [cStringSize + 1];
		
		if(!CFStringGetCString(str, cString, cStringSize + 1, kCFStringEncodingUTF8)) {
			log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger("org.sbooth.AudioEngine.AudioMetadata.MP4");
			LOG4CXX_WARN(logger, "CFStringGetCString() failed");
			return false;			
		}
		
		MP4TagsSetAlbumArtist(tags, cString);
	}
	else
		MP4TagsSetAlbumArtist(tags, NULL);

	// Genre
	str = GetGenre();
	
	if(str) {
		CFIndex cStringSize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8);
		char cString [cStringSize + 1];
		
		if(!CFStringGetCString(str, cString, cStringSize + 1, kCFStringEncodingUTF8)) {
			log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger("org.sbooth.AudioEngine.AudioMetadata.MP4");
			LOG4CXX_WARN(logger, "CFStringGetCString() failed");
			return false;			
		}
		
		MP4TagsSetGenre(tags, cString);
	}
	else
		MP4TagsSetGenre(tags, NULL);
	
	// Release date
	str = GetReleaseDate();
	
	if(str) {
		CFIndex cStringSize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8);
		char cString [cStringSize + 1];
		
		if(!CFStringGetCString(str, cString, cStringSize + 1, kCFStringEncodingUTF8)) {
			log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger("org.sbooth.AudioEngine.AudioMetadata.MP4");
			LOG4CXX_WARN(logger, "CFStringGetCString() failed");
			return false;			
		}
		
		MP4TagsSetReleaseDate(tags, cString);
	}
	else
		MP4TagsSetReleaseDate(tags, NULL);
	
	// Composer
	str = GetComposer();
	
	if(str) {
		CFIndex cStringSize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8);
		char cString [cStringSize + 1];
		
		if(!CFStringGetCString(str, cString, cStringSize + 1, kCFStringEncodingUTF8)) {
			log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger("org.sbooth.AudioEngine.AudioMetadata.MP4");
			LOG4CXX_WARN(logger, "CFStringGetCString() failed");
			return false;			
		}
		
		MP4TagsSetComposer(tags, cString);
	}
	else
		MP4TagsSetComposer(tags, NULL);
	
	// Comment
	str = GetComment();
	
	if(str) {
		CFIndex cStringSize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8);
		char cString [cStringSize + 1];
		
		if(!CFStringGetCString(str, cString, cStringSize + 1, kCFStringEncodingUTF8)) {
			log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger("org.sbooth.AudioEngine.AudioMetadata.MP4");
			LOG4CXX_WARN(logger, "CFStringGetCString() failed");
			return false;			
		}
		
		MP4TagsSetComments(tags, cString);
	}
	else
		MP4TagsSetComments(tags, NULL);
	
	// Track title
	str = GetTitle();
	
	if(str) {
		CFIndex cStringSize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8);
		char cString [cStringSize + 1];
		
		if(!CFStringGetCString(str, cString, cStringSize + 1, kCFStringEncodingUTF8)) {
			log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger("org.sbooth.AudioEngine.AudioMetadata.MP4");
			LOG4CXX_WARN(logger, "CFStringGetCString() failed");
			return false;			
		}
		
		MP4TagsSetName(tags, cString);
	}
	else
		MP4TagsSetName(tags, NULL);

	// Track number and total
	MP4TagTrack trackInfo;
	memset(&trackInfo, 0, sizeof(MP4TagTrack));

	if(GetTrackNumber())
		CFNumberGetValue(GetTrackNumber(), kCFNumberSInt32Type, &trackInfo.index);

	if(GetTrackTotal())
		CFNumberGetValue(GetTrackTotal(), kCFNumberSInt32Type, &trackInfo.total);
	
	MP4TagsSetTrack(tags, &trackInfo);

	// Disc number and total
	MP4TagDisk discInfo;
	memset(&discInfo, 0, sizeof(MP4TagDisk));
		
	if(GetDiscNumber())
		CFNumberGetValue(GetDiscNumber(), kCFNumberSInt32Type, &discInfo.index);
	
	if(GetDiscTotal())
		CFNumberGetValue(GetDiscTotal(), kCFNumberSInt32Type, &discInfo.total);
	
	MP4TagsSetDisk(tags, &discInfo);

	// Compilation
	if(GetCompilation()) {
		uint8_t comp = CFBooleanGetValue(GetCompilation());
		MP4TagsSetCompilation(tags, &comp);
	}
	else
		MP4TagsSetCompilation(tags, NULL);

	// Lyrics
	str = GetLyrics();
	
	if(str) {
		CFIndex cStringSize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8);
		char cString [cStringSize + 1];
		
		if(!CFStringGetCString(str, cString, cStringSize + 1, kCFStringEncodingUTF8)) {
			log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger("org.sbooth.AudioEngine.AudioMetadata.MP4");
			LOG4CXX_WARN(logger, "CFStringGetCString() failed");
			return false;			
		}
		
		MP4TagsSetLyrics(tags, cString);
	}
	else
		MP4TagsSetLyrics(tags, NULL);

	// Album art
	CFDataRef artData = GetFrontCoverArt();
	
	if(artData) {		
		MP4TagArtwork artwork;
		
		artwork.data = reinterpret_cast<void *>(const_cast<UInt8 *>(CFDataGetBytePtr(artData)));
		artwork.size = static_cast<uint32_t>(CFDataGetLength(artData));
		artwork.type = MP4_ART_UNDEFINED;
		
		MP4TagsAddArtwork(tags, &artwork);
	}
	
	// Save our changes
	MP4TagsStore(tags, file);
	
	// Replay Gain
	// Reference loudness
	if(GetReplayGainReferenceLoudness()) {
		float f;
		if(!CFNumberGetValue(GetReplayGainReferenceLoudness(), kCFNumberFloatType, &f)) {
			log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger("org.sbooth.AudioEngine.AudioMetadata.MP4");
			LOG4CXX_WARN(logger, "CFStringGetCString() failed");
			return false;
		}

		char value [8];
		snprintf(value, sizeof(value), "%2.1f dB", f);

		MP4ItmfItem *item = MP4ItmfItemAlloc("----", 1);
		if(NULL != item) {
			item->mean = strdup("com.apple.iTunes");
			item->name = strdup("replaygain_reference_loudness");
			
			item->dataList.elements[0].typeCode = MP4_ITMF_BT_UTF8;
			item->dataList.elements[0].value = reinterpret_cast<uint8_t *>(strdup(value));
			item->dataList.elements[0].valueSize = static_cast<uint32_t>(strlen(value));
		}
	}
	else {
		MP4ItmfItemList *items = MP4ItmfGetItemsByMeaning(file, "com.apple.iTunes", "replaygain_reference_loudness");
		if(items) {
			for(uint32_t i = 0; i < items->size; ++i)
				MP4ItmfRemoveItem(file, items->elements + i);
		}
		MP4ItmfItemListFree(items), items = NULL;
	}

	// Track gain
	if(GetReplayGainTrackGain()) {
		float f;
		if(!CFNumberGetValue(GetReplayGainTrackGain(), kCFNumberFloatType, &f)) {
			log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger("org.sbooth.AudioEngine.AudioMetadata.MP4");
			LOG4CXX_WARN(logger, "CFNumberGetValue() failed");
			return false;
		}
		
		char value [10];
		snprintf(value, sizeof(value), "%+2.2f dB", f);
		
		MP4ItmfItem *item = MP4ItmfItemAlloc("----", 1);
		if(NULL != item) {
			item->mean = strdup("com.apple.iTunes");
			item->name = strdup("replaygain_track_gain");
			
			item->dataList.elements[0].typeCode = MP4_ITMF_BT_UTF8;
			item->dataList.elements[0].value = reinterpret_cast<uint8_t *>(strdup(value));
			item->dataList.elements[0].valueSize = static_cast<uint32_t>(strlen(value));
		}
	}
	else {
		MP4ItmfItemList *items = MP4ItmfGetItemsByMeaning(file, "com.apple.iTunes", "replaygain_track_gain");
		if(items) {
			for(uint32_t i = 0; i < items->size; ++i)
				MP4ItmfRemoveItem(file, items->elements + i);
		}
		MP4ItmfItemListFree(items), items = NULL;
	}

	// Track peak
	if(GetReplayGainTrackPeak()) {
		float f;
		if(!CFNumberGetValue(GetReplayGainTrackPeak(), kCFNumberFloatType, &f)) {
			log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger("org.sbooth.AudioEngine.AudioMetadata.MP4");
			LOG4CXX_WARN(logger, "CFNumberGetValue() failed");
			return false;
		}
		
		char value [12];
		snprintf(value, sizeof(value), "%1.8f", f);
		
		MP4ItmfItem *item = MP4ItmfItemAlloc("----", 1);
		if(NULL != item) {
			item->mean = strdup("com.apple.iTunes");
			item->name = strdup("replaygain_track_peak");
			
			item->dataList.elements[0].typeCode = MP4_ITMF_BT_UTF8;
			item->dataList.elements[0].value = reinterpret_cast<uint8_t *>(strdup(value));
			item->dataList.elements[0].valueSize = static_cast<uint32_t>(strlen(value));
		}
	}
	else {
		MP4ItmfItemList *items = MP4ItmfGetItemsByMeaning(file, "com.apple.iTunes", "replaygain_track_peak");
		if(items) {
			for(uint32_t i = 0; i < items->size; ++i)
				MP4ItmfRemoveItem(file, items->elements + i);
		}
		MP4ItmfItemListFree(items), items = NULL;
	}

	// Album gain
	if(GetReplayGainAlbumGain()) {
		float f;
		if(!CFNumberGetValue(GetReplayGainAlbumGain(), kCFNumberFloatType, &f)) {
			log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger("org.sbooth.AudioEngine.AudioMetadata.MP4");
			LOG4CXX_WARN(logger, "CFNumberGetValue() failed");
			return false;
		}
		
		char value [10];
		snprintf(value, sizeof(value), "%+2.2f dB", f);
		
		MP4ItmfItem *item = MP4ItmfItemAlloc("----", 1);
		if(NULL != item) {
			item->mean = strdup("com.apple.iTunes");
			item->name = strdup("replaygain_album_gain");
			
			item->dataList.elements[0].typeCode = MP4_ITMF_BT_UTF8;
			item->dataList.elements[0].value = reinterpret_cast<uint8_t *>(strdup(value));
			item->dataList.elements[0].valueSize = static_cast<uint32_t>(strlen(value));
		}
	}
	else {
		MP4ItmfItemList *items = MP4ItmfGetItemsByMeaning(file, "com.apple.iTunes", "replaygain_album_gain");
		if(items) {
			for(uint32_t i = 0; i < items->size; ++i)
				MP4ItmfRemoveItem(file, items->elements + i);
		}
		MP4ItmfItemListFree(items), items = NULL;
	}
	
	// Album peak
	if(GetReplayGainAlbumPeak()) {
		float f;
		if(!CFNumberGetValue(GetReplayGainAlbumPeak(), kCFNumberFloatType, &f)) {
			log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger("org.sbooth.AudioEngine.AudioMetadata.MP4");
			LOG4CXX_WARN(logger, "CFNumberGetValue() failed");
			return false;
		}
		
		char value [12];
		snprintf(value, sizeof(value), "%1.8f", f);
		
		MP4ItmfItem *item = MP4ItmfItemAlloc("----", 1);
		if(NULL != item) {
			item->mean = strdup("com.apple.iTunes");
			item->name = strdup("replaygain_album_peak");
			
			item->dataList.elements[0].typeCode = MP4_ITMF_BT_UTF8;
			item->dataList.elements[0].value = reinterpret_cast<uint8_t *>(strdup(value));
			item->dataList.elements[0].valueSize = static_cast<uint32_t>(strlen(value));
		}
	}
	else {
		MP4ItmfItemList *items = MP4ItmfGetItemsByMeaning(file, "com.apple.iTunes", "replaygain_album_peak");
		if(items) {
			for(uint32_t i = 0; i < items->size; ++i)
				MP4ItmfRemoveItem(file, items->elements + i);
		}
		MP4ItmfItemListFree(items), items = NULL;
	}

	// Clean up
	MP4TagsFree(tags), tags = NULL;
	MP4Close(file), file = NULL;

	MergeChangedMetadataIntoMetadata();
	
	return true;
}