[buug] About OSS program

George Wong crazylion at vip.sina.com
Wed Aug 11 05:20:18 PDT 2004


I am doing VOIP modules of a project. There are some troubles when I program after I reading some articles.

After Linux booting, the results of lsmod is:
Module       Size       Used by     Not tainted 
i810_audio   27720       0 (autoclean) 
ac97_codec   13640       0 (autoclean) [i810_audio] 
soundcore    6404        2 (autoclean) [i810_audio] 

There is no error if I do "cat /dev/dsp > hello" and "cat hello > /dev/dsp". But if I try to open () device, it will display "cannot open device: resource or device busy". The result of lsmod is 
Module       Size       Used by     Not tainted 
i810_audio   27720       1 (autoclean) 
ac97_codec   13640       0 (autoclean) [i810_audio] 
soundcore    6404        2 (autoclean) [i810_audio] 

I wrote a short piece of test function. As following:
/*-------open_test.c--------*/ 
#include <stdio.h> 
#include <stdlib.h> 
#include <sys/ioctl.h> 
#include <linux/soundcard.h> 
#include <fcntl.h> 
#include <unistd.h> 


#define DEVICE "/dev/audio" 

int main() 
{ 
	int fd=-1; 
	char cmd[10]; 
	fd = open(DEVICE,O_RDWR); 
	printf("The file descriptor is %d\n",fd); 
	if( fd == -1 ) 
	{ 
		fprintf(stderr,"\nUnable to open audio device.\n"); 
		fflush(stderr); 
	} 
	printf("Please enter command :"); 
	scanf("Please enter command %s",cmd); 
	if(!strcmp(cmd,"quit")) 
	{ 
		close(fd); 
		printf("Has already close the device\n"); 
	} 

	return 0; 
} 
The running result is:
The file descriptor is -1

Unable to open audio device.



I want to ask four questions:
1. After booting, soundcore was used by 2 programs (maybe modules), which they are? How could I find them out? Is it important for the situation that I cannot open audio device using open (2)?

2. Why I cannot open device in following situation?
Module       Size    Used by       Not tainted 
i810_audio   27720   0 (autoclean) 
ac97_codec   13640   0 (autoclean) [i810_audio] 
soundcore    6404    2 (autoclean) [i810_audio] 
And why I could play cd and mp3 in the situation? And I read the code of xmms, it is also using open(2), and why the xmms could open the device and I cannot?

3. A record program which I wrote could run on an embedded platform which we used in project. And I tried char buffer and unsigned buffer, everything is OK. But if I transmit the buffer on the Ethernet, whatever UDP broadcast or TCP streams, I can hear nothing. I doubt that it is the fault of type of buffer, I switch char to unsigned char or unsigned char to char, but it's no use. I am puzzle about which type should I use? I check IPP which is a product of Intel, is define many types of buffer, such as char, unsigned char, short int, int etc. I am not sure which type is best for my application. Is it according to rate, frequency, channel etc. which I set?

4. I try to recompile the kernel, check if it is the faults of driver. But I always encounter some odd error, such as parse error, parameter error etc. We meet this kind of error when we develop the driver of camera under Linux on embedded system. I think the code of kernel should be correct, if it has errors, how does zImage compiled when I install the Linux? My system is redhat9 on TOSHIBA satellite3000.

Following is the record program which used to test:

/*-------try.c-----------*/

#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <stdio.h>
#include <linux/soundcard.h>

#define LENGTH 3    /* The second which record */
#define RATE 8000   /* Sample frequency */
#define SIZE 16      /* bit */
#define CHANNELS 2  /* Channel */

 /* the buffer used to load audio */
//unsigned char buf[LENGTH*RATE*SIZE*CHANNELS/8];
short buf[LENGTH*RATE*SIZE*CHANNELS/8];

int main()
{
  int fd;	/* File descriptor of device */
  int arg;	/* Argument used in ioctl */
  int status;   /* Return value */

  /* Open device */
  fd = open("/dev/dsp", O_RDWR);
  if (fd < 0) {
    perror("open of /dev/dsp failed");
    exit(1);
  }

  /* Set sample bit */
  arg = SIZE;
  status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg);
  if (status == -1)
    perror("SOUND_PCM_WRITE_BITS ioctl failed");
  if (arg != SIZE)
    perror("unable to set sample size");

  /* Set channel */
  arg = CHANNELS; 
  status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg);
  if (status == -1)
    perror("SOUND_PCM_WRITE_CHANNELS ioctl failed");
  if (arg != CHANNELS)
    perror("unable to set number of channels");

  /* Set rate */
  arg = RATE;
  status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg);
  if (status == -1)
    perror("SOUND_PCM_WRITE_WRITE ioctl failed");

  /* Loop, until press Control-C */
  while (1) {
    status = read(fd, buf, sizeof(buf)); /* Record */
    printf("The record size if %d\n",status);
    if (status != sizeof(buf))
      perror("read wrong number of bytes");
    for(status=0;status<20;status++)
    printf("%d:%d\n",status,buf[status]);

    printf("You said:\n");
    status = write(fd, buf, sizeof(buf)); /* Playback */
    printf("The replay size if %d\n",status);
    if (status != sizeof(buf))
      perror("wrote wrong number of bytes");

    /* Waiting for playback end before record */
    status = ioctl(fd, SOUND_PCM_SYNC, 0); 
    if (status == -1)
      perror("SOUND_PCM_SYNC ioctl failed");
  }
}







More information about the buug mailing list