1//========================================================================= 2// FILENAME : tagutils-flc.c 3// DESCRIPTION : FLAC metadata reader 4//========================================================================= 5// Copyright (c) 2008- NETGEAR, Inc. All Rights Reserved. 6//========================================================================= 7 8/* 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program. If not, see <http://www.gnu.org/licenses/>. 21 */ 22 23static int 24_get_flctags(char *filename, struct song_metadata *psong) 25{ 26 FLAC__Metadata_SimpleIterator *iterator = 0; 27 FLAC__StreamMetadata *block; 28 unsigned int sec, ms; 29 int i; 30 int err = 0; 31 32 if(!(iterator = FLAC__metadata_simple_iterator_new())) 33 { 34 DPRINTF(E_FATAL, L_SCANNER, "Out of memory while FLAC__metadata_simple_iterator_new()\n"); 35 return -1; 36 } 37 38 if(!FLAC__metadata_simple_iterator_init(iterator, filename, true, true)) 39 { 40 DPRINTF(E_ERROR, L_SCANNER, "Cannot extract tag from %s [%s]\n", filename, 41 FLAC__Metadata_SimpleIteratorStatusString[FLAC__metadata_simple_iterator_status(iterator)]); 42 goto _exit; 43 } 44 45 do { 46 if(!(block = FLAC__metadata_simple_iterator_get_block(iterator))) 47 { 48 DPRINTF(E_ERROR, L_SCANNER, "Cannot extract tag from %s\n", filename); 49 err = -1; 50 goto _exit; 51 } 52 53 switch(block->type) 54 { 55 case FLAC__METADATA_TYPE_STREAMINFO: 56 if (!block->data.stream_info.sample_rate) 57 break; /* Info is crap, avoid div-by-zero. */ 58 sec = (unsigned int)(block->data.stream_info.total_samples / 59 block->data.stream_info.sample_rate); 60 ms = (unsigned int)(((block->data.stream_info.total_samples % 61 block->data.stream_info.sample_rate) * 1000) / 62 block->data.stream_info.sample_rate); 63 if ((sec == 0) && (ms == 0)) 64 break; /* Info is crap, escape div-by-zero. */ 65 psong->song_length = (sec * 1000) + ms; 66 psong->bitrate = (((uint64_t)(psong->file_size) * 1000) / (psong->song_length / 8)); 67 psong->samplerate = block->data.stream_info.sample_rate; 68 psong->channels = block->data.stream_info.channels; 69 break; 70 71 case FLAC__METADATA_TYPE_VORBIS_COMMENT: 72 for(i = 0; i < block->data.vorbis_comment.num_comments; i++) 73 { 74 vc_scan(psong, 75 (char*)block->data.vorbis_comment.comments[i].entry, 76 block->data.vorbis_comment.comments[i].length); 77 } 78 break; 79#if FLAC_API_VERSION_CURRENT >= 10 80 case FLAC__METADATA_TYPE_PICTURE: 81 if (psong->image) { 82 DPRINTF(E_MAXDEBUG, L_SCANNER, "Ignoring additional image [%s]\n", filename); 83 break; 84 } 85 psong->image_size = block->data.picture.data_length; 86 if((psong->image = malloc(psong->image_size))) 87 memcpy(psong->image, block->data.picture.data, psong->image_size); 88 else 89 DPRINTF(E_ERROR, L_SCANNER, "Out of memory [%s]\n", filename); 90 break; 91#endif 92 default: 93 break; 94 } 95 FLAC__metadata_object_delete(block); 96 } 97 while(FLAC__metadata_simple_iterator_next(iterator)); 98 99 _exit: 100 if(iterator) 101 FLAC__metadata_simple_iterator_delete(iterator); 102 103 return err; 104} 105 106static int 107_get_flcfileinfo(char *filename, struct song_metadata *psong) 108{ 109 psong->lossless = 1; 110 psong->vbr_scale = 1; 111 112 return 0; 113} 114