⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sound_oss.cxx

📁 sloedgy open sip stack source code
💻 CXX
📖 第 1 页 / 共 3 页
字号:
/*
 * 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 + -