📄 sound_oss.cxx
字号:
/*
* sound.cxx
*
* Sound driver implementation.
*
* Portable Windows Library
*
* Copyright (c) 1993-1998 Equivalence Pty. Ltd.
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Portable Windows Library.
*
* The Initial Developer of the Original Code is Equivalence Pty. Ltd.
*
* Portions are Copyright (C) 1993 Free Software Foundation, Inc.
* All Rights Reserved.
*
* Contributor(s): Loopback feature: Philip Edelbrock <phil@netroedge.com>.
*
* $Log: sound_oss.cxx,v $
* Revision 1.1 2006/06/29 04:17:58 joegenbaclor
* *** empty log message ***
*
* Revision 1.10 2006/04/23 18:16:59 dsandras
* Fixed OSS plugin when there is no resampling.
*
* Revision 1.9 2005/11/30 12:47:38 csoutheren
* Removed tabs, reformatted some code, and changed tags for Doxygen
*
* Revision 1.8 2005/08/14 12:58:58 csoutheren
* Fixed build problem on 64bit Linux
*
* Revision 1.7 2004/11/15 13:26:43 csoutheren
* Removed debugging (oops!)
*
* Revision 1.6 2004/11/08 04:04:51 csoutheren
* Added resampling to allow operation on hardware that only supports 48khz
*
* Revision 1.5 2004/11/07 20:01:31 dsandras
* Make sure lastWriteCount is updated.
*
* Revision 1.4 2003/11/18 10:59:06 csoutheren
* Removed ALSA compatibility hack as ALSA users can use the ALSA plugin
*
* Revision 1.3 2003/11/14 05:58:00 csoutheren
* Removed loopback code as this should be in a seperate plugin :)
*
* Revision 1.2 2003/11/12 03:24:15 csoutheren
* Imported plugin code from crs_pwlib_plugin branch and combined with
* new plugin code from Snark of GnomeMeeting
*
* Revision 1.1.2.1 2003/10/07 01:36:51 csoutheren
* nitial checkin of pwlib code to do plugins.
* Modified from original code and concept provided by Snark of Gnomemeeting
*
* Revision 1.59 2003/05/24 10:57:05 rogerhardiman
* If a sound device cannot be opened in RW mode, try just 'R' or 'W' modes.
* Needed for USB web cams with Mics which are read only sound devices when using
* ALSA. Tested by Damien.
*
* Revision 1.58 2003/02/02 18:54:22 rogerh
* FreeBSD changes for support of dspN.M (eg dsp0.0) sound card entries.
* Problem reported by Lars Eggert <larse@isi.edu>
*
* Revision 1.57 2003/01/06 19:25:07 rogerh
* Add NetBSD video support.
* Add correct includes for OSS ioctls (note the proper way to do this now
* is via pwlib commands)
* From Andreas Wrede, taken in part from NetBSD's package system
*
* Revision 1.56 2003/01/06 19:10:22 rogerh
* NetBSD uses /dev/audio and not /dev/dsp
*
* Revision 1.55 2002/12/12 09:03:56 rogerh
* On two FreeBSD machines, Read() calls from the sound card were not blocking
* correctly and returned with less bytes than asked for. This made OpenH323
* close the sound channel. Add a FreeBSD workaround so Read() loops until it
* has all the bytes requested.
*
* Revision 1.54 2002/12/03 23:03:54 rogerh
* oops - remove some test code which should not have been committed
*
* Revision 1.53 2002/12/03 19:11:58 rogerh
* Open sound device in non blocking mode incase it is already open.
*
* Revision 1.52 2002/11/28 12:15:24 rogerh
* Change SetVolume/GetVolume to use the mic and not the igain for the input
* volume.
* Our target audience are likely to be using mics and many broken
* sound drivers do not implement igain properly.
*
* Revision 1.51 2002/10/17 12:57:24 robertj
* Added ability to increase maximum file handles on a process.
*
* Revision 1.50 2002/10/15 10:42:45 rogerh
* Fix loopback mode, which was broken in a recent change.
*
* Revision 1.49 2002/09/29 16:19:28 rogerh
* if /dev/dsp does not exist, do not return it as the default audio device.
* Instead, return the first dsp device.
*
* Revision 1.48 2002/09/29 15:56:49 rogerh
* Revert back to checking for the /dev/soundcard directory to detect devfs.
* If seems that the .devfsd file is not removed when devfs is not being used.
*
* Revision 1.47 2002/09/29 09:26:16 rogerh
* Changes to sound card detection.
* For Damien Sandras, allow /dev/dsp to be added to the list of sound devices
* For FreeBSD, ignore /dev/dspN.M eg /dev/dsp0.2 which are virtual soundcards
*
* Revision 1.46 2002/08/30 07:58:27 craigs
* Added fix for when sound cards are already open, thanks to Damien Sandras
*
* Revision 1.45 2002/08/15 19:57:38 rogerh
* Linux defvs mode is detected with /dev/.devfsd
*
* Revision 1.44 2002/07/04 05:00:36 robertj
* Fixed order of calls for OSS driver setup.
*
* Revision 1.43 2002/06/24 20:01:53 rogerh
* Add support for linux devfs and /dev/sound. Based on code by Snark.
*
* Revision 1.42 2002/06/09 16:33:45 rogerh
* Use new location of soundcard.h on FreeBSD
*
* Revision 1.41 2002/06/05 12:29:15 craigs
* Changes for gcc 3.1
*
* Revision 1.40 2002/05/02 14:19:32 rogerh
* Handle Big Endian systems correctly.
* Patch submitted by andi@fischlustig.de
*
* Revision 1.39 2002/02/11 07:21:46 rogerh
* Fix some non portable code which which seeks out /dev/dsp devices and only
* worked on Linux. (char device for /dev/dsp is 14 on Linux, 30 on FreeBSD)
*
* Revision 1.38 2002/02/09 00:52:01 robertj
* Slight adjustment to API and documentation for volume functions.
*
* Revision 1.37 2002/02/07 20:57:21 dereks
* add SetVolume and GetVolume methods to PSoundChannel
*
* Revision 1.36 2002/01/24 05:57:38 rogerh
* Fix warning
*
* Revision 1.35 2002/01/24 05:55:52 rogerh
* fill lastReadCount (in the base class) when doing a Read.
*
* Revision 1.34 2002/01/07 04:15:38 robertj
* Removed ALSA major device number as this is not how it does its OSS
* compatibility mode, it uses device id 14 as usual.
*
* Revision 1.33 2001/12/08 00:58:41 robertj
* Added ability to stil work with strange sound card setup, thanks Damian Sandras.
*
* Revision 1.32 2001/09/18 05:56:03 robertj
* Fixed numerous problems with thread suspend/resume and signals handling.
*
* Revision 1.31 2001/09/14 05:10:57 robertj
* Fixed compatibility issue with FreeBSD versionof OSS.
*
* Revision 1.30 2001/09/14 04:53:04 robertj
* Improved the detection of sound cards, thanks Miguel Rodr韌uez P閞ez for the ideas.
*
* Revision 1.29 2001/09/10 03:03:36 robertj
* Major change to fix problem with error codes being corrupted in a
* PChannel when have simultaneous reads and writes in threads.
*
* Revision 1.28 2001/09/03 09:15:40 robertj
* Changed GetDeviceNames to try and find actual devices and real devices.
*
* Revision 1.27 2001/08/22 02:23:07 robertj
* Fixed duplicate class name. All PWlib classes should start with P
*
* Revision 1.26 2001/08/21 12:33:25 rogerh
* Make loopback mode actually work. Added the AudioDelay class from OpenMCU
* and made Read() return silence when the buffer is empty.
*
* Revision 1.25 2001/05/14 06:33:19 rogerh
* Add exit cases to loopback mode polling loops to allow the sound channel
* to close properly when a connection closes.
*
* Revision 1.24 2001/02/07 03:34:29 craigs
* Added ability get sound channel parameters
*
* Revision 1.23 2000/10/05 00:04:20 robertj
* Fixed some warnings.
*
* Revision 1.22 2000/07/04 20:34:16 rogerh
* Only use ioctl SNDCTL_DSP_SETDUPLEX is Linux. It is not defined in FreeBSD
* In NetBSD and OpenBSD (using liboss), the ioctl returns EINVAL.
*
* Revision 1.21 2000/07/02 14:18:27 craigs
* Fixed various problems with buffer handling
*
* Revision 1.20 2000/07/02 05:49:43 craigs
* Really fixed race condition in OSS open
*
* Revision 1.19 2000/07/02 04:55:18 craigs
* Fixed stupid mistake with fix for OSS race condition
*
* Revision 1.18 2000/07/02 04:50:44 craigs
* Fixed potential race condition in OSS initialise
*
* Revision 1.17 2000/05/11 02:05:54 craigs
* Fixed problem with PLayFile not recognizing wait flag
*
* Revision 1.16 2000/05/10 02:10:44 craigs
* Added implementation for PlayFile command
*
* Revision 1.15 2000/05/02 08:30:26 craigs
* Removed "memory leaks" caused by brain-dead GNU linker
*
* Revision 1.14 2000/04/09 18:19:23 rogerh
* Add my changes for NetBSD support.
*
* Revision 1.13 2000/03/08 12:17:09 rogerh
* Add OpenBSD support
*
* Revision 1.12 2000/03/04 13:02:28 robertj
* Added simple play functions for sound files.
*
* Revision 1.11 2000/02/15 23:11:34 robertj
* Audio support for FreeBSD, thanks Roger Hardiman.
*
* Revision 1.10 2000/01/08 06:41:08 craigs
* Fixed problem whereby failure to open sound device returns TRUE
*
* Revision 1.9 1999/08/24 13:40:26 craigs
* Fixed problem with EINTR causing sound channel reads and write to fail
* Thanks to phil@netroedge.com!
*
* Revision 1.8 1999/08/17 09:42:22 robertj
* Fixed close of sound channel in loopback mode closing stdin!
*
* Revision 1.7 1999/08/17 09:28:47 robertj
* Added audio loopback psuedo-device (thanks Philip Edelbrock)
*
* Revision 1.6 1999/07/19 01:31:49 craigs
* Major rewrite to assure ioctls are all done in the correct order as OSS seems
* to be incredibly sensitive to this.
*
* Revision 1.5 1999/07/11 13:42:13 craigs
* pthreads support for Linux
*
* Revision 1.4 1999/06/30 13:49:26 craigs
* Added code to allow full duplex audio
*
* Revision 1.3 1999/05/28 14:14:29 robertj
* Added function to get default audio device.
*
* Revision 1.2 1999/05/22 12:49:05 craigs
* Finished implementation for Linux OSS interface
*
* Revision 1.1 1999/02/25 03:45:00 robertj
* Sound driver implementation changes for various unix platforms.
*
* Revision 1.1 1999/02/22 13:24:47 robertj
* Added first cut sound implmentation.
*
*/
#pragma implementation "sound_oss.h"
#include "sound_oss.h"
PCREATE_SOUND_PLUGIN(OSS, PSoundChannelOSS);
///////////////////////////////////////////////////////////////////////////////
// declare type for sound handle dictionary
PDICTIONARY(SoundHandleDict, PString, SoundHandleEntry);
static PMutex dictMutex;
static SoundHandleDict & handleDict()
{
static SoundHandleDict dict;
return dict;
}
///////////////////////////////////////////////////////////////////////////////
SoundHandleEntry::SoundHandleEntry()
{
handle = -1;
direction = 0;
}
///////////////////////////////////////////////////////////////////////////////
PSoundChannelOSS::PSoundChannelOSS()
{
PSoundChannelOSS::Construct();
}
PSoundChannelOSS::PSoundChannelOSS(const PString & device,
Directions dir,
unsigned numChannels,
unsigned sampleRate,
unsigned bitsPerSample)
{
Construct();
Open(device, dir, numChannels, sampleRate, bitsPerSample);
}
void PSoundChannelOSS::Construct()
{
os_handle = -1;
}
PSoundChannelOSS::~PSoundChannelOSS()
{
Close();
}
static BOOL IsNumericString(PString numbers) {
// return true if 'numbers' contains only digits (0 to 9)
// or if it contains digits followed by a '.'
BOOL isNumber = FALSE;
for (PINDEX p = 0; p < numbers.GetLength(); p++) {
if (isdigit(numbers[p])) {
isNumber = TRUE;
} else {
return isNumber;
}
}
return isNumber;
}
static void CollectSoundDevices(PDirectory devdir, POrdinalToString & dsp, POrdinalToString & mixer, BOOL collect_with_names)
{
if (!devdir.Open())
return;
do {
PString filename = devdir.GetEntryName();
PString devname = devdir + filename;
if (devdir.IsSubDir())
CollectSoundDevices(devname, dsp, mixer, collect_with_names);
else {
if (!collect_with_names) {
// On Linux, look at the character device numbers
PFileInfo info;
if (devdir.GetInfo(info) &&info.type == PFileInfo::CharDevice) {
struct stat s;
if (lstat(devname, &s) == 0) {
// OSS compatible audio major device numbers (OSS, SAM9407, etc)
static const unsigned deviceNumbers[] = { 14, 145 };
for (PINDEX i = 0; i < PARRAYSIZE(deviceNumbers); i++) {
if ((s.st_rdev >> 8) == deviceNumbers[i]) {
PINDEX cardnum = (s.st_rdev >> 4) & 15;
if ((s.st_rdev & 15) == 3) // Digital audio minor device number
dsp.SetAt(cardnum, devname);
else if ((s.st_rdev & 15) == 0) // Digital audio minor device number
mixer.SetAt(cardnum, devname);
}
}
}
}
}
else {
// On Linux devfs systems, the major numbers can change dynamically.
// On FreeBSD and other OSs, the major numbes are different to Linux.
// So collect devices by looking for dsp(N) and mixer(N).
// (or /dev/audio(N) and mixer(N) on NetBSD
// Notes. FreeBSD supports audio stream mixing. A single sound card
// may have multiple /dev entries in the form /dev/dspN.M
// eg /dev/dsp0.0 /dev/dsp0.1 /dev/dsp0.2 and /dev/dsp0.3
// When adding these to the 'dsp' string array, only the first one
// found is used.
#ifndef P_NETBSD
// Look for dsp
if (filename == "dsp") {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -