diff options
Diffstat (limited to 'components/music/esd-audio.c')
-rw-r--r-- | components/music/esd-audio.c | 444 |
1 files changed, 0 insertions, 444 deletions
diff --git a/components/music/esd-audio.c b/components/music/esd-audio.c deleted file mode 100644 index 7ab6e6fc4..000000000 --- a/components/music/esd-audio.c +++ /dev/null @@ -1,444 +0,0 @@ - -#include <config.h> -#include "esd-audio.h" - -#include <glib/gmem.h> -#include <glib/gstrfuncs.h> -#include <pthread.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -static gint fd = 0; -static gpointer buffer; -static gboolean going = FALSE, prebuffer, paused = FALSE, remove_prebuffer = FALSE; -static gint buffer_size, prebuffer_size, blk_size = 4096; -static gint rd_index = 0, wr_index = 0; -static gint output_time_offset = 0; -static guint64 written = 0, output_bytes = 0; -static gint bps, ebps; -static gint flush; -static gint channels, frequency, latency; -static AFormat format; -static esd_format_t esd_format; -static gint input_bps, input_format, input_frequency, input_channels; -static gchar *hostname; -static pthread_t buffer_thread; -static void *(*esd_translate)(void *, gint); - - -ESDConfig esd_cfg; -esd_info_t *all_info; -esd_player_info_t *player_info; - -static void -esdout_init (void) -{ - memset (&esd_cfg, 0, sizeof (ESDConfig)); - esd_cfg.port = ESD_DEFAULT_PORT; - esd_cfg.buffer_size = 3000; - esd_cfg.prebuffer = 25; -} - -static gint -get_latency(void) -{ - int fd, amount = 0; - -#ifndef HAVE_ESD_GET_LATENCY - esd_server_info_t *info; -#endif - - fd = esd_open_sound (hostname); - if (fd == -1) { - return 0; - } - -#ifdef HAVE_ESD_GET_LATENCY - amount = esd_get_latency(fd); -#else - info = esd_get_server_info(fd); - if (info) { - if (info->format & ESD_STEREO) { - if (info->format & ESD_BITS16) - amount = (44100 * (ESD_BUF_SIZE + 64)) / info->rate; - else - amount = (44100 * (ESD_BUF_SIZE + 128)) / info->rate; - } else { - if (info->format & ESD_BITS16) - amount = (2 * 44100 * (ESD_BUF_SIZE + 128)) / info->rate; - else - amount = (2 * 44100 * (ESD_BUF_SIZE + 256)) / info->rate; - } - free(info); - } - amount += ESD_BUF_SIZE * 2; -#endif - esd_close (fd); - return amount; -} - -static void * -esd_stou8(void *data, gint length) -{ - int len = length; - unsigned char *dat = (unsigned char *)data; - while (len-- > 0) - *dat++ ^= 0x80; - return data; -} - -static void *esd_utos16sw(void *data, gint length) -{ - int len = length; - short *dat = data; - while ( len > 0 ) { - *dat = GUINT16_SWAP_LE_BE( *dat ) ^ 0x8000; - dat++; - len-=2; - } - return data; -} - -static void *esd_utos16(void *data, gint length) -{ - int len = length; - short *dat = data; - while ( len > 0 ) { - *dat ^= 0x8000; - dat++; - len-=2; - } - return data; -} - -static void *esd_16sw(void *data, gint length) -{ - int len = length; - short *dat = data; - while ( len > 0 ) { - *dat = GUINT16_SWAP_LE_BE( *dat ); - dat++; - len-=2; - } - return data; -} - -static void -esdout_setup_format (AFormat fmt, gint rate, gint nch) -{ - gboolean swap_sign = FALSE; - gboolean swap_16 = FALSE; - - format = fmt; - frequency = rate; - channels = nch; - switch (fmt) - { - case FMT_S8: - swap_sign = TRUE; - case FMT_U8: - esd_format = ESD_BITS8; - break; - case FMT_U16_LE: - case FMT_U16_BE: - case FMT_U16_NE: - swap_sign = TRUE; - case FMT_S16_LE: - case FMT_S16_BE: - case FMT_S16_NE: - esd_format = ESD_BITS16; - break; - } - -#ifdef WORDS_BIGENDIAN - if (fmt == FMT_U16_LE || fmt == FMT_S16_LE) -#else - if (fmt == FMT_U16_BE || fmt == FMT_S16_BE) -#endif - swap_16 = TRUE; - - esd_translate = (void*(*)())NULL; - if (esd_format == ESD_BITS8) { - if (swap_sign == TRUE) - esd_translate = esd_stou8; - } else { - if (swap_sign == TRUE) { - if (swap_16 == TRUE) - esd_translate = esd_utos16sw; - else - esd_translate = esd_utos16; - } else { - if (swap_16 == TRUE) - esd_translate = esd_16sw; - } - } - - bps = rate * nch; - if (esd_format == ESD_BITS16) - bps *= 2; - if(nch == 1) - esd_format |= ESD_MONO; - else - esd_format |= ESD_STEREO; - esd_format |= ESD_STREAM | ESD_PLAY; - - latency = ((get_latency() * frequency) / 44100) * channels; - if (format != FMT_U8 && format != FMT_S8) - latency *= 2; -} - - -gint -esdout_get_written_time (void) -{ - if (!going) - return 0; - return (gint) ((written * 1000) / input_bps); -} - -gint -esdout_get_output_time (void) -{ - guint64 bytes; - - if (!fd || !going) { - return 0; - } - - bytes = output_bytes; - if (!paused) { - bytes -= (bytes < (guint64)latency ? bytes : (guint64)latency); - } - - return output_time_offset + (gint) ((bytes * 1000) / ebps); -} - -/* Returns the number of bytes in our buffer still to be sent to esd. */ -gint -esdout_used (void) -{ - if (wr_index >= rd_index) { - return wr_index - rd_index; - } - return buffer_size - (rd_index - wr_index); -} - -/* Returns TRUE if we can play a track, i.e. we can connect to esd. */ -int -esdout_can_play (void) -{ - int fd; - - fd = esd_open_sound (hostname); - if (fd == -1) { - return FALSE; - } - esd_close (fd); - - return TRUE; -} - -/* Returns TRUE if we are playing a track, i.e. the thread is still streaming - data to esd. */ -int -esdout_playing (void) -{ - /* If our thread is not streaming data to esd, return FALSE. */ - if (!going) - return FALSE; - - /* If we've run out of data to send, we assume the track is done. */ - if (esdout_used () == 0) - return FALSE; - - return TRUE; -} - -gint -esdout_free (void) -{ - if (remove_prebuffer && prebuffer) { - prebuffer = FALSE; - remove_prebuffer = FALSE; - } - - if (prebuffer) { - remove_prebuffer = TRUE; - } - - if (rd_index > wr_index) { - return (rd_index - wr_index) - 1; - } - - return (buffer_size - (wr_index - rd_index)) - 1; -} - -static void -esdout_write_audio (gpointer data, gint length) -{ - AFormat new_format; - gint new_frequency,new_channels; - - new_format = input_format; - new_frequency = input_frequency; - new_channels = input_channels; - - if (new_format != format || new_frequency != frequency || new_channels != channels) { - output_time_offset += (gint) ((output_bytes * 1000) / ebps); - output_bytes = 0; - esdout_setup_format(new_format, new_frequency, new_channels); - frequency = new_frequency; - channels = new_channels; - close(fd); - esdout_set_audio_params(); - } - - if (esd_translate) { - output_bytes += write(fd,esd_translate(data,length),length); - } else { - output_bytes += write(fd,data,length); - } -} - - -void -esdout_write (gpointer ptr, gint length) -{ - gint cnt, off = 0; - - remove_prebuffer = FALSE; - - written += length; - while (length > 0) { - cnt = MIN(length, buffer_size - wr_index); - memcpy((gchar *)buffer + wr_index, (gchar *)ptr + off, cnt); - wr_index = (wr_index + cnt) % buffer_size; - length -= cnt; - off += cnt; - - } -} - -void -esdout_close (void) -{ - if (!going) { - return; - } - - wr_index = 0; - rd_index = 0; - going = 0; - g_free (hostname); - hostname = NULL; - pthread_join (buffer_thread, NULL); -} - -void -esdout_flush (gint time) -{ - flush = time; - while (flush != -1) { - usleep(10000); - } -} - -void -esdout_pause (gboolean p) -{ - paused = p; -} - -static void * -esdout_loop (void *arg) -{ - gint length, cnt; - - while (going) { - if (esdout_used () > prebuffer_size) { - prebuffer = FALSE; - } - - if (esdout_used () > 0 && !paused && !prebuffer) { - length = MIN (blk_size, esdout_used ()); - while (length > 0) { - cnt = MIN(length,buffer_size-rd_index); - esdout_write_audio ((gchar *)buffer + rd_index, cnt); - rd_index=(rd_index+cnt)%buffer_size; - length-=cnt; - } - } else { - usleep (10000); - } - - if (flush != -1) { - output_time_offset = flush; - written = (guint64)(flush / 10) * (guint64)(input_bps / 100); - rd_index = wr_index = output_bytes = 0; - flush = -1; - prebuffer = TRUE; - } - } - - close (fd); - g_free (buffer); - pthread_exit (NULL); - return NULL; /* make gcc happy */ -} - -void -esdout_set_audio_params(void) -{ - /* frequency = GUINT16_SWAP_LE_BE( frequency ); */ - fd = esd_play_stream (esd_format, frequency, hostname, "nautilus-music-view"); - ebps = frequency * channels; - if (format == FMT_U16_BE || format == FMT_U16_LE || format == FMT_S16_BE || format == FMT_S16_LE || format == FMT_S16_NE || format == FMT_U16_NE) - ebps *= 2; -} - -gint -esdout_open (AFormat fmt, gint rate, gint nch) -{ - esdout_init (); - - esdout_setup_format (fmt,rate,nch); - - input_format = format; - input_channels = channels; - input_frequency = frequency; - input_bps = bps; - - buffer_size = (esd_cfg.buffer_size * input_bps) / 1000; - if (buffer_size < 8192) - buffer_size = 8192; - prebuffer_size = (buffer_size * esd_cfg.prebuffer) / 100; - if (buffer_size - prebuffer_size < 4096) - prebuffer_size = buffer_size - 4096; - - buffer = g_malloc0(buffer_size); - - flush = -1; - prebuffer = 1; - wr_index = rd_index = output_time_offset = written = output_bytes = 0; - paused = FALSE; - remove_prebuffer = FALSE; - - if (hostname) - g_free (hostname); - if (esd_cfg.use_remote) - hostname = g_strdup_printf("%s:%d", esd_cfg.server, esd_cfg.port); - else - hostname = NULL; - - esdout_set_audio_params (); - if (fd == -1) { - g_free(buffer); - return 0; - } - going = 1; - - pthread_create (&buffer_thread, NULL, esdout_loop, NULL); - - return 1; -} |