-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Content-Type: multipart/mixed ; boundary="==_Exmh_-6418788280" This is a multipart MIME message. - --==_Exmh_-6418788280 Content-Type: text/plain; charset=us-ascii pbd_AT_Op.Net said: > there are a number of ways of fixing this. > my favorite method is to fill the buffer with silence, then start it > via SND_PCM_START_GO and an explicit start call. I understand perfectly what you mean. Thanks. I fixed ALSArtaudio-block.c according to your suggestion with the SND_PCM_START_GO and this. It works perfectly now (at least for me). I call snd_pcm_go() after writing the first fragment for playback, so I don't need the silence filled in the buffer, (and before getting the first fragment for capture). That way I get exactly what I wanted: transfer started immediately after writing the first fragment. dlphilp_AT_bright.net said: > Btw, it appears that we can have the ALSA driver or OSS-RTAUDIO but > not both. I compiled using both options, and the test files defaulted > to the OSS i/o even with incard/outcard (adc/dac). you mean you did --with-OSS *and* --with-ALSA (or similar, you know what I mean:-)). Yes, you can't select both. I've attached the new working ALSArtaudio-block.c. Try it. It should consume less cpu time. Markus - --==_Exmh_-6418788280 Content-Type: text/plain ; name="ALSArtaudio-block.c"; charset=us-ascii Content-Description: ALSArtaudio-block.c Content-Disposition: attachment; filename="ALSArtaudio-block.c" /* ALSArtaudio.c - hacked version of rtaudio.c to enable realtime full-duplex audio support for csound under Linux/ALSA. This file incorporates the functions from LINUXaudio.c (with the exception of sndsetvolume() which isn't used in this hacked version) so that file is no longer needed - fcf */ /* * $Id: ALSArtaudio.c,v 1.6 1999/06/23 18:23:57 nicb Exp $ */ /* This module is included when RTAUDIO is defined at compile time. It provides an interface between Csound realtime record/play calls and the device-driver code that controls the actual hardware. */ /* This is an updated version of the csound to ALSA interface, and works with latest ALSA 0.5.8. The code in this file (ALSArtaudio-block.c) uses the ALSA block transfer mode. You may want to use stream transfer mode (look at ALSArtaudio-stream.c), which is faster (much less latency = much more realtime than the block mode version used in this file). - Markus Gruber */ #include #include "cs.h" #include "soundio.h" static snd_pcm_t *capture_handle = NULL, *playback_handle = NULL; extern long nrecs; extern OPARMS O; #ifdef PIPES extern FILE* Linepipe; #define _pclose pclose #endif char errorstring[1024]; int playback_go = 1; int capture_go = 1; static int getformat() { int p = 0; switch ( O.informat ) { case AE_UNCH: /* unsigned char - standard Linux 8-bit format */ p = SND_PCM_SFMT_U8; break; case AE_CHAR: /* signed char. supported by ALSA */ p = SND_PCM_SFMT_S8; break; case AE_ULAW: p = SND_PCM_SFMT_MU_LAW; break; case AE_ALAW: p = SND_PCM_SFMT_A_LAW; break; case AE_SHORT: p = SND_PCM_SFMT_S16_LE; /* Linux on Intel x86 is little-endian */ break; case AE_LONG: die("ALSA sound driver does not (yet) support long integer samples"); case AE_FLOAT: die("ALSA sound driver does not (yet) support floating-point samples"); default: die("unknown sample format"); } return (p); } void recopen(int nchnls, int dsize, FLOAT esr, int scale) /* open for audio input */ { extern int incard; static snd_pcm_channel_params_t params; int err; char *cardname; if ((err = snd_card_get_longname(incard, &cardname))) { sprintf(errorstring, "%s\n", snd_strerror(err)); die(errorstring); } fprintf(stderr, "ALSA incard: %s\n", cardname); /* Open ALSA audio driver, card #incard, device #0 in CAPTURE mode */ if((err = snd_pcm_open(&capture_handle, incard, 0, SND_PCM_OPEN_CAPTURE))){ sprintf(errorstring, "Opening CAPTURE channel: %s\n", snd_strerror(err)); die(errorstring); } memset(¶ms, 0, sizeof(snd_pcm_channel_params_t)); params.channel = SND_PCM_CHANNEL_CAPTURE; params.mode = SND_PCM_MODE_BLOCK; params.format.interleave = 1; params.format.format = getformat(); params.format.rate = (int)esr; params.format.voices = nchnls; /* digital */ params.start_mode = SND_PCM_START_GO; params.stop_mode = SND_PCM_STOP_ROLLOVER; params.buf.block.frag_size = O.outbufsamps * O.outsampsiz; params.buf.block.frags_min = 1; params.buf.block.frags_max = -1; if ((err = snd_pcm_plugin_params(capture_handle, ¶ms))) { sprintf(errorstring, "CAPTURE channel parameterizing error: %s\n", snd_strerror(err)); die(errorstring); } if ((err = snd_pcm_plugin_prepare(capture_handle, SND_PCM_CHANNEL_CAPTURE))) { sprintf(errorstring, "CAPTURE channel prepare error: %s\n", snd_strerror(err)); die(errorstring); } fprintf(stderr, "Running CAPTURE mode at %d hz on card #%d\n", params.format.rate, incard); } void playopen(int nchnls, int dsize, FLOAT esr, int scale) /* open for audio output */ { extern int outcard; static snd_pcm_channel_params_t params; int err; char *cardname; if ((err = snd_card_get_longname(outcard, &cardname))) { sprintf(errorstring, "%s\n", snd_strerror(err)); die(errorstring); } fprintf(stderr, "ALSA outcard: %s\n", cardname); /* Open ALSA audio driver, card # outcard, device #0 in PLAYBACK mode */ if((err = snd_pcm_open(&playback_handle, outcard, 0, SND_PCM_OPEN_PLAYBACK))){ sprintf(errorstring, "Opening PLAYBACK channel: %s\n", snd_strerror(err)); die(errorstring); } memset(¶ms, 0, sizeof(snd_pcm_channel_params_t)); params.channel = SND_PCM_CHANNEL_PLAYBACK; params.mode = SND_PCM_MODE_BLOCK; params.format.interleave = 1; params.format.format = getformat(); params.format.rate = (int)esr; params.format.voices = nchnls; /* digital */ params.start_mode = SND_PCM_START_GO; params.stop_mode = SND_PCM_STOP_ROLLOVER; params.buf.block.frag_size = O.outbufsamps * O.outsampsiz; params.buf.block.frags_min = 1; params.buf.block.frags_max = -1; if ((err = snd_pcm_plugin_params(playback_handle, ¶ms))) { sprintf(errorstring, "PLAYBACK channel parameterizing error: %s\n", snd_strerror(err)); die(errorstring); } if ((err = snd_pcm_plugin_prepare(playback_handle, SND_PCM_CHANNEL_PLAYBACK))) { sprintf(errorstring, "PLAYBACK channel prepare error: %s\n", snd_strerror(err)); die(errorstring); } fprintf(stderr, "Running PLAYBACK mode at %d hz on card #%d\n", params.format.rate, outcard); #ifdef HIPRI setscheduler(); #endif } int rtrecord(char *inbuf, int nbytes) /* get samples from ADC */ { int fragsize, count, x=0, i, limit, err; char *buf; /* fprintf(stderr, "reading %d bytes from DAC\n", nbytes); */ fragsize = O.outbufsamps * O.outsampsiz; if (fragsize > nbytes) { x = 1; buf = (char *)alloca(fragsize); } else { buf = inbuf; } if (capture_go) { if ((err = snd_pcm_channel_go(capture_handle, SND_PCM_CHANNEL_CAPTURE))) { sprintf(errorstring, "CAPTURE channel go error: %s\n", snd_strerror(err)); die(errorstring); } capture_go = 0; } if((count = snd_pcm_plugin_read(capture_handle, (void *)buf, (size_t)fragsize)) < 0) { sprintf(errorstring, "Capture error: %s", snd_strerror(count)); die(errorstring); } limit = (count > nbytes ? nbytes : count); if (x) { for (i=0; i nbytes) { buf = (char *)alloca(fragsize); memset(buf, 0, fragsize); for (i=0; i