Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game. |
Notices |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
|
 |
11-27-2003, 01:43 PM
|
#1
|
Member
Registered: Jul 2003
Location: Bedford, UK
Distribution: Slackware 11.0, LFS 6.1
Posts: 519
Rep:
|
OSS API - opening /dev/dsp when device busy
Hi all,
I am writing an audio application, using the OSS API (I will make it work with ALSA too later). My code does the following:
#include <sys/soundcard.h>
#include <sys/ioctl.h>
#include <sys/unistd.h>
#include <sys/fcntl.h>
....
int *p_audio_fd;
if ((*p_audio_fd = open(DEVICE_NAME, O_WRONLY, 0)) == -1)
{
perror(DEVICE_NAME);
retcode = cannot_open_audio_device;
}
However, what actually happens, if the audio device is busy, is that my code simply waits patiently until the audio device becomes available. It then gets on with its processing. This is very nice, but it's not what I want it to do. I want it instead to raise an error like "/dev/dsp cannot be opened - device busy" like I have seen other audio applications do.
Since open() is clearly not returning -1 when the device is busy, as I expected, how do I code this behaviour?
Thanks for your time!
|
|
|
11-29-2003, 08:30 AM
|
#2
|
Member
Registered: Aug 2003
Location: 63123
Distribution: OpenSuSE/Ubuntu
Posts: 419
Rep:
|
I think I might be able to help.
I am familiar with the OSS API and that code should act as you want it to.
Or at least on my machine it does. I have a couple questions though, what device are
you trying to open? Is it /dev/dsp or something else? Also, could you post some of your actual code? I write an app called SOAP, a video game song player written in OSS. You can download it at http://www.sourceforge.net/projects/soap if you want to take a look at my code, its pretty straightforward.
Last edited by jinksys; 11-29-2003 at 08:32 AM.
|
|
|
11-30-2003, 08:40 AM
|
#3
|
LQ Guru
Registered: Nov 2002
Location: Durham, England
Distribution: Fedora Core 4
Posts: 1,565
Rep:
|
Are you sure you're not actually using ALSA with OSS emulation?
Native OSS will return an error if the device is busy. ALSA will block. There is no way around this behaviour that I know of.
|
|
|
12-01-2003, 03:36 AM
|
#4
|
Member
Registered: Jul 2003
Location: Bedford, UK
Distribution: Slackware 11.0, LFS 6.1
Posts: 519
Original Poster
Rep:
|
You're right, I am using the OSS emulation of ALSA. I will give it native ALSA support at a later time, but I also want to maintain OSS-compatibility, as not everyone manages to get ALSA to work.
I will post some of my actual code when I get home. Thanks for your time!
Last edited by vasudevadas; 12-01-2003 at 03:39 AM.
|
|
|
12-01-2003, 09:48 AM
|
#5
|
Member
Registered: Aug 2003
Location: 63123
Distribution: OpenSuSE/Ubuntu
Posts: 419
Rep:
|
My machine users alsa OSS emulation and the code works as expected on it.
|
|
|
12-01-2003, 12:40 PM
|
#6
|
Member
Registered: Jul 2003
Location: Bedford, UK
Distribution: Slackware 11.0, LFS 6.1
Posts: 519
Original Poster
Rep:
|
Very interesting. Now, when I come to try it, if I run my program first and then press play in Xmms, Xmms waits until I kill my application before it can play music. It does not raise an error. It definitely used to, but I believe I would have been using OSS/Free then. Since I was asked, my code to initialise the audio device is:
#include <stdio.h>
#include <sys/soundcard.h>
#include <sys/ioctl.h>
#include <sys/unistd.h>
#include <sys/fcntl.h>
#include "arctracker.h"
#define DEVICE_NAME "/dev/dsp"
return_status initialise_sound_device(int *p_audio_fd,
long *p_sample_rate,
mono_stereo *p_stereo_mode,
format *p_sample_format)
{
return_status retcode = success;
int sample_format = AFMT_S16_LE; /* signed 16-bit little-endian */
int channels = 2;
if ((*p_audio_fd = open(DEVICE_NAME, O_WRONLY, 0)) == -1)
{
perror(DEVICE_NAME);
retcode = cannot_open_audio_device;
}
if (retcode == success)
{
if (ioctl(*p_audio_fd, SNDCTL_DSP_SETFMT, &sample_format) == -1)
{
perror("SNDCTL_DSP_SETFMT");
retcode = cannot_set_sample_format;
}
switch(sample_format)
{
case AFMT_S16_LE:
*p_sample_format = bits_16_signed_little_endian;
break;
case AFMT_S16_BE:
*p_sample_format = bits_16_signed_big_endian;
break;
case AFMT_U8:
*p_sample_format = bits_8_unsigned;
break;
case AFMT_S8:
*p_sample_format = bits_8_signed;
break;
case AFMT_U16_LE:
*p_sample_format = bits_16_unsigned_little_endian;
break;
case AFMT_U16_BE:
*p_sample_format = bits_16_unsigned_big_endian;
break;
default:
fprintf(stderr,"Cannot set audio device to suitable sample format\n");
retcode = bad_sample_format;
}
}
if (retcode == success)
{
if (ioctl(*p_audio_fd, SNDCTL_DSP_CHANNELS, &channels) == -1)
{
perror("SNDCTL_DSP_CHANNELS");
retcode = cannot_set_channels;
}
switch (channels)
{
case 1:
*p_stereo_mode = mono;
break;
case 2:
*p_stereo_mode = stereo;
break;
default:
fprintf(stderr,"Audio output must be in either one or two channels, actual=%d\n", channels);
retcode = bad_channels;
}
}
if (retcode == success)
{
if (ioctl(*p_audio_fd, SNDCTL_DSP_SPEED, p_sample_rate) == -1)
{
perror("SNDCTL_DSP_SPEED");
retcode = cannot_set_sample_rate;
}
}
printf("Opened audio device %s for output, device parameters are:\n", DEVICE_NAME);
printf("Sample format=%d, number of channels=%d, sample rate=%dKHz\n",
sample_format, channels, *p_sample_rate);
return (retcode);
}
Last edited by vasudevadas; 12-01-2003 at 12:41 PM.
|
|
|
12-01-2003, 12:49 PM
|
#7
|
Member
Registered: Jul 2003
Location: Bedford, UK
Distribution: Slackware 11.0, LFS 6.1
Posts: 519
Original Poster
Rep:
|
jinksys, does that mean that you get an error if a program attempts to open the audio device whilst it is already open? Have you any idea how to implement this behaviour? I think I am using ALSA 0.9.0, it is the version shipped as standard with Mandrake 9.1 at any rate.
(Now I see Xmms behaving in the same way as my own code, I am less inclined to view it as aberrant).
|
|
|
12-01-2003, 01:36 PM
|
#8
|
Member
Registered: Aug 2003
Location: 63123
Distribution: OpenSuSE/Ubuntu
Posts: 419
Rep:
|
When I run my program and push play on XMMS it gives me the usual error.
When I run my program after I open XMMS and play a song, it gives me an
error saying that I cannot open the device, its in use.
What output driver does your XMMS use?
|
|
|
12-01-2003, 01:39 PM
|
#9
|
Member
Registered: Jul 2003
Location: Bedford, UK
Distribution: Slackware 11.0, LFS 6.1
Posts: 519
Original Poster
Rep:
|
It's using the ALSA output plugin libALSA.so.
|
|
|
12-01-2003, 02:01 PM
|
#10
|
Member
Registered: Aug 2003
Location: 63123
Distribution: OpenSuSE/Ubuntu
Posts: 419
Rep:
|
Oh, hmm, I use the OSS output driver. See if you have an OSS output driver available, and see if your app behaves any differently.
|
|
|
12-02-2003, 12:11 PM
|
#11
|
Member
Registered: Jul 2003
Location: Bedford, UK
Distribution: Slackware 11.0, LFS 6.1
Posts: 519
Original Poster
Rep:
|
If I set Xmms to use the OSS output plugin, then:
(1) If I run my application first and while it is playing press "play" in Xmms, it will raise an error "Couldn't open audio."
(2) If I start playing a tune in Xmms first and while it is playing try to run my application, the call to open() will block until Xmms releases the audio device.
This is most perplexing!
|
|
|
All times are GMT -5. The time now is 06:49 AM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|