Mercurial > audlegacy-plugins
view src/filewriter/filewriter.c @ 2284:d19b53359b24
cleaned up the sndfile wav plugin, currently limiting it ONLY TO WAV
PLAYBACK. if somebody is more experienced with it and wants to restore
the other formats, go ahead (maybe change the name of the plugin too?).
author | mf0102 <0102@gmx.at> |
---|---|
date | Wed, 09 Jan 2008 15:41:22 +0100 |
parents | 573436f1a56e |
children | 769e17da93dd 6d08e3120615 |
line wrap: on
line source
/* FileWriter-Plugin * (C) copyright 2007 merging of Disk Writer and Out-Lame by Michael Färber * * Original Out-Lame-Plugin: * (C) copyright 2002 Lars Siebold <khandha5@gmx.net> * (C) copyright 2006-2007 porting to audacious by Yoshiki Yazawa <yaz@cc.rim.or.jp> * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "filewriter.h" #include "plugins.h" struct format_info input; static GtkWidget *configure_win = NULL, *configure_vbox; static GtkWidget *path_hbox, *path_label, *path_dirbrowser; static GtkWidget *configure_bbox, *configure_ok, *configure_cancel; static GtkWidget *fileext_hbox, *fileext_label, *fileext_combo, *plugin_button; enum fileext_t { WAV = 0, #ifdef FILEWRITER_MP3 MP3, #endif #ifdef FILEWRITER_VORBIS VORBIS, #endif #ifdef FILEWRITER_FLAC FLAC, #endif FILEEXT_MAX }; static gint fileext = WAV; static gchar *fileext_str[] = { "wav", #ifdef FILEWRITER_MP3 "mp3", #endif #ifdef FILEWRITER_VORBIS "ogg", #endif #ifdef FILEWRITER_FLAC "flac" #endif }; static FileWriter plugin; static GtkWidget *saveplace_hbox, *saveplace; static gboolean save_original = TRUE; static GtkWidget *filenamefrom_hbox, *filenamefrom_label, *filenamefrom_toggle; static gboolean filenamefromtags = TRUE; static GtkWidget *use_suffix_toggle = NULL; static gboolean use_suffix = FALSE; static GtkWidget *prependnumber_toggle; static gboolean prependnumber = FALSE; static gchar *file_path = NULL; static void file_init(void); static void file_about(void); static gint file_open(AFormat fmt, gint rate, gint nch); static void file_write(void *ptr, gint length); static void file_close(void); static void file_flush(gint time); static void file_pause(short p); static gint file_free(void); static gint file_playing(void); static gint file_get_written_time(void); static gint file_get_output_time(void); static void file_configure(void); OutputPlugin file_op = { .description = "FileWriter Plugin", .init = file_init, .about = file_about, .configure = file_configure, .open_audio = file_open, .write_audio = file_write, .close_audio = file_close, .flush = file_flush, .pause = file_pause, .buffer_free = file_free, .buffer_playing = file_playing, .output_time = file_get_output_time, .written_time = file_get_written_time }; OutputPlugin *file_oplist[] = { &file_op, NULL }; SIMPLE_OUTPUT_PLUGIN(filewriter, file_oplist); static void set_plugin(void) { if (fileext < 0 || fileext >= FILEEXT_MAX) fileext = 0; if (fileext == WAV) plugin = wav_plugin; #ifdef FILEWRITER_MP3 if (fileext == MP3) plugin = mp3_plugin; #endif #ifdef FILEWRITER_VORBIS if (fileext == VORBIS) plugin = vorbis_plugin; #endif #ifdef FILEWRITER_FLAC if (fileext == FLAC) plugin = flac_plugin; #endif } static void file_init(void) { ConfigDb *db; /*GtkWidget *menu_root; menu_root = gtk_menu_item_new_with_label(_("FileWriter")); gtk_widget_show(menu_root); audacious_menu_plugin_item_add(AUDACIOUS_MENU_PLAYLIST_RCLICK, menu_root);*/ db = aud_cfg_db_open(); aud_cfg_db_get_int(db, "filewriter", "fileext", &fileext); aud_cfg_db_get_string(db, "filewriter", "file_path", &file_path); aud_cfg_db_get_bool(db, "filewriter", "save_original", &save_original); aud_cfg_db_get_bool(db, "filewriter", "use_suffix", &use_suffix); aud_cfg_db_get_bool(db, "filewriter", "filenamefromtags", &filenamefromtags); aud_cfg_db_get_bool(db, "filewriter", "prependnumber", &prependnumber); aud_cfg_db_close(db); if (!file_path) file_path = g_strdup(g_get_home_dir()); set_plugin(); if (plugin.init) plugin.init(); } void file_about(void) { static GtkWidget *dialog; if (dialog != NULL) return; dialog = audacious_info_dialog(_("About FileWriter-Plugin"), _("FileWriter-Plugin\n\n" "This program is free software; you can redistribute it and/or modify\n" "it under the terms of the GNU General Public License as published by\n" "the Free Software Foundation; either version 2 of the License, or\n" "(at your option) any later version.\n" "\n" "This program is distributed in the hope that it will be useful,\n" "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" "GNU General Public License for more details.\n" "\n" "You should have received a copy of the GNU General Public License\n" "along with this program; if not, write to the Free Software\n" "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,\n" "USA."), _("Ok"), FALSE, NULL, NULL); gtk_signal_connect(GTK_OBJECT(dialog), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &dialog); } static gint file_open(AFormat fmt, gint rate, gint nch) { gchar *filename = NULL, *temp = NULL; const gchar *directory; gint pos; gint rv; Playlist *playlist; input.format = fmt; input.frequency = rate; input.channels = nch; playlist = aud_playlist_get_active(); if(!playlist) return 0; pos = aud_playlist_get_position(playlist); tuple = aud_playlist_get_tuple(playlist, pos); if(!tuple) return 0; if (filenamefromtags) { gchar *utf8 = aud_tuple_formatter_make_title_string(tuple, aud_get_gentitle_format()); g_strchomp(utf8); //chop trailing ^J --yaz filename = g_locale_from_utf8(utf8, -1, NULL, NULL, NULL); g_free(utf8); while (filename != NULL && (temp = strchr(filename, '/')) != NULL) *temp = '-'; } if (filename == NULL) { filename = g_strdup(aud_tuple_get_string(tuple, FIELD_FILE_NAME, NULL)); if (!use_suffix) if ((temp = strrchr(filename, '.')) != NULL) *temp = '\0'; } if (filename == NULL) filename = g_strdup_printf("aud-%d", pos); if (prependnumber) { gint number = aud_tuple_get_int(tuple, FIELD_TRACK_NUMBER, NULL); if (!tuple || !number) number = pos + 1; temp = g_strdup_printf("%.02d %s", number, filename); g_free(filename); filename = temp; } if (save_original) directory = aud_tuple_get_string(tuple, FIELD_FILE_PATH, NULL); else directory = file_path; temp = g_strdup_printf("file://%s/%s.%s", directory, filename, fileext_str[fileext]); g_free(filename); filename = temp; output_file = aud_vfs_fopen(filename, "w"); g_free(filename); if (!output_file) return 0; rv = (plugin.open)(); return rv; } static void convert_buffer(gpointer buffer, gint length) { gint i; if (input.format == FMT_S8) { guint8 *ptr1 = buffer; gint8 *ptr2 = buffer; for (i = 0; i < length; i++) *(ptr1++) = *(ptr2++) ^ 128; } if (input.format == FMT_S16_BE) { gint16 *ptr = buffer; for (i = 0; i < length >> 1; i++, ptr++) *ptr = GUINT16_SWAP_LE_BE(*ptr); } if (input.format == FMT_S16_NE) { gint16 *ptr = buffer; for (i = 0; i < length >> 1; i++, ptr++) *ptr = GINT16_TO_LE(*ptr); } if (input.format == FMT_U16_BE) { gint16 *ptr1 = buffer; guint16 *ptr2 = buffer; for (i = 0; i < length >> 1; i++, ptr2++) *(ptr1++) = GINT16_TO_LE(GUINT16_FROM_BE(*ptr2) ^ 32768); } if (input.format == FMT_U16_LE) { gint16 *ptr1 = buffer; guint16 *ptr2 = buffer; for (i = 0; i < length >> 1; i++, ptr2++) *(ptr1++) = GINT16_TO_LE(GUINT16_FROM_LE(*ptr2) ^ 32768); } if (input.format == FMT_U16_NE) { gint16 *ptr1 = buffer; guint16 *ptr2 = buffer; for (i = 0; i < length >> 1; i++, ptr2++) *(ptr1++) = GINT16_TO_LE((*ptr2) ^ 32768); } } static void file_write(void *ptr, gint length) { if (input.format == FMT_S8 || input.format == FMT_S16_BE || input.format == FMT_U16_LE || input.format == FMT_U16_BE || input.format == FMT_U16_NE) convert_buffer(ptr, length); #ifdef WORDS_BIGENDIAN if (input.format == FMT_S16_NE) convert_buffer(ptr, length); #endif plugin.write(ptr, length); } static void file_close(void) { plugin.close(); if (output_file) { written = 0; aud_vfs_fclose(output_file); } output_file = NULL; } static void file_flush(gint time) { if (time < 0) return; file_close(); file_open(input.format, input.frequency, input.channels); offset = time; } static void file_pause(short p) { } static gint file_free(void) { return plugin.free(); } static gint file_playing(void) { return plugin.playing(); } static gint file_get_written_time(void) { return plugin.get_written_time(); } static gint file_get_output_time(void) { return file_get_written_time(); } static void configure_ok_cb(gpointer data) { ConfigDb *db; fileext = gtk_combo_box_get_active(GTK_COMBO_BOX(fileext_combo)); g_free(file_path); file_path = g_strdup(gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(path_dirbrowser))); use_suffix = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(use_suffix_toggle)); prependnumber = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(prependnumber_toggle)); db = aud_cfg_db_open(); aud_cfg_db_set_int(db, "filewriter", "fileext", fileext); aud_cfg_db_set_string(db, "filewriter", "file_path", file_path); aud_cfg_db_set_bool(db, "filewriter", "save_original", save_original); aud_cfg_db_set_bool(db, "filewriter", "filenamefromtags", filenamefromtags); aud_cfg_db_set_bool(db, "filewriter", "use_suffix", use_suffix); aud_cfg_db_set_bool(db, "filewriter", "prependnumber", prependnumber); aud_cfg_db_close(db); gtk_widget_destroy(configure_win); if (path_dirbrowser) gtk_widget_destroy(path_dirbrowser); } static void fileext_cb(GtkWidget *combo, gpointer data) { fileext = gtk_combo_box_get_active(GTK_COMBO_BOX(fileext_combo)); set_plugin(); gtk_widget_set_sensitive(plugin_button, plugin.configure != NULL); } static void plugin_configure_cb(GtkWidget *button, gpointer data) { if (plugin.configure) plugin.configure(); } static void saveplace_original_cb(GtkWidget *button, gpointer data) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) { gtk_widget_set_sensitive(path_hbox, FALSE); save_original = TRUE; } } static void saveplace_custom_cb(GtkWidget *button, gpointer data) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) { gtk_widget_set_sensitive(path_hbox, TRUE); save_original = FALSE; } } static void filenamefromtags_cb(GtkWidget *button, gpointer data) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) { gtk_widget_set_sensitive(use_suffix_toggle, FALSE); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(use_suffix_toggle), FALSE); use_suffix = FALSE; filenamefromtags = TRUE; } } static void filenamefromfilename_cb(GtkWidget *button, gpointer data) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) { gtk_widget_set_sensitive(use_suffix_toggle, TRUE); filenamefromtags = FALSE; } } static void configure_destroy(void) { if (path_dirbrowser) gtk_widget_destroy(path_dirbrowser); } static void file_configure(void) { GtkTooltips *use_suffix_tooltips; if (!configure_win) { configure_win = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_signal_connect(GTK_OBJECT(configure_win), "destroy", GTK_SIGNAL_FUNC(configure_destroy), NULL); gtk_signal_connect(GTK_OBJECT(configure_win), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &configure_win); gtk_window_set_title(GTK_WINDOW(configure_win), _("File Writer Configuration")); gtk_window_set_position(GTK_WINDOW(configure_win), GTK_WIN_POS_MOUSE); gtk_container_set_border_width(GTK_CONTAINER(configure_win), 10); configure_vbox = gtk_vbox_new(FALSE, 10); gtk_container_add(GTK_CONTAINER(configure_win), configure_vbox); fileext_hbox = gtk_hbox_new(FALSE, 5); gtk_box_pack_start(GTK_BOX(configure_vbox), fileext_hbox, FALSE, FALSE, 0); fileext_label = gtk_label_new(_("Output file format:")); gtk_box_pack_start(GTK_BOX(fileext_hbox), fileext_label, FALSE, FALSE, 0); fileext_combo = gtk_combo_box_new_text(); gtk_combo_box_append_text(GTK_COMBO_BOX(fileext_combo), "WAV"); #ifdef FILEWRITER_MP3 gtk_combo_box_append_text(GTK_COMBO_BOX(fileext_combo), "MP3"); #endif #ifdef FILEWRITER_VORBIS gtk_combo_box_append_text(GTK_COMBO_BOX(fileext_combo), "Vorbis"); #endif #ifdef FILEWRITER_FLAC gtk_combo_box_append_text(GTK_COMBO_BOX(fileext_combo), "FLAC"); #endif gtk_box_pack_start(GTK_BOX(fileext_hbox), fileext_combo, FALSE, FALSE, 0); gtk_combo_box_set_active(GTK_COMBO_BOX(fileext_combo), fileext); g_signal_connect(G_OBJECT(fileext_combo), "changed", G_CALLBACK(fileext_cb), NULL); plugin_button = gtk_button_new_with_label(_("Configure")); gtk_widget_set_sensitive(plugin_button, plugin.configure != NULL); g_signal_connect(G_OBJECT(plugin_button), "clicked", G_CALLBACK(plugin_configure_cb), NULL); gtk_box_pack_end(GTK_BOX(fileext_hbox), plugin_button, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(configure_vbox), gtk_hseparator_new(), FALSE, FALSE, 0); saveplace_hbox = gtk_hbox_new(FALSE, 5); gtk_container_add(GTK_CONTAINER(configure_vbox), saveplace_hbox); saveplace = gtk_radio_button_new_with_label(NULL, _("Save into original directory")); g_signal_connect(G_OBJECT(saveplace), "toggled", G_CALLBACK(saveplace_original_cb), NULL); gtk_box_pack_start(GTK_BOX(saveplace_hbox), saveplace, FALSE, FALSE, 0); saveplace = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(saveplace), _("Save into custom directory")); g_signal_connect(G_OBJECT(saveplace), "toggled", G_CALLBACK(saveplace_custom_cb), NULL); gtk_box_pack_start(GTK_BOX(saveplace_hbox), saveplace, FALSE, FALSE, 0); if (!save_original) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(saveplace), TRUE); path_hbox = gtk_hbox_new(FALSE, 5); gtk_box_pack_start(GTK_BOX(configure_vbox), path_hbox, FALSE, FALSE, 0); path_label = gtk_label_new(_("Output file folder:")); gtk_box_pack_start(GTK_BOX(path_hbox), path_label, FALSE, FALSE, 0); path_dirbrowser = gtk_file_chooser_button_new (_("Pick a folder"), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(path_dirbrowser), file_path); gtk_box_pack_start(GTK_BOX(path_hbox), path_dirbrowser, TRUE, TRUE, 0); if (save_original) gtk_widget_set_sensitive(path_hbox, FALSE); gtk_box_pack_start(GTK_BOX(configure_vbox), gtk_hseparator_new(), FALSE, FALSE, 0); filenamefrom_hbox = gtk_hbox_new(FALSE, 5); gtk_container_add(GTK_CONTAINER(configure_vbox), filenamefrom_hbox); filenamefrom_label = gtk_label_new(_("Get filename from:")); gtk_box_pack_start(GTK_BOX(filenamefrom_hbox), filenamefrom_label, FALSE, FALSE, 0); filenamefrom_toggle = gtk_radio_button_new_with_label(NULL, _("original file tags")); g_signal_connect(G_OBJECT(filenamefrom_toggle), "toggled", G_CALLBACK(filenamefromtags_cb), NULL); gtk_box_pack_start(GTK_BOX(filenamefrom_hbox), filenamefrom_toggle, FALSE, FALSE, 0); filenamefrom_toggle = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(filenamefrom_toggle), _("original filename")); g_signal_connect(G_OBJECT(filenamefrom_toggle), "toggled", G_CALLBACK(filenamefromfilename_cb), NULL); gtk_box_pack_start(GTK_BOX(filenamefrom_hbox), filenamefrom_toggle, FALSE, FALSE, 0); if (!filenamefromtags) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(filenamefrom_toggle), TRUE); use_suffix_toggle = gtk_check_button_new_with_label(_("Don't strip file name extension")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(use_suffix_toggle), use_suffix); gtk_box_pack_start(GTK_BOX(configure_vbox), use_suffix_toggle, FALSE, FALSE, 0); use_suffix_tooltips = gtk_tooltips_new(); gtk_tooltips_set_tip(use_suffix_tooltips, use_suffix_toggle, _("If enabled, the extension from the original filename will not be stripped before adding the new file extension to the end."), NULL); gtk_tooltips_enable(use_suffix_tooltips); if (filenamefromtags) gtk_widget_set_sensitive(use_suffix_toggle, FALSE); gtk_box_pack_start(GTK_BOX(configure_vbox), gtk_hseparator_new(), FALSE, FALSE, 0); prependnumber_toggle = gtk_check_button_new_with_label(_("Prepend track number to filename")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(prependnumber_toggle), prependnumber); gtk_box_pack_start(GTK_BOX(configure_vbox), prependnumber_toggle, FALSE, FALSE, 0); configure_bbox = gtk_hbutton_box_new(); gtk_button_box_set_layout(GTK_BUTTON_BOX(configure_bbox), GTK_BUTTONBOX_END); gtk_button_box_set_spacing(GTK_BUTTON_BOX(configure_bbox), 5); gtk_box_pack_start(GTK_BOX(configure_vbox), configure_bbox, FALSE, FALSE, 0); configure_cancel = gtk_button_new_from_stock(GTK_STOCK_CANCEL); gtk_signal_connect_object(GTK_OBJECT(configure_cancel), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(configure_win)); gtk_box_pack_start(GTK_BOX(configure_bbox), configure_cancel, TRUE, TRUE, 0); configure_ok = gtk_button_new_from_stock(GTK_STOCK_OK); gtk_signal_connect(GTK_OBJECT(configure_ok), "clicked", GTK_SIGNAL_FUNC(configure_ok_cb), NULL); gtk_box_pack_start(GTK_BOX(configure_bbox), configure_ok, TRUE, TRUE, 0); gtk_widget_show_all(configure_win); } } VFSFile *output_file = NULL; guint64 written = 0; guint64 offset = 0; Tuple *tuple = NULL;