static FileInfo *file_info_new(const char *file){ int fd; FileInfo *fi; wave_header_t header; int hsize; struct stat stbuf; int size; int err; if ((fd=open(file,O_RDONLY|O_BINARY))==-1){ ms_error("Failed to open %s : %s",file,strerror(errno)); return NULL; } if (fstat(fd,&stbuf)==-1){ ms_error("could not fstat."); return NULL; } hsize=ms_read_wav_header_from_fd(&header,fd); if (hsize<=0){ ms_error("%s: not a wav file", file); return NULL; } fi=ms_new0(FileInfo,1); size=stbuf.st_size-hsize; fi->buffer=ms_new0(int16_t,size/sizeof(int16_t)); fi->rate=wave_header_get_rate(&header); fi->nchannels=wave_header_get_channel(&header); fi->nsamples=size/(sizeof(int16_t)*fi->nchannels); err=read(fd,fi->buffer,size); if (err==-1){ ms_error("Could not read file: %s",strerror(errno)); goto error; }else if (err<size){ ms_error("Partial read of %i bytes",err); goto error; } return fi; error: file_info_destroy(fi); return NULL; }
/** * Check hash sums in a hash file. * Lines beginning with ';' and '#' are ignored. * * @param hash_file_path - the path of the file with hash sums to verify. * @param chdir - true if function should emulate chdir to directory of filepath before checking it. * @return zero on success, -1 on fail */ int check_hash_file(file_t* file, int chdir) { FILE *fd; char buf[2048]; size_t pos; const char *ralign; timedelta_t timer; struct file_info info; const char* hash_file_path = file->path; int res = 0, line_num = 0; double time; /* process --check-embedded option */ if(opt.mode & MODE_CHECK_EMBEDDED) { unsigned crc32_be; if(find_embedded_crc32(hash_file_path, &crc32_be)) { /* initialize file_info structure */ memset(&info, 0, sizeof(info)); info.full_path = rsh_strdup(hash_file_path); info.file = file; file_info_set_print_path(&info, info.full_path); info.sums_flags = info.hc.hash_mask = RHASH_CRC32; info.hc.flags = HC_HAS_EMBCRC32; info.hc.embedded_crc32_be = crc32_be; res = verify_sums(&info); fflush(rhash_data.out); if(!rhash_data.interrupted) { if(res == 0) rhash_data.ok++; else if(res == -1 && errno == ENOENT) rhash_data.miss++; rhash_data.processed++; } free(info.full_path); file_info_destroy(&info); } else { log_warning(_("file name doesn't contain a CRC32: %s\n"), hash_file_path); return -1; } return 0; } /* initialize statistics */ rhash_data.processed = rhash_data.ok = rhash_data.miss = 0; rhash_data.total_size = 0; if(file->mode & FILE_IFSTDIN) { fd = stdin; hash_file_path = "<stdin>"; } else if( !(fd = rsh_fopen_bin(hash_file_path, "rb") )) { log_file_error(hash_file_path); return -1; } pos = strlen(hash_file_path)+16; ralign = str_set(buf, '-', (pos < 80 ? 80 - (int)pos : 2)); fprintf(rhash_data.out, _("\n--( Verifying %s )%s\n"), hash_file_path, ralign); fflush(rhash_data.out); rhash_timer_start(&timer); /* mark the directory part of the path, by setting the pos index */ if(chdir) { pos = strlen(hash_file_path); for(; pos > 0 && !IS_PATH_SEPARATOR(hash_file_path[pos]); pos--); if(IS_PATH_SEPARATOR(hash_file_path[pos])) pos++; } else pos = 0; /* read crc file line by line */ for(line_num = 0; fgets(buf, 2048, fd); line_num++) { char* line = buf; char* path_without_ext = NULL; /* skip unicode BOM */ if(line_num == 0 && buf[0] == (char)0xEF && buf[1] == (char)0xBB && buf[2] == (char)0xBF) line += 3; if(*line == 0) continue; /* skip empty lines */ if(is_binary_string(line)) { log_error(_("file is binary: %s\n"), hash_file_path); if(fd != stdin) fclose(fd); return -1; } /* skip comments and empty lines */ if(IS_COMMENT(*line) || *line == '\r' || *line == '\n') continue; memset(&info, 0, sizeof(info)); if(!hash_check_parse_line(line, &info.hc, !feof(fd))) continue; if(info.hc.hash_mask == 0) continue; info.print_path = info.hc.file_path; info.sums_flags = info.hc.hash_mask; /* see if crc file contains a hash sum without a filename */ if(info.print_path == NULL) { char* point; path_without_ext = rsh_strdup(hash_file_path); point = strrchr(path_without_ext, '.'); if(point) { *point = '\0'; file_info_set_print_path(&info, path_without_ext); } } if(info.print_path != NULL) { file_t file_to_check; int is_absolute = IS_PATH_SEPARATOR(info.print_path[0]); IF_WINDOWS(is_absolute = is_absolute || (info.print_path[0] && info.print_path[1] == ':')); /* if filename shall be prepended by a directory path */ if(pos && !is_absolute) { size_t len = strlen(info.print_path); info.full_path = (char*)rsh_malloc(pos + len + 1); memcpy(info.full_path, hash_file_path, pos); strcpy(info.full_path + pos, info.print_path); } else { info.full_path = rsh_strdup(info.print_path); } memset(&file_to_check, 0, sizeof(file_t)); file_to_check.path = info.full_path; rsh_file_stat(&file_to_check); info.file = &file_to_check; /* verify hash sums of the file */ res = verify_sums(&info); fflush(rhash_data.out); rsh_file_cleanup(&file_to_check); file_info_destroy(&info); if(rhash_data.interrupted) { free(path_without_ext); break; } /* update statistics */ if(res == 0) rhash_data.ok++; else if(res == -1 && errno == ENOENT) rhash_data.miss++; rhash_data.processed++; } free(path_without_ext); } time = rhash_timer_stop(&timer); fprintf(rhash_data.out, "%s\n", str_set(buf, '-', 80)); print_check_stats(); if(rhash_data.processed != rhash_data.ok) rhash_data.error_flag = 1; if(opt.flags & OPT_SPEED && rhash_data.processed > 1) { print_time_stats(time, rhash_data.total_size, 1); } rhash_data.processed = 0; res = ferror(fd); /* check that crc file has been read without errors */ if(fd != stdin) fclose(fd); return (res == 0 ? 0 : -1); }
/** * Calculate and print file hash sums using printf format. * * @param out a stream to print to * @param file the file to calculate sums for * @param print_path the path to print * @return 0 on success, -1 on fail */ int calculate_and_print_sums(FILE* out, file_t* file, const char *print_path) { struct file_info info; timedelta_t timer; int res = 0; memset(&info, 0, sizeof(info)); info.file = file; info.full_path = rsh_strdup(file->path); file_info_set_print_path(&info, print_path); info.size = 0; info.sums_flags = opt.sum_flags; if(file->mode & FILE_IFSTDIN) { print_path = "(stdin)"; } else { if(file->mode & FILE_IFDIR) return 0; /* don't handle directories */ info.size = file->size; /* total size, in bytes */ } /* initialize percents output */ init_percents(&info); rhash_timer_start(&timer); if(info.sums_flags) { /* calculate sums */ if(calc_sums(&info) < 0) { /* print error unless sharing access error occurred */ if(errno == EACCES) return 0; log_file_error(file->path); res = -1; } if(rhash_data.interrupted) { report_interrupted(); return 0; } } info.time = rhash_timer_stop(&timer); finish_percents(&info, res); if(opt.flags & OPT_EMBED_CRC) { /* rename the file */ rename_file_by_embeding_crc32(&info); } if((opt.mode & MODE_TORRENT) && !opt.bt_batch_file) { save_torrent(&info); } if((opt.mode & MODE_UPDATE) && opt.fmt == FMT_SFV) { /* updating SFV file: print SFV header line */ print_sfv_header_line(rhash_data.upd_fd, file, 0); if(opt.flags & OPT_VERBOSE) { print_sfv_header_line(rhash_data.log, file, 0); fflush(rhash_data.log); } rsh_file_cleanup(file); } if(rhash_data.print_list && res >= 0) { if (!opt.bt_batch_file) { print_line(out, rhash_data.print_list, &info); fflush(out); /* print calculated line to stderr or log-file if verbose */ if((opt.mode & MODE_UPDATE) && (opt.flags & OPT_VERBOSE)) { print_line(rhash_data.log, rhash_data.print_list, &info); fflush(rhash_data.log); } } if((opt.flags & OPT_SPEED) && info.sums_flags) { print_file_time_stats(&info); } } free(info.full_path); file_info_destroy(&info); return res; }
int ms_audio_diff(const char *file1, const char *file2, double *ret, int max_shift_percent, MSAudioDiffProgressNotify func, void *user_data){ FileInfo *fi1,*fi2; int64_t *xcorr; int xcorr_size; int max_shift_samples; int max_index_r; int max_index_l; double max_r, max_l; *ret=0; fi1=file_info_new(file1); if (fi1==NULL) return 0; fi2=file_info_new(file2); if (fi2==NULL){ file_info_destroy(fi1); return -1; } if (fi1->rate!=fi2->rate){ ms_error("Comparing files of different sampling rates is not supported (%d vs %d)", fi1->rate, fi2->rate); return -1; } if (fi1->nchannels!=fi2->nchannels){ ms_error("Comparing files with different number of channels is not supported (%d vs %d)", fi1->nchannels, fi2->nchannels); return -1; } file_info_compute_energy(fi1); file_info_compute_energy(fi2); if (fi1->energy_r==0 || fi2->energy_r==0){ /*avoid division by zero*/ ms_error("One of the two files is pure silence."); return -1; } max_shift_samples = MIN(fi1->nsamples, fi2->nsamples) * MIN(MAX(1, max_shift_percent), 100) / 100; xcorr_size=max_shift_samples*2; xcorr=ms_new0(int64_t,xcorr_size); if (fi1->nchannels == 2){ max_index_r=compute_cross_correlation_interleaved(fi1->buffer,fi1->nsamples,fi2->buffer,fi2->nsamples,xcorr,xcorr_size, func, user_data, 0, max_shift_samples); max_r=xcorr[max_index_r]; ms_message("max_r=%g", (double)max_r); max_r/=sqrt((double)fi1->energy_r*(double)fi2->energy_r); max_index_l=compute_cross_correlation_interleaved(fi1->buffer,fi1->nsamples,fi2->buffer,fi2->nsamples,xcorr,xcorr_size, func, user_data, 1, max_shift_samples); max_l=xcorr[max_index_l]; ms_message("max_l=%g", (double)max_l); max_l/=sqrt((double)fi1->energy_l*(double)fi2->energy_l); ms_message("Max stereo cross-correlation obtained at position [%i,%i], similarity factor=%g,%g", max_index_r-max_shift_samples,max_index_l-max_shift_samples,max_r, max_l); *ret = 0.5 * (fabs(max_r) + fabs(max_l)) * (1 - (double)abs(max_index_r-max_index_l)/(double)xcorr_size); }else{ max_index_r=compute_cross_correlation(fi1->buffer,fi1->nsamples,fi2->buffer,fi2->nsamples,xcorr,xcorr_size, func, user_data, max_shift_samples); max_r=xcorr[max_index_r]; max_r/=(sqrt(fi1->energy_r)*sqrt(fi2->energy_r)); *ret=max_r; ms_message("Max cross-correlation obtained at position [%i], similarity factor=%g",max_index_r-max_shift_samples,*ret); } ms_free(xcorr); file_info_destroy(fi1); file_info_destroy(fi2); return 0; }
static gboolean library_view_update_info(library_view_t* view) { if (view->run_timeout) { // update play buttons playlist_player_t* player = backtobasics_player(view->btb); if (view->btn_play == NULL) { view->btn_play = GTK_WIDGET(gtk_builder_get_object(view->builder, "tbtn_library_play")); } if (view->btn_pause == NULL) { view->btn_pause = GTK_WIDGET(gtk_builder_get_object(view->builder, "tbtn_library_pause")); } GtkWidget* btn_play = view->btn_play; GtkWidget* btn_pause = view->btn_pause; if (!playlist_player_is_playing(player)) { if (!gtk_widget_get_visible(btn_play)) gtk_widget_show_all(btn_play); if (gtk_widget_get_visible(btn_pause)) gtk_widget_hide(btn_pause); } else if (playlist_player_is_playing(player)) { if (gtk_widget_get_visible(btn_play)) gtk_widget_hide(btn_play); if (!gtk_widget_get_visible(btn_pause)) gtk_widget_show_all(btn_pause); } // update slider and time long tr_tm = playlist_player_get_track_position_in_ms(player); track_t* track = playlist_player_get_track(player); int index = playlist_player_get_track_index(player); int a = tr_tm / 1000; int b = view->time_in_ms / 1000; if (a != b) { view->time_in_ms = tr_tm; int min = tr_tm / 1000 / 60; int sec = (tr_tm / 1000) % 60; { char s[200]; sprintf(s,"<span size=\"x-small\"><b><i>%02d:%02d</i></b></span>", min, sec); GtkLabel* lbl = GTK_LABEL(gtk_builder_get_object(view->builder, "lbl_time")); gtk_label_set_markup(lbl, s); // update presets reflect_presets(view->btb); } GtkScale* sc_playback = GTK_SCALE(gtk_builder_get_object(view->builder, "sc_library_playback")); double perc = 0.0; if (track != NULL) { int len_in_ms = track_get_length_in_ms(track); if (len_in_ms != view->len_in_ms) { view->len_in_ms = len_in_ms; int min = len_in_ms / 1000 / 60; int sec = (len_in_ms / 1000) % 60; { char s[200]; sprintf(s,"<span size=\"x-small\"><b><i>%02d:%02d</i></b></span>", min, sec); GtkLabel* lbl = GTK_LABEL(gtk_builder_get_object(view->builder, "lbl_total")); gtk_label_set_markup(lbl, s); } } perc = (((double) tr_tm) / ((double) len_in_ms)) * 100.0; if (!view->sliding) { gtk_range_set_value(GTK_RANGE(sc_playback), perc); } } // update track info if (index != view->track_index || (track != NULL && track_get_id(track) != view->track_id)) { log_debug3("updating track info, index = %d, %p", index, track); view->track_index = index; if (track != NULL) { // fetch lyric if possible if (strcmp(track_get_lyric(track),"") == 0) { struct lyric_cb* cb = (struct lyric_cb*) mc_malloc(sizeof(struct lyric_cb)); cb->track_id = mc_strdup(track_get_id(track)); cb->view = view; fetch_lyric(track, library_view_process_lyric, cb); } else { struct lyric_cb* cb = (struct lyric_cb*) mc_malloc(sizeof(struct lyric_cb)); cb->track_id = mc_strdup(track_get_id(track)); cb->view = view; library_view_process_lyric(mc_strdup(track_get_lyric(track)), cb); } // Print artist info view->track_id = track_get_id(track); log_debug2("artid = %s", track_get_artid(track)); char s[200]; char c = ','; char c1 = ','; char *artist = text_to_html(track_get_artist(track)); char *title = text_to_html(track_get_title(track)); char *piece = text_to_html(track_get_piece(track)); if (strcmp(track_get_artist(track), "") == 0) { c = ' '; } if (strcmp(track_get_piece(track), "") == 0) { c1 = ' '; } snprintf(s, 125, "%s%c %s%c %s", artist, c, piece, c1, title ); mc_free(artist); mc_free(title); mc_free(piece); char ss[400]; log_debug2("s = %s", s); sprintf(ss,"<span size=\"x-small\"><i><b>%s</b></i></span>",s); GtkLabel* lbl = GTK_LABEL(gtk_builder_get_object(view->builder, "lbl_song_info")); gtk_label_set_markup(lbl, ss); log_debug2("artid = %s", track_get_artid(track)); file_info_t* info = file_info_new(track_get_artid(track)); if (!file_info_is_file(info)) { file_info_destroy(info); char *path = backtobasics_logo(view->btb); info = file_info_new(path); mc_free(path); //info = file_info_new(backtobasics_logo(view->btb)); } if (file_info_is_file(info)) { GError *err = NULL; GdkPixbuf* pb = gdk_pixbuf_new_from_file_at_scale(file_info_path(info), view->img_w, view->img_h, TRUE, &err ); if (pb != NULL) { GtkImage* img = GTK_IMAGE(gtk_builder_get_object(view->builder, "img_art")); gtk_image_set_from_pixbuf(img, pb); g_object_unref(pb); } else { log_error3("error loading image art: %d, %s", err->code, err->message); //g_free(err); } } file_info_destroy(info); } log_debug("track hash"); // Select the track in the librarylist if the librarylist is still // the same if (playlist_model_tracks_hash(view->playlist_model) == playlist_player_get_hash(player)) { GtkTreeView* tview = view->tview; GtkTreePath* path = gtk_tree_path_new(); gtk_tree_path_append_index(path, index); gtk_tree_view_set_cursor(tview, path, NULL, FALSE); gtk_tree_path_free(path); } log_debug("track hash 2"); } //log_debug3("lib hash = %lld, pl hash = %lld", view->library_list_hash, playlist_player_get_hash(player)); // TODO if (playlist_model_tracks_hash(view->playlist_model) == playlist_player_get_hash(player)) { //view->track_index = -1; } else { GtkTreeView* tview = view->tview; GtkTreeSelection* sel = gtk_tree_view_get_selection(tview); gtk_tree_selection_unselect_all(sel); } } // update repeat info playlist_player_repeat_t repeat = playlist_player_get_repeat(player); if (view->repeat != repeat) { log_debug3("repeat = %d, view repeat = %d", repeat, view->repeat); view->repeat = repeat; GtkWidget* r_btn = GTK_WIDGET(gtk_builder_get_object(view->builder, "tbtn_repeat")); GtkWidget* r1_btn = GTK_WIDGET(gtk_builder_get_object(view->builder, "tbtn_repeat_one")); GtkWidget* rlist_btn = GTK_WIDGET(gtk_builder_get_object(view->builder, "tbtn_repeat_all")); log_debug4("r = %p, r1 = %p, rall = %p", r_btn, r1_btn, rlist_btn); switch (repeat) { case PLP_NO_REPEAT: { gtk_widget_show_all(r_btn); gtk_widget_hide(rlist_btn); gtk_widget_hide(r1_btn); } break; case PLP_TRACK_REPEAT: { gtk_widget_hide(r_btn); gtk_widget_show_all(r1_btn); gtk_widget_hide(rlist_btn); } break; case PLP_LIST_REPEAT: { gtk_widget_hide(r1_btn); gtk_widget_show_all(rlist_btn); gtk_widget_hide(r_btn); } break; } } return TRUE; } else { return FALSE; } }
void library_view_init(library_view_t* view) { // library view. GObject* object = gtk_builder_get_object(view->builder,"view_library"); g_object_set_data(object, "library_view_t", (gpointer) view); // playlists (initially not viewed) //GtkWidget* scw_playlists = GTK_WIDGET(gtk_builder_get_object(view->builder,"scw_playlists")); //gtk_widget_hide(scw_playlists); // library list GtkTreeView* tview = GTK_TREE_VIEW(gtk_builder_get_object(view->builder, "tv_library")); view->tview = tview; GtkTreeViewColumn *col; GtkCellRenderer* renderer; renderer = gtk_cell_renderer_text_new(); view->cols = (GtkTreeViewColumn**) mc_malloc(sizeof(GtkTreeViewColumn*) * PLAYLIST_MODEL_N_COLUMNS); playlist_column_enum e; for(e = PLAYLIST_MODEL_COL_NR; e < PLAYLIST_MODEL_N_COLUMNS; ++e) { col = gtk_tree_view_column_new_with_attributes(i18n_column_name(e), renderer, "text", e, NULL); gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_FIXED); char path [500]; sprintf(path, "library.column.%s.width", column_id(e)); int width = el_config_get_int(btb_config(view->btb), path, 100); if (width < 10) { width = 100; } g_object_set_data(G_OBJECT(col), "column_id", (gpointer) column_id(e)); gtk_tree_view_column_set_fixed_width(col, width); gtk_tree_view_column_set_reorderable(col, TRUE); gtk_tree_view_column_set_resizable(col, TRUE); gtk_tree_view_column_set_clickable(col, TRUE); g_signal_connect(col, "clicked", (GCallback) library_view_library_col_sort, view); g_signal_connect (col, "notify::width", G_CALLBACK (library_view_col_width_set), view); view->cols[e] = col; g_object_ref(view->cols[e]); gtk_tree_view_append_column(tview, col); } gtk_tree_view_set_model(tview, GTK_TREE_MODEL(playlist_model_gtk_model(view->playlist_model))); // Aspect lists int width; // Genres tview = GTK_TREE_VIEW(gtk_builder_get_object(view->builder, "tv_genre_aspect")); col = gtk_tree_view_column_new_with_attributes(_("Genre"), renderer, "text", 0, NULL); gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_FIXED); //width = el_config_get_int(btb_config(view->btb), "library.aspects.column_width", 200); //gtk_tree_view_column_set_fixed_width(col, width); gtk_tree_view_append_column(tview, col); gtk_tree_view_set_model(tview, string_model_gtk_model(view->genre_model)); // Artists tview = GTK_TREE_VIEW(gtk_builder_get_object(view->builder, "tv_artist_aspect")); col = gtk_tree_view_column_new_with_attributes(_("Artists"), renderer, "text", 0, NULL); gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_FIXED); //width = el_config_get_int(btb_config(view->btb), "library.aspects.column_width", 200); //gtk_tree_view_column_set_fixed_width(col, width); gtk_tree_view_append_column(tview, col); gtk_tree_view_set_model(tview, string_model_gtk_model(view->artist_model)); // Albums tview = GTK_TREE_VIEW(gtk_builder_get_object(view->builder, "tv_album_aspect")); col = gtk_tree_view_column_new_with_attributes(_("Artists"), renderer, "text", 0, NULL); gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_FIXED); //width = el_config_get_int(btb_config(view->btb), "library.aspects.column_width", 200); //gtk_tree_view_column_set_fixed_width(col, width); gtk_tree_view_append_column(tview, col); gtk_tree_view_set_model(tview, string_model_gtk_model(view->album_model)); // Activate genres library_view_aspect_page(view, GENRE_ASPECT); GtkToggleToolButton* g_btn = GTK_TOGGLE_TOOL_BUTTON(gtk_builder_get_object(view->builder, "tbtn_genres")); gtk_toggle_tool_button_set_active(g_btn, TRUE); // playback scale, song info GtkScale* sc_playback = GTK_SCALE(gtk_builder_get_object(view->builder, "sc_library_playback")); gtk_range_set_range(GTK_RANGE(sc_playback), 0.0, 100.0); { char ss[300]; sprintf(ss,"<span size=\"x-small\"><i><b> </b></i></span>"); GtkLabel* lbl = GTK_LABEL(gtk_builder_get_object(view->builder, "lbl_song_info")); gtk_label_set_markup(lbl, ss); } // Set logo { char *path = backtobasics_logo(view->btb); file_info_t* info = file_info_new(path); mc_free(path); if (file_info_is_file(info)) { GError *err = NULL; GdkPixbuf* pb = gdk_pixbuf_new_from_file_at_scale(file_info_path(info), view->img_w, view->img_h, TRUE, &err ); GtkImage* img = GTK_IMAGE(gtk_builder_get_object(view->builder, "img_art")); gtk_widget_set_size_request(GTK_WIDGET(img), view->img_w, view->img_h); if (pb != NULL) { gtk_image_set_from_pixbuf(img, pb); g_object_unref(pb); } else { log_error3("error loading image art: %d, %s", err->code, err->message); //g_free(err); } } file_info_destroy(info); } // Playlists tview = GTK_TREE_VIEW(gtk_builder_get_object(view->builder, "tv_playlists")); col = gtk_tree_view_column_new_with_attributes(_("Playlist"), renderer, "text", 0, NULL); gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_FIXED); width = el_config_get_int(btb_config(view->btb), "library.playlists.column_width", 200); gtk_tree_view_column_set_fixed_width(col, width); gtk_tree_view_append_column(tview, col); gtk_tree_view_set_model(tview, playlists_model_gtk_model(view->playlists_model)); // Lyric view view->lyric_view = WEBKIT_WEB_VIEW(webkit_web_view_new()); view->lbl_lyric_track = GTK_LABEL(gtk_builder_get_object(view->builder, "lbl_lyric_track")); GtkScrolledWindow* scw_lyric = GTK_SCROLLED_WINDOW(gtk_builder_get_object(view->builder, "scw_lyric")); gtk_container_add(GTK_CONTAINER(scw_lyric), GTK_WIDGET(view->lyric_view)); // visibility of columns { const char* names[] = { "chk_col_nr", "chk_col_title", "chk_col_artist", "chk_col_composer", "chk_col_piece", "chk_col_album", "chk_col_albumartist", "chk_col_genre", "chk_col_year", "chk_col_length", NULL }; const playlist_column_enum es[] = { PLAYLIST_MODEL_COL_NR, PLAYLIST_MODEL_COL_TITLE, PLAYLIST_MODEL_COL_ARTIST, PLAYLIST_MODEL_COL_COMPOSER, PLAYLIST_MODEL_COL_PIECE, PLAYLIST_MODEL_COL_ALBUM_TITLE, PLAYLIST_MODEL_COL_ALBUM_ARTIST, PLAYLIST_MODEL_COL_GENRE, PLAYLIST_MODEL_COL_YEAR, PLAYLIST_MODEL_COL_LENGTH, PLAYLIST_MODEL_N_COLUMNS }; int i; for(i = 0;names[i] != NULL; ++i) { GtkCheckMenuItem* item = GTK_CHECK_MENU_ITEM(gtk_builder_get_object(view->builder, names[i])); gtk_widget_set_name(GTK_WIDGET(item), names[i]); char cfgitem[100]; sprintf(cfgitem, "library.cols.%s", names[i]); int yes = el_config_get_int(btb_config(view->btb), cfgitem, 1); gtk_check_menu_item_set_active(item, yes); gtk_tree_view_column_set_visible(view->cols[es[i]], yes); } } // Start timeout every 250 ms g_timeout_add(250, (GSourceFunc) library_view_update_info, view); }
int main(char *argv[],int argc) { mc_init(); el_bool stop = el_false; hre_t re_load = hre_compile("^load(&play)?\\s+(.*)$","i"); hre_t re_play = hre_compile("^play$","i"); hre_t re_pause = hre_compile("^pause$","i"); hre_t re_next = hre_compile("^next$","i"); hre_t re_previous = hre_compile("^prev(ious)?$","i"); hre_t re_track = hre_compile("^track\\s+([0-9]+)$","i"); hre_t re_quhit = hre_compile("^quit$","i"); hre_t re_seek = hre_compile("^seek\\s([0-9]+([.][0-9]+)?)$","i"); hre_t re_quit = hre_compile("^quit$","i"); hre_t re_repeat = hre_compile("^repeat\\s+(off|list|track)$","i"); hre_t re_again = hre_compile("^again$","i"); hre_t re_scan = hre_compile("^scan\\s+(.*)$","i"); file_info_t *history_file = mc_take_over(file_info_new_home(".btb_playlist")); printf("history file: %s\n", file_info_absolute_path(history_file)); printf("history file: %s\n", file_info_path(history_file)); if (file_info_exists(history_file)) { read_history(file_info_absolute_path(history_file)); } i18n_set_language("nl"); printf(_("Starting btb_playlist\n")); playlist_player_t *player = playlist_player_new(); while (!stop) { char* line = readln(">", player); hre_trim(line); if (hre_has_match(re_quit, line)) { stop = el_true; } else if (hre_has_match(re_load, line)) { hre_matches m = hre_match(re_load, line); hre_match_t *mplay = hre_matches_get(m, 1); hre_match_t *match = hre_matches_get(m, 2); char* file = mc_strdup(hre_match_str(match)); char* play = mc_strdup(hre_match_str(mplay)); hre_matches_destroy(m); printf("loading '%s', '%s'\n", file, play); file_info_t *info = file_info_new(file); if (file_info_exists(info)) { if (file_info_is_file(info)) { if (file_info_can_read(info)) { const char *mediafile = NULL; track_array array; if (strcasecmp(file_info_ext(info),"cue") == 0) { array = tracks_from_cue(file_info_absolute_path(info)); track_t* t = track_array_get(array, 0); } else { array = tracks_from_media(file_info_absolute_path(info)); } playlist_t* pl = playlist_new("playlist"); int i; for(i=0; i < track_array_count(array); ++i) { playlist_append(pl, track_array_get(array, i)); } playlist_player_set_playlist(player, pl); track_array_destroy(array); } } } file_info_destroy(info); if (strcasecmp(play,"&play")==0) { playlist_player_play(player); } mc_free(file); mc_free(play); } else if (hre_has_match(re_play, line)) { playlist_player_play(player); } else if (hre_has_match(re_pause, line)) { playlist_player_pause(player); } else if (hre_has_match(re_seek, line)) { hre_matches m = hre_match(re_seek, line); hre_match_t* match = hre_matches_get(m, 1); char* position = mc_strdup(hre_match_str(match)); hre_matches_destroy(m); double s = atof(position); int ms = s * 1000; mc_free(position); playlist_player_seek(player, ms); } else if (hre_has_match(re_next, line)) { playlist_player_next(player); } else if (hre_has_match(re_previous, line)) { playlist_player_previous(player); } else if (hre_has_match(re_track, line)) { hre_matches m = hre_match(re_track, line); hre_match_t* match = hre_matches_get(m, 1); char* nr = mc_strdup(hre_match_str(match)); hre_matches_destroy(m); int index = atoi(nr); mc_free(nr); printf("setting track %d\n",index); playlist_player_set_track(player, index); } else if (hre_has_match(re_repeat, line)) { hre_matches m = hre_match(re_repeat, line); hre_match_t* match = hre_matches_get(m, 1); if (strcasecmp(hre_match_str(match),"track") == 0) { playlist_player_set_repeat(player, PLP_TRACK_REPEAT); } else if (strcasecmp(hre_match_str(match),"list") == 0) { playlist_player_set_repeat(player, PLP_LIST_REPEAT); } else { playlist_player_set_repeat(player, PLP_NO_REPEAT); } hre_matches_destroy(m); } else if (hre_has_match(re_again, line)) { playlist_player_again(player); } else if (hre_has_match(re_scan, line)) { hre_matches m = hre_match(re_scan, line); hre_match_t* match = hre_matches_get(m, 1); printf("scanning %s\n", hre_match_str(match)); library_t* library = library_new(); printf("calling scan_library\n"); //scan_library(library, hre_match_str(match), library_cb); printf("\n"); printf("library: %d tracks\n", library_count(library)); printf("done scanning, destroying library\n"); library_destroy(library); printf("library destroyed\n"); hre_matches_destroy(m); printf("matches destroyed\n"); } mc_free(line); } playlist_player_destroy(player); printf("%d\n",write_history(file_info_absolute_path(history_file))); file_info_destroy(history_file); hre_destroy(re_load); hre_destroy(re_play); hre_destroy(re_pause); hre_destroy(re_quit); hre_destroy(re_seek); hre_destroy(re_track); hre_destroy(re_next); hre_destroy(re_previous); hre_destroy(re_again); hre_destroy(re_repeat); hre_destroy(re_scan); return 0; }