Tom Watson wrote: > I just downloaded a version (most recent I assume) of MPG123. > When I tried to do a 'make linux-alsa' I got a wholw bunch of > errors. While I suspect that this is because they are using an > older oversion of alsa (0.5.x?).
Yes. > and has anyone else done any mods to the mpg123 (or its library). Try the patch below. HTH Clemens -- diff -ur mpg123-pre0.59s-orig/audio.c mpg123-pre0.59s/audio.c --- mpg123-pre0.59s-orig/audio.c Thu Jan 18 15:00:33 2001 +++ mpg123-pre0.59s/audio.c Sat May 22 16:52:21 2004 @@ -17,9 +17,6 @@ ai->output = -1; #ifdef ALSA ai->handle = NULL; - ai->alsa_format.format = -1; - ai->alsa_format.rate = -1; - ai->alsa_format.channels = -1; #endif ai->device = NULL; ai->channels = -1; diff -ur mpg123-pre0.59s-orig/audio.h mpg123-pre0.59s/audio.h --- mpg123-pre0.59s-orig/audio.h Thu Jan 18 15:00:33 2001 +++ mpg123-pre0.59s/audio.h Sat May 22 16:55:10 2004 @@ -42,7 +42,9 @@ #ifdef ALSA -#include <sys/asoundlib.h> +#define ALSA_PCM_NEW_HW_PARAMS_API +#define ALSA_PCM_NEW_SW_PARAMS_API +#include <alsa/asoundlib.h> #endif struct audio_info_struct @@ -59,7 +61,6 @@ int output; #ifdef ALSA snd_pcm_t *handle; - snd_pcm_format_t alsa_format; #endif #ifdef AIX_UMS UMSAudioDevice dev; diff -ur mpg123-pre0.59s-orig/audio_alsa.c mpg123-pre0.59s/audio_alsa.c --- mpg123-pre0.59s-orig/audio_alsa.c Mon Sep 20 16:55:02 1999 +++ mpg123-pre0.59s/audio_alsa.c Sat May 22 21:20:31 2004 @@ -1,189 +1,168 @@ /* - * Driver for Advanced Linux Sound Architecture, http://alsa.jcu.cz + * Driver for Advanced Linux Sound Architecture, http://www.alsa-project.org * * Code by Anders Semb Hermansen <[EMAIL PROTECTED]> - * Cleanups by Jaroslav Kysela <[EMAIL PROTECTED]> + * Cleanups by Jaroslav Kysela <[EMAIL PROTECTED]> * Ville Syrjala <[EMAIL PROTECTED]> + * Modified for ALSA 1.0.x by Clemens Ladisch <[EMAIL PROTECTED]> * - * You can use -a <soundcard #>:<device #>... - * For example: mpg123 -a 1:0 aaa.mpg - * mpg123 -a guspnp:1 aaa.mpg + * You can use -a devicename ... + * For example: mpg123 -a hw:1,0 aaa.mpg + * mpg123 -a guspnp aaa.mpg * * This file comes under GPL license. */ #include "mpg123.h" -#include <stdlib.h> -#include <ctype.h> -#include <sys/asoundlib.h> - -#ifdef SND_LITTLE_ENDIAN -#define SND_PCM_SFMT_S16_NE SND_PCM_SFMT_S16_LE -#define SND_PCM_SFMT_U16_NE SND_PCM_SFMT_U16_LE -#define SND_PCM_FMT_S16_NE SND_PCM_FMT_S16_LE -#define SND_PCM_FMT_U16_NE SND_PCM_FMT_U16_LE -#else -#define SND_PCM_SFMT_S16_NE SND_PCM_SFMT_S16_BE -#define SND_PCM_SFMT_U16_NE SND_PCM_SFMT_U16_BE -#define SND_PCM_FMT_S16_NE SND_PCM_FMT_S16_BE -#define SND_PCM_FMT_U16_NE SND_PCM_FMT_U16_BE -#endif - int audio_open(struct audio_info_struct *ai) { int err; - int card=0,device=0; - char scard[128], sdevice[128]; + const char *pcm_name; if(!ai) return -1; - if(ai->device) { /* parse ALSA device name */ - if(strchr(ai->device,':')) { /* card with device */ - strncpy(scard, ai->device, sizeof(scard)-1); - scard[sizeof(scard)-1] = '\0'; - if (strchr(scard,':')) *strchr(scard,':') = '\0'; - card = snd_card_name(scard); - if (card < 0) { - fprintf(stderr, "wrong soundcard number: %s\n", scard); - exit(1); - } - strncpy(sdevice, strchr(ai->device, ':') + 1, sizeof(sdevice)-1); - } else { - strncpy(sdevice, ai->device, sizeof(sdevice)-1); - } - sdevice[sizeof(sdevice)-1] = '\0'; - device = atoi(sdevice); - if (!isdigit(sdevice[0]) || device < 0 || device > 31) { - fprintf(stderr, "wrong device number: %s\n", sdevice); - exit(1); - } - } - - if((err=snd_pcm_open(&ai->handle, card, device, SND_PCM_OPEN_PLAYBACK)) < 0 ) - { - fprintf(stderr, "open failed: %s\n", snd_strerror(err)); - exit(1); - } - if(audio_reset_parameters(ai) < 0) + pcm_name = ai->device ? ai->device : "default"; + if((err=snd_pcm_open(&ai->handle, pcm_name, SND_PCM_STREAM_PLAYBACK, 0)) < 0) { - audio_close(ai); + fprintf(stderr, "cannot open %s: %s\n", pcm_name, snd_strerror(err)); return -1; } - return 0; + if(ai->format != -1) + /* we're going to play: initialize sample format */ + return audio_reset_parameters(ai); + else + /* query mode; sample format will be set for each query */ + return 0; } -static void audio_set_playback_params(struct audio_info_struct *ai) +int audio_reset_parameters(struct audio_info_struct *ai) { int err; - snd_pcm_playback_info_t pi; - snd_pcm_playback_params_t pp; + snd_pcm_format_t format; + unsigned int rate; + snd_pcm_uframes_t buffer_size; + snd_pcm_uframes_t period_size; + snd_pcm_uframes_t boundary; + snd_pcm_hw_params_t *hw; + snd_pcm_sw_params_t *sw; - if((err=snd_pcm_playback_info(ai->handle, &pi)) < 0 ) + snd_pcm_hw_params_alloca(&hw); + if((err=snd_pcm_hw_params_any(ai->handle, hw)) < 0) { - fprintf(stderr, "playback info failed: %s\n", snd_strerror(err)); - return; /* not fatal error */ + fprintf(stderr, "no configuration available: %s\n", snd_strerror(err)); + return -1; } - - bzero(&pp, sizeof(pp)); - pp.fragment_size = pi.buffer_size/4; - if (pp.fragment_size > pi.max_fragment_size) pp.fragment_size = pi.max_fragment_size; - if (pp.fragment_size < pi.min_fragment_size) pp.fragment_size = pi.min_fragment_size; - pp.fragments_max = -1; - pp.fragments_room = 1; - - if((err=snd_pcm_playback_params(ai->handle, &pp)) < 0 ) + if((err=snd_pcm_hw_params_set_access(ai->handle, hw, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { - fprintf(stderr, "playback params failed: %s\n", snd_strerror(err)); - return; /* not fatal error */ + fprintf(stderr, "pcm doesn't support interleaved access: %s\n", snd_strerror(err)); + return -1; } -} - -int audio_reset_parameters(struct audio_info_struct *ai) -{ - audio_set_format(ai); - audio_set_channels(ai); - audio_set_rate(ai); - - return 0; -} - -int audio_rate_best_match(struct audio_info_struct *ai) -{ - return 0; -} - -int audio_set_rate(struct audio_info_struct *ai) -{ - int ret; - - if(!ai || ai->rate < 0) + switch(ai->format) + { + case AUDIO_FORMAT_SIGNED_16: + format = SND_PCM_FORMAT_S16; + break; + case AUDIO_FORMAT_UNSIGNED_16: + format = SND_PCM_FORMAT_U16; + break; + case AUDIO_FORMAT_UNSIGNED_8: + format = SND_PCM_FORMAT_U8; + break; + case AUDIO_FORMAT_SIGNED_8: + format = SND_PCM_FORMAT_S8; + break; + case AUDIO_FORMAT_ULAW_8: + format = SND_PCM_FORMAT_MU_LAW; + break; + case AUDIO_FORMAT_ALAW_8: + format = SND_PCM_FORMAT_A_LAW; + break; + default: + fprintf(stderr, "invalid sample format %d\n", ai->format); return -1; - - ai->alsa_format.rate=ai->rate; - - if((ret=snd_pcm_playback_format(ai->handle, &ai->alsa_format)) < 0 ) + } + if((err=snd_pcm_hw_params_set_format(ai->handle, hw, format)) < 0) + { + fprintf(stderr, "cannot set format %s: %s\n", + snd_pcm_format_name(format), snd_strerror(err)); return -1; - - audio_set_playback_params(ai); - - return 0; -} - -int audio_set_channels(struct audio_info_struct *ai) -{ - int ret; - - if(ai->alsa_format.channels < 0) - return 0; - - ai->alsa_format.channels = ai->channels; - - if((ret=snd_pcm_playback_format(ai->handle, &ai->alsa_format)) < 0 ) + } + if((err=snd_pcm_hw_params_set_channels(ai->handle, hw, ai->channels)) < 0) + { + fprintf(stderr, "cannot set %d channels: %s\n", ai->channels, snd_strerror(err)); return -1; - - audio_set_playback_params(ai); - - return 0; -} - -int audio_set_format(struct audio_info_struct *ai) -{ - int ret; - - if(ai->format == -1) - return 0; - - switch(ai->format) + } + rate = ai->rate; + if((err=snd_pcm_hw_params_set_rate_near(ai->handle, hw, &rate, NULL)) < 0) { - case AUDIO_FORMAT_SIGNED_16: - default: - ai->alsa_format.format=SND_PCM_SFMT_S16_NE; - break; - case AUDIO_FORMAT_UNSIGNED_8: - ai->alsa_format.format=SND_PCM_SFMT_U8; - break; - case AUDIO_FORMAT_SIGNED_8: - ai->alsa_format.format=SND_PCM_SFMT_S8; - break; - case AUDIO_FORMAT_ULAW_8: - ai->alsa_format.format=SND_PCM_SFMT_MU_LAW; - break; - case AUDIO_FORMAT_ALAW_8: - ai->alsa_format.format=SND_PCM_SFMT_A_LAW; - break; - case AUDIO_FORMAT_UNSIGNED_16: - ai->alsa_format.format=SND_PCM_SFMT_U16_NE; - break; + fprintf(stderr, "cannot set rate %u: %s\n", rate, snd_strerror(err)); + return -1; } - - if((ret=snd_pcm_playback_format(ai->handle, &ai->alsa_format)) < 0 ) + if(rate != ai->rate) + { + fprintf(stderr, "rate %ld not available, using %u\n", ai->rate, rate); + } + buffer_size = rate; /* one second */ + if((err=snd_pcm_hw_params_set_buffer_size_near(ai->handle, hw, &buffer_size)) < 0) + { + fprintf(stderr, "cannot set buffer size: %s\n", snd_strerror(err)); return -1; + } + period_size = buffer_size / 4; + if((err=snd_pcm_hw_params_set_period_size_near(ai->handle, hw, &period_size, NULL)) < 0) + { + fprintf(stderr, "cannot set period size: %s\n", snd_strerror(err)); + return -1; + } + if((err=snd_pcm_hw_params(ai->handle, hw)) < 0) + { + fprintf(stderr, "cannot set hw params: %s\n", snd_strerror(err)); + return -1; + } - audio_set_playback_params(ai); - + snd_pcm_sw_params_alloca(&sw); + if((err=snd_pcm_sw_params_current(ai->handle, sw)) < 0) + { + fprintf(stderr, "cannot get sw params: %s\n", snd_strerror(err)); + return -1; + } + /* start playing when buffer is (almost) full */ + if((err=snd_pcm_sw_params_set_start_threshold(ai->handle, sw, (buffer_size / period_size) * period_size)) < 0) + { + fprintf(stderr, "cannot set start threshold: %s\n", snd_strerror(err)); + return -1; + } + if((err=snd_pcm_sw_params_get_boundary(sw, &boundary)) < 0) + { + fprintf(stderr, "cannot get boundary: %s\n", snd_strerror(err)); + return -1; + } + /* never stop on underruns */ + if((err=snd_pcm_sw_params_set_stop_threshold(ai->handle, sw, boundary)) < 0) + { + fprintf(stderr, "cannot set stop threshold: %s\n", snd_strerror(err)); + return -1; + } + /* wake up on every interrupt */ + if((err=snd_pcm_sw_params_set_avail_min(ai->handle, sw, 1)) < 0) + { + fprintf(stderr, "cannot set min avail: %s\n", snd_strerror(err)); + return -1; + } + /* always write as many frames as possible */ + if((err=snd_pcm_sw_params_set_xfer_align(ai->handle, sw, 1)) < 0) + { + fprintf(stderr, "cannot set transfer alignment: %s\n", snd_strerror(err)); + return -1; + } + if((err=snd_pcm_sw_params(ai->handle, sw)) < 0) + { + fprintf(stderr, "cannot set sw params: %s\n", snd_strerror(err)); + return -1; + } return 0; } @@ -191,7 +170,7 @@ { int i, err; int fmt = -1; - snd_pcm_playback_info_t pi; + snd_pcm_hw_params_t *hw; static int fmts[] = { AUDIO_FORMAT_SIGNED_16, AUDIO_FORMAT_UNSIGNED_16, @@ -199,19 +178,26 @@ AUDIO_FORMAT_ULAW_8, AUDIO_FORMAT_ALAW_8 }; static int afmts[] = { - SND_PCM_FMT_S16_NE, SND_PCM_FMT_U16_NE, - SND_PCM_FMT_U8, SND_PCM_FMT_S8, - SND_PCM_FMT_MU_LAW, SND_PCM_FMT_A_LAW + SND_PCM_FORMAT_S16, SND_PCM_FORMAT_U16, + SND_PCM_FORMAT_U8, SND_PCM_FORMAT_S8, + SND_PCM_FORMAT_MU_LAW, SND_PCM_FORMAT_A_LAW }; - if((err=snd_pcm_playback_info(ai->handle, &pi)) < 0 ) + snd_pcm_hw_params_alloca(&hw); + if((err=snd_pcm_hw_params_any(ai->handle, hw)) < 0) { - fprintf(stderr, "playback info failed: %s\n", snd_strerror(err)); + fprintf(stderr, "no configuration available: %s\n", snd_strerror(err)); return -1; } + if(snd_pcm_hw_params_set_access(ai->handle, hw, SND_PCM_ACCESS_RW_INTERLEAVED)) + return -1; + if(snd_pcm_hw_params_set_channels(ai->handle, hw, ai->channels)) + return -1; + if(snd_pcm_hw_params_set_rate(ai->handle, hw, ai->rate, 0)) + return -1; for (i = 0; i < 6; i++) { - if (pi.formats & afmts[i]) { + if (snd_pcm_hw_params_test_format(ai->handle, hw, afmts[i]) == 0) { if (fmt == -1) fmt = 0; fmt |= fmts[i]; @@ -223,16 +209,14 @@ int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len) { - ssize_t ret; - - ret=snd_pcm_write(ai->handle, buf, len); - - return ret; + snd_pcm_uframes_t frames = snd_pcm_bytes_to_frames(ai->handle, len); + return snd_pcm_writei(ai->handle, buf, frames); } int audio_close(struct audio_info_struct *ai) { - int ret; - ret = snd_pcm_close(ai->handle); - return ret; + if (/* !aborted && */ + snd_pcm_state(ai->handle) == SND_PCM_STATE_RUNNING) + snd_pcm_drain(ai->handle); + return snd_pcm_close(ai->handle); } ------------------------------------------------------- This SF.Net email is sponsored by: Oracle 10g Get certified on the hottest thing ever to hit the market... Oracle 10g. Take an Oracle 10g class now, and we'll give you the exam FREE. http://ads.osdn.com/?ad_id=3149&alloc_id=8166&op=click _______________________________________________ Alsa-devel mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/alsa-devel