summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmp3.c5
-rw-r--r--main.c13
-rw-r--r--playlist.c3
-rw-r--r--psdl.c6
-rw-r--r--streamer.c94
-rw-r--r--streamer.h6
6 files changed, 103 insertions, 24 deletions
diff --git a/cmp3.c b/cmp3.c
index c9a5fd07..d5488fbd 100644
--- a/cmp3.c
+++ b/cmp3.c
@@ -62,6 +62,7 @@ cmp3_init (const char *fname, int track, float start, float end) {
if (cmp3_get_stream_info2 () == -1) {
return -1;
}
+// printf ("song %s samplerate %d\n", fname, cmp3.info.samplesPerSecond);
fseek (buffer.file, 0, SEEK_SET);
// cmp3_decode (); // this 1st run will read 1st frame, but will not decode anything except header
@@ -158,7 +159,6 @@ cmp3_get_stream_info2 (void) {
// layer info
int layer = (hdr & (3<<17)) >> 17;
-// printf ("layer = %xh\n", layer);
// bitrate
int brtable[16] = { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1 };
@@ -180,7 +180,8 @@ cmp3_get_stream_info2 (void) {
int nchannels = (hdr & (0x3 << 6)) >> 6;
nchannels = chantbl[nchannels];
- if (nframe == 0) {
+ if (nframe == 0 || cmp3.info.samplesPerSecond == -1)
+ {
cmp3.info.bitsPerSample = 16;
cmp3.info.channels = nchannels;
cmp3.info.samplesPerSecond = samplerate;
diff --git a/main.c b/main.c
index 1508f5f1..f9ac91fb 100644
--- a/main.c
+++ b/main.c
@@ -11,6 +11,7 @@
#include "messages.h"
#include "gtkplaylist.h"
#include "codec.h"
+#include "streamer.h"
GtkWidget *mainwin;
@@ -18,8 +19,6 @@ int psdl_terminate = 0;
void
psdl_thread (uintptr_t ctx) {
- codec_init_locking ();
- psdl_init ();
psdl_play ();
while (!psdl_terminate) {
uint32_t msg;
@@ -84,14 +83,14 @@ psdl_thread (uintptr_t ctx) {
gtkps_update_songinfo ();
// handle message pump here
}
- psdl_free ();
- codec_free_locking ();
- ps_free ();
}
int
main (int argc, char *argv[]) {
messagepump_init ();
+ codec_init_locking ();
+ streamer_init ();
+ psdl_init ();
thread_start (psdl_thread, 0);
g_thread_init (NULL);
@@ -111,5 +110,9 @@ main (int argc, char *argv[]) {
gdk_threads_leave ();
messagepump_free ();
psdl_terminate = 1;
+ psdl_free ();
+ streamer_free ();
+ codec_free_locking ();
+ ps_free ();
return 0;
}
diff --git a/playlist.c b/playlist.c
index 29cc0089..1a3bf62c 100644
--- a/playlist.c
+++ b/playlist.c
@@ -404,7 +404,7 @@ ps_item_free (playItem_t *it) {
void
ps_set_current (playItem_t *it) {
if (it) {
- printf ("ps_set_current (%s)\n", it->displayname);
+// printf ("ps_set_current (%s)\n", it->displayname);
}
if (it == playlist_current_ptr) {
if (it && it->codec) {
@@ -429,7 +429,6 @@ ps_set_current (playItem_t *it) {
}
if (playlist_current_ptr) {
streamer_reset ();
- printf ("streamer_reset\n");
}
codec_unlock ();
}
diff --git a/psdl.c b/psdl.c
index 50352cd1..31ed3c3d 100644
--- a/psdl.c
+++ b/psdl.c
@@ -12,13 +12,10 @@ int
psdl_init (void) {
SDL_AudioSpec obt;
int formats[] = { AUDIO_S16, -1 };
- int freqs[] = { 22050, 48000, 44100, -1 };
+ int freqs[] = { 44100, 48000, -1 };
const char *fmtnames[] = { "16 bit signed integer" };
int fmt, frq;
int success = 0;
- if (streamer_init () < 0) {
- return -1;
- }
fprintf (stderr, "sdl_player_init\n");
for (fmt = 0; formats[fmt] != -1; fmt++) {
for (frq = 0; freqs[frq] != -1; frq++) {
@@ -50,7 +47,6 @@ psdl_init (void) {
void
psdl_free (void) {
SDL_CloseAudio ();
- streamer_free ();
}
int
diff --git a/streamer.c b/streamer.c
index 9f0f5978..7619e503 100644
--- a/streamer.c
+++ b/streamer.c
@@ -2,10 +2,13 @@
#include <string.h>
#include <stdio.h>
#include <assert.h>
+#include <unistd.h>
#include <samplerate.h>
+#include "threading.h"
#include "codec.h"
#include "playlist.h"
#include "common.h"
+#include "streamer.h"
extern int sdl_player_freq; // hack!
static SRC_STATE *src;
@@ -14,24 +17,60 @@ static int codecleft;
static char g_readbuffer[200000]; // hack!
static float g_fbuffer[200000]; // hack!
static float g_srcbuffer[200000]; // hack!
+static int streaming_terminate;
+
+#define STREAM_BUFFER_SIZE 200000
+static int streambuffer_fill;
+static char streambuffer[STREAM_BUFFER_SIZE+1000];
+static uintptr_t mutex;
+
+static int
+streamer_read_async (char *bytes, int size);
+
+void
+streamer_thread (uintptr_t ctx) {
+ codecleft = 0;
+
+ while (!streaming_terminate) {
+ streamer_lock ();
+ if (streambuffer_fill < STREAM_BUFFER_SIZE) {
+ int sz = STREAM_BUFFER_SIZE - streambuffer_fill;
+ int minsize = 500;
+ if (streambuffer_fill < 16384) {
+ minsize = 16384;
+ }
+ sz = min (minsize, sz);
+// printf ("reading %d\n", sz);
+ int bytesread = streamer_read_async (&streambuffer[streambuffer_fill], sz);
+ streambuffer_fill += bytesread;
+ }
+ streamer_unlock ();
+ usleep (3000);
+ //printf ("fill: %d \r", streambuffer_fill);
+ }
+
+ if (src) {
+ src_delete (src);
+ src = NULL;
+ }
+}
int
streamer_init (void) {
-//// src = src_new (SRC_LINEAR, 2, NULL);
- src = src_new (SRC_SINC_BEST_QUALITY, 2, NULL);
+ mutex = mutex_create ();
+// src = src_new (SRC_SINC_BEST_QUALITY, 2, NULL);
+ src = src_new (SRC_LINEAR, 2, NULL);
if (!src) {
return -1;
}
- codecleft = 0;
+ thread_start (streamer_thread, 0);
return 0;
}
void
streamer_free (void) {
- if (src) {
- src_delete (src);
- src = NULL;
- }
+ streaming_terminate = 1;
+ mutex_free (mutex);
}
void
@@ -41,8 +80,8 @@ streamer_reset (void) { // must be called when current song changes by external
}
// returns number of bytes been read
-int
-streamer_read (char *bytes, int size) {
+static int
+streamer_read_async (char *bytes, int size) {
int initsize = size;
for (;;) {
int bytesread = 0;
@@ -76,10 +115,19 @@ streamer_read (char *bytes, int size) {
int nsamples = size/4;
// convert to codec samplerate
nsamples = nsamples * samplerate / sdl_player_freq * 2;
+ if (!src_is_valid_ratio ((double)sdl_player_freq/samplerate)) {
+ printf ("invalid ratio! %d / %d = %f", sdl_player_freq, samplerate, (float)sdl_player_freq/samplerate);
+ }
assert (src_is_valid_ratio ((double)sdl_player_freq/samplerate));
// read data at source samplerate (with some room for SRC)
int nbytes = (nsamples - codecleft) * 2 * nchannels;
- bytesread = codec->read (g_readbuffer, nbytes);
+ if (nbytes < 0) {
+ nbytes = 0;
+ }
+ else {
+ //printf ("reading %d bytes from mp3\n", nbytes);
+ bytesread = codec->read (g_readbuffer, nbytes);
+ }
codec_unlock ();
// recalculate nsamples according to how many bytes we've got
nsamples = bytesread / (2 * nchannels) + codecleft;
@@ -141,3 +189,29 @@ streamer_read (char *bytes, int size) {
}
return initsize - size;
}
+
+void
+streamer_lock (void) {
+ mutex_lock (mutex);
+}
+
+void
+streamer_unlock (void) {
+ mutex_unlock (mutex);
+}
+
+int
+streamer_read (char *bytes, int size) {
+ streamer_lock ();
+ int sz = min (size, streambuffer_fill);
+ if (sz) {
+ memcpy (bytes, streambuffer, sz);
+ if (sz < streambuffer_fill) {
+ // shift buffer
+ memmove (streambuffer, &streambuffer[sz], streambuffer_fill-sz);
+ }
+ streambuffer_fill -= sz;
+ }
+ streamer_unlock ();
+ return sz;
+}
diff --git a/streamer.h b/streamer.h
index c3cb33d4..eba4fd82 100644
--- a/streamer.h
+++ b/streamer.h
@@ -13,4 +13,10 @@ streamer_read (char *bytes, int size);
void
streamer_reset (void);
+void
+streamer_lock (void);
+
+void
+streamer_unlock (void);
+
#endif // __STREAMER_H