> > Is the application supposed to always add silence at the end to ensure that > > a multiple of period_size has been written? > > It looks like a bug. Could you send me a little C code which triggers this > problem?
Sure, the code is below. Everything is alright until the I drain() before close(). As it happens, drain() only returns seconds later, with an error. Thanks, Guilhem. #include <stdio.h> #include <sys/time.h> #include <stdlib.h> #include <alsa/asoundlib.h> #include "/usr/src/download/alsa-driver-0.9.0rc6/alsa-kernel/pci/pci2103/pci2103-ioctls.h" #define BUFBYTES 512 #define SIMULBYTES 160000 void About(void) { fprintf (stderr, "Syntax: test_write [-8|-16|-U|-A] [device] [file.raw]\n"); exit (-1); } void writei_func(snd_pcm_t *handle, char *data, snd_pcm_uframes_t count) { int ret; while (count > 0) { ret = snd_pcm_writei (handle, data, count); if (ret < 0) { fprintf(stderr, "write to audio interface failed (%s)", snd_strerror (ret)); exit (-1); } if (ret > 0) { count -= ret; data += snd_pcm_samples_to_bytes(handle, ret); } } } main (int argc, char *argv[]) { int i; int err; int card, dev; char card_id[32]; char dev_id[32]; const char *str_result; snd_ctl_t *ctl_handle; snd_ctl_card_info_t *card_info; snd_hwdep_info_t *hwdep_info; snd_hwdep_iface_t iface; snd_hwdep_t *hwdep; snd_pcm_format_t format; snd_pcm_t *playback_handle; snd_pcm_hw_params_t *hw_params; snd_pcm_uframes_t min_align; snd_pcm_sw_params_t *sw_params; char buf[BUFBYTES]; int fd, bytes, samples, size, isPCI2103 = 0; printf("argc=%d [\"%s\", \"%s\", \"%s\"]\n", argc, argv[1], argv[2], argv[3]); if (argc < 3) { fprintf (stderr, "Not enough arguments!!!\n"); About(); } if (argc > 4) { fprintf (stderr, "Too many arguments!!!\n"); About(); } if (!strcmp(argv[1],"-8")) format = SND_PCM_FORMAT_S8; else if (!strcmp(argv[1],"-16")) format = SND_PCM_FORMAT_S16_LE; else if (!strcmp(argv[1],"-U")) format = SND_PCM_FORMAT_MU_LAW; else if (!strcmp(argv[1],"-A")) format = SND_PCM_FORMAT_G726_16KBPS; else { fprintf (stderr, "Unknown format!!!\n"); About(); } card = atoi(argv[2]+3); if (card < 0 || card > 31) { fprintf (stderr, "Wrong argument '%d' in '%s'\n", card, argv[2]); exit (-1); } //////////////////////////////////////////// // Open the CTL device // Get control handle for selected card sprintf(card_id, "hw:%i", card); if ((err = snd_ctl_open(&ctl_handle, card_id, 0)) < 0) { fprintf (stderr, "control open (%s): %s\n", card_id, snd_strerror(err)); exit (-1); } if ((err = snd_ctl_card_info_malloc(&card_info)) < 0) { fprintf (stderr, "cannot allocate card info structure (%s)\n", snd_strerror (err)); exit (-1); } // Read control info from card if ((err = snd_ctl_card_info(ctl_handle, card_info)) < 0) { fprintf (stderr, "control hardware info (%s): %s\n", card_id, snd_strerror(err)); exit (-1); } // We would prefer a PCI2103 card!!! str_result = snd_ctl_card_info_get_driver(card_info); if (strcmp(str_result, "PCI2103")) { fprintf (stderr, "driver (%s): not a PCI2103 type card\n", str_result); } else isPCI2103 = 1; snd_ctl_card_info_free(card_info); // Find hardware dependant device dev = -1; while (1) { if ((err = snd_ctl_hwdep_next_device(ctl_handle, &dev)) < 0) { fprintf (stderr, "hwdep next device (%s): %s\n", card_id, snd_strerror(err)); break; } if (dev < 0) // no more device break; sprintf(dev_id, "hw:%i,%i", card, dev); if (strcmp(dev_id, argv[2])) // wrong device continue; if ((err = snd_hwdep_info_malloc(&hwdep_info)) < 0) { fprintf (stderr, "cannot allocate hwdep info structure (%s)\n", snd_strerror (err)); exit (-1); } snd_hwdep_info_set_device(hwdep_info, dev); if ((err = snd_ctl_hwdep_info(ctl_handle, hwdep_info)) < 0) { if (err != -ENOENT) { fprintf (stderr, "control hwdep info (%s): %s\n", card_id, snd_strerror(err)); exit (-1); } continue; } iface = snd_hwdep_info_get_iface(hwdep_info); snd_hwdep_info_free(hwdep_info); if (iface == SND_HWDEP_IFACE_PCI2103) { //////////////////////////////////////////////////////// // Open the HWDEP device, and test special APIs if ((err = snd_hwdep_open(&hwdep, dev_id, SND_HWDEP_OPEN_DUPLEX)) < 0) { fprintf (stderr, "cannot open hwdep '%s' (%s)\n", dev_id, snd_strerror (err)); exit (-1); } if ((err = snd_hwdep_ioctl(hwdep, PCI2103_SNDIOC_AES_ENABLE, (void *) 1)) < 0) { fprintf (stderr, "cannot enable AES (%s)\n", snd_strerror (err)); exit (-1); } if ((err = snd_hwdep_ioctl(hwdep, PCI2103_SNDIOC_AES_ENABLE, (void *) 0)) < 0) { fprintf (stderr, "cannot disable AES (%s)\n", snd_strerror (err)); exit (-1); } if ((err = snd_hwdep_close(hwdep)) < 0) { fprintf (stderr, "cannot close hwdep (%s)\n", snd_strerror (err)); exit (-1); } } } snd_ctl_close(ctl_handle); //////////////////////////////////////////// // Open the PCM device if ((err = snd_pcm_open (&playback_handle, argv[2], SND_PCM_STREAM_PLAYBACK, 0)) < 0) { fprintf (stderr, "cannot open audio device %s (%s)\n", argv[2], snd_strerror (err)); exit (-1); } if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) { fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n", snd_strerror (err)); exit (-1); } if ((err = snd_pcm_hw_params_any (playback_handle, hw_params)) < 0) { fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n", snd_strerror (err)); exit (-1); } if ((err = snd_pcm_hw_params_set_access (playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { fprintf (stderr, "cannot set access type (%s)\n", snd_strerror (err)); exit (-1); } if ((err = snd_pcm_hw_params_set_format (playback_handle, hw_params, format)) < 0) { fprintf (stderr, "cannot set sample format (%s)\n", snd_strerror (err)); exit (-1); } if ((err = snd_pcm_hw_params_set_rate_near (playback_handle, hw_params, 8000, 0)) < 0) { fprintf (stderr, "cannot set sample rate (%s)\n", snd_strerror (err)); exit (-1); } if ((err = snd_pcm_hw_params_set_channels (playback_handle, hw_params, 1)) < 0) { fprintf (stderr, "cannot set channel count (%s)\n", snd_strerror (err)); exit (-1); } if ((err = snd_pcm_hw_params (playback_handle, hw_params)) < 0) { fprintf (stderr, "cannot set parameters (%s)\n", snd_strerror (err)); exit (-1); } if ((err = snd_pcm_hw_params_get_min_align (hw_params, &min_align)) < 0) { fprintf (stderr, "cannot get minimum transfer align value (%s)\n", snd_strerror (err)); exit (-1); } snd_pcm_hw_params_free (hw_params); if ((err = snd_pcm_sw_params_malloc (&sw_params)) < 0) { fprintf (stderr, "cannot allocate software parameter structure (%s)\n", snd_strerror (err)); exit (-1); } snd_pcm_sw_params_current(playback_handle, sw_params); if ((err = snd_pcm_sw_params_set_xfer_align(playback_handle, sw_params, min_align)) < 0) { fprintf (stderr, "cannot set xfer_align (%s)\n", snd_strerror (err)); exit (-1); } if ((err = snd_pcm_sw_params(playback_handle, sw_params)) < 0) { fprintf (stderr, "unable to install sw params (%s)\n", snd_strerror (err)); exit (-1); } snd_pcm_sw_params_free (sw_params); //////////////////////////////////////////// // Play some tune samples = snd_pcm_bytes_to_samples(playback_handle, BUFBYTES); samples -= samples % min_align; bytes = snd_pcm_samples_to_bytes(playback_handle, samples); if (argc == 4) { fd = open(argv[3], 0); if (fd >= 0) { i = 0; printf("Now playing from a file in chunks of %d samples (%d bytes)\n", samples, bytes); while ((size = read(fd, buf, bytes)) > 0) { fprintf(stderr, "."); fflush(stderr); samples = snd_pcm_bytes_to_samples(playback_handle, size); samples -= samples % min_align; writei_func(playback_handle, buf, samples); } fprintf(stderr, "\n"); fflush(stderr); close(fd); } } else { for ( i = 0; i < bytes; ++i ) buf[i] = 0xFF; printf("Now playing a simulated sound in chunks of %d samples (%d bytes)...\n", samples, bytes); for (i = 0; i < SIMULBYTES; i+=bytes) writei_func(playback_handle, buf, samples); } snd_pcm_drain (playback_handle); printf( "Playing is now finished.\n" ); snd_pcm_close (playback_handle); exit (0); } __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com ------------------------------------------------------- This sf.net email is sponsored by: With Great Power, Comes Great Responsibility Learn to use your power at OSDN's High Performance Computing Channel http://hpc.devchannel.org/ _______________________________________________ Alsa-devel mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/alsa-devel