[xiph-cvs] cvs commit: ices/src im_alsa.c im_alsa.h input.c registry.h Makefile.am

Michael Smith msmith at xiph.org
Sun Dec 29 02:28:30 PST 2002



msmith      02/12/29 05:28:30

  Modified:    .        configure.in
               src      input.c registry.h Makefile.am
  Added:       src      im_alsa.c im_alsa.h
  Log:
  ALSA input module from Jason Chu <jchu at uvic.ca>

Revision  Changes    Path
1.14      +12 -0     ices/configure.in

Index: configure.in
===================================================================
RCS file: /usr/local/cvsroot/ices/configure.in,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- configure.in	29 Oct 2001 15:55:08 -0000	1.13
+++ configure.in	29 Dec 2002 10:28:30 -0000	1.14
@@ -85,6 +85,16 @@
    SUN_CFLAGS="-DHAVE_SUN_AUDIO"
 fi
 
+dnl Check for ALSA audio
+
+AC_CHECK_HEADER(alsa/asoundlib.h, have_alsa=yes, have_alsa=no)
+AM_CONDITIONAL(HAVE_ALSA,test "$have_alsa" = yes)
+
+if test "$have_alsa" = yes; then
+   ALSA_CFLAGS="-DHAVE_ALSA"
+   ALSA_LIBS="-lasound"
+fi
+
 dnl Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
 
@@ -131,6 +141,8 @@
 
 AC_SUBST(OSS_CFLAGS)
 AC_SUBST(SUN_CFLAGS)
+AC_SUBST(ALSA_CFLAGS)
+AC_SUBST(ALSA_LIBS)
 AC_SUBST(SOCKET_LIBS)
 AC_SUBST(XML_LIBS)
 AC_SUBST(SHOUT_LIBS)

<p><p>1.19      +8 -1      ices/src/input.c

Index: input.c
===================================================================
RCS file: /usr/local/cvsroot/ices/src/input.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- input.c	22 Nov 2002 13:01:34 -0000	1.18
+++ input.c	29 Dec 2002 10:28:30 -0000	1.19
@@ -2,7 +2,7 @@
  *  - Main producer control loop. Fetches data from input modules, and controls
  *    submission of these to the instance threads. Timing control happens here.
  *
- * $Id: input.c,v 1.18 2002/11/22 13:01:34 msmith Exp $
+ * $Id: input.c,v 1.19 2002/12/29 10:28:30 msmith Exp $
  * 
  * Copyright (c) 2001 Michael Smith <msmith at labyrinth.net.au>
  *
@@ -40,6 +40,10 @@
 #include "im_sun.h"
 #endif
 
+#ifdef HAVE_ALSA
+#include "im_alsa.h"
+#endif
+
 #ifdef _WIN32
 typedef __int64 int64_t
 typedef unsigned __int64 uint64_t
@@ -74,6 +78,9 @@
 #endif
 #ifdef HAVE_SUN_AUDIO
         { "sun", sun_open_module},
+#endif
+#ifdef HAVE_ALSA
+	{ "alsa", alsa_open_module},
 #endif
         {NULL,NULL}
 };

<p><p>1.3       +8 -1      ices/src/registry.h

Index: registry.h
===================================================================
RCS file: /usr/local/cvsroot/ices/src/registry.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- registry.h	9 Feb 2002 05:07:01 -0000	1.2
+++ registry.h	29 Dec 2002 10:28:30 -0000	1.3
@@ -1,7 +1,7 @@
 /* registry.h
  * - Registry of input/output/processing modules.
  *
- * $Id: registry.h,v 1.2 2002/02/09 05:07:01 msmith Exp $
+ * $Id: registry.h,v 1.3 2002/12/29 10:28:30 msmith Exp $
  *
  * Copyright (c) 2001-2002 Michael Smith <msmith at labyrinth.net.au>
  *
@@ -25,6 +25,10 @@
 #include "im_oss.h"
 #endif 
 
+#ifdef HAVE_ALSA
+#include "im_alsa.h"
+#endif 
+
 /*
 #ifdef HAVE_SUN_AUDIO
 #include "im_sun.h"
@@ -50,6 +54,9 @@
 #endif
 #ifdef HAVE_SUN_AUDIO 
     { "sun", sun_open_module},
+#endif
+#ifdef HAVE_ALSA 
+    { "alsa", alsa_open_module},
 #endif
     {NULL,NULL}
 };

<p><p>1.10      +11 -7     ices/src/Makefile.am

Index: Makefile.am
===================================================================
RCS file: /usr/local/cvsroot/ices/src/Makefile.am,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- Makefile.am	11 Aug 2002 09:45:34 -0000	1.9
+++ Makefile.am	29 Dec 2002 10:28:30 -0000	1.10
@@ -16,25 +16,29 @@
 
 endif
 
+if HAVE_ALSA
+
+alsaheaders = im_alsa.h
+alsasources = im_alsa.c
+
+endif
+
 SUBDIRS = avl thread net log timing
 
 bin_PROGRAMS = ices
 
-noinst_HEADERS = config.h input.h inputmodule.h im_playlist.h signals.h stream.h reencode.h encode.h playlist_basic.h logging.h im_stdinpcm.h $(ossheaders) $(sunheaders) event.h stream_shared.h metadata.h audio.h resample.h
-ices_SOURCES = input.c config.c stream.c ices.c signals.c im_playlist.c reencode.c encode.c playlist_basic.c im_stdinpcm.c $(osssources) $(sunsources) stream_shared.c savefile.c metadata.c stream_rewrite.c playlist_script.c audio.c resample.c
+noinst_HEADERS = config.h input.h inputmodule.h im_playlist.h signals.h stream.h reencode.h encode.h playlist_basic.h logging.h im_stdinpcm.h $(ossheaders) $(sunheaders) $(alsaheaders) event.h stream_shared.h metadata.h audio.h resample.h
+ices_SOURCES = input.c config.c stream.c ices.c signals.c im_playlist.c reencode.c encode.c playlist_basic.c im_stdinpcm.c $(osssources) $(sunsources) $(alsaheaders) stream_shared.c savefile.c metadata.c stream_rewrite.c playlist_script.c audio.c resample.c
 
 ices_LDADD = net/libicenet.la thread/libicethread.la log/libicelog.la\
         avl/libiceavl.la timing/libicetiming.la
 
 LIBS = @LIBS@ -lpthread @SOCKET_LIBS@ @XML_LIBS@ @OGG_LIBS@ @VORBIS_LIBS@\
-       @VORBISENC_LIBS@ @SHOUT_LIBS@
+       @VORBISENC_LIBS@ @SHOUT_LIBS@ @ALSA_LIBS@
 
 CFLAGS = @CFLAGS@ @XML_CFLAGS@ @OGG_CFLAGS@ @VORBIS_CFLAGS@ @SHOUT_CFLAGS@
 
-INCLUDES = -Inet -Ithread -Iavl -Ilog -Itiming $(OSS_CFLAGS) $(SUN_CFLAGS)
-
-# SCCS stuff (for BitKeeper)
-GET = true
+INCLUDES = -Inet -Ithread -Iavl -Ilog -Itiming $(OSS_CFLAGS) $(SUN_CFLAGS) $(ALSA_CFLAGS)
 
 debug:
         $(MAKE) all CFLAGS="@DEBUG@ @XML_CFLAGS@ @OGG_CFLAGS@ @VORBIS_CFLAGS@ @SHOUT_CFLAGS@"

<p><p>1.1                  ices/src/im_alsa.c

Index: im_alsa.c
===================================================================
/* im_alsa.c
 * - Raw PCM input from ALSA devices
 *
 * $Id: im_alsa.c,v 1.1 2002/12/29 10:28:30 msmith Exp $
 *
 * by Jason Chu <jchu at uvic.ca>, based
 * on im_oss.c which is...
 * Copyright (c) 2001 Michael Smith <msmith at labyrinth.net.au>
 *
 * This program is distributed under the terms of the GNU General
 * Public License, version 2. You may use, modify, and redistribute
 * it under the terms of this license. A copy should be included
 * with this source.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <ogg/ogg.h>
#include <sys/soundcard.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <fcntl.h>

<p>#include "thread.h"
#include "config.h"
#include "stream.h"
#include "metadata.h"
#include "inputmodule.h"

#include "im_alsa.h"

#define MODULE "input-alsa/"
#include "logging.h"

#define BUFSIZE 8192

tatic void close_module(input_module_t *mod)
{
        if(mod)
        {
                if(mod->internal)
                {
                        im_alsa_state *s = mod->internal;
                        if(s->fd != NULL)
                                snd_pcm_close(s->fd);
                        thread_mutex_destroy(&s->metadatalock);
                        free(s);
                }
                free(mod);
        }
}
static int event_handler(input_module_t *mod, enum event_type ev, void *param)
{
        im_alsa_state *s = mod->internal;

        switch(ev)
        {
                case EVENT_SHUTDOWN:
                        close_module(mod);
                        break;
                case EVENT_NEXTTRACK:
                        s->newtrack = 1;
                        break;
                case EVENT_METADATAUPDATE:
                        thread_mutex_lock(&s->metadatalock);
                        if(s->metadata)
                        {
                                char **md = s->metadata;
                                while(*md)
                                        free(*md++);
                                free(s->metadata);
                        }
                        s->metadata = (char **)param;
                        s->newtrack = 1;
                        thread_mutex_unlock(&s->metadatalock);
                        break;
                default:
                        LOG_WARN1("Unhandled event %d", ev);
                        return -1;
        }

        return 0;
}

tatic void metadata_update(void *self, vorbis_comment *vc)
{
        im_alsa_state *s = self;
        char **md;

        thread_mutex_lock(&s->metadatalock);

        md = s->metadata;

        if(md)
        {
                while(*md)
                        vorbis_comment_add(vc, *md++);
        }

        thread_mutex_unlock(&s->metadatalock);
}

/* Core streaming function for this module
 * This is what actually produces the data which gets streamed.
 *
 * returns:  >0  Number of bytes read
 *            0  Non-fatal error.
 *           <0  Fatal error.
 */
static int alsa_read(void *self, ref_buffer *rb)
{
        int result;
        im_alsa_state *s = self;

        rb->buf = malloc(BUFSIZE*2*s->channels);
    if(!rb->buf)
        return -1;
        result = snd_pcm_readi(s->fd, rb->buf, BUFSIZE>>2);

        rb->len = result*4;
        rb->aux_data = s->rate*s->channels*2;

        if(s->newtrack)
        {
                rb->critical = 1;
                s->newtrack = 0;
        }

        if (result == -EPIPE)
        {
                snd_pcm_prepare(s->fd);
                return 0;
        }
        else if (result == -EBADFD)
        {
                LOG_ERROR0("Bad descriptor passed to snd_pcm_readi");
                free(rb->buf);
                return -1;
        }

        return rb->len;
}

input_module_t *alsa_open_module(module_param_t *params)
{
        input_module_t *mod = calloc(1, sizeof(input_module_t));
        im_alsa_state *s;
        module_param_t *current;
        char *device = "plughw:0,0"; /* default device */
        int format = AFMT_S16_LE;
        int channels, rate;
        int use_metadata = 1; /* Default to on */

        snd_pcm_stream_t stream = SND_PCM_STREAM_CAPTURE;
        snd_pcm_hw_params_t *hwparams;

        int err;

        mod->type = ICES_INPUT_PCM;
        mod->subtype = INPUT_PCM_LE_16;
        mod->getdata = alsa_read;
        mod->handle_event = event_handler;
        mod->metadata_update = metadata_update;

        mod->internal = calloc(1, sizeof(im_alsa_state));
        s = mod->internal;

        s->fd = NULL; /* Set it to something invalid, for now */
        s->rate = 44100; /* Defaults */
        s->channels = 2; 

        thread_mutex_create(&s->metadatalock);

        current = params;

        while(current)
        {
                if(!strcmp(current->name, "rate"))
                        s->rate = atoi(current->value);
                else if(!strcmp(current->name, "channels"))
                        s->channels = atoi(current->value);
                else if(!strcmp(current->name, "device"))
                        device = current->value;
                else if(!strcmp(current->name, "metadata"))
                        use_metadata = atoi(current->value);
                else if(!strcmp(current->name, "metadatafilename"))
                        ices_config->metadata_filename = current->value;
                else
                        LOG_WARN1("Unknown parameter %s for alsa module", current->name);

                current = current->next;
        }

        snd_pcm_hw_params_alloca(&hwparams);

        if ((err = snd_pcm_open(&s->fd, device, stream, 0)) < 0)
        {
                LOG_ERROR2("Failed to open audio device %s: %s", device, snd_strerror(err));
                goto fail;
        }

        if ((err = snd_pcm_hw_params_any(s->fd, hwparams)) < 0)
        {
                LOG_ERROR1("Failed to initialize hwparams: %s", snd_strerror(err));
                goto fail;
        }
        if ((err = snd_pcm_hw_params_set_access(s->fd, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
        {
                LOG_ERROR1("Error setting access: %s", snd_strerror(err));
                goto fail;
        }
        if ((err = snd_pcm_hw_params_set_format(s->fd, hwparams, SND_PCM_FORMAT_S16_LE)) < 0)
        {
                LOG_ERROR1("Couldn't set sample format to SND_PCM_FORMAT_S16_LE: %s", snd_strerror(err));
                goto fail;
        }
        if ((err = snd_pcm_hw_params_set_rate_near(s->fd, hwparams, s->rate, 0)) < 0)
        {
                LOG_ERROR1("Error setting rate: %s", snd_strerror(err));
                goto fail;
        }
        s->rate = snd_pcm_hw_params_get_rate(hwparams, 0);
        if ((err = snd_pcm_hw_params_set_channels(s->fd, hwparams, s->channels)) < 0)
        {
                LOG_ERROR1("Error setting channels: %s", snd_strerror(err));
                goto fail;
        }
        s->channels = snd_pcm_hw_params_get_channels(hwparams);
        if ((err = snd_pcm_hw_params_set_periods(s->fd, hwparams, 2, 0)) < 0)
        {
                LOG_ERROR1("Error setting periods: %s", snd_strerror(err));
                goto fail;
        }
        if ((err = snd_pcm_hw_params_set_buffer_size_near(s->fd, hwparams, (BUFSIZE * 2)>>2)) < 0)
        {
                LOG_ERROR1("Error setting buffersize: %s", snd_strerror(err));
                goto fail;
        }
        if ((err = snd_pcm_hw_params(s->fd, hwparams)) < 0)
        {
                LOG_ERROR1("Error setting HW params: %s", snd_strerror(err));
                goto fail;
        }

        /* We're done, and we didn't fail! */
        LOG_INFO3("Opened audio device %s at %d channel(s), %d Hz", 
                        device, s->channels, s->rate);

        if(use_metadata)
        {
        if(ices_config->metadata_filename)
            thread_create("im_alsa-metadata", metadata_thread_signal, mod, 1);
        else
                    thread_create("im_alsa-metadata", metadata_thread_stdin, mod, 1);
                LOG_INFO0("Started metadata update thread");
        }

        return mod;

fail:
        close_module(mod); /* safe, this checks for valid contents */
        return NULL;
}

<p><p><p><p>1.1                  ices/src/im_alsa.h

Index: im_alsa.h
===================================================================
/* im_alsa.h
 * - read pcm data from oss devices
 *
 * $Id: im_alsa.h,v 1.1 2002/12/29 10:28:30 msmith Exp $
 *
 * by Jason Chu  <jchu at uvic.ca>, based
 * on im_oss.c which is...
 * Copyright (c) 2001 Michael Smith <msmith at labyrinth.net.au>
 *
 * This program is distributed under the terms of the GNU General
 * Public License, version 2. You may use, modify, and redistribute
 * it under the terms of this license. A copy should be included
 * with this source.
 */

#ifndef __IM_ALSA_H__
#define __IM_ALSA_H__

#include <alsa/asoundlib.h>
#include "inputmodule.h"
#include "thread.h"
#include <ogg/ogg.h>

typedef struct
{
        int rate;
        int channels;

        snd_pcm_t *fd;
        char **metadata;
        int newtrack;
        mutex_t metadatalock;
} im_alsa_state; 

input_module_t *alsa_open_module(module_param_t *params);

#endif  /* __IM_ALSA */

<p><p>--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list