Hello community, here is the log from the commit of package alsa checked in at Mon May 29 18:20:29 CEST 2006. -------- --- alsa/alsa.changes 2006-05-17 15:06:17.000000000 +0200 +++ alsa/alsa.changes 2006-05-29 17:35:29.000000000 +0200 @@ -1,0 +2,9 @@ +Mon May 29 17:33:02 CEST 2006 - tiwai@suse.de + +- added the support of delay callback in alsa external I/O + plugin (for new polypaudio support) +- fix the return value of snd_hctl_wait() +- fix surround40 PCM configuration for ens1370 cards +- added infile option for alsa-lib pcm file plugin + +------------------------------------------------------------------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ alsa.spec ++++++ --- /var/tmp/diff_new_pack.BSrhjJ/_old 2006-05-29 18:20:11.000000000 +0200 +++ /var/tmp/diff_new_pack.BSrhjJ/_new 2006-05-29 18:20:11.000000000 +0200 @@ -21,7 +21,7 @@ Autoreqprov: on Summary: Advanced Linux Sound Architecture Version: 1.0.11 -Release: 33 +Release: 34 Source1: ftp://ftp.alsa-project.org/pub/lib/alsa-lib-%{package_version}.tar.bz2 Source2: ftp://ftp.alsa-project.org/pub/util/alsa-utils-%{package_version}.tar.bz2 Source5: ftp://ftp.alsa-project.org/pub/oss/alsa-oss-%{package_version}.tar.bz2 @@ -377,6 +377,12 @@ %doc alsa-lib*/doc/doxygen/html/* %changelog -n alsa +* Mon May 29 2006 - tiwai@suse.de +- added the support of delay callback in alsa external I/O + plugin (for new polypaudio support) +- fix the return value of snd_hctl_wait() +- fix surround40 PCM configuration for ens1370 cards +- added infile option for alsa-lib pcm file plugin * Wed May 17 2006 - tiwai@suse.de - fix endless loop bug in arecord, also code clean-up. * Mon May 15 2006 - tiwai@suse.de ++++++ alsa-lib-hg-fixes.diff ++++++ --- /var/tmp/diff_new_pack.BSrhjJ/_old 2006-05-29 18:20:12.000000000 +0200 +++ /var/tmp/diff_new_pack.BSrhjJ/_new 2006-05-29 18:20:12.000000000 +0200 @@ -1,6 +1,6 @@ diff -r ae6753322b63 INSTALL --- a/INSTALL Wed Apr 19 12:29:46 2006 +0200 -+++ b/INSTALL Mon May 15 12:41:49 2006 +0200 ++++ b/INSTALL Mon May 29 17:08:22 2006 +0200 @@ -11,11 +11,11 @@ For installation you can use these comma make install @@ -25,21 +25,32 @@ Note: Some automake packages have missing aclocal program. Use newer version in the case. -diff -r ae6753322b63 Makefile.am ---- a/Makefile.am Wed Apr 19 12:29:46 2006 +0200 -+++ b/Makefile.am Mon May 15 12:41:49 2006 +0200 -@@ -6,7 +6,7 @@ SUBDIRS += alsalisp - SUBDIRS += alsalisp - endif - SUBDIRS += test utils --EXTRA_DIST=ChangeLog INSTALL TODO NOTES configure cvscompile libtool depcomp version MEMORY-LEAK -+EXTRA_DIST=ChangeLog INSTALL TODO NOTES configure hgcompile libtool depcomp version MEMORY-LEAK - AUTOMAKE_OPTIONS=foreign +diff -r ae6753322b63 include/pcm_ioplug.h +--- a/include/pcm_ioplug.h Wed Apr 19 12:29:46 2006 +0200 ++++ b/include/pcm_ioplug.h Mon May 29 17:08:22 2006 +0200 +@@ -65,7 +65,7 @@ typedef struct snd_pcm_ioplug_callback s + */ + #define SND_PCM_IOPLUG_VERSION_MAJOR 1 /**< Protocol major version */ + #define SND_PCM_IOPLUG_VERSION_MINOR 0 /**< Protocol minor version */ +-#define SND_PCM_IOPLUG_VERSION_TINY 0 /**< Protocol tiny version */ ++#define SND_PCM_IOPLUG_VERSION_TINY 1 /**< Protocol tiny version */ + /** + * IO-plugin protocol version + */ +@@ -184,6 +184,10 @@ struct snd_pcm_ioplug_callback { + * dump; optional + */ + void (*dump)(snd_pcm_ioplug_t *io, snd_output_t *out); ++ /** ++ * get the delay for the running PCM; optional ++ */ ++ int (*delay)(snd_pcm_ioplug_t *io, snd_pcm_sframes_t *delayp); + }; + - INCLUDES=-I$(top_srcdir)/include diff -r ae6753322b63 include/seq.h --- a/include/seq.h Wed Apr 19 12:29:46 2006 +0200 -+++ b/include/seq.h Mon May 15 12:41:49 2006 +0200 ++++ b/include/seq.h Mon May 29 17:08:22 2006 +0200 @@ -225,17 +225,41 @@ typedef struct _snd_seq_port_info snd_se #define SND_SEQ_PORT_CAP_SUBS_WRITE (1<<6) /**< allow write subscription */ #define SND_SEQ_PORT_CAP_NO_EXPORT (1<<7) /**< routing not allowed */ @@ -95,7 +106,7 @@ size_t snd_seq_port_info_sizeof(void); diff -r ae6753322b63 include/sound/asequencer.h --- a/include/sound/asequencer.h Wed Apr 19 12:29:46 2006 +0200 -+++ b/include/sound/asequencer.h Mon May 15 12:41:49 2006 +0200 ++++ b/include/sound/asequencer.h Mon May 29 17:08:22 2006 +0200 @@ -317,7 +317,7 @@ struct sndrv_seq_ev_sample_control { struct sndrv_seq_ev_sample sample; struct sndrv_seq_ev_cluster cluster; @@ -127,7 +138,7 @@ /* misc. conditioning flags */ diff -r ae6753322b63 include/sound/asound.h --- a/include/sound/asound.h Wed Apr 19 12:29:46 2006 +0200 -+++ b/include/sound/asound.h Mon May 15 12:41:49 2006 +0200 ++++ b/include/sound/asound.h Mon May 29 17:08:22 2006 +0200 @@ -122,7 +122,7 @@ struct sndrv_hwdep_info { int card; /* R: card number */ unsigned char id[64]; /* ID (user selectable) */ @@ -268,7 +279,7 @@ unsigned int mask; diff -r ae6753322b63 include/sound/emu10k1.h --- a/include/sound/emu10k1.h Wed Apr 19 12:29:46 2006 +0200 -+++ b/include/sound/emu10k1.h Mon May 15 12:41:49 2006 +0200 ++++ b/include/sound/emu10k1.h Mon May 29 17:08:22 2006 +0200 @@ -264,7 +264,7 @@ enum emu10k1_ctl_elem_iface { typedef struct { @@ -280,7 +291,7 @@ unsigned char name[44]; /* ASCII name of item */ diff -r ae6753322b63 src/conf.c --- a/src/conf.c Wed Apr 19 12:29:46 2006 +0200 -+++ b/src/conf.c Mon May 15 12:41:49 2006 +0200 ++++ b/src/conf.c Mon May 29 17:08:22 2006 +0200 @@ -3963,7 +3963,7 @@ int snd_config_expand(snd_config_t *conf * \param name Key suffix. * \param result The function puts the handle to the expanded found node at @@ -290,9 +301,20 @@ * * First the key is tried, then, if nothing is found, base.key is tried. * If the value found is a string, this is recursively tried in the +diff -r ae6753322b63 src/conf/cards/ENS1370.conf +--- a/src/conf/cards/ENS1370.conf Wed Apr 19 12:29:46 2006 +0200 ++++ b/src/conf/cards/ENS1370.conf Mon May 29 17:08:22 2006 +0200 +@@ -54,6 +54,7 @@ ENS1370.pcm.rear.0 { + type ctl_elems + hook_args [ + { ++ interface CARD + name "PCM 0 Output also on Line-In Jack" + preserve true + lock true diff -r ae6753322b63 src/conf/cards/ICH4.conf --- a/src/conf/cards/ICH4.conf Wed Apr 19 12:29:46 2006 +0200 -+++ b/src/conf/cards/ICH4.conf Mon May 15 12:41:49 2006 +0200 ++++ b/src/conf/cards/ICH4.conf Mon May 29 17:08:22 2006 +0200 @@ -194,6 +194,7 @@ ICH4.pcm.iec958.0 { hook_args [ { @@ -316,9 +338,76 @@ lock true preserve true value true +diff -r ae6753322b63 src/control/hcontrol.c +--- a/src/control/hcontrol.c Wed Apr 19 12:29:46 2006 +0200 ++++ b/src/control/hcontrol.c Mon May 29 17:08:22 2006 +0200 +@@ -657,22 +657,52 @@ unsigned int snd_hctl_get_count(snd_hctl + * \brief Wait for a HCTL to become ready (i.e. at least one event pending) + * \param hctl HCTL handle + * \param timeout maximum time in milliseconds to wait +- * \return 0 otherwise a negative error code on failure ++ * \return a positive value on success otherwise a negative error code ++ * \retval 0 timeout occurred ++ * \retval 1 an event is pending + */ + int snd_hctl_wait(snd_hctl_t *hctl, int timeout) + { +- struct pollfd pfd; +- int err; +- err = snd_hctl_poll_descriptors(hctl, &pfd, 1); ++ struct pollfd *pfd; ++ unsigned short *revents; ++ int i, npfds, pollio, err, err_poll; ++ ++ npfds = snd_hctl_poll_descriptors_count(hctl); ++ if (npfds <= 0 || npfds >= 16) { ++ SNDERR("Invalid poll_fds %d\n", npfds); ++ return -EIO; ++ } ++ pfd = alloca(sizeof(*pfd) * npfds); ++ revents = alloca(sizeof(*revents) * npfds); ++ err = snd_hctl_poll_descriptors(hctl, pfd, npfds); + if (err < 0) + return err; +- if (! err) +- return 0; +- assert(err == 1); +- err = poll(&pfd, 1, timeout); +- if (err < 0) +- return -errno; +- return 0; ++ if (err != npfds) { ++ SNDMSG("invalid poll descriptors %d\n", err); ++ return -EIO; ++ } ++ do { ++ pollio = 0; ++ err_poll = poll(pfd, npfds, timeout); ++ if (err_poll < 0) { ++ if (errno == EINTR) ++ continue; ++ return -errno; ++ } ++ if (! err_poll) ++ break; ++ err = snd_hctl_poll_descriptors_revents(hctl, pfd, npfds, revents); ++ if (err < 0) ++ return err; ++ for (i = 0; i < npfds; i++) { ++ if (revents[i] & (POLLERR | POLLNVAL)) ++ return -EIO; ++ if ((revents[i] & (POLLIN | POLLOUT)) == 0) ++ continue; ++ pollio++; ++ } ++ } while (! pollio); ++ return err_poll > 0 ? 1 : 0; + } + + /** diff -r ae6753322b63 src/hwdep/hwdep.c --- a/src/hwdep/hwdep.c Wed Apr 19 12:29:46 2006 +0200 -+++ b/src/hwdep/hwdep.c Mon May 15 12:41:49 2006 +0200 ++++ b/src/hwdep/hwdep.c Mon May 29 17:08:22 2006 +0200 @@ -207,6 +207,8 @@ int snd_hwdep_close(snd_hwdep_t *hwdep) int err; assert(hwdep); @@ -330,7 +419,7 @@ return err; diff -r ae6753322b63 src/pcm/pcm_direct.c --- a/src/pcm/pcm_direct.c Wed Apr 19 12:29:46 2006 +0200 -+++ b/src/pcm/pcm_direct.c Mon May 15 12:41:49 2006 +0200 ++++ b/src/pcm/pcm_direct.c Mon May 29 17:08:22 2006 +0200 @@ -82,6 +82,8 @@ int snd_pcm_direct_semaphore_create_or_c return 0; } @@ -474,7 +563,7 @@ } diff -r ae6753322b63 src/pcm/pcm_direct.h --- a/src/pcm/pcm_direct.h Wed Apr 19 12:29:46 2006 +0200 -+++ b/src/pcm/pcm_direct.h Mon May 15 12:41:49 2006 +0200 ++++ b/src/pcm/pcm_direct.h Mon May 29 17:08:22 2006 +0200 @@ -51,8 +51,10 @@ struct slave_params { }; @@ -502,7 +591,7 @@ int snd_pcm_direct_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents); diff -r ae6753322b63 src/pcm/pcm_dmix.c --- a/src/pcm/pcm_dmix.c Wed Apr 19 12:29:46 2006 +0200 -+++ b/src/pcm/pcm_dmix.c Mon May 15 12:41:49 2006 +0200 ++++ b/src/pcm/pcm_dmix.c Mon May 29 17:08:22 2006 +0200 @@ -650,8 +650,10 @@ static int snd_pcm_dmix_close(snd_pcm_t if (dmix->client) snd_pcm_direct_client_discard(dmix); @@ -598,7 +687,7 @@ diff -r ae6753322b63 src/pcm/pcm_dshare.c --- a/src/pcm/pcm_dshare.c Wed Apr 19 12:29:46 2006 +0200 -+++ b/src/pcm/pcm_dshare.c Mon May 15 12:41:49 2006 +0200 ++++ b/src/pcm/pcm_dshare.c Mon May 29 17:08:22 2006 +0200 @@ -464,8 +464,10 @@ static int snd_pcm_dshare_close(snd_pcm_ snd_pcm_direct_server_discard(dshare); if (dshare->client) @@ -693,7 +782,7 @@ diff -r ae6753322b63 src/pcm/pcm_dsnoop.c --- a/src/pcm/pcm_dsnoop.c Wed Apr 19 12:29:46 2006 +0200 -+++ b/src/pcm/pcm_dsnoop.c Mon May 15 12:41:49 2006 +0200 ++++ b/src/pcm/pcm_dsnoop.c Mon May 29 17:08:22 2006 +0200 @@ -360,8 +360,10 @@ static int snd_pcm_dsnoop_close(snd_pcm_ snd_pcm_direct_server_discard(dsnoop); if (dsnoop->client) @@ -788,7 +877,7 @@ diff -r ae6753322b63 src/pcm/pcm_extplug.c --- a/src/pcm/pcm_extplug.c Wed Apr 19 12:29:46 2006 +0200 -+++ b/src/pcm/pcm_extplug.c Mon May 15 12:41:49 2006 +0200 ++++ b/src/pcm/pcm_extplug.c Mon May 29 17:08:22 2006 +0200 @@ -30,6 +30,11 @@ #include "pcm_plugin.h" #include "pcm_extplug.h" @@ -803,19 +892,207 @@ diff -r ae6753322b63 src/pcm/pcm_file.c --- a/src/pcm/pcm_file.c Wed Apr 19 12:29:46 2006 +0200 -+++ b/src/pcm/pcm_file.c Mon May 15 12:41:49 2006 +0200 -@@ -234,7 +234,7 @@ static snd_pcm_sframes_t snd_pcm_file_re ++++ b/src/pcm/pcm_file.c Mon May 29 17:08:22 2006 +0200 +@@ -46,6 +46,8 @@ typedef struct { + snd_pcm_generic_t gen; + char *fname; + int fd; ++ char *ifname; ++ int ifd; + int format; + snd_pcm_uframes_t appl_ptr; + snd_pcm_uframes_t file_ptr_bytes; +@@ -53,6 +55,9 @@ typedef struct { + size_t wbuf_size_bytes; + size_t wbuf_used_bytes; + char *wbuf; ++ size_t rbuf_size_bytes; ++ size_t rbuf_used_bytes; ++ char *rbuf; + snd_pcm_channel_area_t *wbuf_areas; + size_t buffer_bytes; + } snd_pcm_file_t; +@@ -120,6 +125,10 @@ static int snd_pcm_file_close(snd_pcm_t + free((void *)file->fname); + close(file->fd); + } ++ if (file->ifname) { ++ free((void *)file->ifname); ++ close(file->ifd); ++ } + return snd_pcm_generic_close(pcm); + } + +@@ -222,10 +231,20 @@ static snd_pcm_sframes_t snd_pcm_file_re + { + snd_pcm_file_t *file = pcm->private_data; + snd_pcm_channel_area_t areas[pcm->channels]; +- snd_pcm_sframes_t n = snd_pcm_readi(file->gen.slave, buffer, size); +- if (n > 0) { +- snd_pcm_areas_from_buf(pcm, areas, buffer); +- snd_pcm_file_add_frames(pcm, areas, 0, n); ++ snd_pcm_sframes_t n /* , bytesn */; ++ ++ if (file->ifd >= 0) { ++ n = /* bytesn = */ read(file->ifd, buffer, size * pcm->frame_bits / 8); ++ if (n > 0) ++ n = n * 8 / pcm->frame_bits; ++ /* SNDERR("DEBUG: channels = %d, sample_bits = %d, frame_bits = %d, bytes = %d, frames = %d", ++ pcm->channels, pcm->sample_bits, pcm->frame_bits, bytesn, n); */ ++ } else { ++ n = snd_pcm_readi(file->gen.slave, buffer, size); ++ if (n > 0) { ++ snd_pcm_areas_from_buf(pcm, areas, buffer); ++ snd_pcm_file_add_frames(pcm, areas, 0, n); ++ } + } + return n; + } +@@ -234,7 +253,14 @@ static snd_pcm_sframes_t snd_pcm_file_re { snd_pcm_file_t *file = pcm->private_data; snd_pcm_channel_area_t areas[pcm->channels]; - snd_pcm_sframes_t n = snd_pcm_writen(file->gen.slave, bufs, size); -+ snd_pcm_sframes_t n = snd_pcm_readn(file->gen.slave, bufs, size); ++ snd_pcm_sframes_t n; ++ ++ if (file->ifd >= 0) { ++ SNDERR("DEBUG: Noninterleaved read not yet implemented.\n"); ++ return 0; /* TODO: Noninterleaved read */ ++ } ++ ++ n = snd_pcm_readn(file->gen.slave, bufs, size); if (n > 0) { snd_pcm_areas_from_bufs(pcm, areas, bufs); snd_pcm_file_add_frames(pcm, areas, 0, n); +@@ -365,8 +391,11 @@ static snd_pcm_fast_ops_t snd_pcm_file_f + * \brief Creates a new File PCM + * \param pcmp Returns created PCM handle + * \param name Name of PCM +- * \param fname Filename (or NULL if file descriptor is available) +- * \param fd File descriptor ++ * \param fname Output filename (or NULL if file descriptor fd is available) ++ * \param fd Output file descriptor ++ * \param ifname Input filename (or NULL if file descriptor ifd is available) ++ * \param ifd Input file descriptor (if (ifd < 0) && (ifname == NULL), no input ++ * redirection will be performed) + * \param fmt File format ("raw" is supported only) + * \param perm File permission + * \param slave Slave PCM handle +@@ -377,8 +406,8 @@ static snd_pcm_fast_ops_t snd_pcm_file_f + * changed in future. + */ + int snd_pcm_file_open(snd_pcm_t **pcmp, const char *name, +- const char *fname, int fd, const char *fmt, int perm, +- snd_pcm_t *slave, int close_slave) ++ const char *fname, int fd, const char *ifname, int ifd, ++ const char *fmt, int perm, snd_pcm_t *slave, int close_slave) + { + snd_pcm_t *pcm; + snd_pcm_file_t *file; +@@ -395,7 +424,7 @@ int snd_pcm_file_open(snd_pcm_t **pcmp, + if (fname) { + fd = open(fname, O_WRONLY|O_CREAT, perm); + if (fd < 0) { +- SYSERR("open %s failed", fname); ++ SYSERR("open %s for writing failed", fname); + return -errno; + } + } +@@ -405,10 +434,23 @@ int snd_pcm_file_open(snd_pcm_t **pcmp, + close(fd); + return -ENOMEM; + } +- ++ ++ if (ifname) { ++ ifd = open(ifname, O_RDONLY); /* TODO: mind blocking mode */ ++ if (ifd < 0) { ++ SYSERR("open %s for reading failed", ifname); ++ if (fname) ++ close(fd); ++ return -errno; ++ } ++ } ++ + if (fname) + file->fname = strdup(fname); ++ if (ifname) ++ file->ifname = strdup(ifname); + file->fd = fd; ++ file->ifd = ifd; + file->format = format; + file->gen.slave = slave; + file->gen.close_slave = close_slave; +@@ -436,7 +478,8 @@ int snd_pcm_file_open(snd_pcm_t **pcmp, + + \section pcm_plugins_file Plugin: File + +-This plugin stores contents of a PCM stream to file. ++This plugin stores contents of a PCM stream to file, and optionally ++uses an existing file as an input data source (i.e., "virtual mic") + + \code + pcm.name { +@@ -448,11 +491,14 @@ pcm.name { + # or + pcm { } # Slave PCM definition + } +- file STR # Filename ++ file STR # Output filename + or +- file INT # File descriptor number ++ file INT # Output file descriptor number ++ infile STR # Input filename ++ or ++ infile INT # Input file descriptor number + [format STR] # File format (only "raw" at the moment) +- [perm INT] # File permission (octal, default 0600) ++ [perm INT] # Output file permission (octal, def. 0600) + } + \endcode + +@@ -486,9 +532,9 @@ int _snd_pcm_file_open(snd_pcm_t **pcmp, + int err; + snd_pcm_t *spcm; + snd_config_t *slave = NULL, *sconf; +- const char *fname = NULL; ++ const char *fname = NULL, *ifname = NULL; + const char *format = NULL; +- long fd = -1; ++ long fd = -1, ifd = -1; + int perm = 0600; + snd_config_for_each(i, next, conf) { + snd_config_t *n = snd_config_iterator_entry(i); +@@ -513,6 +559,17 @@ int _snd_pcm_file_open(snd_pcm_t **pcmp, + err = snd_config_get_string(n, &fname); + if (err < 0) { + err = snd_config_get_integer(n, &fd); ++ if (err < 0) { ++ SNDERR("Invalid type for %s", id); ++ return -EINVAL; ++ } ++ } ++ continue; ++ } ++ if (strcmp(id, "infile") == 0) { ++ err = snd_config_get_string(n, &ifname); ++ if (err < 0) { ++ err = snd_config_get_integer(n, &ifd); + if (err < 0) { + SNDERR("Invalid type for %s", id); + return -EINVAL; +@@ -556,7 +613,7 @@ int _snd_pcm_file_open(snd_pcm_t **pcmp, + snd_config_delete(sconf); + if (err < 0) + return err; +- err = snd_pcm_file_open(pcmp, name, fname, fd, format, perm, spcm, 1); ++ err = snd_pcm_file_open(pcmp, name, fname, fd, ifname, ifd, format, perm, spcm, 1); + if (err < 0) + snd_pcm_close(spcm); + return err; diff -r ae6753322b63 src/pcm/pcm_hooks.c --- a/src/pcm/pcm_hooks.c Wed Apr 19 12:29:46 2006 +0200 -+++ b/src/pcm/pcm_hooks.c Mon May 15 12:41:49 2006 +0200 ++++ b/src/pcm/pcm_hooks.c Mon May 29 17:08:22 2006 +0200 @@ -397,16 +397,18 @@ static int snd_pcm_hook_add_conf(snd_pcm _err: if (type) @@ -846,7 +1123,7 @@ return 0; diff -r ae6753322b63 src/pcm/pcm_hw.c --- a/src/pcm/pcm_hw.c Wed Apr 19 12:29:46 2006 +0200 -+++ b/src/pcm/pcm_hw.c Mon May 15 12:41:49 2006 +0200 ++++ b/src/pcm/pcm_hw.c Mon May 29 17:08:22 2006 +0200 @@ -1240,6 +1240,8 @@ int snd_pcm_hw_open(snd_pcm_t **pcmp, co fmode |= O_NONBLOCK; if (mode & SND_PCM_ASYNC) @@ -858,7 +1135,7 @@ ret = -errno; diff -r ae6753322b63 src/pcm/pcm_ioplug.c --- a/src/pcm/pcm_ioplug.c Wed Apr 19 12:29:46 2006 +0200 -+++ b/src/pcm/pcm_ioplug.c Mon May 15 12:41:49 2006 +0200 ++++ b/src/pcm/pcm_ioplug.c Mon May 29 17:08:22 2006 +0200 @@ -29,6 +29,11 @@ #include "pcm_local.h" #include "pcm_ioplug.h" @@ -871,9 +1148,38 @@ #ifndef DOC_HIDDEN +@@ -106,8 +111,15 @@ static int snd_pcm_ioplug_hwsync(snd_pcm + + static int snd_pcm_ioplug_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp) + { +- snd_pcm_ioplug_hw_ptr_update(pcm); +- *delayp = snd_pcm_mmap_hw_avail(pcm); ++ ioplug_priv_t *io = pcm->private_data; ++ ++ if (io->data->version >= 0x010001 && ++ io->data->callback->delay) ++ return io->data->callback->delay(io->data, delayp); ++ else { ++ snd_pcm_ioplug_hw_ptr_update(pcm); ++ *delayp = snd_pcm_mmap_hw_avail(pcm); ++ } + return 0; + } + +@@ -872,7 +884,9 @@ int snd_pcm_ioplug_create(snd_pcm_ioplug + ioplug->callback->stop && + ioplug->callback->pointer); + +- if (ioplug->version != SND_PCM_IOPLUG_VERSION) { ++ /* We support 1.0.0 to current */ ++ if (ioplug->version < 0x010000 || ++ ioplug->version > SND_PCM_IOPLUG_VERSION) { + SNDERR("ioplug: Plugin version mismatch\n"); + return -ENXIO; + } diff -r ae6753322b63 src/pcm/pcm_local.h --- a/src/pcm/pcm_local.h Wed Apr 19 12:29:46 2006 +0200 -+++ b/src/pcm/pcm_local.h Mon May 15 12:41:49 2006 +0200 ++++ b/src/pcm/pcm_local.h Mon May 29 17:08:22 2006 +0200 @@ -746,6 +746,8 @@ int snd_pcm_slave_conf(snd_config_t *roo int snd_pcm_slave_conf(snd_config_t *root, snd_config_t *conf, snd_config_t **pcm_conf, unsigned int count, ...); @@ -885,7 +1191,7 @@ int mode, snd_config_t *parent_conf); diff -r ae6753322b63 src/pcm/pcm_meter.c --- a/src/pcm/pcm_meter.c Wed Apr 19 12:29:46 2006 +0200 -+++ b/src/pcm/pcm_meter.c Mon May 15 12:41:49 2006 +0200 ++++ b/src/pcm/pcm_meter.c Mon May 29 17:08:22 2006 +0200 @@ -67,6 +67,7 @@ typedef struct _snd_pcm_meter { pthread_mutex_t running_mutex; pthread_cond_t running_cond; @@ -932,7 +1238,7 @@ /*! \page pcm_plugins diff -r ae6753322b63 src/pcm/pcm_rate.c --- a/src/pcm/pcm_rate.c Wed Apr 19 12:29:46 2006 +0200 -+++ b/src/pcm/pcm_rate.c Mon May 15 12:41:49 2006 +0200 ++++ b/src/pcm/pcm_rate.c Mon May 29 17:08:22 2006 +0200 @@ -68,6 +68,8 @@ struct _snd_pcm_rate { unsigned int put_idx; int16_t *src_buf; @@ -1063,7 +1369,7 @@ SND_PCM_HW_PARAM_RATE, SCONF_MANDATORY, &srate); diff -r ae6753322b63 src/seq/seq.c --- a/src/seq/seq.c Wed Apr 19 12:29:46 2006 +0200 -+++ b/src/seq/seq.c Mon May 15 12:41:49 2006 +0200 ++++ b/src/seq/seq.c Mon May 29 17:08:22 2006 +0200 @@ -915,7 +915,14 @@ static int snd_seq_open_conf(snd_seq_t * _err: if (type_conf) @@ -1119,7 +1425,7 @@ * A port may contain specific midi channels, midi voices and synth voices. diff -r ae6753322b63 src/seq/seq_local.h --- a/src/seq/seq_local.h Wed Apr 19 12:29:46 2006 +0200 -+++ b/src/seq/seq_local.h Mon May 15 12:41:49 2006 +0200 ++++ b/src/seq/seq_local.h Mon May 29 17:08:22 2006 +0200 @@ -76,6 +76,7 @@ struct _snd_seq { int streams; int mode; @@ -1130,7 +1436,7 @@ int client; /* client number */ diff -r ae6753322b63 src/timer/timer.c --- a/src/timer/timer.c Wed Apr 19 12:29:46 2006 +0200 -+++ b/src/timer/timer.c Mon May 15 12:41:49 2006 +0200 ++++ b/src/timer/timer.c Mon May 29 17:08:22 2006 +0200 @@ -171,7 +171,14 @@ static int snd_timer_open_conf(snd_timer _err: if (type_conf) @@ -1158,7 +1464,7 @@ return err; diff -r ae6753322b63 src/timer/timer_local.h --- a/src/timer/timer_local.h Wed Apr 19 12:29:46 2006 +0200 -+++ b/src/timer/timer_local.h Mon May 15 12:41:49 2006 +0200 ++++ b/src/timer/timer_local.h Mon May 29 17:08:22 2006 +0200 @@ -40,6 +40,7 @@ typedef struct { struct _snd_timer { @@ -1177,7 +1483,7 @@ int mode; diff -r ae6753322b63 src/timer/timer_query.c --- a/src/timer/timer_query.c Wed Apr 19 12:29:46 2006 +0200 -+++ b/src/timer/timer_query.c Mon May 15 12:41:49 2006 +0200 ++++ b/src/timer/timer_query.c Mon May 29 17:08:22 2006 +0200 @@ -129,7 +129,14 @@ static int snd_timer_query_open_conf(snd _err: if (type_conf) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Remember to have fun...