> > 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