00001 00007 #include <errno.h> 00008 #include <id3tag.h> 00009 #include <limits.h> 00010 #include <stdbool.h> 00011 #include <stddef.h> 00012 #include <stdio.h> 00013 #include <stdlib.h> 00014 #include <string.h> 00015 #include <wstring.h> 00016 00017 #include "check.h" 00018 #include "config.h" 00019 #include "db5_types.h" 00020 #include "file.h" 00021 #include "logger.h" 00022 #include "mp3_id3.h" 00023 #include "mp3_mpeg.h" 00024 00031 static bool mp3_generate_row_mpeg_size(const char *filename, db5_row *row) 00032 { 00033 FILE *mpeg; 00034 size_t read; 00035 ptrdiff_t offset; 00036 mp3_frame frame; 00037 00038 check(filename != NULL); 00039 check(row != NULL); 00040 00041 add_log(ADDLOG_DEBUG, "[mp3]gen_row_mpeg_size", "retrieving mpeg information for '%s'\n", filename); 00042 00043 mpeg = fopen(filename, "rb"); 00044 if (mpeg == NULL) 00045 { 00046 add_log(ADDLOG_RECOVER, "[mp3]gen_row_mpeg_size", "unable to open file '%s': %s\n", filename, strerror(errno)); 00047 return false; 00048 } 00049 00050 read = fread(file_common_buffer, 1, sizeof(file_common_buffer), mpeg); 00051 if (read == 0) 00052 { 00053 add_log(ADDLOG_RECOVER, "[mp3]gen_row_mpeg_size", "unable to read file '%s'\n", filename); 00054 fclose(mpeg); 00055 return false; 00056 } 00057 00058 fclose(mpeg); 00059 00060 row->filesize = file_filesize(filename); 00061 00062 offset = mp3_next_frame(file_common_buffer, read); 00063 if (offset >= read) 00064 { 00065 add_log(ADDLOG_NOTICE, "[mp3]gen_row_mpeg_size", "unable to find first frame in file '%s'\n", filename); 00066 return false; 00067 } 00068 00069 ws_memswapcpy(&frame, file_common_buffer+offset, sizeof(mp3_frame)); 00070 row->bitrate = mp3_bitrate(&frame); 00071 row->samplerate = mp3_samplerate(&frame); 00072 row->duration = mp3_length(&frame, row->filesize); 00073 00074 return true; 00075 } 00076 00077 00083 #define int_defaultvalue(variable,default) if (variable==ID3_INT_ERROR) variable = default; 00084 00090 static bool mp3_generate_row_id3(const char *filename, db5_row *row) 00091 { 00092 struct id3_file *id3; 00093 struct id3_tag *tag; 00094 00095 char *str; 00096 int num; 00097 00098 check(filename != NULL); 00099 check(row != NULL); 00100 00101 add_log(ADDLOG_DEBUG, "[mp3]gen_row_id3", "retrieving id3 tags for '%s'\n", filename); 00102 00103 id3 = id3_file_open(filename, ID3_FILE_MODE_READONLY); 00104 if (id3 == NULL) 00105 { 00106 add_log(ADDLOG_RECOVER, "[mp3]gen_row_id3", "unable to open file '%s'\n", filename); 00107 return false; 00108 } 00109 00110 tag = id3_file_tag(id3); 00111 if (tag == NULL) 00112 { 00113 add_log(ADDLOG_NOTICE, "[mp3]gen_row_id3", "not tag found in file '%s'\n", filename); 00114 } 00115 00116 row->year = id3_get_int(tag, ID3_FRAME_YEAR); 00117 int_defaultvalue(row->year, 0); 00118 00119 str = id3_get_string(tag, ID3_FRAME_ARTIST); 00120 if (str == ID3_STRING_ERROR) 00121 { 00122 strncpy(row->artist, CONFIG_DEFAULT_ARTIST, membersizeof(db5_row, artist)/2); 00123 } 00124 else 00125 { 00126 strncpy(row->artist, str, membersizeof(db5_row, artist)/2); 00127 free(str); 00128 } 00129 00130 str = id3_get_string(tag, ID3_FRAME_ALBUM); 00131 if (str == ID3_STRING_ERROR) 00132 { 00133 strncpy(row->album, CONFIG_DEFAULT_ALBUM, membersizeof(db5_row, album)/2); 00134 } 00135 else 00136 { 00137 strncpy(row->album, str, membersizeof(db5_row, album)/2); 00138 free(str); 00139 } 00140 00141 str = id3_get_string(tag, ID3_FRAME_TITLE); 00142 if (str == ID3_STRING_ERROR) 00143 { 00144 strncpy(row->title, CONFIG_DEFAULT_TITLE, membersizeof(db5_row, title)/2); 00145 } 00146 else 00147 { 00148 strncpy(row->title, str, membersizeof(db5_row, title)/2); 00149 free(str); 00150 } 00151 00152 row->track = id3_get_int(tag, ID3_FRAME_TRACK); 00153 int_defaultvalue(row->track, 0); 00154 00155 row->year = id3_get_int(tag, ID3_FRAME_YEAR); 00156 int_defaultvalue(row->year, 0); 00157 00158 num = id3_get_int(tag, ID3_FRAME_GENRE); 00159 if (num == ID3_INT_ERROR || num >= ID3_NB_GENRES) 00160 { 00161 strncpy(row->genre, CONFIG_DEFAULT_GENRE, membersizeof(db5_row, genre)/2); 00162 } 00163 else 00164 { 00165 strncpy(row->genre, id3_genres[num], membersizeof(db5_row, genre)/2); 00166 } 00167 00168 id3_file_close(id3); 00169 00170 return true; 00171 } 00172 00173 bool mp3_generate_row(const char *filename, db5_row *row) 00174 { 00175 check(filename != NULL); 00176 check(row != NULL); 00177 00178 add_log(ADDLOG_DEBUG, "[mp3]gen_row", "preparing information for '%s'\n", filename); 00179 00180 if (!mp3_generate_row_mpeg_size(filename, row)) 00181 { 00182 add_log(ADDLOG_RECOVER, "[mp3]gen_row", "unable to retrieve music length information for '%s'\n", filename); 00183 } 00184 if (!mp3_generate_row_id3(filename, row)) 00185 { 00186 add_log(ADDLOG_RECOVER, "[mp3]gen_row", "unable to retrieve id3 tags for '%s'\n", filename); 00187 } 00188 00189 return true; 00190 } 00191