Ejemplo n.º 1
0
gboolean m4a_can_convert() {
    gchar *cmd = m4a_get_conversion_cmd();
    /*
     * Return TRUE if
     * Command exists and fully formed
     * Target format is NOT set to AAC
     * convert_m4a preference is set to TRUE
     */
    return cmd && cmd[0] && (prefs_get_int("conversion_target_format") != TARGET_FORMAT_AAC)
            && prefs_get_int("convert_m4a");
}
Ejemplo n.º 2
0
/* Logs tracks (@track) that could not be updated with info from mserv
 database for some reason. Pop up a window with the log by calling
 with @track = NULL, or remove the log by calling with @track = -1.
 @txt (if available) is added as an explanation as to why it was
 impossible to retrieve mserv information */
void display_mserv_problems(Track *track, gchar *txt) {
    gchar *buf;
    static gint track_nr = 0;
    static GString *str = NULL;

    if ((track == NULL) && str) {
        if (prefs_get_int("mserv_use") && prefs_get_int("mserv_report_probs") && str->len) { /* Some tracks have had problems. Print a notice */
            buf
                    = g_strdup_printf(ngettext("No mserv information could be retrieved for the following track", "No mserv information could be retrieved for the following %d tracks", track_nr), track_nr);
            gtkpod_confirmation(-1, /* gint id, */
            FALSE, /* gboolean modal, */
            _("mserv data retrieval problem"), /* title */
            buf, /* label */
            str->str, /* scrolled text */
            NULL, 0, NULL, /* option 1 */
            NULL, 0, NULL, /* option 2 */
            TRUE, /* gboolean confirm_again, */
            "mserv_report_probs",/* confirm_again_key,*/
            CONF_NULL_HANDLER, /* ConfHandler ok_handler,*/
            NULL, /* don't show "Apply" button */
            NULL, /* cancel_handler,*/
            NULL, /* gpointer user_data1,*/
            NULL); /* gpointer user_data2,*/
            g_free(buf);
        }
        display_mserv_problems((void *) -1, NULL);
    }

    if (track == (void *) -1) { /* clean up */
        if (str)
            g_string_free(str, TRUE);
        str = NULL;
        track_nr = 0;
        gtkpod_tracks_statusbar_update();
    }
    else if (prefs_get_int("mserv_use") && prefs_get_int("mserv_report_probs") && track) {
        /* add info about it to str */
        buf = get_track_info(track, TRUE);
        if (!str) {
            track_nr = 0;
            str = g_string_sized_new(2000); /* used to keep record */
        }
        if (txt)
            g_string_append_printf(str, "%s (%s)\n", buf, txt);
        else
            g_string_append_printf(str, "%s\n", buf);
        g_free(buf);
        ++track_nr; /* count tracks */
    }
}
Ejemplo n.º 3
0
static gboolean
oss_loadsettings (void *dp,
		  prefs_node *f)
{
    oss_driver * const d = dp;

    prefs_get_string(f, "oss-devdsp", d->p_devdsp);
    prefs_get_int(f, "oss-resolution", &d->p_resolution);
    prefs_get_int(f, "oss-channels", &d->p_channels);
    prefs_get_int(f, "oss-mixfreq", &d->p_mixfreq);
    prefs_get_int(f, "oss-fragsize", &d->p_fragsize);

    prefs_init_from_structure(d);

    return TRUE;
}
Ejemplo n.º 4
0
/* init plugin                                                         */
static int http_init(void)
{
    http_buffer_size = prefs_get_int (ap_prefs, "http", "buffer_size", DEFAULT_HTTP_BUFFER_SIZE);

    /* Be sure http.buffer_size is available in config */
    prefs_set_int (ap_prefs, "http", "buffer_size", http_buffer_size);

    return 1;
}
Ejemplo n.º 5
0
void
tips_dialog_load_settings (void)
{
    prefs_node *f;

    f = prefs_open_read("tips");
    if(f) {
	prefs_get_int(f, "show-tips", &tips_dialog_show_tips);
	prefs_get_int(f, "last-tip", &tips_dialog_last_tip);
	prefs_close(f);
    }

    if(tips_dialog_last_tip >= TIPS_COUNT || tips_dialog_last_tip < 0) {
	tips_dialog_last_tip = 0;
    }

    return;
}
GtkWidget *init_playlist_display_preferences() {
    GtkBuilder *prefbuilder;
    GtkWidget *w = NULL;

    gchar *glade_path = g_build_filename(get_glade_dir(), "playlist_display.xml", NULL);
    prefbuilder = gtkpod_builder_xml_new(glade_path);
    w = gtkpod_builder_xml_get_widget(prefbuilder, "prefs_window");
    notebook = gtkpod_builder_xml_get_widget(prefbuilder, "playlist_settings_notebook");
    g_object_ref(notebook);
    gtk_container_remove(GTK_CONTAINER(w), notebook);
    gtk_widget_destroy(w);
    g_free(glade_path);

    switch (prefs_get_int("pm_sort")) {
    case SORT_ASCENDING:
        w = gtkpod_builder_xml_get_widget(prefbuilder, "pm_ascend");
        break;
    case SORT_DESCENDING:
        w = gtkpod_builder_xml_get_widget(prefbuilder, "pm_descend");
        break;
    case SORT_NONE:
        w = gtkpod_builder_xml_get_widget(prefbuilder, "pm_none");
        break;
    }

    if (w)
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), TRUE);

    if ((w = gtkpod_builder_xml_get_widget(prefbuilder, "pm_cfg_case_sensitive"))) {
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), prefs_get_int("pm_case_sensitive"));
    }

    gtk_builder_connect_signals(prefbuilder, NULL);
    g_object_unref(prefbuilder);

    return notebook;
}
Ejemplo n.º 7
0
/**
 * Sort the given list of tracks based on the clarity_sort preference
 */
GList *_sort_track_list(GList *tracks) {
    enum GtkPodSortTypes value = prefs_get_int("clarity_sort");

    switch(value) {
        case SORT_ASCENDING:
            tracks = g_list_sort(tracks, (GCompareFunc) compare_tracks);
            break;
        case SORT_DESCENDING:
            tracks = g_list_sort(tracks, (GCompareFunc) compare_tracks);
            tracks = g_list_reverse(tracks);
            break;
        default:
            // Do Nothing
            break;
    }

    return tracks;
}
Ejemplo n.º 8
0
static gboolean
alsa_loadsettings (void *dp,
		  prefs_node *f)
{
    alsa_driver * const d = dp;

    prefs_get_int(f, "alsa-resolution", &d->p_resolution);
    prefs_get_int(f, "alsa-channels", &d->p_channels);
    prefs_get_int(f, "alsa-mixfreq", &d->p_mixfreq);
    prefs_get_int(f, "alsa-fragsize", &d->p_fragsize);

    prefs_get_int(f, "alsa-card", &d->card_number);
    prefs_get_int(f, "alsa-device", &d->device_number);

    prefs_init_from_structure(d);

    return TRUE;
}
Ejemplo n.º 9
0
static gboolean
alsa_loadsettings (void *dp,
		  prefs_node *f)
{
    alsa_driver * const d = dp;
    guint i;
    gchar buf[32];

    //!!! Port all preferences to gchar, gint, etc...
    if(prefs_get_string(f, "alsa1x-device", buf)) {
	g_free(d->device);
        d->device = g_strdup(buf);
    }

    prefs_get_int(f, "alsa1x-resolution", &d->bits);
    prefs_get_int(f, "alsa1x-stereo", &d->stereo);
    prefs_get_int(f, "alsa1x-playrate", &d->playrate);
    prefs_get_int(f, "alsa1x-buffer_size", &d->buffer_size);
    prefs_get_int(f, "alsa1x-num_periods", &d->num_periods);
    prefs_get_int(f, "alsa1x-can_8", &d->can8);
    prefs_get_int(f, "alsa1x-can_16", &d->can16);
    prefs_get_int(f, "alsa1x-can_mono", &d->canmono);
    prefs_get_int(f, "alsa1x-can_stereo", &d->canstereo);
    prefs_get_int(f, "alsa1x-signedness_8", &d->signedness8);
    prefs_get_int(f, "alsa1x-signedness_16", &d->signedness16);
    prefs_get_int(f, "alsa1x-period_size_min", (int *)&d->persizemin);
    prefs_get_int(f, "alsa1x-period_size_max", (int *)&d->persizemax);

    for(i = 0; i < NUM_FORMATS; i++) {
	g_sprintf(buf, "alsa1x-devcap[%u].minfreq", i);
	prefs_get_int(f, buf, &d->devcap[i].minfreq);
	g_sprintf(buf, "alsa1x-devcap[%u].maxfreq", i);
	prefs_get_int(f, buf, &d->devcap[i].maxfreq);
	g_sprintf(buf, "alsa1x-devcap[%u].minbufsize", i);
	prefs_get_int(f, buf, (int *)&d->devcap[i].minbufsize);
	g_sprintf(buf, "alsa1x-devcap[%u].maxbufsize", i);
	prefs_get_int(f, buf, (int *)&d->devcap[i].maxbufsize);
    }

    prefs_get_int(f, "alsa1x-verbose", (int *)&d->verbose);
    prefs_get_str_array(f, "alsa1x-device-list", load_dev_func, d);
    gtk_combo_box_set_active(GTK_COMBO_BOX(d->alsa_device), 0);

    prefs_init_from_structure(d);

    return TRUE;
}
Ejemplo n.º 10
0
void gtkpod_init(int argc, char *argv[]) {
    AnjutaPluginManager *plugin_manager;
    AnjutaProfileManager *profile_manager;
    AnjutaApp *app;
    AnjutaStatus *status;
    AnjutaProfile *profile;
    GFile *session_profile;
    GError *error = NULL;

    gchar *default_profile_file = NULL;
    gchar *user_profile_file = NULL;

    gchar *ui_file = NULL;
    gchar *remembered_plugins = NULL;
    gchar *session_dir = NULL;
    gchar *splash = NULL;

    /* Initialise important directories */
    init_directories(argv);

    register_stock_icon(GTKPOD_ICON, GTKPOD_ICON_STOCK_ID);

    /* Initialise the ui file */
    ui_file = g_build_filename(get_ui_dir(), "gtkpod.ui", NULL);
    anjuta_set_ui_file_path(ui_file);

    /* Register the application icon */
    register_stock_icon("gtkpod", GTKPOD_APP_ICON_STOCK_ID);

    /* Initialize application class instance*/
    app = ANJUTA_APP(anjuta_app_new());
    gtkpod_app = GTKPOD_APP(app);

    /* Initialise the preferences as required for the display of the splash screen */
    prefs_init(argc, argv);

    /* Show some progress as the app is initialised */
    status = anjuta_shell_get_status(ANJUTA_SHELL(app), NULL);
    anjuta_status_progress_add_ticks(status, 1);

    /* Show the splash screen if user requires */
    if (! prefs_get_int(DISABLE_SPLASH_SCREEN)) {
        splash = g_build_filename(get_icon_dir(), "gtkpod-splash.png", NULL);
        if (g_file_test(splash, G_FILE_TEST_IS_REGULAR))
            anjuta_status_set_splash(status, splash, 100);
        else {
            anjuta_status_disable_splash(status, TRUE);
        }

        g_free(splash);
    }

    /*
     * initialise gtkpod library items. Needs to be safety threaded due
     * to splash screen.
     */
    gdk_threads_enter();
    gp_init(argc, argv);
    gdk_threads_leave();

    /* Add blocking widgets from the framework */
    add_blocked_widget(app->toolbar);
    add_blocked_widget(app->view_menu);

    /* Set up shutdown signals */
    g_signal_connect(G_OBJECT(app), "delete_event", G_CALLBACK(
                    on_gtkpod_delete_event), NULL);
    g_signal_connect(G_OBJECT(app), "destroy", G_CALLBACK(on_gtkpod_destroy),
            NULL);

    plugin_manager = anjuta_shell_get_plugin_manager(ANJUTA_SHELL(app), NULL);
    profile_manager = anjuta_shell_get_profile_manager(ANJUTA_SHELL(app), NULL);

    /* Restore remembered plugins */
    remembered_plugins = g_settings_get_string(app->settings, GTKPOD_REMEMBERED_PLUGINS);
    if (remembered_plugins)
        anjuta_plugin_manager_set_remembered_plugins(plugin_manager, remembered_plugins);
    g_free(remembered_plugins);

    /* Load default profile */
    default_profile_file = get_default_profile_path();
    profile = anjuta_profile_new(USER_PROFILE_NAME, plugin_manager);
    session_profile = g_file_new_for_path(default_profile_file);
    anjuta_profile_add_plugins_from_xml(profile, session_profile, TRUE, &error);
    if (error) {
        anjuta_util_dialog_error(GTK_WINDOW(app), "%s", error->message);
        g_error_free(error);
        error = NULL;
    }
    g_object_unref(session_profile);
    g_free(default_profile_file);

    /* Load user session profile */
    user_profile_file = get_user_profile_path();
    session_profile = g_file_new_for_path(user_profile_file);
    if (g_file_query_exists(session_profile, NULL)) {
        anjuta_profile_add_plugins_from_xml(profile, session_profile, FALSE, &error);
        if (error) {
            anjuta_util_dialog_error(GTK_WINDOW(app), "%s", error->message);
            g_error_free(error);
            error = NULL;
        }
    }
    anjuta_profile_set_sync_file(profile, session_profile);
    g_object_unref(session_profile);
    g_free(user_profile_file);

    /* Load profile */
    anjuta_profile_manager_freeze(profile_manager);
    anjuta_profile_manager_push(profile_manager, profile, &error);
    if (error) {
        anjuta_util_dialog_error(GTK_WINDOW(app), "%s", error->message);
        g_error_free(error);
        error = NULL;
    }

    /* Prepare for session save and load on profile change */
    g_signal_connect (profile_manager, "profile-scoped",
            G_CALLBACK (on_profile_scoped), app);

    anjuta_profile_manager_thaw(profile_manager, &error);

    if (error) {
        anjuta_util_dialog_error(GTK_WINDOW(app), "%s", error->message);
        g_error_free(error);
        error = NULL;
    }

    g_signal_connect (profile_manager, "profile-descoped",
            G_CALLBACK (on_profile_descoped), app);

    gdk_threads_enter();
    gp_init_itdbs();
    gdk_threads_leave();

    /* Load layout.*/
    session_dir = get_user_session_dir();
    if (!g_file_test(session_dir, G_FILE_TEST_IS_DIR))
        session_dir = g_strdup(get_data_dir());

    /* Restore session */
    anjuta_shell_session_load(ANJUTA_SHELL(app), session_dir, NULL);
    g_free(session_dir);

    anjuta_status_progress_tick(status, NULL, _("Loaded Session..."));
    anjuta_status_disable_splash(status, TRUE);

    gtk_window_set_default_icon_name("gtkpod");
    gtk_window_set_auto_startup_notification(TRUE);

    gtk_window_set_role(GTK_WINDOW(app), "gtkpod-app");
    gtk_widget_show(GTK_WIDGET(app));
}
Ejemplo n.º 11
0
/* Updates mserv data (rating only) of @track using filename @name to
 look up mserv information.
 Return TRUE if successfully updated (or disabled), FALSE if not */
gboolean update_mserv_data_from_file(gchar *name, Track *track) {
    gboolean success = TRUE;

    if (!name || !track)
        return FALSE;

    if (g_file_test(name, G_FILE_TEST_IS_DIR))
        return FALSE;
    if (!g_file_test(name, G_FILE_TEST_EXISTS)) {
        gchar *buf = g_strdup_printf(_("Local filename not valid (%s)"), name);
        display_mserv_problems(track, buf);
        g_free(buf);
        return FALSE;
    }

    if (prefs_get_int("mserv_use")) {
        /* try getting the user's rating from the mserv db */
        gchar *music_root = prefs_get_string("path_mserv_music_root");
        gchar *trackinfo_root = prefs_get_string("path_mserv_trackinfo_root");

        /* we expect music_root and trackinfo_root to be initialized */
        if (!music_root)
            music_root = g_strdup("");
        if (!trackinfo_root)
            trackinfo_root = g_strdup("");

        success = FALSE;
        /* printf("mroot %s troot %s fname %s\n", music_root, trackinfo_root, name); */

        /* first, check if the file is in the mserv music directory */
        if (*music_root == 0 || strstr(name, music_root)) {
            gchar *infoname =
                    g_strdup_printf("%s%c%s.trk", trackinfo_root, G_DIR_SEPARATOR, &(name[strlen(music_root)]));
            /* printf("trying %s\n", infoname); */
            FILE *fp = fopen(infoname, "r");
            if (fp) {
                /* printf("opened\n");*/
                gchar buff[PATH_MAX];
                gchar *username = prefs_get_string("mserv_username");
                guint usernamelen;
                g_return_val_if_fail (username, (fclose (fp), FALSE));
                usernamelen = strlen(username);
                while (fgets(buff, PATH_MAX, fp)) {
                    /* printf("username %s (%d) read %s\n",
                     * prefs_get_string("mserv_username"), usernamelen,
                     * buff);*/
                    if (strncmp(buff, username, usernamelen) == 0 && buff[usernamelen] == (gchar) '=') {
                        /* found it */
                        track->rating = atoi(&buff[usernamelen + 1]) * ITDB_RATING_STEP;
                        /* printf("found it, = %d\n",
                         orig_track->rating/ITDB_RATING_STEP); */
                        success = TRUE;
                        break; /* while(fgets(... */
                    }
                }
                fclose(fp);
                g_free(username);
                if (!success) {
                    gchar *username = prefs_get_string("mserv_username");
                    gchar *buf = g_strdup_printf(_("No information found for user '%s' in '%s'"), username, infoname);
                    display_mserv_problems(track, buf);
                    g_free(buf);
                    g_free(username);
                }
            }
            else {
                gchar *buf = g_strdup_printf(_("mserv data file (%s) not available for track (%s)"), infoname, name);
                display_mserv_problems(track, buf);
                g_free(buf);
            }
            g_free(infoname);
        }
        else {
            gchar *buf = g_strdup_printf(_("Track (%s) not in mserv music root directory (%s)"), name, music_root);
            display_mserv_problems(track, buf);
            g_free(buf);
        }
        g_free(music_root);
        g_free(trackinfo_root);
    }

    while (widgets_blocked && gtk_events_pending())
        gtk_main_iteration();

    return success;
}
Ejemplo n.º 12
0
int main(int argc, char **argv)
{
    const char *device_param = default_pcm_device;
    char *prefsdir;
    char thefile[1024];
    char str[1024];
    float start_vol = 1.0;
    int ap_result = 0;
    int use_fragsize = -1; // Initialized
    int use_fragcount = -1; // later
    int do_loopsong = 0;
    int do_looplist = 0;
    int do_enqueue = 0;
    int do_replace = 0;
    int do_realtime = 0;
    int do_remote_control = 0;
    int do_shuffle = 0;
    int do_start = 0;
    int do_stop = 0;
    int do_prev = 0;
    int do_next = 0;
    int do_pause = 0;
    int do_jump = -1;
    int do_clear = 0;
    int do_seek = -1;
    int do_relative = 0;
    int do_setvol = 0;
    int do_quit = 0;
    int do_status = 0;
    int do_speed = 0;
    float speed_val = 0.0;
    int do_onebyone = 0;

    int use_freq = OUTPUT_RATE;
    float use_vol = 1.0;
    int use_session = 0;
    int do_crossfade = 0;
    int do_save = 1;
    int bool_val = 0;
    const char *use_output = NULL;
    char *use_interface = NULL;
    char *use_config = NULL;
    char *use_loopsong = NULL;
    char *use_onebyone = NULL;
    char *use_looplist = NULL;

    int opt;
    int option_index;
    const char *options = "Cc:d:eEf:F:g:hi:J:I:l:n:NMp:qrs:vRSQVxo:";
    struct option long_options[] = {
        /*	{ "long_option", take_argument, 0, 'short_option' }, */
        { "config", 1, 0, 'c' },
        { "device", 1, 0, 'd' },
        { "enqueue", 0, 0, 'e' },
        { "replace", 0, 0, 'E' },
        { "fragsize", 1, 0, 'f' },
        { "frequency", 1, 0, 'F' },
        { "fragcount", 1, 0, 'g' },
        { "help", 0, 0, 'h' },
        { "interface", 1, 0, 'i' },
        { "volume", 1, 0, 'Y' },
        { "session", 1, 0, 'n' },
        { "nosave", 0, 0, 'N' },
        { "path", 1, 0, 'p' },
        { "quiet", 0, 0, 'q' },
        { "realtime", 0, 0, 'r' },
        { "script", 1, 0, 'I'},
        { "session-name", 1, 0, 's' },
        { "version", 0, 0, 'v' },
        { "verbose", 0, 0, 'V' },
        { "reverb", 0, 0, 'R' },
        { "loopsong", 1, 0, 'L' },
        { "looplist", 1, 0, 'P' },
        { "crossfade", 0, 0, 'x' },
        { "output", 1, 0, 'o' },
        { "stop", 0, 0, 'U' },
        { "pause", 0, 0, 'O' },
        { "start", 0, 0, 'T' },
        { "shuffle", 0, 0, 'S' },
        { "prev", 0, 0, 'Q' },
        { "next", 0, 0, 'M' },
        { "jump", 1, 0, 'J' },
        { "seek", 1, 0, 'X' },
        { "relative", 1, 0, 'Z' },
        { "speed", 1, 0, 'H' },
        { "clear", 0, 0, 'C' },
        { "startvolume", 1, 0, 'l' },
        { "quit", 0, 0, 'A' },
        { "status", 0, 0, 'B' },
        { "onebyone", 1, 0, 't' },

        // Options that we want to be able to pass on to gtk_init(). See man
        // gtk-options(7).
        // Give all of these an option number of 128 because we're going to
        // ignore them option switch statement anyway.
        { "gtk-module", 1, 0, 128 },
        { "gtk-debug", 1, 0, 128 },
        { "gtk-no-debug", 1, 0, 128 },
        { "g-fatal-warnings", 0, 0, 128 },

        { "display", 1, 0, 128 },
        { "screen", 1, 0, 128 },
        { "sync", 0, 0, 128 },
        { "no-xshm", 0, 0, 128 },
        { "name", 1, 0, 128 },
        { "class", 1, 0, 128 },
        { "gxid_host", 1, 0, 128 },
        { "gxid_port", 1, 0, 128 },
        { "xim-preedit", 0, 0, 128 },
        { "xim-status", 0, 0, 128 },
        { "gdk-debug", 1, 0, 128 },
        { "gdk-no-debug", 1, 0, 128 },

        // End of list marker.
        { 0, 0, 0, 0 }
    };


    // First setup signal handler
    signal(SIGPIPE, nonfatal_sighandler);   // PIPE (socket control)
    signal(SIGTERM, exit_sighandler);	// kill
    signal(SIGHUP, exit_sighandler);	// kill -HUP / xterm closed
    signal(SIGINT, exit_sighandler);	// Interrupt from keyboard
    signal(SIGQUIT, exit_sighandler);	// Quit from keyboard
    // fatal errors
    signal(SIGBUS, exit_sighandler);	// bus error
    //signal(SIGSEGV, exit_sighandler);	// segfault
    signal(SIGILL, exit_sighandler);	// illegal instruction
    signal(SIGFPE, exit_sighandler);	// floating point exc.
    signal(SIGABRT, exit_sighandler);	// abort()

    // Enable locale support
#ifdef ENABLE_NLS
    setlocale (LC_ALL, "");
    bindtextdomain(PACKAGE, LOCALEDIR);
    textdomain(PACKAGE);
    bind_textdomain_codeset (PACKAGE, "UTF-8");
#endif

    // Init global mutexes
    pthread_mutex_init(&playlist_sort_seq_mutex, NULL);
#if !defined(EMBEDDED)
    init_effects();
#endif
    while ((opt = getopt_long(argc, argv, options, long_options, &option_index)) != EOF) {
        switch(opt) {
        case 'A':
            do_remote_control = 1;
            do_quit = 1;
            break;
        case 'B':
            do_remote_control = 1;
            do_status = 1;
            break;
        case 'c':
            if (strlen(optarg) < 1023) {
                use_config = optarg;
            } else {
                alsaplayer_error("config file path too long");
                return 1;
            }
            break;
        case 'd':
            device_param = optarg;
            break;
        case 'E':
            do_replace = 1;
        case 'e':
            do_enqueue = 1;
            break;
        case 'f':
            use_fragsize = atoi(optarg);
            if (!use_fragsize) {
                alsaplayer_error("invalid fragment size");
                return 1;
            }
            if (use_fragsize > 32768) {
                alsaplayer_error("fragment size (%d) out of range (0-32768)", use_fragsize);
                return 1;
            }
            break;
        case 'F':
            use_freq = atoi(optarg);
            if (use_freq < 8000 || use_freq > 48000) {
                alsaplayer_error("frequency (%d) out of range (8000-48000)", use_freq);
                return 1;
            }
            break;
        case 'g':
            use_fragcount = atoi(optarg);
            if (use_fragcount < 2 || use_fragcount > 128) {
                alsaplayer_error("fragcount (%d) out of range (2-128)", use_fragcount);
                return 1;
            }
            break;
        case 'h':
            help();
            return 0;
        case 'H':
            if ((sscanf(optarg, "%f", &speed_val))) {
                do_remote_control = 1;
                do_speed = 1;
            }
            break;
        case 'i':
            use_interface = optarg;
            break;
        case 'l':
            start_vol = atof(optarg);
            if (start_vol < 0.0 || start_vol > 1.0) {
                alsaplayer_error("volume (%.3f) out of range: using 1.0", start_vol);
                start_vol = 1.0;
            }
            break;
        case 'L':
            do_remote_control = 1;
            do_loopsong = 1;
            use_loopsong = optarg;
            break;
        case 'Y':
            do_remote_control = 1;
            do_setvol = 1;
            use_vol = atof(optarg);
            if (use_vol < 0.0 || use_vol > 1.0) {
                alsaplayer_error("volume (%.3f) out of range: using 1.0", use_vol);
                use_vol = 1.0;
            }
            break;
        case 'n':
            use_session = atoi(optarg);
            break;
        case 'N':
            do_save = 0;
            break;
        case 'O':
            do_remote_control = 1;
            do_pause = 1;
            break;
        case 'p':
            global_pluginroot = optarg;
            break;
        case 'q':
            global_quiet = 1;
            break;
        case 'r':
            do_realtime = 1;
            break;
        case 's':
            if (strlen(optarg) < 32) {
                global_session_name = strdup(optarg);
            } else {
                alsaplayer_error("max 32 char session name, ignoring");
            }
            break;
        case 'v':
            version();
            return 0;
        case 'V':
            global_verbose = 1;
            break;
        case 'R':
            break;
        case 'P':
            do_remote_control = 1;
            do_looplist = 1;
            use_looplist = optarg;
            break;
        case 'x':
            do_crossfade = 1;
            break;
        case 'o':
            use_output = optarg;
            break;
        case '?':
            return 1;
        case 'I':
            global_interface_script = optarg;
            break;
        case 'U':
            do_remote_control = 1;
            do_stop = 1;
            break;
        case 'T':
            do_remote_control = 1;
            do_start = 1;
            break;
        case 'S':
            do_remote_control = 1;
            do_shuffle = 1;
            break;
        case 'Q':
            do_remote_control = 1;
            do_prev = 1;
            break;
        case 'M':
            do_remote_control = 1;
            do_next = 1;
            break;
        case 'J':
            do_remote_control = 1;
            do_jump = atoi(optarg);
            break;
        case 'C':
            do_remote_control = 1;
            do_clear = 1;
            break;
        case 'X':
            do_remote_control = 1;
            do_seek = atoi(optarg);
            break;
        case 'Z':
            do_remote_control = 1;
            do_relative = 1;
            do_seek = atoi(optarg);
            break;
        case 't':
            do_remote_control = 1;
            do_onebyone = 1;
            use_onebyone = optarg;
            break;
        case 128:
            // Gtk-option which we ignore.
            break;
        default:
            alsaplayer_error("Unknown option '%c'", opt);
            break;
        }
    }

    prefsdir = get_prefsdir();

    mkdir(prefsdir, 0700);	/* XXX We don't do any error checking here */
    snprintf(thefile, sizeof(thefile)-21, "%s/config", prefsdir);
    if (use_config)
        ap_prefs = prefs_load(use_config);
    else
        ap_prefs = prefs_load(thefile);
    if (!ap_prefs) {
        alsaplayer_error("Invalid config file %s\n", use_config ? use_config : thefile);
        return 1;
    }
    /* Initialize some settings (and populate the prefs system if needed */

    if (use_fragsize < 0)
        use_fragsize = prefs_get_int(ap_prefs, "main", "period_size", 4096);
    if (use_fragcount < 0)
        use_fragcount = prefs_get_int(ap_prefs, "main", "period_count", 8);


    if (global_verbose)
        puts(copyright_string);

    if (!global_pluginroot) {
        global_pluginroot = strdup (ADDON_DIR);
    }


    if (use_session == 0) {
        for (; use_session < MAX_REMOTE_SESSIONS+1; use_session++) {
            ap_result = ap_session_running(use_session);

            if (ap_result)
                break;
        }
        if (use_session == (MAX_REMOTE_SESSIONS+1)) {
            //alsaplayer_error("No remote session found");
            if (do_remote_control) {
                alsaplayer_error("No active sessions");
                return 1;
            }
            do_enqueue = 0;
        } else {
            //alsaplayer_error("Found session %d", use_session);
            if (prefs_get_bool(ap_prefs, "main", "multiopen", 1) == 0) {
                // We should not spawn another alsaplayer
                //alsaplayer_error("Using session %d, not doing multiopen", use_session);
                do_enqueue = 1;
                do_replace = 1;
            }
        }
    }

    // Check if we're in remote control mode
    if (do_remote_control) {
        if (do_quit) {
            ap_quit(use_session);
            return 0;
        } else if (do_status) {
            char res[1024];
            float fres;
            int ires;
            fprintf(stdout, "---------------- Session ----------------\n");
            if (ap_get_session_name(use_session, res) && strlen(res))
                fprintf(stdout, "name: %s\n", res);
            if (ap_get_playlist_length(use_session, &ires))
                fprintf(stdout, "playlist_length: %d\n", ires);
            if (ap_get_volume(use_session, &fres))
                fprintf(stdout, "volume: %.2f\n", fres);
            if (ap_get_speed(use_session, &fres))
                fprintf(stdout, "speed: %d%%\n", (int)(fres * 100));
            fprintf(stdout, "-------------- Current Track ------------\n");
            if (ap_get_artist(use_session, res) && strlen(res))
                fprintf(stdout, "artist: %s\n", res);
            if (ap_get_title(use_session, res) && strlen(res))
                fprintf(stdout, "title: %s\n", res);
            if (ap_get_album(use_session, res) && strlen(res))
                fprintf(stdout, "album: %s\n", res);
            if (ap_get_genre(use_session, res) && strlen(res))
                fprintf(stdout, "genre: %s\n", res);
            if (ap_get_file_path(use_session, res) && strlen(res))
                fprintf(stdout, "path: %s\n", res);
            if (ap_get_blocks(use_session, &ires))
                fprintf(stdout, "blocks: %d\n", ires);
            if (ap_get_length(use_session, &ires))
                fprintf(stdout, "length: %d second%s\n", ires, (ires == 1) ? "": "s");
            if (ap_get_position(use_session, &ires))
                fprintf(stdout, "position: %d\n", ires);
            fprintf(stdout, "-----------------------------------------\n");
            return 0;
        } else if (do_setvol) {
            ap_set_volume(use_session, use_vol);
            return 0;
        } else if (do_shuffle) {
            ap_shuffle_playlist(use_session);
            return 0;
        } else if (do_start) {
            ap_play(use_session);
            return 0;
        } else if (do_stop) {
            ap_stop(use_session);
            return 0;
        } else if (do_pause) {
            if (ap_is_paused(use_session, &bool_val)) {
                if (bool_val)
                    ap_unpause(use_session);
                else
                    ap_pause(use_session);
            }
            return 0;
        } else if (do_next) {
            ap_next(use_session);
            return 0;
        } else if (do_prev) {
            ap_prev(use_session);
            return 0;
        } else if (do_jump >= 0) {
            ap_jump_to(use_session, do_jump);
            return 0;
        } else if (do_clear) {
            ap_clear_playlist(use_session);
            return 0;
        } else if (do_relative) {
            if (do_seek != 0)
                ap_set_position_relative(use_session, do_seek);
            return 0;
        } else if (do_speed) {
            if (speed_val < -10.0 || speed_val > 10.0) {
                alsaplayer_error("Speed out of range, must be between -10.00 and 10.00");
                return 1;
            }
            ap_set_speed(use_session, speed_val);
            return 0;
        } else if (do_seek >= 0) {
            ap_set_position(use_session, do_seek);
            return 0;
        } else if (do_loopsong) {
            if (strcasecmp(use_loopsong, "on") != 0) {
                do_loopsong = false;
            }
            ap_set_looping(use_session, do_loopsong);
            return 0;
        } else if (do_onebyone) {
            if (strcasecmp(use_onebyone, "on") != 0) {
                do_onebyone = false;
            }
            ap_set_onebyone(use_session, do_onebyone);
            return 0;
        } else if (do_looplist) {
            if (strcasecmp(use_looplist, "on") != 0) {
                do_looplist = false;
            }
            ap_set_playlist_looping(use_session, do_looplist);
            return 0;
        } else
            alsaplayer_error("No remote control command executed.");
    }


    // Check if we need to enqueue the files
    if (do_enqueue) {
        char queue_name[2048];
        int count = 0;
        int was_playing = 0;
        int playlist_length = 0;

        count = optind;
        ap_result = 1;

        if (do_replace && count < argc) {
            ap_is_playing(use_session, &was_playing);
            if (was_playing) {
                ap_stop(use_session);
            }
            ap_clear_playlist(use_session);
        } else {
            ap_get_playlist_length(use_session, &playlist_length);
            if (!playlist_length) { // Empty list so fire up after add
                was_playing = 1;
            }
        }
        while (count < argc && ap_result) {
            if (is_playlist(argv[count])) {
                ap_add_playlist(use_session, argv[count]);
                count++;
                continue;
            }
            if (argv[count][0] != '/' &&
                    strncmp(argv[count], "http://", 7) != 0 &&
                    strncmp(argv[count], "ftp://", 6) != 0) {
                // Not absolute so append cwd
                if (getcwd(queue_name, 1024) == NULL) {
                    alsaplayer_error("error getting cwd");
                    return 1;
                }
                ap_strlcat(queue_name, "/", sizeof(queue_name));
                ap_strlcat(queue_name, argv[count], sizeof(queue_name));
            } else
                ap_strlcpy(queue_name, argv[count], sizeof(queue_name));
            count++;
            //alsaplayer_error("Adding %s", queue_name);
            ap_result = ap_add_path(use_session, queue_name);
            //alsaplayer_error("ap_result = %d", ap_result);
        }
        if (was_playing)
            ap_jump_to(use_session, 1);
        if (ap_result)
            return 0;
    }

    AlsaNode *node;

    // Check if we want jack
    if (strcmp(argv[0], "jackplayer") == 0) {
        use_output = "jack";
    }

    // Check the output option
    if (use_output == NULL) {
        use_output = prefs_get_string(ap_prefs, "main",
                                      "default_output", "alsa");
    }

    // Else do the usual plugin based thing
    node = new AlsaNode(use_output, device_param, do_realtime);

    if (!node->RegisterPlugin(use_output)) {
        alsaplayer_error("Failed to load output plugin \"%s\". Trying defaults.", use_output);
        if (!node->RegisterPlugin())
            return 1;
    }
    int output_is_ok = 0;
    int output_alternate = 0;

    do {
        if (!node || !node->ReadyToRun()) {
            alsaplayer_error
            ("failed to load output plugin (%s). exitting...",
             use_output ? use_output: "alsa,etc.");
            return 1;
        }
        if (!node->SetSamplingRate(use_freq) ||
                !node->SetStreamBuffers(use_fragsize, use_fragcount, 2)) {
            alsaplayer_error
            ("failed to configure output device...trying OSS");
            /* Special case for OSS, since it's easiest to get going, so try it */
            if (!output_alternate) {
                output_alternate = 1;
                node->RegisterPlugin("oss");
                continue;
            } else {
                return 1;
            }
        }
        output_is_ok = 1;	/* output device initialized */
    } while (!output_is_ok);

    // Initialise reader
    reader_init ();

    // Initialise playlist - must be done before things try to register with it
    playlist = new Playlist(node);

    if (!prefs_get_bool(ap_prefs, "main", "play_on_start", false))
        playlist->Pause();
    else
        playlist->UnPause();

    if (!playlist) {
        alsaplayer_error("Failed to create Playlist object");
        return 1;
    }
    // Add any command line arguments to the playlist
    if (optind < argc) {
        std::vector < std::string > newitems;
        while (optind < argc) {
            if (is_playlist(argv[optind])) {
                if (global_verbose)
                    alsaplayer_error("Loading playlist (%s)", argv[optind]);
                playlist->Load(std::string(argv[optind++]),
                               playlist->Length(), false);
            } else {
                newitems.push_back(std::string(argv[optind++]));
            }
        }
        playlist->Insert(newitems, playlist->Length());
    } else {
        prefsdir = get_prefsdir();
        snprintf(thefile, sizeof(thefile)-28, "%s/alsaplayer.m3u", prefsdir);
        playlist->Load(thefile, playlist->Length(), false);
    }

    // Loop song
    if (do_loopsong) {
        playlist->LoopSong();
    }
    // Loop Playlist
    if (do_looplist) {
        playlist->LoopPlaylist();
    }
    // Play songs one by one
    if (do_onebyone) {
        playlist->SetOneByOne();
    }
    // Cross fading
    if (do_crossfade) {
        playlist->Crossfade();
    }
    // Set start volume
    playlist->GetCorePlayer()->SetVolume(start_vol);


    interface_plugin_info_type interface_plugin_info;
    interface_plugin *ui;

    if (get_interface_from_argv0 (argv[0], str))
        use_interface = str;

    if (use_interface && *use_interface) {
        if (!(interface_plugin_info = load_interface(use_interface))) {
            alsaplayer_error("Failed to load interface %s\n", use_interface);
            goto _fatal_err;
        }
    } else {
        const char *interface = prefs_get_string
                                (ap_prefs, "main", "default_interface", "gtk2");
        // if we're trying to use the old gtk-1 interface, use gtk-2 instead
        if (strcmp (interface, "gtk") == 0)
            interface = "gtk2";
        // if we're trying to use the gtk interface, but we have no
        // $DISPLAY, use the text interface instead
        if (strcmp (interface, "gtk2") == 0 && !getenv("DISPLAY"))
            interface = "text";
        if (!(interface_plugin_info = load_interface(interface))) {
            if (!(interface_plugin_info = load_interface(prefs_get_string
                                          (ap_prefs, "main", "fallback_interface", "text")))) {
                alsaplayer_error("Failed to load text interface. This is bad (%s,%s,%s)",
                                 interface, interface,
                                 global_pluginroot);
                goto _fatal_err;
            }
        }
    }
    if (interface_plugin_info) {
        ui = interface_plugin_info();

        if (global_verbose)
            printf("Interface plugin: %s\n", ui->name);
        if (!ui->init()) {
            alsaplayer_error("Failed to load interface plugin. Should fall back to text\n");
        } else {
            control_socket_start(playlist, ui);
            ui->start(playlist, argc, argv);
            ui->close();
            // Unfortunately gtk+ is a pig when it comes to
            // cleaning up its resources; it doesn't!
            // so we can never safely dlclose gtk+ based
            // user interfaces, bah!
            //dlclose(ui->handle);
            control_socket_stop();
        }
    }
    // Save playlist before exit
    prefsdir = get_prefsdir();
    snprintf(thefile, sizeof(thefile)-25, "%s/alsaplayer", prefsdir);
    playlist->Save(thefile, PL_FORMAT_M3U);

    // Save preferences
    if (ap_prefs && do_save) {
        if (prefs_save(ap_prefs) < 0) {
            alsaplayer_error("failed to save preferences.");
        }
    }

_fatal_err:
    delete playlist;
    //delete p;
    delete node;
    if (global_session_name)
        free(global_session_name);

    return 0;
}
Ejemplo n.º 13
0
gboolean wav_can_convert() {
    gchar *cmd = wav_get_conversion_cmd();
    return cmd && cmd[0] && prefs_get_int("convert_wav");
}
Ejemplo n.º 14
0
/**
 * Using the given track, set the metadata of the target
 * file
 */
void AP_write_metadata(Track *track, const char *filePath, GError **error) {
    ExtraTrackData *etr;
    gchar *atom;
    gchar *value;

    g_return_if_fail(track);

    APar_ScanAtoms(filePath);

    if (metadata_style != ITUNES_STYLE) {
        gchar *fbuf = charset_to_utf8(filePath);
        gtkpod_log_error(error, g_strdup_printf(_("ERROR %s is not itunes style."), fbuf));
        g_free(fbuf);
        return;
    }

    // Title
    set_limited_text_atom_value(TITLE, track->title);

    // Artist
    set_limited_text_atom_value(ARTIST, track->artist);

    // Album Artist
    set_limited_text_atom_value(ALBUM_ARTIST, track->albumartist);

    // Album
    set_limited_text_atom_value(ALBUM, track->album);

    // Genre
    APar_MetaData_atomGenre_Set(track->genre);

    // Track Number and Total
    atom = g_strdup_printf("%s.%s.%s", ILST_FULL_ATOM, TRACK_NUM_AND_TOTAL, DATA);
    if (track->track_nr == 0) {
        APar_RemoveAtom(atom, VERSIONED_ATOM, 0);
    }
    else {
        gchar *track_info = g_strdup_printf("%d / %d", track->track_nr, track->tracks);
        short tracknumData_atom = APar_MetaData_atom_Init(atom, track_info, AtomFlags_Data_Binary);
        APar_Unified_atom_Put(tracknumData_atom, NULL, UTF8_iTunesStyle_256glyphLimited, 0, 16);
        APar_Unified_atom_Put(tracknumData_atom, NULL, UTF8_iTunesStyle_256glyphLimited, track->track_nr, 16);
        APar_Unified_atom_Put(tracknumData_atom, NULL, UTF8_iTunesStyle_256glyphLimited, track->tracks, 16);
        APar_Unified_atom_Put(tracknumData_atom, NULL, UTF8_iTunesStyle_256glyphLimited, 0, 16);
        g_free(track_info);
    }
    g_free(atom);

    // Disk Number and Total
    atom = g_strdup_printf("%s.%s.%s", ILST_FULL_ATOM, DISK_NUM_AND_TOTAL, DATA);
    if (track->cd_nr == 0) {
        APar_RemoveAtom(atom, VERSIONED_ATOM, 0);
    }
    else {
        gchar *disk_info = g_strdup_printf("%d / %d", track->cd_nr, track->cds);
        short disknumData_atom = APar_MetaData_atom_Init(atom, disk_info, AtomFlags_Data_Binary);
        APar_Unified_atom_Put(disknumData_atom, NULL, UTF8_iTunesStyle_256glyphLimited, 0, 16);
        APar_Unified_atom_Put(disknumData_atom, NULL, UTF8_iTunesStyle_256glyphLimited, track->cd_nr, 16);
        APar_Unified_atom_Put(disknumData_atom, NULL, UTF8_iTunesStyle_256glyphLimited, track->cds, 16);
        g_free(disk_info);
    }
    g_free(atom);

    // Comment
    set_limited_text_atom_value(COMMENT, track->comment);

    // Year
    gchar *yr = NULL;
    if (track->year > 0)
        yr = g_strdup_printf("%d", track->year);

    set_limited_text_atom_value(YEAR, yr);

    if (yr)
        g_free(yr);

    // Lyrics
    etr = (ExtraTrackData *) track->userdata;
    if (etr)
        write_lyrics_internal(etr->lyrics, filePath, error);

    // Composer
    set_limited_text_atom_value(COMPOSER, track->composer);

    // Grouping
    set_limited_text_atom_value(GROUPING, track->grouping);

    // Description
    set_limited_text_atom_value(DESCRIPTION, track->description);

    // TV Network
    set_limited_text_atom_value(TV_NETWORK_NAME, track->tvnetwork);

    // TV Show Name
    set_limited_text_atom_value(TV_SHOW, track->tvshow);

    // TV Episode
    set_limited_text_atom_value(TV_EPISODE, track->tvepisode);

    // Compilation
    atom = g_strdup_printf("%s.%s.%s", ILST_FULL_ATOM, COMPILATION, DATA);
    if (!track->compilation) {
        APar_RemoveAtom(atom, VERSIONED_ATOM, 0);
    }
    else {
        //compilation: [0, 0, 0, 0,   boolean_value]; BUT that first uint32_t is already accounted for in APar_MetaData_atom_Init
        value = g_strdup_printf("%d", track->compilation);
        short compilationData_atom = APar_MetaData_atom_Init(atom, value, AtomFlags_Data_UInt);
        APar_Unified_atom_Put(compilationData_atom, NULL, UTF8_iTunesStyle_256glyphLimited, 1, 8); //a hard coded uint8_t of: 1 is compilation
        g_free(value);
    }
    g_free(atom);

    // Tempo / BPM
    atom = g_strdup_printf("%s.%s.%s", ILST_FULL_ATOM, TEMPO, DATA);
    if (!track->BPM) {
        APar_RemoveAtom(atom, VERSIONED_ATOM, 0);
    }
    else {
        //bpm is [0, 0, 0, 0,   0, bpm_value]; BUT that first uint32_t is already accounted for in APar_MetaData_atom_Init
        value = g_strdup_printf("%d", track->BPM);
        short bpmData_atom = APar_MetaData_atom_Init(atom, value, AtomFlags_Data_UInt);
        APar_Unified_atom_Put(bpmData_atom, NULL, UTF8_iTunesStyle_256glyphLimited, track->BPM, 16);
        g_free(value);
    }
    g_free(atom);

    // Media Type
    atom = g_strdup_printf("%s.%s.%s", ILST_FULL_ATOM, MEDIA_TYPE, DATA);
    guint8 mediaTypeTag = mediaTypeToMediaTypeTag(track->mediatype);
    value = g_strdup_printf("%d", track->season_nr);
    short stikData_atom = APar_MetaData_atom_Init(atom, value, AtomFlags_Data_UInt);
    APar_Unified_atom_Put(stikData_atom, NULL, UTF8_iTunesStyle_256glyphLimited, mediaTypeTag, 8);
    g_free(value);
    g_free(atom);

    // TV Season No.
    atom = g_strdup_printf("%s.%s.%s", ILST_FULL_ATOM, TV_SEASON_NO, DATA);
    if (track->season_nr == 0) {
        APar_RemoveAtom(atom, VERSIONED_ATOM, 0);
    }
    else {
        value = g_strdup_printf("%d", track->season_nr);
        short tvseasonData_atom = APar_MetaData_atom_Init(atom, value, AtomFlags_Data_UInt);
        APar_Unified_atom_Put(tvseasonData_atom, NULL, UTF8_iTunesStyle_256glyphLimited, 0, 16);
        APar_Unified_atom_Put(tvseasonData_atom, NULL, UTF8_iTunesStyle_256glyphLimited, track->season_nr, 16);
        g_free(value);
    }
    g_free(atom);

    // TV Episode No.
    atom = g_strdup_printf("%s.%s.%s", ILST_FULL_ATOM, TV_EPISODE_NO, DATA);
    if (track->episode_nr == 0) {
        APar_RemoveAtom(atom, VERSIONED_ATOM, 0);
    }
    else {
        value = g_strdup_printf("%d", track->episode_nr);
        short tvepisodenumData_atom = APar_MetaData_atom_Init(atom, value, AtomFlags_Data_UInt);
        APar_Unified_atom_Put(tvepisodenumData_atom, NULL, UTF8_iTunesStyle_256glyphLimited, 0, 16);
        APar_Unified_atom_Put(tvepisodenumData_atom, NULL, UTF8_iTunesStyle_256glyphLimited, track->episode_nr, 16);
        g_free(value);
    }
    g_free(atom);

    // Keywords
    set_limited_text_atom_value(KEYWORD, track->keywords);

    // Podcast Category
    set_limited_text_atom_value(CATEGORY, track->category);

    // Podcast URL
    atom = g_strdup_printf("%s.%s.%s", ILST_FULL_ATOM, PODCAST_URL, DATA);
    if (!track->podcasturl || strlen(track->podcasturl) == 0) {
        APar_RemoveAtom(atom, VERSIONED_ATOM, 0);
    }
    else {
        short podcasturlData_atom = APar_MetaData_atom_Init(atom, track->podcasturl, AtomFlags_Data_Binary);
        APar_Unified_atom_Put(podcasturlData_atom, track->podcasturl, UTF8_iTunesStyle_Binary, 0, 0);
    }
    g_free(atom);

    // Gapless Playback
    atom = g_strdup_printf("%s.%s.%s", ILST_FULL_ATOM, GAPLESS_FLAG, DATA);
    if (!track->gapless_track_flag) {
        APar_RemoveAtom(atom, VERSIONED_ATOM, 0);
    }
    else {
        value = g_strdup_printf("%d", track->gapless_track_flag);
        short gaplessData_atom = APar_MetaData_atom_Init(atom, value, AtomFlags_Data_UInt);
        APar_Unified_atom_Put(gaplessData_atom, NULL, UTF8_iTunesStyle_256glyphLimited, 1, 8); //a hard coded uint8_t of: 1 is gapl
        g_free(value);
    }
    g_free(atom);

    // Sort Title
    set_limited_text_atom_value(SORT_TITLE, track->sort_title);

    // Sort Artist
    set_limited_text_atom_value(SORT_ARTIST, track->sort_artist);

    // Sort Album Artist
    set_limited_text_atom_value(SORT_ALBUM_ARTIST, track->sort_albumartist);

    // Sort Composer
    set_limited_text_atom_value(SORT_COMPOSER, track->sort_composer);

    // Sort Album
    set_limited_text_atom_value(SORT_ALBUM, track->sort_album);

    // Sort TV Show
    set_limited_text_atom_value(SORT_TV_SHOW, track->sort_tvshow);

    if (prefs_get_int("coverart_apic")) {
        GdkPixbuf *pixbuf = (GdkPixbuf*) itdb_artwork_get_pixbuf(track->itdb->device, track->artwork, -1, -1);
        if (!pixbuf) {
            // Destroy any existing artwork if any
            APar_MetaData_atomArtwork_Set("REMOVE_ALL", NULL);
        }
        else {
            gchar *tmp_file = g_build_filename(g_get_tmp_dir(), "ttt.jpg", NULL);
            GError *pixbuf_err = NULL;

            gdk_pixbuf_save(pixbuf, tmp_file, "jpeg", &pixbuf_err, "quality", "100", NULL);

            if (!pixbuf_err) {
                APar_MetaData_atomArtwork_Set(tmp_file, NULL);
                g_remove(tmp_file);
            }
            else {
                gtkpod_log_error(error, g_strdup_printf(_("ERROR failed to change track file's artwork.") ));
                g_error_free(pixbuf_err);
                return;
            }

            g_free(tmp_file);
            g_object_unref(pixbuf);
        }
    }

    // after all the modifications are enacted on the tree in memory
    // then write out the changes
    APar_DetermineAtomLengths();
    openSomeFile(filePath, true);
    APar_WriteFile(filePath, NULL, true);

    APar_FreeMemory();
}
Ejemplo n.º 15
0
/**
 * Open and scan the metadata of the m4a/mp4/... file
 * and populate the given track.
 */
void AP_read_metadata(const char *filePath, Track *track) {
    FILE *mp4File;
    Trackage *trackage;
    uint8_t track_cur;
    uint8_t txttrack_cur;
    gboolean audio_or_video_found = FALSE;
    gboolean has_quicktime_chaps = FALSE;
    uint32_t timescale = 0;

    APar_ScanAtoms(filePath, true);
    mp4File = openSomeFile(filePath, true);

    trackage = APar_ExtractDetails(mp4File, SHOW_TRACK_INFO);

    for (track_cur = 0; track_cur < trackage->total_tracks; ++track_cur) {
        TrackInfo *info = trackage->infos[track_cur];

        if ((info->type_of_track & AUDIO_TRACK) || (info->type_of_track & VIDEO_TRACK)
                        || (info->type_of_track & DRM_PROTECTED_TRACK)) {

            /*
             * the info->duration is in the track's timescale units so must be divided by that
             * value to get seconds, while track->tracklen in gtkpod is in ms
             */
            float duration = ((float) info->duration / (float) info->parent->movie_info->timescale) * 1000;
            track->tracklen = (gint32) duration;

            track->bitrate = APar_calculate_bitrate(info);
            track->samplerate = info->media_sample_rate;
            audio_or_video_found = TRUE;
            break;
        }
    }
    for (txttrack_cur = 0; audio_or_video_found && txttrack_cur < trackage->total_tracks; ++txttrack_cur) {
        TrackInfo *txtinfo = trackage->infos[txttrack_cur];
        char buf[128];
        // search for chapter track
        if (!(txtinfo->type_of_track & TEXT_TRACK))
            continue;
        // see if the AV track's chap refers to this text track
        // chap: 0: atom size  4: 'chap'  8,12,...,8+(N-1)*4: (0: referenced track ID)
        snprintf(buf, sizeof(buf), "moov.trak[%u].tref.chap", track_cur + 1);
        AtomicInfo* chapAtom = APar_FindAtom(buf, false, SIMPLE_ATOM, 0);
        if (!chapAtom)
            continue;
        int entry_count = (chapAtom->AtomicLength - 8) / 4;
        for (int i = 0; i < entry_count; ++i) {
            if (APar_read32(buf, mp4File, chapAtom->AtomicStart + 8 + i * 4) == txtinfo->track_id) {
                has_quicktime_chaps = TRUE;
                timescale = txtinfo->media_sample_rate;
                break;
            }
        }
        if (has_quicktime_chaps)
            break;
    }
    if (has_quicktime_chaps) {
        // found a chapter... now get the chapter data from the text track
        char buf[128];

        // stts: 0: atom size  4: 'stts'  8: version  12: entry count  16,24,...,16+(N-1)*8: (0: frame count 4: duration)
        snprintf(buf, sizeof(buf), "moov.trak[%u].mdia.minf.stbl.stts", txttrack_cur + 1);
        AtomicInfo* sampleAtom = APar_FindAtom(buf, false, VERSIONED_ATOM, 0);

        // stsz: 0: atom size  4: 'stsz'  8: version  12: size of all (or 0)  16: entry count  20,24,...,20+(N-1)*4: (0: sample size)
        snprintf(buf, sizeof(buf), "moov.trak[%u].mdia.minf.stbl.stsz", txttrack_cur + 1);
        AtomicInfo* sampleSizeAtom = APar_FindAtom(buf, false, VERSIONED_ATOM, 0);

        // stco: 0: atom size  4: 'stco'  8: version  12: entry count  16,20,...,16+(N-1)*4: (0: sample byte offset)
        snprintf(buf, sizeof(buf), "moov.trak[%u].mdia.minf.stbl.stco", txttrack_cur + 1);
        AtomicInfo* sampleOffsetAtom = APar_FindAtom(buf, false, VERSIONED_ATOM, 0);

        // We must have a valid sampleAtom to know chapter times. If sampleSizeAtom or sampleOffsetAtom is invalid,
        // we can do without them (and instead create a default chapter name).
        if (sampleAtom && sampleAtom->AtomicLength >= 16) {
            Itdb_Chapterdata *chapterdata = itdb_chapterdata_new();
            uint32_t stts_entry_count = APar_read32(buf, mp4File, sampleAtom->AtomicStart + 12);
            uint32_t stsz_entry_count = !sampleSizeAtom || sampleSizeAtom->AtomicLength < 20 ? 0 :
                APar_read32(buf, mp4File, sampleSizeAtom->AtomicStart + 16);
            uint32_t stco_entry_count = !sampleOffsetAtom || sampleOffsetAtom->AtomicLength < 16 ? 0 :
                APar_read32(buf, mp4File, sampleOffsetAtom->AtomicStart + 12);
            uint32_t stsz_all_size = !sampleSizeAtom || sampleSizeAtom->AtomicLength < 16 ? 0 :
                APar_read32(buf, mp4File, sampleSizeAtom->AtomicStart + 12);

            uint32_t start_time = 0;

            u_int32_t max_frame_size = stsz_all_size; // if stsz_all_size specified, use only that size
            for (int i = 0; !stsz_all_size && i < stsz_entry_count; ++i) {
                uint32_t chap_name_len = APar_read32(buf, mp4File, sampleSizeAtom->AtomicStart + 20 + i * 4);
                if (chap_name_len > max_frame_size)
                    max_frame_size = chap_name_len;
            }
            max_frame_size += 1; // for trailing '\0' (unneeded?), and to make sure that malloc() gets passed at least 1
            char * namebuf = (char *)malloc(max_frame_size * sizeof(char));
            for (int i = 0; i < stts_entry_count; ++i) {
                gchar *title = NULL;
                uint32_t chap_name_len = stsz_all_size;
                uint32_t chap_offset = 0;
                if (stsz_all_size == 0 && i < stsz_entry_count)
                    chap_name_len = APar_read32(buf, mp4File, sampleSizeAtom->AtomicStart + 20 + i * 4);
                if (i < stco_entry_count)
                    chap_offset = APar_read32(buf, mp4File, sampleOffsetAtom->AtomicStart + 16 + i * 4);
                if (chap_offset != 0)
                    APar_readX(namebuf, mp4File, chap_offset, chap_name_len);
                else // If the location of the chapter name is unknown, trigger default chapter naming
                    chap_name_len = 0;
                if (chap_name_len > 2) {
                    int titlelength = (namebuf[0] << 8) + namebuf[1];
                    // if the stsz atom and the title value disagree, use the smaller one for safety
                    titlelength = (titlelength > chap_name_len) ? chap_name_len : titlelength;
                    // If a title begins with 0xFFFE, it's a UTF-16 title
                    if (titlelength >= 2 && namebuf[2] == 0xff && namebuf[3] == 0xfe)
                        title = g_utf16_to_utf8((const gunichar2 *) &namebuf[4], titlelength - 2, NULL, NULL, NULL);
                    else
                        title = g_strndup(&namebuf[2], titlelength);
                }
                else
                {
                    // chapter title couldn't be found; create our own titles (and some ipods don't display them anyway).
                    // Translators: this string is used to create a chapter title when no chapter title could be found
                    title = g_strdup_printf(_("Chapter %3d"), i);
                }

                if (!timescale) // assume 1000, also, don't divide by 0
                    timescale = 1000;
                double duration_ms = (double)start_time * 1000.0 / (double)timescale;

                itdb_chapterdata_add_chapter(chapterdata, duration_ms, title);
                g_free(title);

                if (i < (stts_entry_count - 1)) // skip this stage after the last chapter has been added
                {
                    uint32_t frame_count = APar_read32(buf, mp4File, sampleAtom->AtomicStart + 16 + i * 8);
                    uint32_t duration = APar_read32(buf, mp4File, sampleAtom->AtomicStart + 20 + i * 8);
                    start_time += frame_count * duration;
                }
            }
            if (namebuf)
                free(namebuf);
            if (track->chapterdata) // if there was already chapter data, don't leak it
                itdb_chapterdata_free(track->chapterdata);
            track->chapterdata = itdb_chapterdata_duplicate(chapterdata);
            itdb_chapterdata_free(chapterdata);
        }
    }
    // TODO: add support for Nero-style mp4 chapters

    if (prefs_get_int("readtags")) {
        char* value = NULL;

        // MP4 Title
        value = find_atom_value(TITLE);
        if (value) {
            track->title = g_strdup(value);
            free(value);
        }

        // MP4 Artist
        value = find_atom_value(ARTIST);
        if (value) {
            track->artist = g_strdup(value);
            free(value);
        }

        // MP4 Album Artist
        value = find_atom_value(ALBUM_ARTIST);
        if (value) {
            track->albumartist = g_strdup(value);
            free(value);
        }

        // MP4 Composer
        value = find_atom_value(COMPOSER);
        if (value) {
            track->composer = g_strdup(value);
            free(value);
        }

        // MP4 Comment
        value = find_atom_value(COMMENT);
        if (value) {
            track->comment = g_strdup(value);
            free(value);
        }

        // MP4 Description
        value = find_atom_value(DESCRIPTION);
        if (value) {
            track->description = g_strdup(value);
            free(value);
        }

        // MP4 Keywords
        value = find_atom_value(KEYWORD);
        if (value) {
            track->keywords = g_strdup(value);
            free(value);
        }

        // MP4 Year
        value = find_atom_value(YEAR);
        if (value) {
            track->year = atoi(value);
            free(value);
        }

        // MP4 Album
        value = find_atom_value(ALBUM);
        if (value) {
            track->album = g_strdup(value);
            free(value);
        }

        // MP4 Track No. and Total
        value = find_atom_value(TRACK_NUM_AND_TOTAL);
        if (value) {
            const char* delimiter = " of ";
            char *result = NULL;
            result = strtok(value, delimiter);
            if (result)
                track->track_nr = atoi(result);

            result = strtok(NULL, delimiter);
            if (result)
                track->tracks = atoi(result);

            free(value);
        }

        // MP4 Disk No. and Total
        value = find_atom_value(DISK_NUM_AND_TOTAL);
        if (value) {
            const char* delimiter = " of ";
            char *result = NULL;
            result = strtok(value, delimiter);
            if (result)
                track->cd_nr = atoi(result);

            result = strtok(NULL, delimiter);
            if (result)
                track->cds = atoi(result);

            free(value);
        }

        // MP4 Grouping
        value = find_atom_value(GROUPING);
        if (value) {
            track->grouping = g_strdup(value);
            free(value);
        }

        // MP4 Genre - note: can be either a standard or custom genre
        // standard genre
        value = find_atom_value(STANDARD_GENRE);
        if (value) {
            track->genre = charset_to_utf8(value);
            // Should not free standard genres
        }
        else {
            // custom genre
            value = find_atom_value(CUSTOM_GENRE);
            if (value) {
                track->genre = g_strdup(value);
                free(value);
            }
        }

        // MP4 Tempo / BPM
        value = find_atom_value(TEMPO);
        if (value) {
            track->BPM = atoi(value);
            free(value);
        }

        // MP4 Lyrics
        value = find_atom_value(LYRICS);
        if (value) {
            track->lyrics_flag = 0x01;
            free(value);
        }

        // MP4 TV Show
        value = find_atom_value(TV_SHOW);
        if (value) {
            track->tvshow = g_strdup(value);
            free(value);
        }

        // MP4 TV Episode
        value = find_atom_value(TV_EPISODE);
        if (value) {
            track->tvepisode = g_strdup(value);
            free(value);
        }

        // MP4 TV Episode No.
        value = find_atom_value(TV_EPISODE_NO);
        if (value) {
            track->episode_nr = atoi(value);
            free(value);
        }

        // MP4 TV Network
        value = find_atom_value(TV_NETWORK_NAME);
        if (value) {
            track->tvnetwork = g_strdup(value);
            free(value);
        }

        // MP4 TV Season No.
        value = find_atom_value(TV_SEASON_NO);
        if (value) {
            track->season_nr = atoi(value);
            free(value);
        }

        // MP4 Media Type
        value = find_atom_value(MEDIA_TYPE);
        if (value) {
            stiks * stik = MatchStikString(value);
            if (stik)
            {
                track->mediatype = mediaTypeTagToMediaType(stik->stik_number);
            }
            // Should not free standard media types
        }

        // MP4 Compilation flag
        value = find_atom_value(COMPILATION);
        if (value) {
            track->compilation = !g_strcmp0("true", value);
            free(value);
        }

        // MP4 Category
        value = find_atom_value(CATEGORY);
        if (value) {
            track->category = g_strdup(value);
            free(value);
        }

        // MP4 Podcast URL
        value = find_atom_value(PODCAST_URL);
        if (value) {
            track->podcasturl = g_strdup(value);
            free(value);
        }

        value = find_atom_value(GAPLESS_FLAG);
        if (value) {
            track->gapless_track_flag = atoi(value);
            free(value);
        }

        // MP4 Sort Title
        value = find_atom_value(SORT_TITLE);
        if (value) {
            track->sort_title = g_strdup(value);
            free(value);
        }

        // MP4 Sort Artist
        value = find_atom_value(SORT_ARTIST);
        if (value) {
            track->sort_artist = g_strdup(value);
            free(value);
        }

        // MP4 Sort Album Artist
        value = find_atom_value(SORT_ALBUM_ARTIST);
        if (value) {
            track->sort_albumartist = g_strdup(value);
            free(value);
        }

        // MP4 Sort Composer
        value = find_atom_value(SORT_COMPOSER);
        if (value) {
            track->sort_composer = g_strdup(value);
            free(value);
        }

        // MP4 Sort Album
        value = find_atom_value(SORT_ALBUM);
        if (value) {
            track->sort_album = g_strdup(value);
            free(value);
        }

        // MP4 Sort TV Show
        value = find_atom_value(SORT_TV_SHOW);
        if (value) {
            track->sort_tvshow = g_strdup(value);
            free(value);
        }

        if (prefs_get_int("coverart_apic")) {
            gchar *tmp_file_prefix = g_build_filename(g_get_tmp_dir(), "ttt", NULL);
            gchar *tmp_file;

            AtomicInfo *info = find_atom("covr");
            if (info) {

                // Extract the data to a temporary file
                tmp_file = APar_ExtractAAC_Artwork(info->AtomicNumber, tmp_file_prefix, 1);
                g_free(tmp_file_prefix);

                if (tmp_file && g_file_test(tmp_file, G_FILE_TEST_EXISTS)) {

                    // Set the thumbnail using the tmp file
                    GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(tmp_file, NULL);
                    if (pixbuf) {
                        itdb_track_set_thumbnails_from_pixbuf(track, pixbuf);
                        g_object_unref(pixbuf);
                    }

                    g_remove(tmp_file);
                }

                if (tmp_file)
                    g_free(tmp_file);
            }
        }
    }

    APar_FreeMemory();

}
Ejemplo n.º 16
0
static void *
draw_thread_func(void * UNUSED (arg))
{
	Bool configured = FALSE;

	window_w = prefs_get_int(ap_prefs, "opengl_spectrum", "width", DEFAULT_W);
	window_h = prefs_get_int(ap_prefs, "opengl_spectrum", "height", DEFAULT_H);

	if ((window = create_window(window_w, window_h)) == 0)
	{
		alsaplayer_error("unable to create window");
		pthread_exit(NULL);
	}

	XMapWindow(dpy, window);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glFrustum(-1, 1, -1, 1, 1.5, 10);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LESS);

	while(going)
	{
		while(XPending(dpy))
		{
			XEvent event;
			KeySym keysym;
			char buf[16];

			XNextEvent(dpy, &event);
			switch(event.type)
			{
			case ConfigureNotify:
				glViewport(0,0,event.xconfigure.width, event.xconfigure.height);
				window_w = event.xconfigure.width;
				window_h = event.xconfigure.height;
				prefs_set_int(ap_prefs, "opengl_spectrum", "width", window_w);
				prefs_set_int(ap_prefs, "opengl_spectrum", "height", window_h);
				configured = TRUE;
				break;
			case KeyPress:


				XLookupString (&event.xkey, buf, 16, &keysym, NULL);
				switch(keysym)
				{
				case XK_Escape:

					going = FALSE;
					break;
				case XK_z:
					/*xmms_remote_playlist_prev(oglspectrum_vp.xmms_session); */
					break;
				case XK_x:
					/*xmms_remote_play(oglspectrum_vp.xmms_session); */
					break;
				case XK_c:
					/*xmms_remote_pause(oglspectrum_vp.xmms_session); */
					break;
				case XK_v:
					/*xmms_remote_stop(oglspectrum_vp.xmms_session); */
					break;
				case XK_b:
					/* xmms_remote_playlist_next(oglspectrum_vp.xmms_session); */
					break;
				case XK_Up:
					x_speed -= 0.1;
					if(x_speed < -3.0)
						x_speed = -3.0;
					break;
				case XK_Down:
					x_speed += 0.1;
					if(x_speed > 3.0)
						x_speed = 3.0;
					break;
				case XK_Left:
					y_speed -= 0.1;
					if(y_speed < -3.0)
						y_speed = -3.0;

					break;
				case XK_Right:
					y_speed += 0.1;
					if(y_speed > 3.0)
						y_speed = 3.0;
					break;
				case XK_w:
					z_speed -= 0.1;
					if(z_speed < -3.0)
						z_speed = -3.0;
					break;
				case XK_q:
					z_speed += 0.1;
					if(z_speed > 3.0)
						z_speed = 3.0;
					break;
				case XK_Return:
					x_speed = 0.0;
					y_speed = 0.5;
					z_speed = 0.0;
					x_angle = 20.0;
					y_angle = 45.0;
					z_angle = 0.0;
					break;
				}

				break;
			case ClientMessage:
				if ((Atom)event.xclient.data.l[0] == wm_delete_window_atom)
				{
					going = FALSE;
				}
				break;
			}
		}
		if(configured)
		{
			x_angle += x_speed;
			if(x_angle >= 360.0)
				x_angle -= 360.0;

			y_angle += y_speed;
			if(y_angle >= 360.0)
				y_angle -= 360.0;

			z_angle += z_speed;
			if(z_angle >= 360.0)
				z_angle -= 360.0;

			draw_bars();
		}
	}

	if (glxcontext)
	{
		glXMakeCurrent(dpy, 0, NULL);
		glXDestroyContext(dpy, glxcontext);
		glxcontext = NULL;
	}
	if (window)
	{
		if (grabbed_pointer)
		{
			XUngrabPointer(dpy, CurrentTime);
			grabbed_pointer = FALSE;
		}

		XDestroyWindow(dpy, window);
		window = 0;
	}
	pthread_mutex_unlock(&scope_mutex);
	stop_display(0); /* Close down display */
	pthread_exit(NULL);
}