/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * GnoWavCut -- a GNOME/GTK+ based RIFF PCM Wave File splitter * Copyright (C) 2000 Yoichi Imai * * 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 "config.h" #include "wave.h" #include "main.h" #include "utils.h" #include "prefs.h" #include #include #include #include #include #include #define BUFFER 128 /* #define MOVE_SEC 4 #define MINI_PLAY_SEC 3 #define MINI_PREVIEW_PLAY TRUE */ #define MINI_LONG_MOVE_SEC 0.2 #define MINI_MOVE_SEC 0.04 static void wave_play_loop(gpointer data, gint fd, GdkInputCondition condition); static void wave_update_time_digit(GnoWavCut *gnowavcut); static void wave_play_loop_mini(gpointer data, gint fd, GdkInputCondition condition); static void wave_play_mini(GnoWavCut *gnowavcut); static void wave_ff_mini(GnoWavCut *gnowavcut, float move_sec); static void wave_rew_mini(GnoWavCut *gnowavcut, float move_sec); static void wave_update_mini_time_digit(GnoWavCut *gnowavcut); static void wave_seek_if_mini_playing(GnoWavCut *gnowavcut); static void wave_seek_if_mini_playing(GnoWavCut *gnowavcut) { if(gnowavcut->now_mini_playing == TRUE) { gtk_input_remove(gnowavcut->input_tag); lseek(gnowavcut->wave_fd, gnowavcut->mini_old_point, SEEK_SET); wave_update_time_digit(gnowavcut); gnowavcut->now_mini_playing = FALSE; } } static void wave_update_mini_time_digit(GnoWavCut *gnowavcut) { WaveInfo *wave_info; int now_point; gchar *time; wave_info = gnowavcut->wave_info; g_return_if_fail(gnowavcut->now_playing == TRUE); now_point = lseek(gnowavcut->wave_fd, 0, SEEK_CUR); gnowavcut->mini_old_point = now_point; time = utils_get_mini_time_from_cur(wave_info, now_point); gtk_label_set_text(GTK_LABEL(gnowavcut->label_mini), time); g_free(time); } static void wave_update_time_digit(GnoWavCut *gnowavcut) { WaveInfo *wave_info; gchar *time; int now_point; gfloat percent; if (gnowavcut->hscale_can_move == FALSE) return; g_return_if_fail(gnowavcut->now_playing == TRUE); wave_info = gnowavcut->wave_info; now_point = lseek(gnowavcut->wave_fd, 0, SEEK_CUR); time = utils_get_time_from_seconds((now_point - WAVE_HEADER_SIZE) / wave_info->size_per_sec); gtk_label_set_text(GTK_LABEL(gnowavcut->label_middle), time); percent = (gfloat) (now_point - WAVE_HEADER_SIZE) / wave_info->data_size * 100; gtk_adjustment_set_value(GTK_ADJUSTMENT(gnowavcut->hadj), percent); g_free(time); } static void wave_play_loop(gpointer data, gint fd, GdkInputCondition condition) { GnoWavCut *gnowavcut; WaveInfo *wave_info; int len; static short int tmp[BUFFER]; gnowavcut = (GnoWavCut *)data; wave_info = gnowavcut->wave_info; if((len = read(gnowavcut->wave_fd, tmp, BUFFER * sizeof(short int))) > 0) { write(fd, tmp, len); wave_update_time_digit(gnowavcut); if(settings->wave_use_volume_bar) { /* Experimental! */ gtk_adjustment_set_value(GTK_ADJUSTMENT(gnowavcut->volume_adj), fabs((double) tmp[0])); } } else { utils_gnowavcut_if_playing(gnowavcut, FALSE); } } static void wave_play_loop_mini(gpointer data, gint fd, GdkInputCondition condition) { GnoWavCut *gnowavcut; WaveInfo *wave_info; int len; static short int tmp[BUFFER]; gnowavcut = (GnoWavCut *)data; wave_info = gnowavcut->wave_info; gnowavcut->now_mini_playing = TRUE; if(gnowavcut->mini_play_size <= 0) { gtk_input_remove(gnowavcut->input_tag); lseek(gnowavcut->wave_fd, gnowavcut->mini_old_point, SEEK_SET); wave_update_time_digit(gnowavcut); gtk_widget_set_sensitive(gnowavcut->hscale, TRUE); gtk_widget_set_sensitive(gnowavcut->buttons->button_stop, TRUE); gtk_widget_set_sensitive(gnowavcut->buttons->button_ff, TRUE); gtk_widget_set_sensitive(gnowavcut->buttons->button_rew, TRUE); gtk_widget_set_sensitive(gnowavcut->buttons->button_play, TRUE); gnowavcut->now_mini_playing = FALSE; return; } if((len = read(gnowavcut->wave_fd, tmp, BUFFER * sizeof(short int))) > 0) { write(fd, tmp, len); gnowavcut->mini_play_size -= len; wave_update_time_digit(gnowavcut); if(settings->wave_use_volume_bar) { /* Experimental! */ gtk_adjustment_set_value(GTK_ADJUSTMENT(gnowavcut->volume_adj), fabs((double) tmp[0])); } } else { utils_gnowavcut_if_playing(gnowavcut, FALSE); } } static void wave_play_mini(GnoWavCut *gnowavcut) { WaveInfo *wave_info; wave_info = gnowavcut->wave_info; g_return_if_fail(gnowavcut->now_playing == TRUE); g_return_if_fail(gnowavcut->now_pause == TRUE); wave_seek_if_mini_playing(gnowavcut); gnowavcut->mini_old_point = lseek(gnowavcut->wave_fd, 0, SEEK_CUR); gnowavcut->mini_play_size = settings->wave_mini_play_sec * wave_info->size_per_sec; gnowavcut->input_tag = gdk_input_add(gnowavcut->dsp_fd, GDK_INPUT_WRITE, wave_play_loop_mini, gnowavcut); gtk_widget_set_sensitive(gnowavcut->buttons->button_play, FALSE); gtk_widget_set_sensitive(gnowavcut->buttons->button_pause, FALSE); gtk_widget_set_sensitive(gnowavcut->buttons->button_stop, FALSE); gtk_widget_set_sensitive(gnowavcut->buttons->button_ff, FALSE); gtk_widget_set_sensitive(gnowavcut->buttons->button_rew, FALSE); gtk_widget_set_sensitive(gnowavcut->hscale, FALSE); } static void wave_ff_mini(GnoWavCut *gnowavcut, float move_sec) { WaveInfo *wave_info; int seek_size; wave_info = gnowavcut->wave_info; g_return_if_fail(gnowavcut->now_playing == TRUE); wave_seek_if_mini_playing(gnowavcut); seek_size = wave_info->size_per_sec * move_sec; seek_size -= seek_size % wave_info->size_per_sample; gnowavcut->mini_old_point = lseek(gnowavcut->wave_fd, seek_size, SEEK_CUR); wave_update_mini_time_digit(gnowavcut); if(settings->wave_mini_preview_play) wave_play_mini(gnowavcut); } static void wave_rew_mini(GnoWavCut *gnowavcut, float move_sec) { WaveInfo *wave_info; int seek_size; int now_point; wave_info = gnowavcut->wave_info; g_return_if_fail(gnowavcut->now_playing == TRUE); wave_seek_if_mini_playing(gnowavcut); now_point = lseek(gnowavcut->wave_fd, 0, SEEK_CUR); seek_size = wave_info->size_per_sec * move_sec; seek_size -= seek_size % wave_info->size_per_sample; if (now_point < WAVE_HEADER_SIZE + seek_size) gnowavcut->mini_old_point = lseek(gnowavcut->wave_fd, WAVE_HEADER_SIZE, SEEK_SET); else gnowavcut->mini_old_point = lseek(gnowavcut->wave_fd, -(seek_size), SEEK_CUR); wave_update_mini_time_digit(gnowavcut); if(settings->wave_mini_preview_play) wave_play_mini(gnowavcut); } void wave_play_cb(GtkWidget *widget, gpointer data) { GnoWavCut *gnowavcut; WaveInfo *wave_info; int format; gnowavcut = (GnoWavCut *)data; wave_info = gnowavcut->wave_info; if(gnowavcut->file_name == NULL) return; if(gnowavcut->now_playing == TRUE) { if(gnowavcut->now_pause == TRUE) { gnowavcut->input_tag = gdk_input_add(gnowavcut->dsp_fd, GDK_INPUT_WRITE, wave_play_loop, gnowavcut); gtk_widget_set_sensitive(gnowavcut->buttons->button_play, FALSE); gtk_widget_set_sensitive(gnowavcut->buttons->button_pause, TRUE); utils_mini_control_set_sensitive(gnowavcut, FALSE); gnowavcut->now_pause = FALSE; gtk_label_set_text(GTK_LABEL(gnowavcut->label_mini), ""); } return; } if((gnowavcut->wave_fd = open(gnowavcut->file_name, O_RDONLY)) == -1) { utils_msgbox_error(_("File open error")); return; } if((gnowavcut->dsp_fd = open(settings->wave_dsp_dev, O_WRONLY)) == -1) { utils_msgbox_error(_("DSP open error")); return; } format = AFMT_S16_LE; ioctl(gnowavcut->dsp_fd, SOUND_PCM_WRITE_BITS, &format); format = wave_info->channels; ioctl(gnowavcut->dsp_fd, SOUND_PCM_WRITE_CHANNELS, &format); format = wave_info->samples_per_sec; ioctl(gnowavcut->dsp_fd, SOUND_PCM_WRITE_RATE, &format); lseek(gnowavcut->wave_fd, WAVE_HEADER_SIZE, SEEK_SET); gnowavcut->input_tag = gdk_input_add(gnowavcut->dsp_fd, GDK_INPUT_WRITE, wave_play_loop, gnowavcut); utils_gnowavcut_if_playing(gnowavcut, TRUE); } void wave_pause_cb(GtkWidget *widget, gpointer data) { GnoWavCut *gnowavcut; gnowavcut = (GnoWavCut *)data; gdk_input_remove(gnowavcut->input_tag); gnowavcut->input_tag = -1; utils_mini_control_set_sensitive(gnowavcut, TRUE); gtk_widget_set_sensitive(gnowavcut->buttons->button_pause, FALSE); gtk_widget_set_sensitive(gnowavcut->buttons->button_play, TRUE); gnowavcut->now_pause = TRUE; gnowavcut->mini_old_point = lseek(gnowavcut->wave_fd, 0, SEEK_CUR); wave_update_mini_time_digit(gnowavcut); } void wave_stop_cb(GtkWidget *widget, gpointer data) { GnoWavCut *gnowavcut; gnowavcut = (GnoWavCut *)data; g_return_if_fail(gnowavcut->now_playing == TRUE); utils_gnowavcut_if_playing(gnowavcut, FALSE); } void wave_ff_cb(GtkWidget *widget, gpointer data) { GnoWavCut *gnowavcut; WaveInfo *wave_info; gnowavcut = (GnoWavCut *)data; wave_info = gnowavcut->wave_info; g_return_if_fail(gnowavcut->now_playing == TRUE); lseek(gnowavcut->wave_fd, wave_info->size_per_sec * settings->wave_move_sec, SEEK_CUR); wave_update_time_digit(gnowavcut); if(gnowavcut->now_pause == TRUE) wave_update_mini_time_digit(gnowavcut); } void wave_rew_cb(GtkWidget *widget, gpointer data) { GnoWavCut *gnowavcut; WaveInfo *wave_info; int now_point; gnowavcut = (GnoWavCut *)data; wave_info = gnowavcut->wave_info; g_return_if_fail(gnowavcut->now_playing == TRUE); now_point = lseek(gnowavcut->wave_fd, 0, SEEK_CUR); if (now_point < WAVE_HEADER_SIZE + settings->wave_move_sec * wave_info->size_per_sec) lseek(gnowavcut->wave_fd, WAVE_HEADER_SIZE, SEEK_SET); else lseek(gnowavcut->wave_fd, -(wave_info->size_per_sec * settings->wave_move_sec), SEEK_CUR); wave_update_time_digit(gnowavcut); if(gnowavcut->now_pause == TRUE) wave_update_mini_time_digit(gnowavcut); } void wave_jump_using_hscale(GnoWavCut *gnowavcut) { gfloat value; int jump_point; WaveInfo *wave_info; g_return_if_fail(gnowavcut->now_playing == TRUE); wave_info = gnowavcut->wave_info; value = GTK_ADJUSTMENT(gnowavcut->hadj)->value; jump_point = (gint) wave_info->data_size * (value / 100) /* + WAVE_HADER_SIZE */ ; jump_point -= jump_point % wave_info->size_per_sample; jump_point += WAVE_HEADER_SIZE; wave_jump(gnowavcut, jump_point); } void wave_jump(GnoWavCut *gnowavcut, int point) { g_return_if_fail(gnowavcut->wave_fd != -1); lseek(gnowavcut->wave_fd, point, SEEK_SET); wave_update_time_digit(gnowavcut); if(gnowavcut->now_pause == TRUE) wave_update_mini_time_digit(gnowavcut); } void wave_play_mini_cb(GtkWidget *widget, gpointer data) { GnoWavCut *gnowavcut; gnowavcut = (GnoWavCut *)data; wave_play_mini(gnowavcut); } void wave_rew_mini_long_cb(GtkWidget *widget, gpointer data) { wave_rew_mini((GnoWavCut *)data, MINI_LONG_MOVE_SEC); } void wave_rew_mini_cb(GtkWidget *widget, gpointer data) { wave_rew_mini((GnoWavCut *)data, MINI_MOVE_SEC); } void wave_ff_mini_long_cb(GtkWidget *widget, gpointer data) { wave_ff_mini((GnoWavCut *)data, MINI_LONG_MOVE_SEC); } void wave_ff_mini_cb(GtkWidget *widget, gpointer data) { wave_ff_mini((GnoWavCut *)data, MINI_MOVE_SEC); }