/* xmms - graphically mp3 player.. * Copyright (C) 1998-1999 Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies * * 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 #include #include "common.h" #include "config.h" #include "instrum.h" #include "output.h" #include "mid.h" #include #include #include #include "playmidi.h" #include "controls.h" #include #include #include "gmvoices.h" extern ControlMode dumb_control_mode; extern PlayMode xmms_play_mode; void aboutbox(void); void configure(void); int read_config_file(char *); void init_tables(void); void skip_to(int); InputPlugin mid_ip= { NULL, NULL, "Timidity Player 0.01", mid_init, aboutbox, configure, is_our_file, NULL, play_file, stop, plugin_mid_pause, seek, NULL, get_time, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; unsigned int total_time; WaveFile *wav_file=NULL; pthread_t decode_thread; MidiEvent *event; int32 events, samples; int got_a_configuration; static GtkWidget *about_window = NULL; static GtkWidget *configure_window = NULL; int timer_id; int vu_level[16], vu_delta[16]; int configure_window_ready; InputPlugin *get_iplugin_info(void) { return &mid_ip; } void mid_init(void) { ctl=&dumb_control_mode; play_mode=&xmms_play_mode; ctl->open(1,1); got_a_configuration=0; if (!read_config_file(CONFIG_FILE)) got_a_configuration=1; init_tables(); control_ratio=32; } int is_our_file(char *filename) { char *ext; ext=strrchr(filename,'.'); if(ext) { if(!strcasecmp(ext,".mid")) { return 1; } } return 0; } void *play_loop(void *arg) { play_midi(event, events, samples); if (free_instruments_afterwards) free_instruments(); free(event); /* wav_file->going=0; */ wav_file->eof=1; while(mid_ip.output->buffer_playing()) usleep(1000); pthread_exit(NULL); } void play_file(char *filename) { char *temp, *name; wav_file=malloc(sizeof(WaveFile)); memset(wav_file,0,sizeof(WaveFile)); if(mid_ip.output->open_audio(FMT_S16_LE,44100,2)==0) { free(wav_file); wav_file=NULL; return; } temp=strrchr(filename,'/'); if(!temp) temp=filename; else temp++; name=malloc(strlen(filename)+1); strcpy(name, temp); *strrchr(name,'.')=0; play_midi_file(filename); mid_ip.set_info(name, (total_time*10)/441 ,44100*32, 44100,2); free(name); wav_file->seek_to=-1; wav_file->going=1; pthread_create(&decode_thread, NULL, play_loop, NULL); } void stop(void) { if(wav_file) { if(wav_file->going) { wav_file->going=0; pthread_join(decode_thread,NULL); mid_ip.output->close_audio(); free(wav_file); wav_file=NULL; } } } void plugin_mid_pause(short p) { mid_ip.output->pause(p); } extern int sample_count; void seek(int time) { skip_to(time*44100); mid_ip.output->flush(time*1000); } int get_time(void) { if(wav_file->going) if(!wav_file->eof) return mid_ip.output->output_time(); return -1; } gfloat volmin=-255.0; gfloat volmax=0.0; gfloat volval; int rvol[16]; int soloc[16]; int solo; GtkAdjustment *vol[16]; GtkWidget *channames[16]; void slider_set(GtkAdjustment *adj, GtkWidget *slider) { int i; i=atoi(gtk_widget_get_name(slider)); channel[i].volume=adj->value; } void idle_timer(void *arg) { int i; if(configure_window && configure_window_ready) { for(i=0;i<16; i++) if (vu_delta[i]) { /* decay meter */ vu_level[i] -= vu_delta[i]; if (vu_level[i] < 0) vu_level[i] = vu_delta[i] = 0; show_mid_volume(i); } } else { gtk_timeout_remove(timer_id); } } void set_prog_name(int c, int n) { if(configure_window && configure_window_ready) { gtk_label_set(channames[c], gmvoice[n]); } } void solof(GtkWidget *w) { int i, j; i=atoi(gtk_widget_get_name(w)); if(soloc[i]) { soloc[i]=0; solo=0; channel[i].volume=0; for(j=0;j<16;j++) { if(soloc[j]) { solo=1; } } if(!solo) { for(j=0;j<16;j++) { channel[j].volume=-rvol[j]; } } } else { if(!solo) { solo=1; for(j=0;j<16;j++) { rvol[j]=-channel[j].volume; channel[j].volume=0; } } soloc[i]=1; channel[i].volume=127; } gtk_widget_draw(w, NULL); } void mid_note(int c, int n, int s) { GtkWidget *widget; if(configure_window && configure_window_ready) { widget=configure_window; gdk_window_clear_area(widget->window, 38+34*c, 100+n*2, 7, 4); if(s) gdk_draw_line(widget->window, widget->style->fg_gc[widget->state], 38+34*c, 100+n*2, 42+34*c, 100+n*2); } } void show_mid_volume(c) { GtkWidget *widget; if(configure_window && configure_window_ready) { widget=configure_window; gdk_window_clear_area(widget->window, 35+34*c, 200, 2, 200); gdk_draw_line(widget->window, widget->style->fg_gc[widget->state], 36+34*c, 400, 36+34*c, 400-vu_level[c]); } } void configure() { GtkWidget *hbox1; GtkWidget *slider; GtkWidget *configure_exit; GtkWidget *vbox; GtkWidget *button; GtkWidget *label; gfloat step=1.0; gfloat page_increment=10.0; char name[4]; char lname[128]; int i; if (!configure_window) { configure_window_ready=0; configure_window = gtk_dialog_new(); gtk_object_set_data(GTK_OBJECT (configure_window), "config window", configure_window); gtk_window_set_title(GTK_WINDOW(configure_window), "Configure Timidity plugin"); gtk_window_set_policy (GTK_WINDOW (configure_window), FALSE, FALSE, FALSE); gtk_window_set_position (GTK_WINDOW (configure_window), GTK_WIN_POS_MOUSE); gtk_signal_connect (GTK_OBJECT (configure_window), "destroy", GTK_SIGNAL_FUNC (gtk_widget_destroyed), &configure_window); gtk_container_border_width (GTK_CONTAINER (configure_window), 10); gtk_widget_show(GTK_DIALOG(configure_window)->vbox); hbox1=gtk_hbox_new(FALSE, 0); gtk_widget_show(hbox1); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(configure_window)->vbox), GTK_WIDGET(hbox1), TRUE, TRUE, 10); for(i=0;i<16;i++) { vu_level[i]=vu_delta[i]=soloc[i]=0; volval=-channel[i].volume; vol[i]=gtk_adjustment_new(volval, volmin, volmax, step, page_increment, (gfloat) 5.0); volval=0; slider=gtk_vscale_new(vol[i]); gtk_widget_set_name(slider, name); gtk_signal_connect(GTK_OBJECT(vol[i]), "value_changed", GTK_SIGNAL_FUNC(slider_set), slider); gtk_widget_set_usize(GTK_WIDGET(slider), 30, 300); gtk_widget_show(slider); vbox=gtk_vbox_new(FALSE, 0); gtk_widget_show(vbox); label=gtk_entry_new_with_max_length(4); gtk_widget_set_usize(GTK_WIDGET(label), 30, 20); gtk_entry_set_text(label, name); gtk_widget_show(label); gtk_scale_set_draw_value(slider, FALSE); button=gtk_toggle_button_new_with_label("S"); gtk_widget_set_name(button, name); gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(solof), GTK_OBJECT(button)); gtk_widget_show(button); lname[4]=0; channames[i]=gtk_label_new(lname); gtk_widget_show(channames[i]); gtk_box_pack_start(GTK_BOX(vbox), channames[i], TRUE, TRUE, 10); gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 10); gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 10); gtk_box_pack_start(GTK_BOX(vbox), slider, TRUE, TRUE, 10); gtk_box_pack_start(GTK_BOX(hbox1), vbox, TRUE, TRUE, 2); } configure_exit = gtk_button_new_with_label ("Ok"); gtk_signal_connect_object (GTK_OBJECT (configure_exit), "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy), GTK_OBJECT (configure_window)); gtk_widget_show(configure_exit); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(configure_window)->action_area), configure_exit, TRUE, TRUE, 10); gtk_widget_show(configure_window); configure_window_ready=1; timer_id=gtk_timeout_add(100, (GtkFunction) idle_timer, NULL); } else { gdk_window_raise (configure_window->window); } } void aboutbox () { GtkWidget *dialog_vbox1; GtkWidget *hbox1; GtkWidget *label1; GtkWidget *dialog_action_area1; GtkWidget *about_exit; if (!about_window) { about_window = gtk_dialog_new (); gtk_object_set_data (GTK_OBJECT (about_window), "about_window", about_window); gtk_window_set_title (GTK_WINDOW (about_window), "About timidity plugin"); gtk_window_set_policy (GTK_WINDOW (about_window), FALSE, FALSE, FALSE); gtk_window_set_position (GTK_WINDOW (about_window), GTK_WIN_POS_MOUSE); gtk_signal_connect (GTK_OBJECT (about_window), "destroy", GTK_SIGNAL_FUNC (gtk_widget_destroyed), &about_window); gtk_container_border_width (GTK_CONTAINER (about_window), 10); dialog_vbox1 = GTK_DIALOG (about_window)->vbox; gtk_object_set_data (GTK_OBJECT (about_window), "dialog_vbox1", dialog_vbox1); gtk_widget_show (dialog_vbox1); gtk_container_border_width (GTK_CONTAINER (dialog_vbox1), 5); hbox1 = gtk_hbox_new (FALSE, 0); gtk_object_set_data (GTK_OBJECT (about_window), "hbox1", hbox1); gtk_widget_show (hbox1); gtk_box_pack_start (GTK_BOX (dialog_vbox1), hbox1, TRUE, TRUE, 0); gtk_container_border_width (GTK_CONTAINER (hbox1), 5); gtk_widget_realize(about_window); label1 = gtk_label_new ("Timidity Plugin\nhttp://ban.joh.cam.ac.uk/~cr212/xmms-plugin/timidity/\nPorted to x11amp by Chris Reed"); gtk_object_set_data (GTK_OBJECT (about_window), "label1", label1); gtk_widget_show (label1); gtk_box_pack_start (GTK_BOX (hbox1), label1, TRUE, TRUE, 0); dialog_action_area1 = GTK_DIALOG (about_window)->action_area; gtk_object_set_data (GTK_OBJECT (about_window), "dialog_action_area1", dialog_action_area1); gtk_widget_show (dialog_action_area1); gtk_container_border_width (GTK_CONTAINER (dialog_action_area1), 10); about_exit = gtk_button_new_with_label ("Ok"); gtk_signal_connect_object (GTK_OBJECT (about_exit), "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy), GTK_OBJECT (about_window)); gtk_object_set_data (GTK_OBJECT (about_window), "about_exit", about_exit); gtk_widget_show (about_exit); gtk_box_pack_start (GTK_BOX (dialog_action_area1), about_exit, TRUE, TRUE, 0); gtk_widget_show (about_window); } else { gdk_window_raise (about_window->window); } }