# HG changeset patch # User Sascha Hlusiak # Date 1200837227 -3600 # Node ID 5b37a9f2d0cc005563d7c5365b39171ac81d8fb6 # Parent 0be42d83221776663c66717d18104a1ba1063157# Parent 7b38e28464eefcbea28a305eb32c2e22ca814cb1 Branch merge diff -r 0be42d832217 -r 5b37a9f2d0cc src/cdaudio-ng/cdaudio-ng.c --- a/src/cdaudio-ng/cdaudio-ng.c Sun Jan 20 14:52:44 2008 +0100 +++ b/src/cdaudio-ng/cdaudio-ng.c Sun Jan 20 14:53:47 2008 +0100 @@ -2,7 +2,7 @@ * Audacious CD Digital Audio plugin * * Copyright (c) 2007 Calin Crisan - * + * * 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; under version 3 of the License. @@ -16,10 +16,6 @@ * along with this program. If not, see . */ -/* TODO (added by ccr) - * - maybe make CDDB lib optional? - * - use_cddb/use_cdtext don't seem to be checked in all necessary places. why? - */ #include "config.h" @@ -51,22 +47,23 @@ #include "cdaudio-ng.h" #include "configure.h" -struct cdng_cfg_t cdng_cfg; -static gint firsttrackno = -1; -static gint lasttrackno = -1; -static CdIo_t *pcdio = NULL; -static trackinfo_t *trackinfo = NULL; -static gboolean is_paused = FALSE; -static gint playing_track = -1; -static dae_params_t *pdae_params = NULL; -static InputPlayback *pglobalinputplayback = NULL; -static GtkWidget *main_menu_item, *playlist_menu_item; + +struct cdng_cfg_t cdng_cfg; +static gint firsttrackno = -1; +static gint lasttrackno = -1; +static CdIo_t *pcdio = NULL; +static trackinfo_t *trackinfo = NULL; +static gboolean is_paused = FALSE; +static gint playing_track = -1; +static dae_params_t *pdae_params = NULL; +static InputPlayback *pglobalinputplayback = NULL; +static GtkWidget *main_menu_item, *playlist_menu_item; +static GThread *scan_cd_thread = NULL; static void cdaudio_init(void); static void cdaudio_about(void); static void cdaudio_configure(void); static gint cdaudio_is_our_file(gchar *filename); -static GList *cdaudio_scan_dir(gchar *dirname); static void cdaudio_play_file(InputPlayback *pinputplayback); static void cdaudio_stop(InputPlayback *pinputplayback); static void cdaudio_pause(InputPlayback *pinputplayback, gshort paused); @@ -79,8 +76,11 @@ static Tuple *cdaudio_get_song_tuple(gchar *filename); static void menu_click(void); -static Tuple *create_tuple_from_trackinfo(gchar *filename); +static Tuple *create_tuple_from_trackinfo_and_filename(gchar *filename); +static Tuple *create_tuple_from_trackinfo(int trackno); static void dae_play_loop(dae_params_t *pdae_params); +static void *scan_cd(void *nothing); +static void scan_cd_threaded(); static gint calculate_track_length(gint startlsn, gint endlsn); static gint find_trackno_from_filename(gchar *filename); static void cleanup_on_error(void); @@ -92,7 +92,7 @@ .about = cdaudio_about, .configure = cdaudio_configure, .is_our_file = cdaudio_is_our_file, - .scan_dir = cdaudio_scan_dir, +// .scan_cd = cdaudio_scan_cd, .play_file = cdaudio_play_file, .stop = cdaudio_stop, .pause = cdaudio_pause, @@ -136,9 +136,9 @@ { ConfigDb *db; gchar *menu_item_text; - + debug("cdaudio_init()\n"); - + memset(&cdng_cfg, 0, sizeof(cdng_cfg)); if ((db = aud_cfg_db_open()) == NULL) { @@ -159,7 +159,7 @@ if (!aud_cfg_db_get_bool(db, "CDDA", "use_dae", &cdng_cfg.use_dae)) */ cdng_cfg.use_dae = TRUE; - + if (!aud_cfg_db_get_int(db, "CDDA", "limitspeed", &cdng_cfg.limitspeed)) cdng_cfg.limitspeed = 1; if (!aud_cfg_db_get_bool(db, "CDDA", "use_cdtext", &cdng_cfg.use_cdtext)) @@ -177,7 +177,7 @@ if (!aud_cfg_db_get_bool(db, "CDDA", "debug", &cdng_cfg.debug)) cdng_cfg.debug = FALSE; if (!aud_cfg_db_get_bool(db, "audacious", "use_proxy", &cdng_cfg.use_proxy)) - cdng_cfg.debug = FALSE; + cdng_cfg.use_proxy = FALSE; if (!aud_cfg_db_get_string(db, "audacious", "proxy_host", &cdng_cfg.proxy_host)) cdng_cfg.proxy_host = g_strdup(""); if (!aud_cfg_db_get_int(db, "audacious", "proxy_port", &cdng_cfg.proxy_port)) @@ -200,14 +200,14 @@ gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(main_menu_item), gtk_image_new_from_stock(GTK_STOCK_CDROM, GTK_ICON_SIZE_MENU)); gtk_widget_show(main_menu_item); audacious_menu_plugin_item_add(AUDACIOUS_MENU_MAIN, main_menu_item); - g_signal_connect(G_OBJECT(main_menu_item), "button_press_event", G_CALLBACK(menu_click), NULL); - + g_signal_connect(G_OBJECT(main_menu_item), "button_press_event", G_CALLBACK(menu_click), NULL); + playlist_menu_item = gtk_image_menu_item_new_with_label(menu_item_text); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(playlist_menu_item), gtk_image_new_from_stock(GTK_STOCK_CDROM, GTK_ICON_SIZE_MENU)); gtk_widget_show(playlist_menu_item); audacious_menu_plugin_item_add(AUDACIOUS_MENU_PLAYLIST, playlist_menu_item); - g_signal_connect(G_OBJECT(playlist_menu_item), "button_press_event", G_CALLBACK(menu_click), NULL); - + g_signal_connect(G_OBJECT(playlist_menu_item), "button_press_event", G_CALLBACK(menu_click), NULL); + aud_uri_set_plugin("cdda://", &inputplugin); } @@ -255,19 +255,13 @@ /* no CD information yet */ if (pcdio == NULL) { debug("no CD information, scanning\n"); - cdaudio_scan_dir(CDDA_DEFAULT); + scan_cd_threaded(NULL); } /* reload the cd information if the media has changed */ - if (cdio_get_media_changed(pcdio) && pcdio != NULL) { + if (pcdio != NULL && cdio_get_media_changed(pcdio)) { debug("CD changed, rescanning\n"); - if (cdaudio_scan_dir(CDDA_DEFAULT) == NULL) - pcdio = NULL; - } - - if (pcdio == NULL) { - debug("\"%s\" is not our file\n", filename); - return FALSE; + scan_cd_threaded(NULL); } /* check if the requested track actually exists on the current audio cd */ @@ -276,7 +270,7 @@ debug("\"%s\" is not our file\n", filename); return FALSE; } - + debug("\"%s\" is our file\n", filename); return TRUE; } @@ -306,258 +300,30 @@ } -static GList *cdaudio_scan_dir(gchar *dirname) -{ - gint trackno; - - debug("cdaudio_scan_dir(\"%s\")\n", dirname); - - /* if the given dirname does not belong to us, we return NULL */ - if (strstr(dirname, CDDA_DEFAULT) == NULL) { - debug("\"%s\" directory does not belong to us\n", dirname); - return NULL; - } - - /* find an available, audio capable, cd drive */ - if (cdng_cfg.device != NULL && strlen(cdng_cfg.device) > 0) { - pcdio = cdio_open(cdng_cfg.device, DRIVER_UNKNOWN); - if (pcdio == NULL) { - cdaudio_error("Failed to open CD device \"%s\".\n", cdng_cfg.device); - return NULL; - } - } - else { - gchar **ppcd_drives = cdio_get_devices_with_cap(NULL, CDIO_FS_AUDIO, false); - pcdio = NULL; - if (ppcd_drives != NULL && *ppcd_drives != NULL) { /* we have at least one audio capable cd drive */ - pcdio = cdio_open(*ppcd_drives, DRIVER_UNKNOWN); - if (pcdio == NULL) { - cdaudio_error("Failed to open CD.\n"); - cleanup_on_error(); - return NULL; - } - debug("found cd drive \"%s\" with audio capable media\n", *ppcd_drives); - } - else { - cdaudio_error("Unable to find or access a CDDA capable drive.\n"); - cleanup_on_error(); - return NULL; - } - if (ppcd_drives != NULL && *ppcd_drives != NULL) - cdio_free_device_list(ppcd_drives); - } - - /* limit read speed */ - if (cdng_cfg.limitspeed > 0 && cdng_cfg.use_dae) { - debug("setting drive speed limit to %dx\n", cdng_cfg.limitspeed); - if (cdio_set_speed(pcdio, cdng_cfg.limitspeed) != DRIVER_OP_SUCCESS) - cdaudio_error("Failed to set drive speed to %dx.\n", cdng_cfg.limitspeed); - } - - /* get general track initialization */ - cdrom_drive_t *pcdrom_drive = cdio_cddap_identify_cdio(pcdio, 1, NULL); // todo : check return / NULL - firsttrackno = cdio_get_first_track_num(pcdrom_drive->p_cdio); - lasttrackno = cdio_get_last_track_num(pcdrom_drive->p_cdio); - if (firsttrackno == CDIO_INVALID_TRACK || lasttrackno == CDIO_INVALID_TRACK) { - cdaudio_error("Failed to retrieve first/last track number.\n"); - cleanup_on_error(); - return NULL; - } - debug("first track is %d and last track is %d\n", firsttrackno, lasttrackno); - - g_free(trackinfo); - trackinfo = (trackinfo_t *) g_new(trackinfo_t, (lasttrackno + 1)); - - cdaudio_set_fullinfo(&trackinfo[0], - cdio_get_track_lsn(pcdrom_drive->p_cdio, 0), - cdio_get_track_last_lsn(pcdrom_drive->p_cdio, CDIO_CDROM_LEADOUT_TRACK), - "", "", ""); - - for (trackno = firsttrackno; trackno <= lasttrackno; trackno++) { - cdaudio_set_fullinfo(&trackinfo[trackno], - cdio_get_track_lsn(pcdrom_drive->p_cdio, trackno), - cdio_get_track_last_lsn(pcdrom_drive->p_cdio, trackno), - "", "", ""); - - if (trackinfo[trackno].startlsn == CDIO_INVALID_LSN || trackinfo[trackno].endlsn == CDIO_INVALID_LSN) { - cdaudio_error("Failed to retrieve stard/end lsn for track %d.\n", trackno); - cleanup_on_error(); - return NULL; - } - } - - /* initialize de cddb subsystem */ - cddb_conn_t *pcddb_conn = NULL; - cddb_disc_t *pcddb_disc = NULL; - cddb_track_t *pcddb_track = NULL; - - if (cdng_cfg.use_cddb) { - pcddb_conn = cddb_new(); - if (pcddb_conn == NULL) - cdaudio_error("Failed to create the cddb connection.\n"); - else { - debug("getting CDDB info\n"); - - if (cdng_cfg.use_proxy) { - cddb_http_proxy_enable(pcddb_conn); - cddb_set_http_proxy_server_name(pcddb_conn, cdng_cfg.proxy_host); - cddb_set_http_proxy_server_port(pcddb_conn, cdng_cfg.proxy_port); - cddb_set_http_proxy_username(pcddb_conn, cdng_cfg.proxy_username); - cddb_set_http_proxy_password(pcddb_conn, cdng_cfg.proxy_password); - cddb_set_server_name(pcddb_conn, cdng_cfg.cddb_server); - cddb_set_server_port(pcddb_conn, cdng_cfg.cddb_port); - } - else - if (cdng_cfg.cddb_http) { - cddb_http_enable(pcddb_conn); - cddb_set_server_name(pcddb_conn, cdng_cfg.cddb_server); - cddb_set_server_port(pcddb_conn, cdng_cfg.cddb_port); - } - else { - cddb_set_server_name(pcddb_conn, cdng_cfg.cddb_server); - cddb_set_server_port(pcddb_conn, cdng_cfg.cddb_port); - } - - pcddb_disc = cddb_disc_new(); - for (trackno = firsttrackno; trackno <= lasttrackno; trackno++) { - pcddb_track = cddb_track_new(); - cddb_track_set_frame_offset(pcddb_track, trackinfo[trackno].startlsn); - cddb_disc_add_track(pcddb_disc, pcddb_track); - } - - msf_t startmsf, endmsf; - cdio_get_track_msf(pcdio, 1, &startmsf); - cdio_get_track_msf(pcdio, CDIO_CDROM_LEADOUT_TRACK, &endmsf); - cddb_disc_set_length(pcddb_disc, cdio_audio_get_msf_seconds(&endmsf) - cdio_audio_get_msf_seconds(&startmsf)); - - cddb_disc_calc_discid(pcddb_disc); - int discid = cddb_disc_get_discid(pcddb_disc); - debug("CDDB disc id = %x\n", discid); - - gint matches; - if ((matches = cddb_query(pcddb_conn, pcddb_disc)) == -1) { - if (cddb_errno(pcddb_conn) == CDDB_ERR_OK) - cdaudio_error("Failed to query the CDDB server\n"); - else - cdaudio_error("Failed to query the CDDB server: %s\n", cddb_error_str(cddb_errno(pcddb_conn))); - - cddb_disc_destroy(pcddb_disc); - pcddb_disc = NULL; - } - else { - if (matches == 0) { - debug("no cddb info available for this disc\n"); - - cddb_disc_destroy(pcddb_disc); - pcddb_disc = NULL; - } - else { - debug("CDDB disc category = \"%s\"\n", cddb_disc_get_category_str(pcddb_disc)); - - cddb_read(pcddb_conn, pcddb_disc); - if (cddb_errno(pcddb_conn) != CDDB_ERR_OK) { - cdaudio_error("failed to read the cddb info: %s\n", cddb_error_str(cddb_errno(pcddb_conn))); - cddb_disc_destroy(pcddb_disc); - pcddb_disc = NULL; - } - else { - debug("we have got the cddb info\n"); - cdaudio_set_strinfo(&trackinfo[0], - cddb_disc_get_artist(pcddb_disc), - cddb_disc_get_title(pcddb_disc), - cddb_disc_get_genre(pcddb_disc)); - } - } - } - } - } - - /* adding trackinfo[0] information (the disc) */ - if (cdng_cfg.use_cdtext) { - debug("getting cd-text information for disc\n"); - cdtext_t *pcdtext = cdio_get_cdtext(pcdrom_drive->p_cdio, 0); - if (pcdtext == NULL || pcdtext->field[CDTEXT_TITLE] == NULL) { - debug("no cd-text available for disc\n"); - } - else { - cdaudio_set_strinfo(&trackinfo[0], - pcdtext->field[CDTEXT_PERFORMER] ? pcdtext->field[CDTEXT_PERFORMER] : "", - pcdtext->field[CDTEXT_TITLE] ? pcdtext->field[CDTEXT_TITLE] : "", - pcdtext->field[CDTEXT_GENRE] ? pcdtext->field[CDTEXT_GENRE] : ""); - } - } - - /* add track "file" names to the list */ - GList *list = NULL; - for (trackno = firsttrackno; trackno <= lasttrackno; trackno++) { - list = g_list_append(list, g_strdup_printf("track%02u.cda", trackno)); - cdtext_t *pcdtext = NULL; - if (cdng_cfg.use_cdtext) { - debug("getting cd-text information for track %d\n", trackno); - pcdtext = cdio_get_cdtext(pcdrom_drive->p_cdio, trackno); - if (pcdtext == NULL || pcdtext->field[CDTEXT_PERFORMER] == NULL) { - debug("no cd-text available for track %d\n", trackno); - pcdtext = NULL; - } - } - - if (pcdtext != NULL) { - cdaudio_set_strinfo(&trackinfo[trackno], - pcdtext->field[CDTEXT_PERFORMER] ? pcdtext->field[CDTEXT_PERFORMER] : "", - pcdtext->field[CDTEXT_TITLE] ? pcdtext->field[CDTEXT_TITLE] : "", - pcdtext->field[CDTEXT_GENRE] ? pcdtext->field[CDTEXT_GENRE] : ""); - } - else - if (pcddb_disc != NULL) { - cddb_track_t *pcddb_track = cddb_disc_get_track(pcddb_disc, trackno - 1); - cdaudio_set_strinfo(&trackinfo[trackno], - cddb_track_get_artist(pcddb_track), - cddb_track_get_title(pcddb_track), - cddb_disc_get_genre(pcddb_disc)); - } - else { - cdaudio_set_strinfo(&trackinfo[trackno], "", "", ""); - g_snprintf(trackinfo[trackno].name, DEF_STRING_LEN, "CD Audio Track %02u", trackno); - } - } - - if (cdng_cfg.debug) { - debug("disc has : performer = \"%s\", name = \"%s\", genre = \"%s\"\n", - trackinfo[0].performer, trackinfo[0].name, trackinfo[0].genre); - - for (trackno = firsttrackno; trackno <= lasttrackno; trackno++) { - debug("track %d has : performer = \"%s\", name = \"%s\", genre = \"%s\", startlsn = %d, endlsn = %d\n", - trackno, trackinfo[trackno].performer, trackinfo[trackno].name, trackinfo[trackno].genre, trackinfo[trackno].startlsn, trackinfo[trackno].endlsn); - } - } - - if (pcddb_disc != NULL) - cddb_disc_destroy(pcddb_disc); - - if (pcddb_conn != NULL) - cddb_destroy(pcddb_conn); - - return list; -} - static void cdaudio_play_file(InputPlayback *pinputplayback) { Tuple *tuple; gchar *title; - + debug("cdaudio_play_file(\"%s\")\n", pinputplayback->filename); pglobalinputplayback = pinputplayback; if (trackinfo == NULL) { debug("no CD information, scanning\n"); - cdaudio_scan_dir(CDDA_DEFAULT); + if (scan_cd_thread != NULL) + g_thread_join(scan_cd_thread); + else + scan_cd(pinputplayback); } - - if (cdio_get_media_changed(pcdio)) { - debug("CD changed, rescanning\n"); - cdaudio_scan_dir(CDDA_DEFAULT); - } + else + if (cdio_get_media_changed(pcdio)) { + debug("CD changed, rescanning\n"); + if (scan_cd_thread != NULL) + g_thread_join(scan_cd_thread); + else + scan_cd(pinputplayback); + } if (trackinfo == NULL) { debug("no CD information can be retrieved, aborting\n"); @@ -576,7 +342,7 @@ playing_track = trackno; is_paused = FALSE; - tuple = create_tuple_from_trackinfo(pinputplayback->filename); + tuple = create_tuple_from_trackinfo_and_filename(pinputplayback->filename); title = aud_tuple_formatter_make_title_string(tuple, aud_get_gentitle_format()); pinputplayback->set_params(pinputplayback, title, calculate_track_length(trackinfo[trackno].startlsn, trackinfo[trackno].endlsn), 1411200, 44100, 2); @@ -818,8 +584,8 @@ { debug("cdaudio_get_song_info(\"%s\")\n", filename); - gint trackno = find_trackno_from_filename(filename); - Tuple *tuple = create_tuple_from_trackinfo(filename); + Tuple *tuple = create_tuple_from_trackinfo_and_filename(filename); + int trackno = find_trackno_from_filename(filename); if (tuple) { *title = aud_tuple_formatter_process_string(tuple, aud_get_gentitle_format()); @@ -833,7 +599,7 @@ { debug("cdaudio_get_song_tuple(\"%s\")\n", filename); - return create_tuple_from_trackinfo(filename); + return create_tuple_from_trackinfo_and_filename(filename); } @@ -842,10 +608,21 @@ */ static void menu_click() { - GList *list, *node; - gchar *filename; - - if (!(list = cdaudio_scan_dir(CDDA_DEFAULT))) { + gchar filename[DEF_STRING_LEN]; + gboolean available = TRUE; + + /* reload the cd information if the media has changed, or no track information is available */ + if (pcdio == NULL || cdio_get_media_changed(pcdio)) { + debug("CD changed, rescanning\n"); + + available = FALSE; + if (scan_cd_thread != NULL) + return; + else + available = (scan_cd(NULL) != NULL); + } + + if (!available) { const gchar *markup = N_("No playable CD found.\n\n" "No CD inserted, or inserted CD is not an audio CD.\n"); @@ -861,17 +638,49 @@ return; } - for (node = list; node; node = g_list_next(node)) { - filename = g_build_filename(CDDA_DEFAULT, node->data, NULL); - aud_playlist_add(aud_playlist_get_active(), filename); - g_free(filename); - g_free(node->data); + int trackno; + for (trackno = firsttrackno; trackno <= lasttrackno; trackno++) { + g_snprintf(filename, DEF_STRING_LEN, "track%02u.cda", trackno); + gchar *pathname = g_build_filename(CDDA_DEFAULT, filename, NULL); + aud_playlist_add(aud_playlist_get_active(), pathname); + } +} + +static Tuple *create_tuple_from_trackinfo(int trackno) +{ + Tuple *tuple = aud_tuple_new(); + + if (trackinfo == NULL) + return tuple; + + if (trackno < firsttrackno || trackno > lasttrackno) + return tuple; + + if(strlen(trackinfo[trackno].performer)) { + aud_tuple_associate_string(tuple, FIELD_ARTIST, NULL, trackinfo[trackno].performer); + } + if(strlen(trackinfo[0].name)) { + aud_tuple_associate_string(tuple, FIELD_ALBUM, NULL, trackinfo[0].name); + } + if(strlen(trackinfo[trackno].name)) { + aud_tuple_associate_string(tuple, FIELD_TITLE, NULL, trackinfo[trackno].name); } - g_list_free(list); + aud_tuple_associate_int(tuple, FIELD_TRACK_NUMBER, NULL, trackno); + aud_tuple_associate_string(tuple, -1, "ext", "cda"); //XXX should do? --yaz + + aud_tuple_associate_int(tuple, FIELD_LENGTH, NULL, + calculate_track_length(trackinfo[trackno].startlsn, trackinfo[trackno].endlsn)); + + if(strlen(trackinfo[trackno].genre)) { + aud_tuple_associate_string(tuple, FIELD_GENRE, NULL, trackinfo[trackno].genre); + } + //tuple->year = 0; todo: set the year + + return tuple; } -static Tuple *create_tuple_from_trackinfo(gchar *filename) +static Tuple *create_tuple_from_trackinfo_and_filename(gchar *filename) { Tuple *tuple = aud_tuple_new_from_filename(filename); @@ -892,13 +701,13 @@ if(strlen(trackinfo[trackno].name)) { aud_tuple_associate_string(tuple, FIELD_TITLE, NULL, trackinfo[trackno].name); } - + aud_tuple_associate_int(tuple, FIELD_TRACK_NUMBER, NULL, trackno); aud_tuple_associate_string(tuple, -1, "ext", "cda"); //XXX should do? --yaz aud_tuple_associate_int(tuple, FIELD_LENGTH, NULL, calculate_track_length(trackinfo[trackno].startlsn, trackinfo[trackno].endlsn)); - + if(strlen(trackinfo[trackno].genre)) { aud_tuple_associate_string(tuple, FIELD_GENRE, NULL, trackinfo[trackno].genre); } @@ -950,7 +759,7 @@ /* compute the actual number of sectors to read */ gint lsncount = CDDA_DAE_FRAMES <= (pdae_params->endlsn - pdae_params->currlsn + 1) ? CDDA_DAE_FRAMES : (pdae_params->endlsn - pdae_params->currlsn + 1); - + /* check too see if we have reached the end of the song */ if (lsncount <= 0) { sleep(3); @@ -974,14 +783,14 @@ while (pdae_params->pplayback->playing && remainingbytes > 0 && pdae_params->seektime == -1) { /* compute the actual number of bytes to play */ gint bytecount = CDIO_CD_FRAMESIZE_RAW <= remainingbytes ? CDIO_CD_FRAMESIZE_RAW : remainingbytes; - + /* wait until the output buffer has enough room */ while (pdae_params->pplayback->playing && pdae_params->pplayback->output->buffer_free() < bytecount && pdae_params->seektime == -1) g_usleep(1000); - + /* play the sound :) */ if (pdae_params->pplayback->playing && pdae_params->seektime == -1) - pdae_params->pplayback->pass_audio(pdae_params->pplayback, FMT_S16_LE, 2, + pdae_params->pplayback->pass_audio(pdae_params->pplayback, FMT_S16_LE, 2, bytecount, bytebuff, &pdae_params->pplayback->playing); remainingbytes -= bytecount; bytebuff += bytecount; @@ -998,6 +807,273 @@ g_free(buffer); } +static void scan_cd_threaded() +{ + if (scan_cd_thread != NULL) { + debug("A scan_cd thread is already running.\n"); + return; + } + + scan_cd_thread = g_thread_create((GThreadFunc)scan_cd, NULL, TRUE, NULL); + if (scan_cd_thread == NULL) { + cdaudio_error("Failed to create the thread for retrieving song information.\n"); + return; + } +} + + +static void *scan_cd(void *nothing) +{ + debug("scan_cd started\n"); + + gint trackno; + + /* find an available, audio capable, cd drive */ + if (cdng_cfg.device != NULL && strlen(cdng_cfg.device) > 0) { + pcdio = cdio_open(cdng_cfg.device, DRIVER_UNKNOWN); + if (pcdio == NULL) { + cdaudio_error("Failed to open CD device \"%s\".\n", cdng_cfg.device); + scan_cd_thread = NULL; + return NULL; + } + } + else { + gchar **ppcd_drives = cdio_get_devices_with_cap(NULL, CDIO_FS_AUDIO, false); + pcdio = NULL; + if (ppcd_drives != NULL && *ppcd_drives != NULL) { /* we have at least one audio capable cd drive */ + pcdio = cdio_open(*ppcd_drives, DRIVER_UNKNOWN); + if (pcdio == NULL) { + cdaudio_error("Failed to open CD.\n"); + cleanup_on_error(); + scan_cd_thread = NULL; + return NULL; + } + debug("found cd drive \"%s\" with audio capable media\n", *ppcd_drives); + } + else { + cdaudio_error("Unable to find or access a CDDA capable drive.\n"); + cleanup_on_error(); + scan_cd_thread = NULL; + return NULL; + } + if (ppcd_drives != NULL && *ppcd_drives != NULL) + cdio_free_device_list(ppcd_drives); + } + + /* limit read speed */ + if (cdng_cfg.limitspeed > 0 && cdng_cfg.use_dae) { + debug("setting drive speed limit to %dx\n", cdng_cfg.limitspeed); + if (cdio_set_speed(pcdio, cdng_cfg.limitspeed) != DRIVER_OP_SUCCESS) + cdaudio_error("Failed to set drive speed to %dx.\n", cdng_cfg.limitspeed); + } + + /* general track initialization */ + cdrom_drive_t *pcdrom_drive = cdio_cddap_identify_cdio(pcdio, 1, NULL); // todo : check return / NULL + firsttrackno = cdio_get_first_track_num(pcdrom_drive->p_cdio); + lasttrackno = cdio_get_last_track_num(pcdrom_drive->p_cdio); + if (firsttrackno == CDIO_INVALID_TRACK || lasttrackno == CDIO_INVALID_TRACK) { + cdaudio_error("Failed to retrieve first/last track number.\n"); + cleanup_on_error(); + scan_cd_thread = NULL; + return NULL; + } + debug("first track is %d and last track is %d\n", firsttrackno, lasttrackno); + + g_free(trackinfo); + trackinfo = (trackinfo_t *) g_new(trackinfo_t, (lasttrackno + 1)); + + cdaudio_set_fullinfo(&trackinfo[0], + cdio_get_track_lsn(pcdrom_drive->p_cdio, 0), + cdio_get_track_last_lsn(pcdrom_drive->p_cdio, CDIO_CDROM_LEADOUT_TRACK), + "", "", ""); + + for (trackno = firsttrackno; trackno <= lasttrackno; trackno++) { + cdaudio_set_fullinfo(&trackinfo[trackno], + cdio_get_track_lsn(pcdrom_drive->p_cdio, trackno), + cdio_get_track_last_lsn(pcdrom_drive->p_cdio, trackno), + "", "", ""); + + if (trackinfo[trackno].startlsn == CDIO_INVALID_LSN || trackinfo[trackno].endlsn == CDIO_INVALID_LSN) { + cdaudio_error("Failed to retrieve stard/end lsn for track %d.\n", trackno); + cleanup_on_error(); + scan_cd_thread = NULL; + return NULL; + } + } + + /* get trackinfo[0] cdtext information (the disc) */ + if (cdng_cfg.use_cdtext) { + debug("getting cd-text information for disc\n"); + cdtext_t *pcdtext = cdio_get_cdtext(pcdrom_drive->p_cdio, 0); + if (pcdtext == NULL || pcdtext->field[CDTEXT_TITLE] == NULL) { + debug("no cd-text available for disc\n"); + } + else { + cdaudio_set_strinfo(&trackinfo[0], + pcdtext->field[CDTEXT_PERFORMER] ? pcdtext->field[CDTEXT_PERFORMER] : "", + pcdtext->field[CDTEXT_TITLE] ? pcdtext->field[CDTEXT_TITLE] : "", + pcdtext->field[CDTEXT_GENRE] ? pcdtext->field[CDTEXT_GENRE] : ""); + } + } + + /* get track information from cdtext */ + gboolean cdtext_was_available = FALSE; + for (trackno = firsttrackno; trackno <= lasttrackno; trackno++) { + cdtext_t *pcdtext = NULL; + if (cdng_cfg.use_cdtext) { + debug("getting cd-text information for track %d\n", trackno); + pcdtext = cdio_get_cdtext(pcdrom_drive->p_cdio, trackno); + if (pcdtext == NULL || pcdtext->field[CDTEXT_PERFORMER] == NULL) { + debug("no cd-text available for track %d\n", trackno); + pcdtext = NULL; + } + } + + if (pcdtext != NULL) { + cdaudio_set_strinfo(&trackinfo[trackno], + pcdtext->field[CDTEXT_PERFORMER] ? pcdtext->field[CDTEXT_PERFORMER] : "", + pcdtext->field[CDTEXT_TITLE] ? pcdtext->field[CDTEXT_TITLE] : "", + pcdtext->field[CDTEXT_GENRE] ? pcdtext->field[CDTEXT_GENRE] : ""); + cdtext_was_available = TRUE; + } + else { + cdaudio_set_strinfo(&trackinfo[trackno], "", "", ""); + g_snprintf(trackinfo[trackno].name, DEF_STRING_LEN, "CD Audio Track %02u", trackno); + } + } + + if (!cdtext_was_available) { + /* initialize de cddb subsystem */ + cddb_conn_t *pcddb_conn = NULL; + cddb_disc_t *pcddb_disc = NULL; + cddb_track_t *pcddb_track = NULL; + + if (cdng_cfg.use_cddb) { + pcddb_conn = cddb_new(); + if (pcddb_conn == NULL) + cdaudio_error("Failed to create the cddb connection.\n"); + else { + debug("getting CDDB info\n"); + + if (cdng_cfg.use_proxy) { + cddb_http_proxy_enable(pcddb_conn); + cddb_set_http_proxy_server_name(pcddb_conn, cdng_cfg.proxy_host); + cddb_set_http_proxy_server_port(pcddb_conn, cdng_cfg.proxy_port); + cddb_set_http_proxy_username(pcddb_conn, cdng_cfg.proxy_username); + cddb_set_http_proxy_password(pcddb_conn, cdng_cfg.proxy_password); + cddb_set_server_name(pcddb_conn, cdng_cfg.cddb_server); + cddb_set_server_port(pcddb_conn, cdng_cfg.cddb_port); + } + else + if (cdng_cfg.cddb_http) { + cddb_http_enable(pcddb_conn); + cddb_set_server_name(pcddb_conn, cdng_cfg.cddb_server); + cddb_set_server_port(pcddb_conn, cdng_cfg.cddb_port); + } + else { + cddb_set_server_name(pcddb_conn, cdng_cfg.cddb_server); + cddb_set_server_port(pcddb_conn, cdng_cfg.cddb_port); + } + + pcddb_disc = cddb_disc_new(); + for (trackno = firsttrackno; trackno <= lasttrackno; trackno++) { + pcddb_track = cddb_track_new(); + cddb_track_set_frame_offset(pcddb_track, trackinfo[trackno].startlsn); + cddb_disc_add_track(pcddb_disc, pcddb_track); + } + + msf_t startmsf, endmsf; + cdio_get_track_msf(pcdio, 1, &startmsf); + cdio_get_track_msf(pcdio, CDIO_CDROM_LEADOUT_TRACK, &endmsf); + cddb_disc_set_length(pcddb_disc, cdio_audio_get_msf_seconds(&endmsf) - cdio_audio_get_msf_seconds(&startmsf)); + + cddb_disc_calc_discid(pcddb_disc); + int discid = cddb_disc_get_discid(pcddb_disc); + debug("CDDB disc id = %x\n", discid); + + gint matches; + if ((matches = cddb_query(pcddb_conn, pcddb_disc)) == -1) { + if (cddb_errno(pcddb_conn) == CDDB_ERR_OK) + cdaudio_error("Failed to query the CDDB server\n"); + else + cdaudio_error("Failed to query the CDDB server: %s\n", cddb_error_str(cddb_errno(pcddb_conn))); + + cddb_disc_destroy(pcddb_disc); + pcddb_disc = NULL; + } + else { + if (matches == 0) { + debug("no cddb info available for this disc\n"); + + cddb_disc_destroy(pcddb_disc); + pcddb_disc = NULL; + } + else { + debug("CDDB disc category = \"%s\"\n", cddb_disc_get_category_str(pcddb_disc)); + + cddb_read(pcddb_conn, pcddb_disc); + if (cddb_errno(pcddb_conn) != CDDB_ERR_OK) { + cdaudio_error("failed to read the cddb info: %s\n", cddb_error_str(cddb_errno(pcddb_conn))); + cddb_disc_destroy(pcddb_disc); + pcddb_disc = NULL; + } + else { + debug("we have got the cddb info\n"); + cdaudio_set_strinfo(&trackinfo[0], + cddb_disc_get_artist(pcddb_disc), + cddb_disc_get_title(pcddb_disc), + cddb_disc_get_genre(pcddb_disc)); + + int trackno; + for (trackno = firsttrackno; trackno <= lasttrackno; trackno++) { + cddb_track_t *pcddb_track = cddb_disc_get_track(pcddb_disc, trackno - 1); + cdaudio_set_strinfo(&trackinfo[trackno], + cddb_track_get_artist(pcddb_track), + cddb_track_get_title(pcddb_track), + cddb_disc_get_genre(pcddb_disc)); + } + } + } + } + } + } + + if (pcddb_disc != NULL) + cddb_disc_destroy(pcddb_disc); + + if (pcddb_conn != NULL) + cddb_destroy(pcddb_conn); + } + + if (cdng_cfg.debug) { + debug("disc has : performer = \"%s\", name = \"%s\", genre = \"%s\"\n", + trackinfo[0].performer, trackinfo[0].name, trackinfo[0].genre); + + for (trackno = firsttrackno; trackno <= lasttrackno; trackno++) { + debug("track %d has : performer = \"%s\", name = \"%s\", genre = \"%s\", startlsn = %d, endlsn = %d\n", + trackno, trackinfo[trackno].performer, trackinfo[trackno].name, trackinfo[trackno].genre, trackinfo[trackno].startlsn, trackinfo[trackno].endlsn); + } + } + + /* + if (pinputplayback != NULL) { + for (trackno = firsttrackno; trackno <= lasttrackno; trackno++) { + Tuple *tuple = create_tuple_from_trackinfo(trackno); + gchar *title = aud_tuple_formatter_make_title_string(tuple, aud_get_gentitle_format()); + + pinputplayback->set_params(pinputplayback, title, calculate_track_length(trackinfo[trackno].startlsn, trackinfo[trackno].endlsn), 1411200, 44100, 2); + g_free(title); + aud_tuple_free(tuple); + } + } + */ + + debug("scan_cd ended\n"); + + scan_cd_thread = NULL; + return (void* ) -1; +} + static gint calculate_track_length(gint startlsn, gint endlsn) { return ((endlsn - startlsn + 1) * 1000) / 75; diff -r 0be42d832217 -r 5b37a9f2d0cc src/cdaudio-ng/configure.c --- a/src/cdaudio-ng/configure.c Sun Jan 20 14:52:44 2008 +0100 +++ b/src/cdaudio-ng/configure.c Sun Jan 20 14:53:47 2008 +0100 @@ -266,7 +266,7 @@ { configure_values_to_gui(); gtk_widget_show(configwindow); - gtk_window_present(GTK_WINDOW(configwindow)); + gtk_window_present(GTK_WINDOW(configwindow)); } diff -r 0be42d832217 -r 5b37a9f2d0cc src/evdev-plug/ed_common.h --- a/src/evdev-plug/ed_common.h Sun Jan 20 14:52:44 2008 +0100 +++ b/src/evdev-plug/ed_common.h Sun Jan 20 14:53:47 2008 +0100 @@ -30,7 +30,7 @@ #include "../../config.h" -#define ED_VERSION_PLUGIN "0.2" +#define ED_VERSION_PLUGIN "0.2p1" #define ED_VERSION_CONFIG "0" #define PLAYER_LOCALRC_FILE "evdev-plug.conf" diff -r 0be42d832217 -r 5b37a9f2d0cc src/evdev-plug/ed_internals.c --- a/src/evdev-plug/ed_internals.c Sun Jan 20 14:52:44 2008 +0100 +++ b/src/evdev-plug/ed_internals.c Sun Jan 20 14:53:47 2008 +0100 @@ -378,13 +378,13 @@ /* parse content of /proc/bus/input/devices */ regcomp( &preg, - "I:[^\n]*\nN: Name=\"([^\n]*)\"\nP: Phys=([^\n]*)\n[^\n]+\nH: Handlers=[^\n]*(event[0-9]+)[^\n]*\n" , + "I:[^\n]*\nN: Name=\"([^\n]*)\"\nP: Phys=([^\n]*)\n([^\n]+\n)*H: Handlers=[^\n]*(event[0-9]+)[^\n]*\n" , REG_ICASE | REG_EXTENDED ); while ( search_offset > -1 ) { - size_t nmatch = 4; - regmatch_t submatch[4]; + size_t nmatch = 5; + regmatch_t submatch[5]; if ( regexec( &preg , &buffer[search_offset] , nmatch , submatch , 0 ) == 0 ) { @@ -408,13 +408,13 @@ submatch[2].rm_eo - submatch[2].rm_so ); } - if ( submatch[3].rm_so != -1 ) /* check validity of filename sub-expression */ + if ( submatch[4].rm_so != -1 ) /* check validity of filename sub-expression */ { device_file = g_string_new( "" ); GString *device_test = g_string_new( "" ); g_string_append_len( device_file , - &buffer[(search_offset + submatch[3].rm_so)] , - submatch[3].rm_eo - submatch[3].rm_so ); + &buffer[(search_offset + submatch[4].rm_so)] , + submatch[4].rm_eo - submatch[4].rm_so ); /* let's check if the filename actually exists in /dev */ g_string_printf( device_test , "/dev/input/%s" , (char*)device_file->str ); diff -r 0be42d832217 -r 5b37a9f2d0cc src/neon/neon.c --- a/src/neon/neon.c Sun Jan 20 14:52:44 2008 +0100 +++ b/src/neon/neon.c Sun Jan 20 14:53:47 2008 +0100 @@ -484,6 +484,7 @@ int ret; const ne_status* status; + ne_uri* rediruri; _ENTER; @@ -501,9 +502,10 @@ /* * Try to connect to the server. */ - _DEBUG("Connecting..."); + _DEBUG("<%p> Connecting...", handle); ret = ne_begin_request(handle->request); status = ne_get_status(handle->request); + _DEBUG("<%p> Return: %d, Status: %d", handle, ret, status->code); if ((NE_OK == ret) && (401 == status->code)) { /* * Authorization required. Reconnect to @@ -514,10 +516,18 @@ ret = ne_begin_request(handle->request); } + if ((NE_OK == ret) && ((301 == status->code) || (302 == status->code) || (303 == status->code) || (307 == status->code))) { + /* + * Redirect encountered. Reconnect. + */ + ne_end_request(handle->request); + ret = NE_REDIRECT; + } + switch (ret) { case NE_OK: /* URL opened OK */ - _DEBUG("URL opened OK"); + _DEBUG("<%p> URL opened OK", handle); handle->content_start = startbyte; handle->pos = startbyte; handle_headers(handle); @@ -526,22 +536,25 @@ case NE_REDIRECT: /* We hit a redirect. Handle it. */ - _DEBUG("Redirect encountered"); + _DEBUG("<%p> Redirect encountered", handle); handle->redircount += 1; - handle->purl = (ne_uri*)ne_redirect_location(handle->session); + rediruri = (ne_uri*)ne_redirect_location(handle->session); ne_request_destroy(handle->request); - if (NULL == handle->purl) { - _ERROR("Could not parse redirect response"); + + if (NULL == rediruri) { + _ERROR("<%p> Could not parse redirect response", handle); _LEAVE -1; } + ne_uri_free(handle->purl); + ne_uri_copy(handle->purl, rediruri); _LEAVE 1; break; default: /* Something went wrong. */ - _ERROR("Could not open URL: %d", ret); + _ERROR("<%p> Could not open URL: %d", ret); if (1 == ret) { - _ERROR("neon error string: %s", ne_get_error(handle->session)); + _ERROR("<%p> neon error string: %s", ne_get_error(handle->session)); } ne_request_destroy(handle->request); _LEAVE -1; @@ -598,14 +611,15 @@ _LEAVE -1; } - if (0 == handle->purl->port) { - handle->purl->port = 80; - } - while (handle->redircount < 10) { - _DEBUG("<%p> Creating session", handle); + if (0 == handle->purl->port) { + handle->purl->port = ne_uri_defaultport(handle->purl->scheme); + } + + _DEBUG("<%p> Creating session to %s://%s:%d", handle, handle->purl->scheme, handle->purl->host, handle->purl->port); handle->session = ne_session_create(handle->purl->scheme, handle->purl->host, handle->purl->port); + ne_redirect_register(handle->session); ne_add_server_auth(handle->session, NE_AUTH_BASIC, server_auth_callback, (void *)handle); ne_set_session_flag(handle->session, NE_SESSFLAG_ICYPROTO, 1); ne_set_session_flag(handle->session, NE_SESSFLAG_PERSIST, 0); @@ -615,7 +629,6 @@ ne_set_read_timeout(handle->session, 10); ne_set_useragent(handle->session, "Audacious/1.4.0"); - ne_redirect_register(handle->session); if (use_proxy) { _DEBUG("<%p> Using proxy: %s:%d", handle, proxy_host, proxy_port); @@ -631,6 +644,9 @@ ne_session_destroy(handle->session); _LEAVE -1; } + + _DEBUG("<%p> Following redirect...", handle); + ne_session_destroy(handle->session); } /* diff -r 0be42d832217 -r 5b37a9f2d0cc src/paranormal/libcalc/parser.c --- a/src/paranormal/libcalc/parser.c Sun Jan 20 14:52:44 2008 +0100 +++ b/src/paranormal/libcalc/parser.c Sun Jan 20 14:53:47 2008 +0100 @@ -489,8 +489,10 @@ /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM +int yylex (YYSTYPE *yylval, void *yyparam); # define YYLEX yylex (&yylval, YYLEX_PARAM) #else +int yylex (YYSTYPE *yylval); # define YYLEX yylex (&yylval) #endif @@ -751,6 +753,7 @@ #endif #endif /* ! YYPARSE_PARAM */ +int yyerror (char *s); @@ -1392,7 +1395,7 @@ old_locale = setlocale (LC_ALL, NULL); saved_locale = g_strdup (old_locale); setlocale (LC_ALL, "C"); - sscanf (((VFSBuffer *)(pc->input->handle))->iter, "%lf", &yylval->d_value); + sscanf ((const char*)((VFSBuffer *)(pc->input->handle))->iter, "%lf", &yylval->d_value); while (isdigit(c) || c == '.') { diff -r 0be42d832217 -r 5b37a9f2d0cc src/scrobbler/configure.c --- a/src/scrobbler/configure.c Sun Jan 20 14:52:44 2008 +0100 +++ b/src/scrobbler/configure.c Sun Jan 20 14:53:47 2008 +0100 @@ -21,8 +21,11 @@ #include #include "configure.h" +#include "plugin.h" GtkWidget *entry1, *entry2, *ge_entry1, *ge_entry2, *cfgdlg; +guint apply_timeout = 0; /* ID of timeout to save new config */ +gboolean running = TRUE; /* if plugin threads are running */ static char *hexify(char *pass, int len) { @@ -41,43 +44,79 @@ return buf; } -static void saveconfig(GtkWidget *wid __attribute__((unused)), gpointer data) +static void saveconfig(void) { - ConfigDb *cfgfile; + ConfigDb *cfgfile; + + const char *uid = gtk_entry_get_text(GTK_ENTRY(entry1)); + const char *pwd = gtk_entry_get_text(GTK_ENTRY(entry2)); + const char *ge_uid = gtk_entry_get_text(GTK_ENTRY(ge_entry1)); + const char *ge_pwd = gtk_entry_get_text(GTK_ENTRY(ge_entry2)); + + if ((cfgfile = aud_cfg_db_open())) { + md5_state_t md5state; + unsigned char md5pword[16], ge_md5pword[16]; - const char *uid = gtk_entry_get_text(GTK_ENTRY(entry1)); - const char *pwd = gtk_entry_get_text(GTK_ENTRY(entry2)); - const char *ge_uid = gtk_entry_get_text(GTK_ENTRY(ge_entry1)); - const char *ge_pwd = gtk_entry_get_text(GTK_ENTRY(ge_entry2)); - - if ((cfgfile = aud_cfg_db_open())) - { - md5_state_t md5state; - unsigned char md5pword[16], ge_md5pword[16]; - - aud_cfg_db_set_string(cfgfile, "audioscrobbler", "username", (char *)uid); - aud_cfg_db_set_string(cfgfile, "audioscrobbler", "ge_username", (char *)ge_uid); + if (uid != NULL && uid[0] != '\0' && strlen(uid) && + pwd != NULL && pwd[0] != '\0' && strlen(pwd)) + { + aud_cfg_db_set_string(cfgfile, "audioscrobbler", "username", (char *)uid); + md5_init(&md5state); + md5_append(&md5state, (unsigned const char *)pwd, strlen(pwd)); + md5_finish(&md5state, md5pword); + aud_cfg_db_set_string(cfgfile, "audioscrobbler", "password", + hexify((char*)md5pword, sizeof(md5pword))); + } else if (!uid || uid[0] == '\0') { + aud_cfg_db_set_string(cfgfile, "audioscrobbler", "username", ""); + aud_cfg_db_set_string(cfgfile, "audioscrobbler", "password", ""); + } - if (pwd != NULL && pwd[0] != '\0' && strlen(pwd)) - { - md5_init(&md5state); - md5_append(&md5state, (unsigned const char *)pwd, strlen(pwd)); - md5_finish(&md5state, md5pword); - aud_cfg_db_set_string(cfgfile, "audioscrobbler", "password", - hexify((char*)md5pword, sizeof(md5pword))); - } + if (ge_uid != NULL && ge_uid[0] != '\0' && strlen(ge_uid) && + ge_pwd != NULL && ge_pwd[0] != '\0' && strlen(ge_pwd)) + { + aud_cfg_db_set_string(cfgfile, "audioscrobbler", "ge_username", (char *)ge_uid); + md5_init(&md5state); + md5_append(&md5state, (unsigned const char *)ge_pwd, strlen(ge_pwd)); + md5_finish(&md5state, ge_md5pword); + aud_cfg_db_set_string(cfgfile, "audioscrobbler", "ge_password", + hexify((char*)ge_md5pword, sizeof(ge_md5pword))); + } else if (!ge_uid || ge_uid[0] == '\0') { + aud_cfg_db_set_string(cfgfile, "audioscrobbler", "ge_username", ""); + aud_cfg_db_set_string(cfgfile, "audioscrobbler", "ge_password", ""); + } + + aud_cfg_db_close(cfgfile); + } +} - if (ge_pwd != NULL && ge_pwd[0] != '\0' && strlen(ge_pwd)) - { - md5_init(&md5state); - md5_append(&md5state, (unsigned const char *)ge_pwd, strlen(ge_pwd)); - md5_finish(&md5state, ge_md5pword); - aud_cfg_db_set_string(cfgfile, "audioscrobbler", "ge_password", - hexify((char*)ge_md5pword, sizeof(ge_md5pword))); - } +static gboolean apply_config_changes(gpointer data) { + apply_timeout = 0; + saveconfig(); + start(); + running = TRUE; + return FALSE; +} - aud_cfg_db_close(cfgfile); - } +void configure_cleanup(void) { + if (apply_timeout) { /* config has been changed, but wasn't saved yet */ + g_source_remove(apply_timeout); + apply_timeout = 0; + saveconfig(); + } +} + +static void +entry_changed(GtkWidget *widget, gpointer data) +{ + if (running) { + stop(); + running = FALSE; + } + + if (apply_timeout) + g_source_remove(apply_timeout); + + apply_timeout = g_timeout_add_seconds(10, (GSourceFunc) apply_config_changes, NULL); } /* Generated by glade, sorta. */ @@ -140,7 +179,6 @@ gtk_entry_set_visibility(GTK_ENTRY(entry2), FALSE); gtk_widget_show (entry2); gtk_table_attach_defaults (GTK_TABLE (table1), entry2, 1, 2, 3, 4); - g_signal_connect(entry2, "changed", (GCallback) saveconfig, NULL); label1 = gtk_label_new (_("Last.FM")); gtk_label_set_use_markup (GTK_LABEL (label1), TRUE); @@ -180,7 +218,6 @@ gtk_entry_set_visibility(GTK_ENTRY(ge_entry2), FALSE); gtk_widget_show (ge_entry2); gtk_table_attach_defaults (GTK_TABLE (table1), ge_entry2, 1, 2, 3, 4); - g_signal_connect(ge_entry2, "changed", (GCallback) saveconfig, NULL); label1 = gtk_label_new (_("Gerpok")); gtk_label_set_use_markup (GTK_LABEL (label1), TRUE); @@ -219,6 +256,11 @@ aud_cfg_db_close(db); } + g_signal_connect(entry1, "changed", G_CALLBACK(entry_changed), NULL); + g_signal_connect(entry2, "changed", G_CALLBACK(entry_changed), NULL); + g_signal_connect(ge_entry1, "changed", G_CALLBACK(entry_changed), NULL); + g_signal_connect(ge_entry2, "changed", G_CALLBACK(entry_changed), NULL); + return vbox2; } diff -r 0be42d832217 -r 5b37a9f2d0cc src/scrobbler/configure.h --- a/src/scrobbler/configure.h Sun Jan 20 14:52:44 2008 +0100 +++ b/src/scrobbler/configure.h Sun Jan 20 14:53:47 2008 +0100 @@ -2,5 +2,6 @@ #define _CONFIGURE_H_ GtkWidget* create_cfgdlg (void); +void configure_cleanup(void); #endif diff -r 0be42d832217 -r 5b37a9f2d0cc src/scrobbler/plugin.c --- a/src/scrobbler/plugin.c Sun Jan 20 14:52:44 2008 +0100 +++ b/src/scrobbler/plugin.c Sun Jan 20 14:53:47 2008 +0100 @@ -23,6 +23,7 @@ #include #include +#include "plugin.h" #include "scrobbler.h" #include "gerpok.h" #include "gtkstuff.h" @@ -30,7 +31,6 @@ #include "fmt.h" #include "configure.h" -#define XS_CS xmms_scrobbler.xmms_session #define XS_SLEEP 1 #define HS_SLEEP 10 @@ -100,17 +100,13 @@ } } -static void init(void) -{ +void start(void) { char *username = NULL, *password = NULL; char *ge_username = NULL, *ge_password = NULL; ConfigDb *cfgfile; sc_going = 1; ge_going = 1; GError **moo = NULL; - cfgdlg = create_cfgdlg(); - - aud_prefswin_page_new(cfgdlg, "Scrobbler", DATA_DIR "/images/audioscrobbler.png"); if ((cfgfile = aud_cfg_db_open()) != NULL) { aud_cfg_db_get_string(cfgfile, "audioscrobbler", "username", @@ -180,10 +176,7 @@ pdebug("plugin started", DEBUG); } -static void cleanup(void) -{ - aud_prefswin_page_destroy(cfgdlg); - +void stop(void) { if (!sc_going && !ge_going) return; pdebug("about to lock mutex", DEBUG); @@ -219,6 +212,20 @@ aud_hook_dissociate("playback end", aud_hook_playback_end); } +static void init(void) +{ + start(); + cfgdlg = create_cfgdlg(); + aud_prefswin_page_new(cfgdlg, "Scrobbler", DATA_DIR "/images/audioscrobbler.png"); +} + +static void cleanup(void) +{ + stop(); + configure_cleanup(); + aud_prefswin_page_destroy(cfgdlg); +} + static void *xs_thread(void *data __attribute__((unused))) { int run = 1; diff -r 0be42d832217 -r 5b37a9f2d0cc src/scrobbler/plugin.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/scrobbler/plugin.h Sun Jan 20 14:53:47 2008 +0100 @@ -0,0 +1,7 @@ +#ifndef PLUGIN_H +#define PLUGIN_H + +void start(void); +void stop(void); + +#endif diff -r 0be42d832217 -r 5b37a9f2d0cc src/scrobbler/scrobbler.c --- a/src/scrobbler/scrobbler.c Sun Jan 20 14:52:44 2008 +0100 +++ b/src/scrobbler/scrobbler.c Sun Jan 20 14:53:47 2008 +0100 @@ -20,7 +20,7 @@ #define SCROBBLER_HS_WAIT 1800 #define SCROBBLER_SB_WAIT 10 #define SCROBBLER_VERSION "1.2" -#define SCROBBLER_IMPLEMENTATION "0.1" /* This is the implementation, not the player version. */ +#define SCROBBLER_IMPLEMENTATION "0.2" /* This is the implementation, not the player version. */ #define SCROBBLER_SB_MAXLEN 1024 #define CACHE_SIZE 1024 diff -r 0be42d832217 -r 5b37a9f2d0cc src/timidity/libtimidity/playmidi.c --- a/src/timidity/libtimidity/playmidi.c Sun Jan 20 14:52:44 2008 +0100 +++ b/src/timidity/libtimidity/playmidi.c Sun Jan 20 14:53:47 2008 +0100 @@ -774,9 +774,9 @@ song->current_event++; } if (song->current_event->time > end_sample) - compute_data(song, (sint8 **)&ptr, end_sample-song->current_sample); + compute_data(song, (sint8 **)(void*)&ptr, end_sample-song->current_sample); else - compute_data(song, (sint8 **)&ptr, song->current_event->time-song->current_sample); + compute_data(song, (sint8 **)(void*)&ptr, song->current_event->time-song->current_sample); } return samples * song->bytes_per_sample; } diff -r 0be42d832217 -r 5b37a9f2d0cc src/tta/ttadec.c --- a/src/tta/ttadec.c Sun Jan 20 14:52:44 2008 +0100 +++ b/src/tta/ttadec.c Sun Jan 20 14:53:47 2008 +0100 @@ -472,7 +472,7 @@ } int get_samples (byte *buffer) { - unsigned int k, depth, unary, binary; + unsigned int k, depth, unary, binary=0; byte *p = buffer; decoder *dec = tta; int *prev = cache; diff -r 0be42d832217 -r 5b37a9f2d0cc src/vorbis/vorbis.c --- a/src/vorbis/vorbis.c Sun Jan 20 14:52:44 2008 +0100 +++ b/src/vorbis/vorbis.c Sun Jan 20 14:53:47 2008 +0100 @@ -2,6 +2,7 @@ * Copyright (C) Tony Arcieri * Copyright (C) 2001-2002 Haavard Kvaalen * Copyright (C) 2007 William Pitcock + * Copyright (C) 2008 Cristi Măgherușan * * ReplayGain processing Copyright (C) 2002 Gian-Carlo Pascutto * @@ -230,95 +231,6 @@ } } -static int -vorbis_process_data(InputPlayback *playback, int last_section, - gboolean use_rg, float rg_scale) -{ - char pcmout[4096]; - int bytes; - float **pcm; - - /* - * A vorbis physical bitstream may consist of many logical - * sections (information for each of which may be fetched from - * the vf structure). This value is filled in by ov_read to - * alert us what section we're currently decoding in case we - * need to change playback settings at a section boundary - */ - int current_section = last_section; - - g_mutex_lock(vf_mutex); - if (use_rg) { - bytes = - ov_read_float(&vf, &pcm, sizeof(pcmout) / 2 / channels, - ¤t_section); - if (bytes > 0) - bytes = vorbis_process_replaygain(pcm, bytes, channels, - pcmout, rg_scale); - } - else { - bytes = ov_read(&vf, pcmout, sizeof(pcmout), - (int) (G_BYTE_ORDER == G_BIG_ENDIAN), - 2, 1, ¤t_section); - } - - /* - * We got some sort of error. Bail. - */ - if (bytes <= 0 && bytes != OV_HOLE) { - g_mutex_unlock(vf_mutex); - playback->playing = 0; - playback->output->buffer_free(); - playback->output->buffer_free(); - playback->eof = TRUE; - return last_section; - } - - if (current_section != last_section) { - /* - * The info struct is different in each section. vf - * holds them all for the given bitstream. This - * requests the current one - */ - vorbis_info *vi = ov_info(&vf, -1); - - if (vi->channels > 2) { - playback->eof = TRUE; - g_mutex_unlock(vf_mutex); - return current_section; - } - - - if (vi->rate != samplerate || vi->channels != channels) { - samplerate = vi->rate; - channels = vi->channels; - playback->output->buffer_free(); - playback->output->buffer_free(); - playback->output->close_audio(); - if (!playback->output-> - open_audio(FMT_S16_NE, vi->rate, vi->channels)) { - playback->error = TRUE; - playback->eof = TRUE; - g_mutex_unlock(vf_mutex); - return current_section; - } - playback->output->flush(ov_time_tell(&vf) * 1000); - } - } - - g_mutex_unlock(vf_mutex); - - playback->pass_audio(playback, FMT_S16_NE, channels, bytes, pcmout, &playback->playing); - - if (!playback->playing) - return current_section; - - if (seekneeded != -1) - do_seek(playback); - - return current_section; -} - static gpointer vorbis_play_loop(gpointer arg) { @@ -350,12 +262,23 @@ fd->fd = stream; datasource = (void *) fd; + char pcmout[4096]; + int bytes; + float **pcm; + /* * The open function performs full stream detection and * machine initialization. None of the rest of ov_xx() works * without it + * + * A vorbis physical bitstream may consist of many logical + * sections (information for each of which may be fetched from + * the vf structure). This value is filled in by ov_read to + * alert us what section we're currently decoding in case we + * need to change playback settings at a section boundary */ - + + g_mutex_lock(vf_mutex); if (ov_open_callbacks(datasource, &vf, NULL, 0, aud_vfs_is_streaming(fd->fd) ? vorbis_callbacks_stream : vorbis_callbacks) < 0) { vorbis_callbacks.close_func(datasource); @@ -403,57 +326,146 @@ */ while (playback->playing) { - int current_section; - - if (seekneeded != -1) - do_seek(playback); - + if (playback->eof) { g_usleep(20000); continue; } - current_section = vorbis_process_data(playback, last_section, - use_rg, rg_scale); + if (seekneeded != -1) + do_seek(playback); + + + int current_section = last_section; - if (current_section != last_section) { + g_mutex_lock(vf_mutex); + if (use_rg) { + bytes = + ov_read_float(&vf, &pcm, sizeof(pcmout) / 2 / channels, + ¤t_section); + if (bytes > 0) + bytes = vorbis_process_replaygain(pcm, bytes, channels, + pcmout, rg_scale); + } + else { + bytes = ov_read(&vf, pcmout, sizeof(pcmout), + (int) (G_BYTE_ORDER == G_BIG_ENDIAN), + 2, 1, ¤t_section); + } + + /* + * We got some sort of error. Bail. + */ + if (bytes <= 0 && bytes != OV_HOLE) { + /* + * EOF + */ + playback->playing = 0; + playback->output->buffer_free(); + playback->output->buffer_free(); + playback->eof = TRUE; + current_section = last_section; + } + + + + if (current_section <= last_section) { /* - * set total play time, bitrate, rate, and channels of - * current section + * The info struct is different in each section. vf + * holds them all for the given bitstream. This + * requests the current one */ - if (title) - g_free(title); + vorbis_info *vi = ov_info(&vf, -1); + + if (vi->channels > 2) { + playback->eof = TRUE; + g_mutex_unlock(vf_mutex); + goto stop_processing; + } + - g_mutex_lock(vf_mutex); - title = vorbis_generate_title(&vf, filename); - use_rg = vorbis_update_replaygain(&rg_scale); + if (vi->rate != samplerate || vi->channels != channels) { + samplerate = vi->rate; + channels = vi->channels; + playback->output->buffer_free(); + playback->output->buffer_free(); + playback->output->close_audio(); + if (!playback->output-> + open_audio(FMT_S16_NE, vi->rate, vi->channels)) { + playback->error = TRUE; + playback->eof = TRUE; + g_mutex_unlock(vf_mutex); + goto stop_processing; + } + playback->output->flush(ov_time_tell(&vf) * 1000); + } + } - if (time != -1) - time = ov_time_total(&vf, -1) * 1000; + g_mutex_unlock(vf_mutex); + + playback->pass_audio(playback, FMT_S16_NE, channels, bytes, pcmout, &playback->playing); - g_mutex_unlock(vf_mutex); + if (!playback->playing) + goto stop_processing; + + if (seekneeded != -1) + do_seek(playback); - playback->set_params(playback, title, time, br, samplerate, channels); - timercount = playback->output->output_time(); + stop_processing: + + if (current_section <= last_section) { + /* + * set total play time, bitrate, rate, and channels of + * current section + */ + if (title) + g_free(title); + + g_mutex_lock(vf_mutex); + title = vorbis_generate_title(&vf, filename); + use_rg = vorbis_update_replaygain(&rg_scale); - last_section = current_section; + if (time != -1) + time = ov_time_total(&vf, -1) * 1000; + + g_mutex_unlock(vf_mutex); + + playback->set_params(playback, title, time, br, samplerate, channels); + + timercount = playback->output->output_time(); + + last_section = current_section; + } - } - if (!playback->error) - playback->output->close_audio(); +} + + + +if (!playback->error) + playback->output->close_audio(); /* fall through intentional */ - play_cleanup: - g_free(title); + /*this loop makes it not skip the last ~4 seconds, but the playback + * timer isn't updated in this period, so it still needs a bit of work + * + * majeru + */ +while(playback->output->buffer_playing()&& playback->output->buffer_free()) + g_usleep(50000); - /* - * ov_clear closes the stream if its open. Safe to call on an - * uninitialized structure as long as we've zeroed it - */ + +play_cleanup: +g_free(title); + +/* + * ov_clear closes the stream if its open. Safe to call on an + * uninitialized structure as long as we've zeroed it + */ g_mutex_lock(vf_mutex); ov_clear(&vf); g_mutex_unlock(vf_mutex); playback->playing = 0; + playback->output->buffer_free(); return NULL; } @@ -886,7 +898,7 @@ if (handle->probe == FALSE) { ret = aud_vfs_fclose(handle->fd); -// g_free(handle); // it causes double free. i'm not really sure that commenting out at here is correct. --yaz +/* g_free(handle); it causes double free. i'm not really sure that commenting out at here is correct. --yaz*/ } return ret; diff -r 0be42d832217 -r 5b37a9f2d0cc src/wma/libffwma/fft.c --- a/src/wma/libffwma/fft.c Sun Jan 20 14:52:44 2008 +0100 +++ b/src/wma/libffwma/fft.c Sun Jan 20 14:53:47 2008 +0100 @@ -301,9 +301,9 @@ } return 0; fail: - av_freep(&s->revtab); - av_freep(&s->exptab); - av_freep(&s->exptab1); + av_freep((void*)&s->revtab); + av_freep((void*)&s->exptab); + av_freep((void*)&s->exptab1); return -1; } @@ -431,8 +431,8 @@ void fft_end(FFTContext *s) { - av_freep(&s->revtab); - av_freep(&s->exptab); - av_freep(&s->exptab1); + av_freep((void*)&s->revtab); + av_freep((void*)&s->exptab); + av_freep((void*)&s->exptab1); } diff -r 0be42d832217 -r 5b37a9f2d0cc src/wma/libffwma/mdct.c --- a/src/wma/libffwma/mdct.c Sun Jan 20 14:52:44 2008 +0100 +++ b/src/wma/libffwma/mdct.c Sun Jan 20 14:53:47 2008 +0100 @@ -52,8 +52,8 @@ goto fail; return 0; fail: - av_freep(&s->tcos); - av_freep(&s->tsin); + av_freep((void*)&s->tcos); + av_freep((void*)&s->tsin); return -1; } @@ -169,7 +169,7 @@ void ff_mdct_end(MDCTContext *s) { - av_freep(&s->tcos); - av_freep(&s->tsin); + av_freep((void*)&s->tcos); + av_freep((void*)&s->tsin); fft_end(&s->fft); }