[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