summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-01-26 21:21:26 +0100
committerGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-01-26 21:21:26 +0100
commit7262368b6897b41188f0cf6844ca875027d425a4 (patch)
treed1c1050014f7f2ac0c7238f03d27b17873a3f003 /plugins
parent90877724d03c71111c2b47fd6ea6eb3ebce88dd4 (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.c49
-rw-r--r--plugins/gtkui/callbacks.c10
-rw-r--r--plugins/gtkui/callbacks.h4
-rw-r--r--plugins/gtkui/deadbeef.glade8
-rw-r--r--plugins/gtkui/interface.c16
-rw-r--r--plugins/oss/oss.c3
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);