/* $Id$ */ /* * Cantus Tag Editor * Copyright © 2002-2004 by Samuel Abels * Copyright © 2007 by Tim Huetz * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see **/ #ifdef HAVE_CONFIG_H # include #endif #define ENABLE_OGG #ifdef ENABLE_OGG #include /*********************************************************************** * BELOW FOLLOW THE STATICS **********************************************************************/ /* Stolen from XMMS (and modified heavily) * XMMS - Cross-platform multimedia player * Copyright (C) 1998-2001 Peter Alm, Mikael Alm, Olle Hallnas, * Thomas Nilsson and 4Front Technologies * Copyright (C) 1999-2001 Ha*vard Kva*len * Copyright (C) 2001, Jorn Baayen */ static int Ogg_Tag_Write_File(FILE * file_in, char * filename_in, vcedit_state * state) { char *filename_tmp; FILE *file_out; int return_code = 0; filename_tmp = g_strdup_printf("%s.tempXXXXX", filename_in); if ((file_out = fopen(filename_tmp, "wb")) == NULL) { fclose(file_out); remove(filename_tmp); g_free(filename_tmp); fclose(file_in); return 2; } if (vcedit_write(state, file_out) < 0) return_code = 3; fclose(file_in); if (fclose(file_out) != 0) return_code = 4; if ((return_code != 0) || (rename(filename_tmp, filename_in) < 0)) { remove(filename_tmp); return_code = 5; } g_free(filename_tmp); return return_code; } static void store_vorbis_field(Tag *tag, char *field) { char *endptr = NULL; char *field_data = NULL; int name_len = 0; /* field name is not UTF8 */ endptr = strchr(field, '='); if (endptr) { name_len = (endptr - field - 1); /* field data is. */ field_data = convert_from_utf8(endptr + 1); if (g_strncasecmp(field, "title", name_len) == 0) strncpy(tag->title, field_data, 1024); if (g_strncasecmp(field, "artist", name_len) == 0) strncpy(tag->artist, field_data, 1024); if (g_strncasecmp(field, "album", name_len) == 0) strncpy(tag->album, field_data, 1024); if (g_strncasecmp(field, "date", name_len) == 0 || g_strncasecmp(field, "year", name_len) == 0) strncpy(tag->year, field_data, 4); if (g_strncasecmp(field, "description", name_len) == 0 || g_strncasecmp(field, "comment", name_len) == 0) strncpy(tag->comment, field_data, 1024); if (g_strncasecmp(field, "tracknumber", name_len) == 0) strncpy(tag->track, field_data, 19); if (g_strncasecmp(field, "genre", name_len) == 0) strncpy(tag->genre, field_data, 512); free(field_data); } } /*********************************************************************** * END OF STATICS **********************************************************************/ int get_vorbis_tag(Tag * tag, const char * filename) { FILE *oggfile; OggVorbis_File vf; char **ptr = NULL; // Open file oggfile = fopen(filename, "rb"); if (!oggfile) return 1; // Pipe the file to libogg if (ov_open(oggfile, &vf, NULL, 0) < 0) { fclose(oggfile); return 2; } // Parse the comments, and put them into the tag struct for (ptr = ov_comment(&vf, -1)->user_comments; *ptr; ++ptr) { store_vorbis_field(tag, *ptr); } // cleanup ov_clear(&vf); return (0); } /* Stolen from XMMS. * Copyright (C) 1998-2001 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies * Copyright (C) 1999-2001 Ha*vard Kva*len * Copyright (C) 2001, Jorn Baayen */ int set_vorbis_tag(Tag * tag, const char * filename) { FILE *oggfile; vcedit_state *state; char *tagstring, *string1, *filenamec; vorbis_comment *vc; int i = 0; // Open file oggfile = fopen(filename, "rb"); if (!oggfile) return (1); state = vcedit_new_state(); // Allocate memory for 'state' if (vcedit_open(state, oggfile) < 0) { g_print ("ERROR: Failed to open file: '%s' as vorbis (%s).\n", filename, vcedit_error(state)); fclose(oggfile); return (2); } // Get data from tag vc = vcedit_comments(state); vorbis_comment_clear(vc); vorbis_comment_init(vc); // Title if (tag->title) { tagstring = g_strconcat("TITLE=", tag->title, NULL); string1 = convert_to_utf8(tagstring); vorbis_comment_add(vc, string1); g_free(tagstring); g_free(string1); } // Artist if (tag->artist) { tagstring = g_strconcat("ARTIST=", tag->artist, NULL); string1 = convert_to_utf8(tagstring); vorbis_comment_add(vc, string1); g_free(tagstring); g_free(string1); } // Album if (tag->album) { tagstring = g_strconcat("ALBUM=", tag->album, NULL); string1 = convert_to_utf8(tagstring); vorbis_comment_add(vc, string1); g_free(tagstring); g_free(string1); } // Year if (tag->year) { tagstring = g_strconcat("DATE=", tag->year, NULL); string1 = convert_to_utf8(tagstring); vorbis_comment_add(vc, string1); g_free(tagstring); g_free(string1); tagstring = g_strconcat("YEAR=", tag->year, NULL); string1 = convert_to_utf8(tagstring); vorbis_comment_add(vc, string1); g_free(tagstring); g_free(string1); } // Track if (tag->track) { tagstring = g_strconcat("TRACKNUMBER=", tag->track, NULL); string1 = convert_to_utf8(tagstring); vorbis_comment_add(vc, string1); g_free(tagstring); g_free(string1); } // Genre if (tag->genre) { tagstring = g_strconcat("GENRE=", tag->genre, NULL); string1 = convert_to_utf8(tagstring); vorbis_comment_add(vc, string1); g_free(tagstring); g_free(string1); } // Comment // We write the comment using the "both" format if (tag->comment) { tagstring = g_strconcat("DESCRIPTION=", tag->comment, NULL); string1 = convert_to_utf8(tagstring); vorbis_comment_add(vc, string1); g_free(tagstring); g_free(string1); tagstring = g_strconcat("COMMENT=", tag->comment, NULL); string1 = convert_to_utf8(tagstring); vorbis_comment_add(vc, string1); g_free(tagstring); g_free(string1); } filenamec = g_strdup(filename); // Write tag if ((i = Ogg_Tag_Write_File(oggfile, filenamec, state)) != 0) { g_print("ERROR: Failed to write comments to file " "'%s' (ERR: %i).\n", filename, i); return (3); } g_free(filenamec); vcedit_clear(state); return (0); } int del_vorbis_tag(const char * filename) { FILE *oggfile; char *filenamec = NULL; vcedit_state *state; vorbis_comment *vc; int i = 0; // Open file oggfile = fopen(filename, "rb"); if (!oggfile) return (1); state = vcedit_new_state(); // Allocate memory for 'state' if (vcedit_open(state, oggfile) < 0) { g_print ("ERROR: Failed to open file: '%s' as vorbis (%s).\n", filename, vcedit_error(state)); fclose(oggfile); return (2); } // Get data from tag vc = vcedit_comments(state); vorbis_comment_clear(vc); vorbis_comment_init(vc); // Since vorbis lib does not use a const char* filenamec = g_strdup(filename); // Write tag if ((i = Ogg_Tag_Write_File(oggfile, filenamec, state)) != 0) { g_print("ERROR: Failed to write comments " "to file '%s' (ERR: %i).\n", filename, i); return (3); } g_free(filenamec); vcedit_clear(state); return (0); } #endif