[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