/* GMP3Info - Displays and allows editing of MP3 ID3 tags and various technical aspects of MP3 files (GTK interface) gmp3info.c - main part of GTK version of MP3Info Copyright (C) 2000-2006 Cedric Tefft 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 2 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, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *************************************************************************** rmc, Feb/2001 - Added a file open dialog Added the Tech Info Window Added an about box GMP3Info can now be launched without an argument */ #include #include #define __MAIN #include "mp3info.h" #undef __MAIN gchar *gtext_genre(unsigned char genre); unsigned char gget_genre (char *genre); int kill_if_esc(GtkWidget *widget, GdkEventKey *event, gpointer obj); void create_techinfo_win(void); void open_mp3_file(void); int load_mp3(char *filename); void read_new_mp3(GtkWidget *button, GtkWidget *file); void quick_popup(char *title, char *message); void about_mp3info(void); GtkWidget *id3win,*id3win_frame_global; GtkWidget *id3win_frame_title,*id3win_frame_artist,*id3win_frame_album; GtkWidget *id3win_frame_year,*id3win_frame_comment, *id3win_frame_albyear; GtkWidget *id3win_frame_genre,*id3win_frame_track,*id3win_frame_comtrack; GtkWidget *id3win_text_title,*id3win_text_artist,*id3win_text_album; GtkWidget *id3win_text_year,*id3win_text_comment,*id3win_combo_genre; GtkWidget *id3win_text_track; GtkWidget *id3win_frame_buttons,*id3win_ok_button,*id3win_cancel_button; GtkWidget *id3win_menu_bar, *id3win_menu_file, *id3win_menu_fcont; GtkWidget *id3win_menu_info, *id3win_menu_open, *id3win_menu_help; GtkWidget *id3win_menu_hcont, *id3win_menu_about; GList *genrelist=NULL; gchar track[4]="",fbuf[4]; unsigned char genre=255; FILE *fp; unsigned char sig[2]; unsigned int track_num; mp3info mp3; int read_only=0; void exit_save( GtkWidget *widget, GtkWidget *data) { char tmp[31]; if (mp3.file) { if(!read_only) { strcpy(mp3.id3.title,gtk_entry_get_text(GTK_ENTRY(id3win_text_title))); strcpy(mp3.id3.artist,gtk_entry_get_text(GTK_ENTRY(id3win_text_artist))); strcpy(mp3.id3.album,gtk_entry_get_text(GTK_ENTRY(id3win_text_album))); strcpy(mp3.id3.year,gtk_entry_get_text(GTK_ENTRY(id3win_text_year))); strcpy(mp3.id3.comment,gtk_entry_get_text(GTK_ENTRY(id3win_text_comment))); strcpy(tmp,gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(id3win_combo_genre)->entry))); mp3.id3.genre[0]=gget_genre(tmp); strcpy(tmp,gtk_entry_get_text(GTK_ENTRY(id3win_text_track))); mp3.id3.track[0]=atoi(tmp); /* if (mp3.id3.track[0] > 255) mp3.id3.track[0]=255; */ write_tag(&mp3); } fclose(mp3.file); } gtk_main_quit(); } int main(int argc, char *argv[] ) { int i; char track_text[4]; gtk_init (&argc, &argv); id3win=gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(id3win),"MP3info - An ID3 tag editor"); gtk_window_set_policy (GTK_WINDOW(id3win), FALSE,FALSE,FALSE); gtk_widget_set_usize(id3win,450,360); gtk_container_border_width(GTK_CONTAINER(id3win),5); gtk_signal_connect(GTK_OBJECT(id3win), "delete_event", (GtkSignalFunc) gtk_exit, NULL); id3win_frame_global=gtk_vbox_new(FALSE,5); /* rmcc was here */ id3win_menu_bar = gtk_menu_bar_new(); gtk_widget_show(id3win_menu_bar); gtk_box_pack_start(GTK_BOX(id3win_frame_global), id3win_menu_bar, FALSE, TRUE, 1); id3win_menu_file = gtk_menu_item_new_with_label("File"); gtk_widget_show(id3win_menu_file); gtk_container_add(GTK_CONTAINER(id3win_menu_bar), id3win_menu_file); id3win_menu_fcont = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(id3win_menu_file), id3win_menu_fcont); id3win_menu_open = gtk_menu_item_new_with_label("Open New "); gtk_widget_show(id3win_menu_open); gtk_container_add(GTK_CONTAINER(id3win_menu_fcont), id3win_menu_open); gtk_signal_connect(GTK_OBJECT(id3win_menu_open), "activate", GTK_SIGNAL_FUNC(open_mp3_file), NULL); id3win_menu_info = gtk_menu_item_new_with_label("Info "); gtk_widget_show(id3win_menu_info); gtk_container_add(GTK_CONTAINER(id3win_menu_fcont), id3win_menu_info); gtk_signal_connect(GTK_OBJECT(id3win_menu_info), "activate", GTK_SIGNAL_FUNC(create_techinfo_win), NULL); id3win_menu_help = gtk_menu_item_new_with_label(" Help"); gtk_widget_show(id3win_menu_help); gtk_container_add(GTK_CONTAINER(id3win_menu_bar), id3win_menu_help); gtk_menu_item_right_justify(GTK_MENU_ITEM(id3win_menu_help)); id3win_menu_hcont = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(id3win_menu_help), id3win_menu_hcont); id3win_menu_about = gtk_menu_item_new_with_label("About "); gtk_widget_show(id3win_menu_about); gtk_container_add(GTK_CONTAINER(id3win_menu_hcont), id3win_menu_about); gtk_signal_connect(GTK_OBJECT(id3win_menu_about), "activate", GTK_SIGNAL_FUNC(about_mp3info), NULL); /* rmcc has left the building */ id3win_frame_title=gtk_frame_new("Title"); gtk_container_border_width(GTK_CONTAINER(id3win_frame_title),5); id3win_text_title=gtk_entry_new_with_max_length(30); gtk_container_add(GTK_CONTAINER(id3win_frame_title),id3win_text_title); gtk_box_pack_start(GTK_BOX(id3win_frame_global),id3win_frame_title,TRUE,TRUE,0); id3win_frame_artist=gtk_frame_new("Artist"); gtk_container_border_width(GTK_CONTAINER(id3win_frame_artist),5); id3win_text_artist=gtk_entry_new_with_max_length(30); gtk_container_add(GTK_CONTAINER(id3win_frame_artist),id3win_text_artist); gtk_box_pack_start(GTK_BOX(id3win_frame_global),id3win_frame_artist,TRUE,TRUE,0); id3win_frame_albyear=gtk_hbox_new(FALSE,30); id3win_frame_album=gtk_frame_new("Album"); gtk_container_border_width(GTK_CONTAINER(id3win_frame_album),5); id3win_text_album=gtk_entry_new_with_max_length(30); gtk_container_add(GTK_CONTAINER(id3win_frame_album),id3win_text_album); gtk_box_pack_start(GTK_BOX(id3win_frame_albyear),id3win_frame_album,TRUE,TRUE,0); id3win_frame_year=gtk_frame_new("Year"); gtk_widget_set_usize(id3win_frame_year,2,0); gtk_container_border_width(GTK_CONTAINER(id3win_frame_year),5); id3win_text_year=gtk_entry_new_with_max_length(4); gtk_container_add(GTK_CONTAINER(id3win_frame_year),id3win_text_year); gtk_box_pack_start(GTK_BOX(id3win_frame_albyear),id3win_frame_year,TRUE,TRUE,0); gtk_box_pack_start(GTK_BOX(id3win_frame_global),id3win_frame_albyear,TRUE,TRUE,0); id3win_frame_comtrack=gtk_hbox_new(FALSE,30); id3win_frame_comment=gtk_frame_new("Comment"); gtk_container_border_width(GTK_CONTAINER(id3win_frame_comment),5); id3win_text_comment=gtk_entry_new_with_max_length(30); gtk_container_add(GTK_CONTAINER(id3win_frame_comment),id3win_text_comment); gtk_box_pack_start(GTK_BOX(id3win_frame_comtrack),id3win_frame_comment,TRUE,TRUE,0); id3win_frame_track=gtk_frame_new("Track"); gtk_widget_set_usize(id3win_frame_track,2,0); gtk_container_border_width(GTK_CONTAINER(id3win_frame_track),5); id3win_text_track=gtk_entry_new_with_max_length(3); gtk_container_add(GTK_CONTAINER(id3win_frame_track),id3win_text_track); gtk_box_pack_start(GTK_BOX(id3win_frame_comtrack),id3win_frame_track,TRUE,TRUE,0); gtk_box_pack_start(GTK_BOX(id3win_frame_global),id3win_frame_comtrack,TRUE,TRUE,0); id3win_frame_genre=gtk_frame_new("Genre"); gtk_container_border_width(GTK_CONTAINER(id3win_frame_genre),5); id3win_combo_genre=gtk_combo_new(); for(i=0;i 0) sprintf(track_text,"%d",(int)mp3.id3.track[0]); else track_text[0]=0; gtk_entry_set_text(GTK_ENTRY(id3win_text_track),track_text); gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(id3win_combo_genre)->entry), gtext_genre(mp3.id3.genre[0])); } else { open_mp3_file(); } gtk_main(); return(0); } gchar *gtext_genre(unsigned char genre) { int genre_num = (int) genre; if(genre_num <= MAXGENRE) { return((gchar *)typegenre[genre_num]); } else { return((gchar *)""); } } unsigned char gget_genre (char *genre) { int num_genre=0; if(genre[0] == '\0') { return 255; } sscanf(genre,"%u",&num_genre); if(num_genre == 0) { if(genre[0] != '0') { while(num_genre++ <= MAXGENRE) { if(!strcasecmp(genre,typegenre[num_genre-1])) { return num_genre-1; } } num_genre=256; } } if(num_genre < 0 || num_genre > MAXGENRE) { num_genre=255; } return (unsigned char) num_genre; } /* rmcc was here */ void create_techinfo_win(void) { GtkWidget *infowin_main, *infowin_main_frame; GtkWidget *infowin_exit_button, *infowin_button_frame; GtkWidget *infowin_text_media, *infowin_text_bitrate; GtkWidget *infowin_text_emphasis, *infowin_text_crc; GtkWidget *infowin_text_copyright, *infowin_text_original; GtkWidget *infowin_text_padding, *infowin_text_length; GtkWidget *infowin_text_frequency; int ibuf,ibuf2; char buf[1023]; char *layer_text[] = { "I", "II", "III" }; infowin_main = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_widget_set_usize(infowin_main, 230, 300); gtk_container_border_width(GTK_CONTAINER(infowin_main), 15); gtk_window_set_title(GTK_WINDOW(infowin_main), "MP3 Technical Info"); gtk_window_set_policy(GTK_WINDOW(infowin_main), FALSE, FALSE, FALSE); gtk_signal_connect_object(GTK_OBJECT(infowin_main), "key_press_event", GTK_SIGNAL_FUNC(kill_if_esc), (gpointer) infowin_main); infowin_main_frame=gtk_vbox_new(FALSE,5); if (mp3.header_isvalid) { sprintf(buf,"Media Type: MPEG %s Layer %s",mp3.header.version ? ((mp3.header.version==2) ? "2.5" : "1.0") : "2.0", layer_text[header_layer(&mp3.header)-1]); infowin_text_media=gtk_label_new(buf); gtk_box_pack_start(GTK_BOX(infowin_main_frame),infowin_text_media,TRUE,TRUE,0); sprintf(buf,"Bitrate: %i KB/s",header_bitrate(&mp3.header)); infowin_text_bitrate=gtk_label_new(buf); gtk_box_pack_start(GTK_BOX(infowin_main_frame),infowin_text_bitrate,TRUE,TRUE,0); sprintf(buf,"Frequency: %iKHz",header_frequency(&mp3.header)/1000); infowin_text_frequency=gtk_label_new(buf); gtk_box_pack_start(GTK_BOX(infowin_main_frame),infowin_text_frequency,TRUE,TRUE,0); ibuf=mp3.seconds / 60; ibuf2=mp3.seconds % 60; sprintf(buf,"Length: %i:%02i",ibuf,ibuf2); infowin_text_length=gtk_label_new(buf); gtk_box_pack_start(GTK_BOX(infowin_main_frame),infowin_text_length,TRUE,TRUE,0); sprintf(buf,"Emphasis: %s",header_emphasis(&mp3.header)); infowin_text_emphasis=gtk_label_new(buf); gtk_box_pack_start(GTK_BOX(infowin_main_frame),infowin_text_emphasis,TRUE,TRUE,0); sprintf(buf,"CRC: %s",!mp3.header.crc ? "Yes" : "No"); infowin_text_crc=gtk_label_new(buf); gtk_box_pack_start(GTK_BOX(infowin_main_frame),infowin_text_crc,TRUE,TRUE,0); sprintf(buf,"Copyright: %s",mp3.header.copyright ? "Yes" : "No"); infowin_text_copyright=gtk_label_new(buf); gtk_box_pack_start(GTK_BOX(infowin_main_frame),infowin_text_copyright,TRUE,TRUE,0); sprintf(buf,"Original: %s",mp3.header.original ? "Yes" : "No"); infowin_text_original=gtk_label_new(buf); gtk_box_pack_start(GTK_BOX(infowin_main_frame),infowin_text_original,TRUE,TRUE,0); sprintf(buf,"Padding: %s",mp3.header.padding ? "Yes" : "No"); infowin_text_padding=gtk_label_new(buf); gtk_box_pack_start(GTK_BOX(infowin_main_frame),infowin_text_padding,TRUE,TRUE,0); } else { sprintf(buf,"This file's header\nis invalid.\n\nNo information\navailable"); infowin_text_media=gtk_label_new(buf); gtk_box_pack_start(GTK_BOX(infowin_main_frame),infowin_text_media,TRUE,TRUE,0); } infowin_button_frame=gtk_hbox_new(TRUE,30); gtk_widget_set_usize(infowin_button_frame,30,20); gtk_box_pack_start(GTK_BOX(infowin_main_frame),infowin_button_frame,TRUE,TRUE,0); infowin_exit_button = gtk_button_new_with_label("Exit"); gtk_widget_show(infowin_exit_button); gtk_box_pack_end(GTK_BOX(infowin_button_frame), infowin_exit_button, FALSE, TRUE, 0); gtk_signal_connect_object(GTK_OBJECT(infowin_exit_button), "pressed", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(infowin_main)); gtk_container_add(GTK_CONTAINER(infowin_main),infowin_main_frame); gtk_widget_show_all(infowin_main); } void open_mp3_file(void) { GtkWidget *filewin_main; filewin_main=gtk_file_selection_new("Use another MP3 File"); gtk_signal_connect_object(GTK_OBJECT(filewin_main), "key_press_event", (GtkSignalFunc) kill_if_esc, (gpointer) filewin_main); gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(filewin_main)->cancel_button), "pressed", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(filewin_main)); gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(filewin_main)->ok_button), "clicked", (GtkSignalFunc) read_new_mp3, filewin_main); gtk_widget_show(filewin_main); } void read_new_mp3(GtkWidget *button, GtkWidget *file) { char *filename; filename = (char *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(file)); if (load_mp3(filename) == 1) { gtk_widget_destroy(file); gtk_entry_set_text(GTK_ENTRY(id3win_text_title),mp3.id3.title); gtk_entry_set_text(GTK_ENTRY(id3win_text_artist),mp3.id3.artist); gtk_entry_set_text(GTK_ENTRY(id3win_text_album),mp3.id3.album); gtk_entry_set_text(GTK_ENTRY(id3win_text_year),mp3.id3.year); gtk_entry_set_text(GTK_ENTRY(id3win_text_comment),mp3.id3.comment); gtk_entry_set_text(GTK_ENTRY(id3win_text_track),(char *)mp3.id3.track); gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(id3win_combo_genre)->entry), gtext_genre(mp3.id3.genre[0])); } } int load_mp3(char *filename) { mp3info nmp3; memset(&nmp3,0,sizeof(mp3info)); if ( !( nmp3.file=fopen(filename,"rb+") ) ) { if((nmp3.file=fopen(filename,"rb"))) read_only=1; else { if (id3win) { quick_popup("Error in file", "Error opening MP3 file."); } else { g_print("Error opening MP3 file."); } return 0; } } nmp3.filename=filename; get_mp3_info(&nmp3,SCAN_QUICK,0); if(!nmp3.header_isvalid && !nmp3.id3_isvalid) { if (id3win) { quick_popup("Error in file", "File is corrupt or is not a standard MP3 file!"); } else { g_print("File is corrupt or is not a standard MP3 file!\n"); } return 0; } else { mp3=nmp3; return 1; } return 0; } int kill_if_esc(GtkWidget *widget, GdkEventKey *event, gpointer obj) { if(event && event->type == GDK_KEY_PRESS && event->keyval == GDK_Escape) { gtk_widget_destroy(GTK_WIDGET(obj)); gtk_signal_emit_stop_by_name(GTK_OBJECT(widget), "key_press_event"); } return(TRUE); } void quick_popup(char *title, char *message) { GtkWidget *popupwin, *popupwin_main, *popupwin_msg, *popupwin_ok; char *markup; popupwin = gtk_dialog_new(); gtk_widget_realize(popupwin); gtk_container_border_width(GTK_CONTAINER(popupwin), 12); gtk_window_set_title(GTK_WINDOW(popupwin), title); popupwin_main = GTK_DIALOG(popupwin)->vbox; popupwin_msg=gtk_label_new(NULL); markup = g_markup_printf_escaped("%s",message); gtk_label_set_markup(GTK_LABEL(popupwin_msg),markup); g_free (markup); gtk_box_pack_start(GTK_BOX(popupwin_main),popupwin_msg,TRUE,TRUE,0); popupwin_ok = gtk_button_new_with_label(" OK "); gtk_signal_connect_object(GTK_OBJECT(popupwin_ok), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(popupwin)); gtk_signal_connect_object(GTK_OBJECT(popupwin), "key_press_event", (GtkSignalFunc) kill_if_esc, (gpointer) popupwin); gtk_box_pack_end(GTK_BOX(popupwin_main), popupwin_ok, TRUE, FALSE, 0); gtk_widget_show_all(popupwin); } void about_mp3info(void) { quick_popup(VERSION,"MP3Info\n" " An ID3 Tag Editor\n\n\n" " Original author: Ricardo Cerqueira \n" " Current maintainer: Cedric Tefft \n" " (C) 1999-2006 Ricardo Cerqueira, Cedric Tefft\n\n"); } /* rmcc has left the building */