libmp3splt
|
00001 /********************************************************** 00002 * libmp3splt -- library based on mp3splt, 00003 * for mp3/ogg splitting without decoding 00004 * 00005 * Copyright (c) 2002-2005 M. Trotta - <mtrotta@users.sourceforge.net> 00006 * Copyright (c) 2005-2011 Alexandru Munteanu - io_fx@yahoo.fr 00007 * 00008 *********************************************************/ 00009 00010 /********************************************************** 00011 * This program is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU General Public License 00013 * as published by the Free Software Foundation; either version 2 00014 * of the License, or (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software 00023 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 00024 * 02111-1307, USA. 00025 *********************************************************/ 00026 00031 #include <string.h> 00032 #include <ctype.h> 00033 #include <math.h> 00034 00035 #include "splt.h" 00036 #include "cddb_cue_common.h" 00037 00038 #include "cddb.h" 00039 00040 static void splt_cddb_process_line(char **l, cddb_utils *cdu, splt_state *state); 00041 static void splt_cddb_process_disc_length_line(const char *line_content, cddb_utils *cdu, splt_state *state); 00042 static void splt_cddb_convert_points(cddb_utils *cdu, splt_state *state); 00043 static void splt_cddb_process_offset_line(const char *line_content, cddb_utils *cdu, splt_state *state); 00044 static cddb_utils *splt_cddb_cdu_new(splt_state *state, int *error); 00045 static void splt_cddb_cdu_free(cddb_utils **cdu); 00046 static void splt_cddb_process_year_line(const char *line_content, 00047 cddb_utils *cdu, splt_state *state); 00048 static void splt_cddb_process_genre_line(char *line_content, cddb_utils *cdu, splt_state *state); 00049 static void splt_cddb_process_dtitle_line(const char *line_content, cddb_utils *cdu, splt_state *state); 00050 static void splt_cddb_process_ttitle_line(const char *line_content, cddb_utils *cdu, splt_state *state); 00051 static void splt_cddb_process_id3g_line(const char *line_content, cddb_utils *cdu, splt_state *state); 00052 00053 int splt_cddb_put_splitpoints(const char *file, splt_state *state, int *error) 00054 { 00055 if (file == NULL) 00056 { 00057 *error = SPLT_INVALID_CDDB_FILE; 00058 return 0; 00059 } 00060 00061 splt_c_put_info_message_to_client(state, 00062 _(" reading informations from CDDB file %s ...\n"),file); 00063 00064 splt_t_free_splitpoints_tags(state); 00065 00066 *error = SPLT_CDDB_OK; 00067 00068 int err = SPLT_OK; 00069 FILE *file_input = NULL; 00070 char *line = NULL; 00071 int tracks = 0; 00072 00073 cddb_utils *cdu = splt_cddb_cdu_new(state, &err); 00074 if (err < 0) { *error = err; return tracks; } 00075 cdu->file = file; 00076 00077 if (!(file_input=splt_io_fopen(file, "r"))) 00078 { 00079 splt_e_set_strerror_msg_with_data(state, file); 00080 *error = SPLT_ERROR_CANNOT_OPEN_FILE; 00081 return tracks; 00082 } 00083 00084 if (fseek(file_input, 0, SEEK_SET) != 0) 00085 { 00086 splt_e_set_strerror_msg_with_data(state, file); 00087 *error = SPLT_ERROR_SEEKING_FILE; 00088 goto function_end; 00089 } 00090 00091 err = splt_tu_set_tags_field(state, 0, SPLT_TAGS_GENRE, SPLT_UNDEFINED_GENRE); 00092 if (err < 0) { *error = err; goto function_end; } 00093 00094 while ((line = splt_io_readline(file_input, error)) != NULL) 00095 { 00096 if (*error < 0) { goto function_end; } 00097 00098 splt_cddb_process_line(&line, cdu, state); 00099 tracks = cdu->tracks; 00100 if (cdu->error < 0) { *error = cdu->error; goto function_end; } 00101 } 00102 00103 splt_cc_put_filenames_from_tags(state, tracks, error); 00104 00105 function_end: 00106 splt_cddb_cdu_free(&cdu); 00107 00108 if (line) 00109 { 00110 free(line); 00111 line = NULL; 00112 } 00113 00114 if (fclose(file_input) != 0) 00115 { 00116 splt_e_set_strerror_msg_with_data(state, file); 00117 *error = SPLT_ERROR_CANNOT_CLOSE_FILE; 00118 } 00119 file_input = NULL; 00120 00121 if (*error >= 0) 00122 { 00123 splt_c_put_info_message_to_client(state, _(" Tracks: %d\n\n"), tracks); 00124 } 00125 00126 return tracks; 00127 } 00128 00129 static void splt_cddb_process_line(char **l, cddb_utils *cdu, splt_state *state) 00130 { 00131 if (!l || !*l) { return; } 00132 00133 char *line = *l; 00134 00135 splt_su_line_to_unix(line); 00136 splt_su_str_cut_last_char(line); 00137 00138 char *line_content = NULL; 00139 if ((line_content = strstr(line, "Track frame offset")) != NULL) 00140 { 00141 cdu->read_offsets = SPLT_TRUE; 00142 } 00143 else if ((line_content = strstr(line, "Disc length")) != NULL) 00144 { 00145 splt_cddb_process_disc_length_line(line_content, cdu, state); 00146 } 00147 else if (cdu->read_offsets) 00148 { 00149 splt_cddb_process_offset_line(line, cdu, state); 00150 } 00151 else if ((line_content = strstr(line, "YEAR")) != NULL) 00152 { 00153 splt_cddb_process_year_line(line_content, cdu, state); 00154 } 00155 else if ((line_content = strstr(line, "GENRE")) != NULL) 00156 { 00157 splt_cddb_process_genre_line(line_content, cdu, state); 00158 } 00159 else if ((line_content = strstr(line, "DTITLE")) != NULL) 00160 { 00161 splt_cddb_process_dtitle_line(line_content, cdu, state); 00162 } 00163 else if ((line_content = strstr(line, "TTITLE")) != NULL) 00164 { 00165 splt_cddb_process_ttitle_line(line_content, cdu, state); 00166 } 00167 else if ((line_content = strstr(line, "ID3G")) != NULL) 00168 { 00169 splt_cddb_process_id3g_line(line_content, cdu, state); 00170 } 00171 00172 free(*l); 00173 *l = NULL; 00174 } 00175 00176 static void splt_cddb_process_id3g_line(const char *line_content, cddb_utils *cdu, splt_state *state) 00177 { 00178 int err = SPLT_OK; 00179 00180 int id3g = atoi(line_content + 6); 00181 if (id3g < SPLT_ID3V1_NUMBER_OF_GENRES) 00182 { 00183 err = splt_tu_set_tags_field(state, 0, SPLT_TAGS_GENRE, splt_id3v1_genres[id3g]); 00184 if (err < 0) { cdu->error = err; return; } 00185 } 00186 } 00187 00188 static void splt_cddb_process_ttitle_line(const char *line_content, cddb_utils *cdu, splt_state *state) 00189 { 00190 int err = SPLT_OK; 00191 00192 int index = atoi(line_content+6); 00193 00194 char *equal_ptr = NULL; 00195 if ((equal_ptr = strchr(line_content, '=')) == NULL) 00196 { 00197 splt_e_set_error_data(state, cdu->file); 00198 cdu->error = SPLT_INVALID_CDDB_FILE; 00199 return; 00200 } 00201 00202 if (equal_ptr == line_content) 00203 { 00204 splt_e_set_error_data(state, cdu->file); 00205 cdu->error = SPLT_INVALID_CDDB_FILE; 00206 return; 00207 } 00208 00209 char *slash = strchr(equal_ptr, '/'); 00210 if (slash != NULL) 00211 { 00212 char *title = splt_su_trim_spaces(slash + 1); 00213 err = splt_tu_set_tags_field(state, index, SPLT_TAGS_TITLE, title); 00214 if (err < 0) { cdu->error = err; return; } 00215 *slash = '\0'; 00216 00217 char *performer = splt_su_trim_spaces(equal_ptr + 1); 00218 err = splt_tu_set_tags_field(state, index, SPLT_TAGS_PERFORMER, performer); 00219 if (err < 0) { cdu->error = err; return; } 00220 } 00221 else 00222 { 00223 char *title = splt_su_trim_spaces(equal_ptr + 1); 00224 err = splt_tu_set_tags_field(state, index, SPLT_TAGS_TITLE, title); 00225 if (err < 0) { cdu->error = err; return; } 00226 } 00227 } 00228 00229 static void splt_cddb_process_dtitle_line(const char *line_content, cddb_utils *cdu, splt_state *state) 00230 { 00231 int err = SPLT_OK; 00232 00233 char *equal_ptr = NULL; 00234 if ((equal_ptr = strchr(line_content, '=')) == NULL) 00235 { 00236 splt_e_set_error_data(state, cdu->file); 00237 cdu->error = SPLT_INVALID_CDDB_FILE; 00238 return; 00239 } 00240 00241 int we_have_album = SPLT_FALSE; 00242 00243 char *slash = strchr(equal_ptr, '/'); 00244 if (slash != NULL) 00245 { 00246 char *album = splt_su_trim_spaces(slash + 1); 00247 err = splt_tu_set_tags_field(state, 0, SPLT_TAGS_ALBUM, album); 00248 if (err < 0) { cdu->error = err; return; } 00249 *slash = '\0'; 00250 we_have_album = SPLT_TRUE; 00251 } 00252 00253 char *artist = splt_su_trim_spaces(equal_ptr + 1); 00254 err = splt_tu_set_tags_field(state, 0, SPLT_TAGS_ARTIST, artist); 00255 if (err < 0) { cdu->error = err; return; } 00256 00257 splt_c_put_info_message_to_client(state, _("\n Artist: %s\n"), artist); 00258 if (we_have_album) 00259 { 00260 splt_c_put_info_message_to_client(state, _(" Album: %s\n"), 00261 splt_tu_get_tags_field(state, 0, SPLT_TAGS_ALBUM)); 00262 } 00263 } 00264 00265 static void splt_cddb_process_genre_line(char *line_content, cddb_utils *cdu, splt_state *state) 00266 { 00267 char *genre = line_content + 6; 00268 splt_su_cut_spaces_from_end(genre); 00269 00270 if (*genre == '\0') 00271 { 00272 return; 00273 } 00274 00275 int err = splt_tu_set_tags_field(state, 0, SPLT_TAGS_GENRE, genre); 00276 if (err < 0) { cdu->error = err; } 00277 } 00278 00279 static void splt_cddb_process_year_line(const char *line_content, 00280 cddb_utils *cdu, splt_state *state) 00281 { 00282 int err = splt_tu_set_tags_field(state, 0, SPLT_TAGS_YEAR, line_content+5); 00283 if (err < 0) { cdu->error = err; } 00284 } 00285 00286 static void splt_cddb_process_disc_length_line(const char *line_content, 00287 cddb_utils *cdu, splt_state *state) 00288 { 00289 int err = SPLT_OK; 00290 00291 cdu->read_offsets = SPLT_FALSE; 00292 00293 splt_t_set_splitnumber(state, cdu->tracks); 00294 splt_t_clean_split_data(state, cdu->tracks); 00295 00296 double value = splt_su_str_line_to_double(line_content); 00297 err = splt_sp_append_splitpoint(state, value * 100, NULL, SPLT_SPLITPOINT); 00298 00299 if (err < 0) { cdu->error = err; return; } 00300 00301 splt_cddb_convert_points(cdu, state); 00302 } 00303 00304 static void splt_cddb_convert_points(cddb_utils *cdu, splt_state *state) 00305 { 00306 int err = SPLT_OK; 00307 00308 long first_point = splt_sp_get_splitpoint_value(state, 0, &err); 00309 if (err < 0) { cdu->error = err; return; } 00310 00311 int i = 0; 00312 for (i = cdu->tracks - 1; i >= 0; i--) 00313 { 00314 long point = splt_sp_get_splitpoint_value(state, i, &err); 00315 if (err < 0) { cdu->error = err; return; } 00316 00317 //cddb specs 00318 long difference = point - first_point; 00319 float value = (float) difference / 75.f; 00320 err = splt_sp_set_splitpoint_value(state, i, (long) ceilf(value)); 00321 if (err < 0) { cdu->error = err; return; } 00322 } 00323 } 00324 00325 static void splt_cddb_process_offset_line(const char *line, 00326 cddb_utils *cdu, splt_state *state) 00327 { 00328 if (splt_su_str_line_has_digit(line)) 00329 { 00330 int err = SPLT_OK; 00331 00332 double value = splt_su_str_line_to_double(line); 00333 err = splt_sp_append_splitpoint(state, value * 100, NULL, SPLT_SPLITPOINT); 00334 00335 if (err < 0) { cdu->error = err; return; } 00336 00337 cdu->tracks++; 00338 } 00339 } 00340 00341 static cddb_utils *splt_cddb_cdu_new(splt_state *state, int *error) 00342 { 00343 cddb_utils *cdu = malloc(sizeof(cddb_utils)); 00344 if (cdu == NULL) 00345 { 00346 *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY; 00347 return NULL; 00348 } 00349 00350 cdu->read_offsets = SPLT_FALSE; 00351 cdu->error = SPLT_OK; 00352 cdu->tracks = 0; 00353 cdu->file = NULL; 00354 cdu->field_counter = 0; 00355 00356 return cdu; 00357 } 00358 00359 static void splt_cddb_cdu_free(cddb_utils **cdu) 00360 { 00361 if (!cdu || !*cdu) 00362 { 00363 return; 00364 } 00365 00366 free(*cdu); 00367 *cdu = NULL; 00368 } 00369