-------- Original Message --------
Subject: Re: [Alsa-user] Problem with sound (Creative SB Live!)
Date: Sun, 6 Jun 2004 13:22:55 +0200
From: Carlo Wood <[EMAIL PROTECTED]>
To: William M. Quarles <[EMAIL PROTECTED]>
References: <[EMAIL PROTECTED]>
<[EMAIL PROTECTED]> <[EMAIL PROTECTED]>

On Sat, Jun 05, 2004 at 04:02:07PM -0400, William M. Quarles wrote:
Carlo Wood wrote:
<snip>
>Also, the SB Live only has two periods for recording,
>if your application set small periods then the total
>buffer is small - possibly smaller than the application
>is waiting for before processing.
<snip>

How can I change the period size and the number of periods that ALSA uses? Is it possible with ALSA to set the recording buffer beyond the hardware limit of the sound card? Is the period-size problem an application-side issue or an ALSA-side issue?

Thanks,
William

I don't know this from my head either - I never code sound stuff (anymore). You'll have to read some HOWTO from internet. Google for SNDCTL_DSP perhaps.

Here is a code snippet that I used to determine the total
buffer size (or more in general, if the viavoice application has
a chance to work) - but don't ask me anymore how it works.

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <sys/soundcard.h>
#include <time.h>

int main(void)
{
  int fd;
  int res = 0x7fff0009;
  audio_buf_info info;
  int prev_size = 0;
  do
  {
    ++res;
    close(fd);
    fd = open("/dev/dsp", O_RDONLY);
    if (fd == -1) { perror("open"); exit(127); }
    if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &res) == -1) {
      perror("ioctl"); exit(127); }
    if (ioctl(fd, SNDCTL_DSP_GETISPACE, &info) == -1) {
      perror("read"); exit(127); }
    printf("    Allocated %d buffers of %d bytes.\n", info.fragstotal,
info.fragsize);
    if (prev_size == info.fragsize * info.fragstotal)
    {
      if (info.fragsize * info.fragstotal < 8192)
        printf("    It seems impossible to set a recording buffer with a\n"
               "    total size of at least 8192 bytes.  This is not
going\n"
               "    to work with ViaVoice.  Sorry.\n");
      else
      {
        printf("    It seems impossible to set a recording buffer with
a buffer\n"
               "    that is sufficiently large.  It is very likely that
you\n"
               "    will run into problems with viavoice (buffer
overruns)\n");
        exit(0);
      }
      exit(126);
    }
    prev_size = info.fragsize * info.fragstotal;
  }
  while (info.fragsize * (info.fragstotal - 1) < 8192);
  printf("    Successfully allocated a buffer that is large enough.\n");
  fprintf(stderr, "%02x\n", res & 0xff);
  res = AFMT_S16_LE;
  if (ioctl(fd, SNDCTL_DSP_SETFMT, &res) == -1) {
    perror("ioctl"); exit(127); }
  res = 0;
  if (ioctl(fd, SNDCTL_DSP_STEREO, &res) == -1) {
    perror("ioctl"); exit(127); }
  res = 22050;
  if (ioctl(fd, SOUND_PCM_READ_RATE, 0xbfffdcfc) == -1) {
    perror("ioctl"); exit(127); }
  char buf[1024];
  if (read(fd, buf, sizeof(buf)) < 0) { perror("read"); exit(127); }
  static struct timespec naptime = { 0, 100000000 };
  int count = 0;
  do {
    if (ioctl(fd, SNDCTL_DSP_GETISPACE, &info) == -1) {
      perror("read"); exit(127); }
    nanosleep(&naptime, 0);
    if (++count == 20) { printf("Failed to cause an xrun.\n"); exit(0); }
  } while(info.bytes < info.fragsize * info.fragstotal);
  printf("    Successfully caused an xrun.\n");
  printf("    non-blocking fragments: %d\n", info.fragments);
  printf("    non-blocking bytes: %d\n", info.bytes);
  ssize_t bufsize = info.bytes;
  ssize_t trlen = 0;
  int nf = 0;
  for (;;)
  {
    if (info.fragments > 0) {
      ssize_t rlen;
      if ((rlen = read(fd, buf, sizeof(buf))) < 0)
      { perror("read"); exit(127); }
      trlen += rlen;
      if (trlen > bufsize) {
        printf("    Read %d bytes: stream successfully restarted.\n",
trlen);
        break;
      }
      nf = 0;
    }
    else if (++nf > 10) {
      printf("    Stream is not restarted after xrun.\n");
      exit(1);
    }
    if (ioctl(fd, SNDCTL_DSP_GETISPACE, &info) == -1) {
      perror("read"); exit(127); }
  }
  close(fd);
  return 0;
}


-- Carlo Wood <[EMAIL PROTECTED]>




------------------------------------------------------- This SF.Net email is sponsored by the new InstallShield X.
From Windows to Linux, servers to mobile, InstallShield X is the one
installation-authoring solution that does it all. Learn more and
evaluate today! http://www.installshield.com/Dev2Dev/0504
_______________________________________________
Alsa-user mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-user

Reply via email to