Browse Source

Added : alsa support


			
			
				pull/2/head
			
			
		
Henri Fallon 26 years ago
parent
commit
a7dd995f4c
  1. 1
      AUTHORS
  2. 1
      ChangeLog
  3. 2
      INSTALL
  4. 10
      Makefile.in
  5. 2
      TODO
  6. 290
      configure
  7. 3
      configure.in
  8. 108
      plugins/alsa/alsa.c
  9. 328
      plugins/alsa/aout_alsa.c
  10. 1
      src/misc/plugins.c

1
AUTHORS

@ -18,4 +18,5 @@
Stéphane Borel <stef@via.ecp.fr>
Renaud Dartus <reno@via.ecp.fr>
Henri Fallon <henri@via.ecp.fr>

1
ChangeLog

@ -17,6 +17,7 @@
advantage of the SMP machines.
* Added --enable-debug, --enable-stats, and --disable-optims in the
GNU configure stuff.
* Added alsa audio support (plugin)
Mon, 28 Aug 2000 02:34:18 +0200
0.1.99i :

2
INSTALL

@ -11,7 +11,7 @@ A typical way to configure the vlc is :
For a full compilation, you may try :
./configure --prefix=/usr --enable-mmx --enable-gnome --enable-fb \
--enable-glide --enable-ggi --enable-mga --enable-esd
--enable-glide --enable-ggi --enable-mga --enable-esd --enable-alsa
See `./configure --help' for more information.

10
Makefile.in

@ -339,10 +339,13 @@ PLUGIN_YUVMMX = plugins/yuvmmx/yuvmmx.o \
plugins/yuvmmx/video_yuv24.o \
plugins/yuvmmx/video_yuv32.o
PLUGIN_ALSA = plugins/alsa/alsa.o \
plugins/alsa/aout_alsa.o
PLUGIN_OBJ = $(PLUGIN_BEOS) $(PLUGIN_DSP) $(PLUGIN_DUMMY) $(PLUGIN_ESD) \
$(PLUGIN_FB) $(PLUGIN_GGI) $(PLUGIN_GLIDE) $(PLUGIN_GNOME) \
$(PLUGIN_MGA) $(PLUGIN_X11) $(PLUGIN_YUV) $(PLUGIN_YUVMMX) \
$(PLUGIN_SDL)
$(PLUGIN_SDL) $(PLUGIN_ALSA)
#
# Other lists of files
#
@ -475,6 +478,11 @@ lib/dsp.so: $(PLUGIN_DSP)
$(PLUGIN_DSP): %.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
lib/alsa.so: $(PLUGIN_ALSA)
ld -shared -o $@ $^
$(PLUGIN_ALSA): %.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
lib/dummy.so: $(PLUGIN_DUMMY)
ld -shared -o $@ $^
$(PLUGIN_DUMMY): %.o: %.c

2
TODO

@ -157,7 +157,7 @@ Urgency: Normal
Description: ALSA audio output support
ALSA is the Advanced Linux Sound Architecture and is believed to be
technically superior to the usual OSS support found in the Linux kernel.
Status: Todo
Status: Done ( henri )
Task: 0x28
Difficulty: Guru

290
configure

File diff suppressed because it is too large

3
configure.in

@ -115,6 +115,9 @@ AC_ARG_ENABLE(glide,
AC_ARG_ENABLE(gnome,
[ --enable-gnome Gnome support (default disabled)],
[if test x$enable_gnome = xyes; then PLUGINS=${PLUGINS}"gnome "; ALIASES=${ALIASES}"gvlc "; fi])
AC_ARG_ENABLE(alsa,
[ --enable-alsa Alsa sound drivers supprt (default disabled)],
[if test x$enable_alsa = xyes; then PLUGINS=${PLUGINS}"alsa "; fi])
AC_ARG_ENABLE(x11,
[ --enable-x11 X11 support (default enabled)])
if test x$enable_x11 != xno; then PLUGINS=${PLUGINS}"x11 "; fi

108
plugins/alsa/alsa.c

@ -0,0 +1,108 @@
/*****************************************************************************
* dsp.c : OSS /dev/dsp plugin for vlc
*****************************************************************************
* Copyright (C) 2000 VideoLAN
*
* Authors:
* Henri Fallon <henri@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#include "defs.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/asoundlib.h> /* for alsa :) */
#include <fcntl.h>
#include <stdlib.h> /* malloc(), free() */
// #include <unistd.h> /* close() */
#include "config.h"
#include "common.h" /* boolean_t, byte_t */
#include "threads.h"
#include "mtime.h"
#include "tests.h"
#include "plugins.h"
#include "interface.h"
#include "audio_output.h"
#include "video.h"
#include "video_output.h"
#include "main.h"
/*****************************************************************************
* Exported prototypes
*****************************************************************************/
static void aout_GetPlugin( p_aout_thread_t p_aout );
/* Audio output */
int aout_AlsaOpen ( aout_thread_t *p_aout );
int aout_AlsaReset ( aout_thread_t *p_aout );
int aout_AlsaSetFormat ( aout_thread_t *p_aout );
int aout_AlsaSetChannels ( aout_thread_t *p_aout );
int aout_AlsaSetRate ( aout_thread_t *p_aout );
long aout_AlsaGetBufInfo ( aout_thread_t *p_aout, long l_buffer_info );
void aout_AlsaPlaySamples ( aout_thread_t *p_aout, byte_t *buffer,
int i_size );
void aout_AlsaClose ( aout_thread_t *p_aout );
/*****************************************************************************
* GetConfig: get the plugin structure and configuration
*****************************************************************************/
plugin_info_t * GetConfig( void )
{
int i_fd;
plugin_info_t * p_info = (plugin_info_t *) malloc( sizeof(plugin_info_t) );
p_info->psz_name = "Alsa plugin";
p_info->psz_version = VERSION;
p_info->psz_author = "the VideoLAN team <vlc@videolan.org>";
p_info->aout_GetPlugin = aout_GetPlugin;
p_info->vout_GetPlugin = NULL;
p_info->intf_GetPlugin = NULL;
p_info->yuv_GetPlugin = NULL;
/* TODO : test if alsa is available */
p_info->i_score = 0x100;
/* If this plugin was requested, score it higher */
if( TestMethod( AOUT_METHOD_VAR, "alsa" ) )
{
p_info->i_score += 0x200;
}
return( p_info );
}
/*****************************************************************************
* Following functions are only called through the p_info structure
*****************************************************************************/
static void aout_GetPlugin( p_aout_thread_t p_aout )
{
p_aout->p_sys_open = aout_AlsaOpen;
p_aout->p_sys_reset = aout_AlsaReset;
p_aout->p_sys_setformat = aout_AlsaSetFormat;
p_aout->p_sys_setchannels = aout_AlsaSetChannels;
p_aout->p_sys_setrate = aout_AlsaSetRate;
p_aout->p_sys_getbufinfo = aout_AlsaGetBufInfo;
p_aout->p_sys_playsamples = aout_AlsaPlaySamples;
p_aout->p_sys_close = aout_AlsaClose;
}

328
plugins/alsa/aout_alsa.c

@ -0,0 +1,328 @@
/*****************************************************************************
* aout_alsa.c : Alsa functions library
*****************************************************************************
* Copyright (C) 2000 VideoLAN
*
* Authors:
* Henri Fallon <henri@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include <errno.h> /* ENOMEM */
#include <fcntl.h> /* open(), O_WRONLY */
#include <sys/ioctl.h> /* ioctl() */
#include <string.h> /* strerror() */
#include <unistd.h> /* write(), close() */
#include <stdio.h> /* "intf_msg.h" */
#include <stdlib.h> /* calloc(), malloc(), free() */
#include <sys/asoundlib.h>
#include <linux/asound.h>
#include "config.h"
#include "common.h" /* boolean_t, byte_t */
#include "threads.h"
#include "mtime.h"
#include "plugins.h"
#include "audio_output.h" /* aout_thread_t */
#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
#include "main.h"
typedef struct alsa_device_s
{
int i_num;
} alsa_device_t;
typedef struct alsa_card_s
{
int i_num;
} alsa_card_t;
/* here we store plugin dependant informations */
typedef struct aout_sys_s
{
snd_pcm_t * p_alsa_handle;
alsa_device_t * p_alsa_device;
alsa_card_t * p_alsa_card;
snd_pcm_channel_params_t s_alsa_channel_params;
snd_pcm_format_t s_alsa_format;
} aout_sys_t;
/*****************************************************************************
* aout_AlsaOpen : creates a handle and opens an alsa device
*****************************************************************************/
int aout_AlsaOpen( aout_thread_t *p_aout )
{
int i_open_returns;
/* Allocate structures */
p_aout->p_sys = malloc( sizeof( aout_sys_t ) );
if( p_aout->p_sys == NULL )
{
intf_ErrMsg("error: %s\n", strerror(ENOMEM) );
return( 1 );
}
p_aout->p_sys->p_alsa_device = malloc( sizeof( alsa_device_t) );
p_aout->p_sys->p_alsa_card = malloc( sizeof( alsa_device_t ) );
if( ( p_aout->p_sys->p_alsa_device == NULL ) ||
( p_aout->p_sys->p_alsa_card == NULL ) )
{
intf_ErrMsg ( "error: %s\n", strerror(ENOMEM) );
return ( 1 );
}
/* Initialize */
p_aout->p_sys->p_alsa_device->i_num = 0;
p_aout->p_sys->p_alsa_card->i_num = 0;
/* FIXME : why not other format ? */
p_aout->i_format = AOUT_FMT_S16_LE;
/* FIXME : why always 2 channels ?*/
p_aout->i_channels = 2;
p_aout->l_rate = main_GetIntVariable( AOUT_RATE_VAR, AOUT_RATE_DEFAULT );
/* Open device */
if ( ( i_open_returns = snd_pcm_open( &(p_aout->p_sys->p_alsa_handle),
p_aout->p_sys->p_alsa_card->i_num,
p_aout->p_sys->p_alsa_device->i_num,
SND_PCM_OPEN_PLAYBACK ) ) )
{
intf_ErrMsg ( "could not open alsa device; error code : %i\n",
i_open_returns );
return ( 1 );
}
return ( 0 );
intf_ErrMsg("Alsa device open \n\n");
}
/*****************************************************************************
* aout_AlsaSetFormat : sets the alsa output format
*****************************************************************************/
int aout_AlsaSetFormat ( aout_thread_t *p_aout )
{
int i_set_param_returns;
int i_prepare_playback_returns;
int i_playback_go_returns;
/* Fill with zeros */
memset(&p_aout->p_sys->s_alsa_channel_params,0,
sizeof(p_aout->p_sys->s_alsa_channel_params));
/* Fill the s_alsa_channel_params structure */
/* Tranfer mode and direction*/
p_aout->p_sys->s_alsa_channel_params.channel = SND_PCM_CHANNEL_PLAYBACK ;
p_aout->p_sys->s_alsa_channel_params.mode = SND_PCM_MODE_STREAM;
/* Format and rate */
p_aout->p_sys->s_alsa_channel_params.format.interleave = 1;
if ( p_aout->i_format == AOUT_FMT_S16_LE )
p_aout->p_sys->s_alsa_channel_params.format.format =
SND_PCM_SFMT_S16_LE;
else
p_aout->p_sys->s_alsa_channel_params.format.format =
SND_PCM_SFMT_S16_BE;
p_aout->p_sys->s_alsa_channel_params.format.rate = p_aout->l_rate;
p_aout->p_sys->s_alsa_channel_params.format.voices = p_aout->i_channels ;
/* When to start playing and when to stop */
p_aout->p_sys->s_alsa_channel_params.start_mode = SND_PCM_START_DATA;
p_aout->p_sys->s_alsa_channel_params.stop_mode = SND_PCM_STOP_STOP;
/* Buffer information . I have chosen the stream mode here
* instead of the block mode. I don't know whether i'm wrong
* but it seemed more logical */
p_aout->p_sys->s_alsa_channel_params.buf.stream.queue_size = 131072;
/* Fill with silence */
p_aout->p_sys->s_alsa_channel_params.buf.stream.fill = SND_PCM_FILL_NONE ;
p_aout->p_sys->s_alsa_channel_params.buf.stream.max_fill = 0 ;
/* Now we pass this to the driver */
i_set_param_returns = snd_pcm_channel_params (
p_aout->p_sys->p_alsa_handle,
&(p_aout->p_sys->s_alsa_channel_params) );
if ( i_set_param_returns )
{
intf_ErrMsg ( "ALSA_PLUGIN : Unable to set parameters; exit = %i\n",
i_set_param_returns );
intf_ErrMsg( "This means : %s\n\n",
snd_strerror( i_set_param_returns ) );
return ( 1 );
}
/* we shall now prepare the channel */
i_prepare_playback_returns =
snd_pcm_playback_prepare ( p_aout->p_sys->p_alsa_handle );
if ( i_prepare_playback_returns )
{
intf_ErrMsg ( "ALSA_PLUGIN : Unable to prepare channel : exit = %i\n",
i_prepare_playback_returns );
intf_ErrMsg( "This means : %s\n\n",
snd_strerror( i_set_param_returns ) );
return ( 1 );
}
/* then we may go */
i_playback_go_returns =
snd_pcm_playback_go ( p_aout->p_sys->p_alsa_handle );
if ( i_playback_go_returns )
{
intf_ErrMsg ( "ALSA_PLUGIN : Unable to prepare channel (bis) :
exit = %i\n", i_playback_go_returns );
intf_ErrMsg( "This means : %s\n\n",
snd_strerror( i_set_param_returns ) );
return ( 1 );
}
return ( 0 );
}
/*****************************************************************************
* aout_AlsaReset: resets the dsp
*****************************************************************************/
int aout_AlsaReset ( aout_thread_t *p_aout )
{
/* TODO : put something in here, such as close and open again
* or check status, drain, flush, .... */
return ( 0 );
}
/*****************************************************************************
* aout_AlsaSetChannels: sets mono, stereo and other modes
*****************************************************************************/
int aout_AlsaSetChannels ( aout_thread_t *p_aout )
{
/* TODO : normally, nothing
* everything should be done in the AlsaSetFormat, as far a I understand
* the alsa documentation
*/
return ( 0 );
}
/*****************************************************************************
* aout_AlsaSetRate: sets the audio output rate
*****************************************************************************
* As in the previous function, the rate is supposed to be set in the
* AlsaSetFormat function
*****************************************************************************/
int aout_AlsaSetRate ( aout_thread_t *p_aout )
{
return ( 0 );
}
/*****************************************************************************
* aout_AlsaGetBufInfo: buffer status query
*****************************************************************************/
long aout_AlsaGetBufInfo ( aout_thread_t *p_aout, long l_buffer_limit )
{
snd_pcm_channel_status_t alsa_channel_status;
int i_alsa_get_status_returns;
memset (&alsa_channel_status, 0, sizeof(alsa_channel_status));
i_alsa_get_status_returns = snd_pcm_channel_status (
p_aout->p_sys->p_alsa_handle, &alsa_channel_status );
if ( i_alsa_get_status_returns )
{
intf_ErrMsg ( "Error getting alsa buffer info; exit=%i\n",
i_alsa_get_status_returns );
intf_ErrMsg ( "This means : %s \n\n",
snd_strerror ( i_alsa_get_status_returns ) );
return ( 1 );
}
switch (alsa_channel_status.status)
{
case SND_PCM_STATUS_NOTREADY : intf_ErrMsg("Status NOT READY \n \n");
break;
case SND_PCM_STATUS_UNDERRUN : {
int i_drain_returns;
intf_ErrMsg(
"Status UNDERRUN ... draining \n \n");
i_drain_returns =
snd_pcm_playback_prepare(
p_aout->p_sys->p_alsa_handle );
if ( i_drain_returns )
{
intf_ErrMsg(
"Error : could not flush : %i\n",
i_drain_returns);
intf_ErrMsg(
"This means : %s\n",
snd_strerror(i_drain_returns));
}
break;
}
}
return ( alsa_channel_status.count );
}
/*****************************************************************************
* aout_AlsaPlaySamples
*****************************************************************************/
void aout_AlsaPlaySamples ( aout_thread_t *p_aout, byte_t *buffer, int i_size )
{
int i_write_returns;
i_write_returns = (int) snd_pcm_write (
p_aout->p_sys->p_alsa_handle, (void *)buffer, (size_t) i_size );
if ( i_write_returns <= 0 )
{
intf_ErrMsg ( "Error writing blocks; exit=%i\n", i_write_returns );
intf_ErrMsg ( "This means : %s\n", snd_strerror( i_write_returns ) );
}
}
/*****************************************************************************
* aout_AlsaClose : close the Alsa device
*****************************************************************************/
void aout_AlsaClose ( aout_thread_t *p_aout )
{
int i_close_returns;
i_close_returns = snd_pcm_close ( p_aout->p_sys->p_alsa_handle );
if ( i_close_returns )
{
intf_ErrMsg( "Error closing alsa device; exit=%i\n",i_close_returns );
intf_ErrMsg( "This means : %s\n\n",snd_strerror( i_close_returns ) );
}
}

1
src/misc/plugins.c

@ -107,6 +107,7 @@ void bank_Init( plugin_bank_t * p_bank )
/* Audio pluins */
SEEK_PLUGIN( "dsp" );
SEEK_PLUGIN( "esd" );
SEEK_PLUGIN( "alsa" );
/* Dummy plugin */
SEEK_PLUGIN( "dummy" );

Loading…
Cancel
Save