summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--callbacks.c4
-rw-r--r--palsa.c60
-rw-r--r--playlist.c5
-rw-r--r--streamer.c6
-rw-r--r--streamer.h2
5 files changed, 64 insertions, 13 deletions
diff --git a/callbacks.c b/callbacks.c
index 3418280a..78a7b9c1 100644
--- a/callbacks.c
+++ b/callbacks.c
@@ -93,7 +93,7 @@ on_playlist_realize (GtkWidget *widget,
// setup drag-drop target
gtk_drag_dest_set (widget, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP, &entry, 1, GDK_ACTION_COPY | GDK_ACTION_MOVE);
gtk_drag_dest_add_uri_targets (widget);
- gtk_drag_dest_set_track_motion (widget, TRUE);
+// gtk_drag_dest_set_track_motion (widget, TRUE);
}
@@ -452,7 +452,7 @@ on_playlist_drag_failed (GtkWidget *widget,
GtkDragResult arg2,
gpointer user_data)
{
- return FALSE;
+ return TRUE;
}
diff --git a/palsa.c b/palsa.c
index 7ab6b4e8..978bdaaa 100644
--- a/palsa.c
+++ b/palsa.c
@@ -24,6 +24,8 @@ static int bufsize = 4096*4;
static float volume = 1;
static int alsa_terminate = 0;
static int alsa_rate = 48000;
+static int state = 0; // 0 = stopped, 1 = playing, 2 = pause
+static uintptr_t mutex;
static void
palsa_callback (char *stream, int len);
@@ -36,6 +38,7 @@ palsa_init (void) {
int err;
snd_pcm_hw_params_t *hw_params;
snd_pcm_sw_params_t *sw_params;
+ state = 0;
if ((err = snd_pcm_open (&audio, "default", SND_PCM_STREAM_PLAYBACK, 0))) {
fprintf (stderr, "could not open audio device (%s)\n",
@@ -134,8 +137,10 @@ palsa_init (void) {
printf ("AUDIO: Unable to allocate memory for sample buffers.\n");
goto open_error;
}
+ snd_pcm_pause (audio, 1); // put into STOPPED state
alsa_terminate = 0;
+ mutex = mutex_create ();
thread_start (palsa_thread, 0);
return 0;
@@ -152,44 +157,70 @@ open_error:
void
palsa_free (void) {
if (audio) {
+ mutex_lock (mutex);
alsa_terminate = 1;
- usleep (1000);
snd_pcm_close(audio);
audio = NULL;
if (samplebuffer) {
free (samplebuffer);
samplebuffer = NULL;
}
+ mutex_unlock (mutex);
+ mutex_free (mutex);
}
}
int
palsa_play (void) {
// start updating thread
+ int err;
+ if (state == 0) {
+#if 0
+ if ((err = snd_pcm_drop (audio)) < 0) {
+ fprintf (stderr, "cannot drop audio interface(%s)\n",
+ snd_strerror (err));
+ }
+#endif
+ if ((err = snd_pcm_prepare (audio)) < 0) {
+ fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
+ snd_strerror (err));
+ }
+ streamer_reset (1);
+ }
+ if (state != 1) {
+ state = 1;
+ snd_pcm_pause (audio, 0);
+ }
return 0;
}
int
palsa_stop (void) {
// set stop state
+ state = 0;
+ snd_pcm_pause (audio, 1);
return 0;
}
int
palsa_ispaused (void) {
// return pause state
- return 0;
+ return (state == 2);
}
int
palsa_pause (void) {
// set pause state
+ state = 2;
+ snd_pcm_pause (audio, 1);
return 0;
}
int
palsa_unpause (void) {
// unset pause state
+ state = 1;
+ snd_pcm_pause (audio, 0);
return 0;
}
@@ -206,14 +237,24 @@ palsa_get_rate (void) {
static void
palsa_thread (uintptr_t context) {
int err;
- while (!alsa_terminate) {
+ for (;;) {
+ mutex_lock (mutex);
+ if (alsa_terminate) {
+ mutex_unlock (mutex);
+ break;
+ }
/* wait till the interface is ready for data, or 1 second
has elapsed.
*/
+// if (state != 1) {
+// usleep (1000);
+// continue;
+// }
if ((err = snd_pcm_wait (audio, 1000)) < 0) {
- fprintf (stderr, "poll failed (%s)\n", strerror (errno));
- break;
+ mutex_unlock (mutex);
+ fprintf (stderr, "alsa poll failed (%s)\n", strerror (errno));
+ continue;
}
/* find out how much space is available for playback data */
@@ -221,12 +262,14 @@ palsa_thread (uintptr_t context) {
snd_pcm_sframes_t frames_to_deliver;
if ((frames_to_deliver = snd_pcm_avail_update (audio)) < 0) {
if (frames_to_deliver == -EPIPE) {
+ mutex_unlock (mutex);
fprintf (stderr, "an xrun occured\n");
- break;
+ continue;
} else {
+ mutex_unlock (mutex);
fprintf (stderr, "unknown ALSA avail update return value (%d)\n",
frames_to_deliver);
- break;
+ continue;
}
}
@@ -238,8 +281,9 @@ palsa_thread (uintptr_t context) {
if ((err = snd_pcm_writei (audio, buf, frames_to_deliver)) < 0) {
fprintf (stderr, "write failed (%s)\n", snd_strerror (err));
}
+ mutex_unlock (mutex);
+ usleep (0); // let other threads gain some spin (avoid deadlock)
}
- alsa_terminate = 0;
}
static void
diff --git a/playlist.c b/playlist.c
index 5f55f807..830ab003 100644
--- a/playlist.c
+++ b/playlist.c
@@ -676,6 +676,8 @@ ps_set_current (playItem_t *it) {
int ret = 0;
int from = ps_get_idx_of (playlist_current_ptr);
int to = ps_get_idx_of (it);
+#if 0
+ // this produces some kind of bug in the beginning of track
if (it == playlist_current_ptr) {
if (it && it->codec) {
codec_lock ();
@@ -684,6 +686,7 @@ ps_set_current (playItem_t *it) {
}
return ret;
}
+#endif
codec_lock ();
if (playlist_current_ptr && playlist_current_ptr->codec) {
playlist_current_ptr->codec->free ();
@@ -701,7 +704,7 @@ ps_set_current (playItem_t *it) {
}
}
if (playlist_current_ptr) {
- streamer_reset ();
+ streamer_reset (0);
}
codec_unlock ();
messagepump_push (M_SONGCHANGED, 0, from, to);
diff --git a/streamer.c b/streamer.c
index b31e2803..4df07e91 100644
--- a/streamer.c
+++ b/streamer.c
@@ -50,6 +50,7 @@ streamer_thread (uintptr_t ctx) {
usleep (3000);
}
}
+ p_play ();
}
streamer_lock ();
if (streambuffer_fill < STREAM_BUFFER_SIZE) {
@@ -93,8 +94,11 @@ streamer_free (void) {
}
void
-streamer_reset (void) { // must be called when current song changes by external reasons
+streamer_reset (int full) { // must be called when current song changes by external reasons
codecleft = 0;
+ if (full) {
+ streambuffer_fill = 0;
+ }
src_reset (src);
}
diff --git a/streamer.h b/streamer.h
index ac32963d..2607c292 100644
--- a/streamer.h
+++ b/streamer.h
@@ -11,7 +11,7 @@ int
streamer_read (char *bytes, int size);
void
-streamer_reset (void);
+streamer_reset (int full);
void
streamer_lock (void);