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