diff options
author | Alexey Yakovenko <wakeroid@gmail.com> | 2010-01-26 21:21:26 +0100 |
---|---|---|
committer | Alexey Yakovenko <wakeroid@gmail.com> | 2010-01-26 21:21:26 +0100 |
commit | 7262368b6897b41188f0cf6844ca875027d425a4 (patch) | |
tree | d1c1050014f7f2ac0c7238f03d27b17873a3f003 /plugins | |
parent | 90877724d03c71111c2b47fd6ea6eb3ebce88dd4 (diff) |
fixed samplerate switching bugs in streamer
better sound configuration
multiple fixes to ALSA and streamer
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/alsa/alsa.c | 49 | ||||
-rw-r--r-- | plugins/gtkui/callbacks.c | 10 | ||||
-rw-r--r-- | plugins/gtkui/callbacks.h | 4 | ||||
-rw-r--r-- | plugins/gtkui/deadbeef.glade | 8 | ||||
-rw-r--r-- | plugins/gtkui/interface.c | 16 | ||||
-rw-r--r-- | plugins/oss/oss.c | 3 |
6 files changed, 54 insertions, 36 deletions
diff --git a/plugins/alsa/alsa.c b/plugins/alsa/alsa.c index 157814ce..ca6b4e4d 100644 --- a/plugins/alsa/alsa.c +++ b/plugins/alsa/alsa.c @@ -34,6 +34,7 @@ DB_functions_t *deadbeef; static snd_pcm_t *audio; //static int bufsize = -1; static int alsa_terminate; +static int requested_rate = -1; static int alsa_rate = 44100; static int state; // one of output_state_t static uintptr_t mutex; @@ -232,6 +233,10 @@ palsa_init (void) { mutex = deadbeef->mutex_create (); + if (requested_rate != -1) { + alsa_rate = requested_rate; + } + if (palsa_set_hw_params (alsa_rate) < 0) { goto open_error; } @@ -308,26 +313,25 @@ open_error: int palsa_change_rate (int rate) { - return 0; + trace ("palsa_change_rate: %d\n", rate); + requested_rate = rate; if (!audio) { - return 0; + return alsa_rate; } if (rate == alsa_rate) { - trace ("palsa_change_rate: same rate (%d), ignored\n", rate); + trace ("palsa_change_rate: ignored\n", rate); return rate; } - trace ("trying to change samplerate to: %d\n", rate); - deadbeef->mutex_lock (mutex); + state = OUTPUT_STATE_STOPPED; snd_pcm_drop (audio); + deadbeef->mutex_lock (mutex); int ret = palsa_set_hw_params (rate); - if (state != OUTPUT_STATE_STOPPED) { - snd_pcm_start (audio); - } deadbeef->mutex_unlock (mutex); if (ret < 0) { - return -1; + trace ("palsa_change_rate: impossible to set samplerate to %d\n", rate); + return alsa_rate; } - trace ("chosen samplerate: %d Hz\n", alsa_rate); + trace ("chosen samplerate: %d\n", alsa_rate); return alsa_rate; } @@ -386,9 +390,8 @@ palsa_play (void) { } else { if ((err = snd_pcm_prepare (audio)) < 0) { - perror ("snd_pcm_prepare"); - trace ("cannot prepare audio interface for use (%s)\n", - snd_strerror (err)); + trace ("cannot prepare audio interface for use (%d, %s)\n", + err, snd_strerror (err)); return -1; } } @@ -499,23 +502,25 @@ palsa_thread (void *context) { deadbeef->mutex_lock (mutex); if ((err = snd_pcm_wait (audio, 1000)) < 0) { - perror ("snd_pcm_wait"); if (err == -ESTRPIPE) { - perror ("snd_pcm_writei"); - trace ("alsa: trying to recover from suspend...\n"); + trace ("alsa: trying to recover from suspend... (error=%d, %s)\n", err, snd_strerror (err)); deadbeef->sendmessage (M_REINIT_SOUND, 0, 0, 0); deadbeef->mutex_unlock (mutex); break; } - else { + else if (err == -EPIPE) { // this pretty frequent condition, no spam here - perror ("snd_pcm_wait"); -// trace ("alsa: trying to recover from xrun...\n"); +// trace ("alsa: snd_pcm_wait error=%d, %s\n", err, snd_strerror (err)); snd_pcm_prepare (audio); snd_pcm_start (audio); deadbeef->mutex_unlock (mutex); continue; } + else { + trace ("alsa: snd_pcm_wait error=%d, %s\n", err, snd_strerror (err)); + deadbeef->mutex_unlock (mutex); + continue; + } } /* find out how much space is available for playback data */ int written = 0; @@ -583,6 +588,7 @@ palsa_callback (char *stream, int len) { static int palsa_configchanged (DB_event_t *ev, uintptr_t data) { + trace ("alsa: config option changed, restarting\n"); int alsa_resample = deadbeef->conf_get_int ("alsa.resample", 0); const char *alsa_soundcard = deadbeef->conf_get_str ("alsa_soundcard", "default"); if (alsa_resample != conf_alsa_resample @@ -644,6 +650,10 @@ alsa_load (DB_functions_t *api) { return DB_PLUGIN (&plugin); } +static const char settings_dlg[] = + "property \"Enable software resampling\" checkbox alsa.resample 0;\n" +; + // define plugin interface static DB_output_t plugin = { DB_PLUGIN_SET_API_VERSION @@ -658,6 +668,7 @@ static DB_output_t plugin = { .plugin.website = "http://deadbeef.sf.net", .plugin.start = alsa_start, .plugin.stop = alsa_stop, + .plugin.configdialog = settings_dlg, .init = palsa_init, .free = palsa_free, .change_rate = palsa_change_rate, diff --git a/plugins/gtkui/callbacks.c b/plugins/gtkui/callbacks.c index 603c5267..108d0f29 100644 --- a/plugins/gtkui/callbacks.c +++ b/plugins/gtkui/callbacks.c @@ -1562,7 +1562,7 @@ on_preferences_activate (GtkMenuItem *menuitem, // alsa resampling - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (w, "pref_alsa_resampling")), deadbeef->conf_get_int ("alsa.resample", 0)); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (w, "pref_dynsamplerate")), deadbeef->conf_get_int ("playback.dynsamplerate", 0)); // alsa freeonstop gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (w, "pref_alsa_freewhenstopped")), deadbeef->conf_get_int ("alsa.freeonstop", 0)); @@ -1691,11 +1691,11 @@ on_pref_output_plugin_changed (GtkComboBox *combobox, } void -on_pref_alsa_resampling_clicked (GtkButton *button, +on_pref_dynsamplerate_clicked (GtkButton *button, gpointer user_data) { int active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); - deadbeef->conf_set_int ("alsa.resample", active); + deadbeef->conf_set_int ("playback.dynsamplerate", active); deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0); } @@ -2035,6 +2035,7 @@ on_prop_entry_changed(GtkEditable *editable, gpointer user_data) { const char *key = g_object_get_data (G_OBJECT (editable), "key"); if (key) { deadbeef->conf_set_str (key, gtk_entry_get_text (GTK_ENTRY (editable))); + deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0); } } @@ -2043,6 +2044,7 @@ on_prop_checkbox_clicked (GtkButton *button, gpointer user_data) { const char *key = g_object_get_data (G_OBJECT (button), "key"); if (key) { deadbeef->conf_set_int (key, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))); + deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0); } } @@ -2059,6 +2061,7 @@ on_prop_browse_file (GtkButton *button, gpointer user_data) { if (folder) { deadbeef->conf_set_str ("filechooser.lastdir", folder); g_free (folder); + deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0); } if (response == GTK_RESPONSE_OK) { gchar *file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dlg)); @@ -2451,3 +2454,4 @@ on_trackproperties_delete_event (GtkWidget *widget, } + diff --git a/plugins/gtkui/callbacks.h b/plugins/gtkui/callbacks.h index cee7b241..c30fc05d 100644 --- a/plugins/gtkui/callbacks.h +++ b/plugins/gtkui/callbacks.h @@ -803,3 +803,7 @@ on_gpl1_activate (GtkMenuItem *menuitem, void on_lgpl1_activate (GtkMenuItem *menuitem, gpointer user_data); + +void +on_pref_dynsamplerate_clicked (GtkButton *button, + gpointer user_data); diff --git a/plugins/gtkui/deadbeef.glade b/plugins/gtkui/deadbeef.glade index 022a1515..e8d8de9d 100644 --- a/plugins/gtkui/deadbeef.glade +++ b/plugins/gtkui/deadbeef.glade @@ -1591,7 +1591,7 @@ <child> <widget class="GtkLabel" id="label5"> <property name="visible">True</property> - <property name="label" translatable="yes">Software ALSA resampling</property> + <property name="label" translatable="yes">Allow dynamic samplerate switching</property> <property name="use_underline">False</property> <property name="use_markup">False</property> <property name="justify">GTK_JUSTIFY_LEFT</property> @@ -1689,17 +1689,17 @@ </child> <child> - <widget class="GtkCheckButton" id="pref_alsa_resampling"> + <widget class="GtkCheckButton" id="pref_dynsamplerate"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="label" translatable="yes"></property> + <property name="label" translatable="yes">(WARNING: turning this on this might break gapless playback)</property> <property name="use_underline">True</property> <property name="relief">GTK_RELIEF_NORMAL</property> <property name="focus_on_click">True</property> <property name="active">False</property> <property name="inconsistent">False</property> <property name="draw_indicator">True</property> - <signal name="clicked" handler="on_pref_alsa_resampling_clicked" last_modification_time="Sat, 24 Oct 2009 16:50:34 GMT"/> + <signal name="clicked" handler="on_pref_dynsamplerate_clicked" last_modification_time="Tue, 26 Jan 2010 19:46:12 GMT"/> </widget> <packing> <property name="left_attach">1</property> diff --git a/plugins/gtkui/interface.c b/plugins/gtkui/interface.c index ca824c85..9b7c6161 100644 --- a/plugins/gtkui/interface.c +++ b/plugins/gtkui/interface.c @@ -1271,7 +1271,7 @@ create_prefwin (void) GtkWidget *label4; GtkWidget *label23; GtkWidget *pref_soundcard; - GtkWidget *pref_alsa_resampling; + GtkWidget *pref_dynsamplerate; GtkWidget *pref_replaygain_scale; GtkWidget *pref_alsa_freewhenstopped; GtkWidget *pref_src_quality; @@ -1353,7 +1353,7 @@ create_prefwin (void) (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment (GTK_MISC (label6), 0, 0.5); - label5 = gtk_label_new ("Software ALSA resampling"); + label5 = gtk_label_new ("Allow dynamic samplerate switching"); gtk_widget_show (label5); gtk_table_attach (GTK_TABLE (table3), label5, 0, 1, 2, 3, (GtkAttachOptions) (GTK_FILL), @@ -1380,9 +1380,9 @@ create_prefwin (void) (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0); - pref_alsa_resampling = gtk_check_button_new_with_mnemonic (""); - gtk_widget_show (pref_alsa_resampling); - gtk_table_attach (GTK_TABLE (table3), pref_alsa_resampling, 1, 2, 2, 3, + pref_dynsamplerate = gtk_check_button_new_with_mnemonic ("(WARNING: turning this on this might break gapless playback)"); + gtk_widget_show (pref_dynsamplerate); + gtk_table_attach (GTK_TABLE (table3), pref_dynsamplerate, 1, 2, 2, 3, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0), 0, 0); @@ -1624,8 +1624,8 @@ create_prefwin (void) g_signal_connect ((gpointer) pref_soundcard, "changed", G_CALLBACK (on_pref_soundcard_changed), NULL); - g_signal_connect ((gpointer) pref_alsa_resampling, "clicked", - G_CALLBACK (on_pref_alsa_resampling_clicked), + g_signal_connect ((gpointer) pref_dynsamplerate, "clicked", + G_CALLBACK (on_pref_dynsamplerate_clicked), NULL); g_signal_connect ((gpointer) pref_replaygain_scale, "clicked", G_CALLBACK (on_pref_replaygain_scale_clicked), @@ -1676,7 +1676,7 @@ create_prefwin (void) GLADE_HOOKUP_OBJECT (prefwin, label4, "label4"); GLADE_HOOKUP_OBJECT (prefwin, label23, "label23"); GLADE_HOOKUP_OBJECT (prefwin, pref_soundcard, "pref_soundcard"); - GLADE_HOOKUP_OBJECT (prefwin, pref_alsa_resampling, "pref_alsa_resampling"); + GLADE_HOOKUP_OBJECT (prefwin, pref_dynsamplerate, "pref_dynsamplerate"); GLADE_HOOKUP_OBJECT (prefwin, pref_replaygain_scale, "pref_replaygain_scale"); GLADE_HOOKUP_OBJECT (prefwin, pref_alsa_freewhenstopped, "pref_alsa_freewhenstopped"); GLADE_HOOKUP_OBJECT (prefwin, pref_src_quality, "pref_src_quality"); diff --git a/plugins/oss/oss.c b/plugins/oss/oss.c index 13fd8ec7..a7d716da 100644 --- a/plugins/oss/oss.c +++ b/plugins/oss/oss.c @@ -130,11 +130,10 @@ oss_init (void) { static int oss_change_rate (int rate) { if (!fd) { - oss_rate = rate; return oss_rate; } if (rate == oss_rate) { - trace ("oss_change_rate: same rate (%d), ignored\n", rate); + trace ("oss_change_rate: ignored\n", rate); return rate; } deadbeef->mutex_lock (mutex); |