#include <sound.h>
Inheritance diagram for PSoundChannel:
Construction | |
enum | Directions { Recorder, Player } |
PSoundChannel () | |
Create a sound channel. | |
PSoundChannel (const PString &device, Directions dir, unsigned numChannels=1, unsigned sampleRate=8000, unsigned bitsPerSample=16) | |
virtual | ~PSoundChannel () |
Channel set up functions | |
enum | { MaxVolume = 100 } |
virtual PBoolean | SetFormat (unsigned numChannels=1, unsigned sampleRate=8000, unsigned bitsPerSample=16) |
virtual unsigned | GetChannels () const |
Get the number of channels (mono/stereo) in the sound. | |
virtual unsigned | GetSampleRate () const |
Get the sample rate in samples per second. | |
virtual unsigned | GetSampleSize () const |
Get the sample size in bits per sample. | |
virtual PBoolean | SetBuffers (PINDEX size, PINDEX count=2) |
virtual PBoolean | GetBuffers (PINDEX &size, PINDEX &count) |
virtual PBoolean | SetVolume (unsigned volume) |
virtual PBoolean | GetVolume (unsigned &volume) |
Open functions | |
virtual PBoolean | Open (const PString &device, Directions dir, unsigned numChannels=1, unsigned sampleRate=8000, unsigned bitsPerSample=16) |
virtual PBoolean | IsOpen () const |
virtual PBoolean | Close () |
virtual int | GetHandle () const |
virtual PString | GetName () const |
Get the name of the open channel. | |
virtual PBoolean | Abort () |
static PStringArray | GetDriverNames (PPluginManager *pluginMgr=NULL) |
static PStringArray | GetDriversDeviceNames (const PString &driverName, Directions direction, PPluginManager *pluginMgr=NULL) |
static PStringArray | GetDeviceNames (const PString &driverName, Directions direction, PPluginManager *pluginMgr=NULL) |
static PSoundChannel * | CreateChannel (const PString &driverName, PPluginManager *pluginMgr=NULL) |
static PSoundChannel * | CreateChannelByName (const PString &deviceName, Directions direction, PPluginManager *pluginMgr=NULL) |
static PSoundChannel * | CreateOpenedChannel (const PString &driverName, const PString &deviceName, Directions direction, unsigned numChannels=1, unsigned sampleRate=8000, unsigned bitsPerSample=16, PPluginManager *pluginMgr=NULL) |
static PString | GetDefaultDevice (Directions dir) |
static PStringArray | GetDeviceNames (Directions direction, PPluginManager *pluginMgr=NULL) |
Public Member Functions | |
Play functions | |
virtual PBoolean | Write (const void *buf, PINDEX len) |
virtual PINDEX | GetLastWriteCount () const |
virtual PBoolean | PlaySound (const PSound &sound, PBoolean wait=PTrue) |
virtual PBoolean | PlayFile (const PFilePath &file, PBoolean wait=PTrue) |
virtual PBoolean | HasPlayCompleted () |
virtual PBoolean | WaitForPlayCompletion () |
Record functions | |
virtual PBoolean | Read (void *buf, PINDEX len) |
PINDEX | GetLastReadCount () const |
virtual PBoolean | RecordSound (PSound &sound) |
virtual PBoolean | RecordFile (const PFilePath &file) |
virtual PBoolean | StartRecording () |
virtual PBoolean | IsRecordBufferFull () |
virtual PBoolean | AreAllRecordBuffersFull () |
virtual PBoolean | WaitForRecordBufferFull () |
virtual PBoolean | WaitForAllRecordBuffersFull () |
Protected Attributes | |
PSoundChannel * | baseChannel |
As an abstract class, this represents a sound schannel. Drivers for real, platform dependent sound hardware will be ancestors of this class and can be found in the plugins section of PWLib.
A sound driver is either playing or recording. If simultaneous playing and recording is desired, two instances of PSoundChannel must be created.
The sound is buffered and the size and number of buffers should be set before playing/recording. Each call to Write() will use one buffer, so care needs to be taken not to use a large number of small writes but tailor the buffers to the size of each write you make.
Similarly for reading, an entire buffer must be read before any of it is available to a Read() call. Note that once a buffer is filled you can read it a byte at a time if desired, but as soon as all the data in the buffer is used returned, the next read will wait until the entire next buffer is read from the hardware. So again, tailor the number and size of buffers to the application. To avoid being blocked until the buffer fills, you can use the StartRecording() function to initiate the buffer filling, and the IsRecordingBufferFull() function to determine when the Read() function will no longer block.
Note that this sound channel is implicitly a linear PCM channel. No data conversion is performed on data to/from the channel.
PSoundChannel::PSoundChannel | ( | ) |
Create a sound channel.
PSoundChannel::PSoundChannel | ( | const PString & | device, | |
Directions | dir, | |||
unsigned | numChannels = 1 , |
|||
unsigned | sampleRate = 8000 , |
|||
unsigned | bitsPerSample = 16 | |||
) |
Create a sound channel. Create a reference to the sound drivers for the platform.
device | Name of sound driver/device |
dir | Sound I/O direction |
numChannels | Number of channels eg mono/stereo |
sampleRate | Samples per second |
bitsPerSample | Number of bits per sample |
virtual PSoundChannel::~PSoundChannel | ( | ) | [virtual] |
virtual PBoolean PSoundChannel::Abort | ( | ) | [virtual] |
Abort the background playing/recording of the sound channel.
virtual PBoolean PSoundChannel::AreAllRecordBuffersFull | ( | ) | [virtual] |
Determine if all of the record buffer allocated has been filled. There is an implicit Abort() of the recording if this occurs and recording is stopped. The channel may need to be closed and opened again to start a new recording.
virtual PBoolean PSoundChannel::Close | ( | ) | [virtual] |
Close the channel, shutting down the link to the data source.
Reimplemented from PChannel.
static PSoundChannel* PSoundChannel::CreateChannel | ( | const PString & | driverName, | |
PPluginManager * | pluginMgr = NULL | |||
) | [static] |
Create the sound channel that corresponds to the specified driver name.
driverName | Name of driver |
pluginMgr | Plug in manager, use default if NULL |
static PSoundChannel* PSoundChannel::CreateChannelByName | ( | const PString & | deviceName, | |
Directions | direction, | |||
PPluginManager * | pluginMgr = NULL | |||
) | [static] |
deviceName | Name of device |
direction | Direction for device (record or play) |
pluginMgr | Plug in manager, use default if NULL |
static PSoundChannel* PSoundChannel::CreateOpenedChannel | ( | const PString & | driverName, | |
const PString & | deviceName, | |||
Directions | direction, | |||
unsigned | numChannels = 1 , |
|||
unsigned | sampleRate = 8000 , |
|||
unsigned | bitsPerSample = 16 , |
|||
PPluginManager * | pluginMgr = NULL | |||
) | [static] |
Create an opened sound channel that corresponds to the specified names. If the driverName parameter is an empty string or "*" then CreateChannelByName is used with the deviceName parameter which is assumed to be a value returned from GetAllDeviceNames().
driverName | Name of driver |
deviceName | Name of device |
direction | Direction for device (record or play) |
numChannels | Number of channels 1=mon, 2=stereo |
sampleRate | Sample rate |
bitsPerSample | Bits per sample |
pluginMgr | Plug in manager, use default if NULL |
virtual PBoolean PSoundChannel::GetBuffers | ( | PINDEX & | size, | |
PINDEX & | count | |||
) | [virtual] |
Get the internal buffers for the sound channel I/O.
virtual unsigned PSoundChannel::GetChannels | ( | ) | const [virtual] |
Get the number of channels (mono/stereo) in the sound.
static PString PSoundChannel::GetDefaultDevice | ( | Directions | dir | ) | [static] |
Get the name for the default sound devices/driver that is on this platform. Note that a named device may not necessarily do both playing and recording so the arrays returned with the dir# parameter in each value is not necessarily the same.
This will return a list of uniqie device names across all of the available drivers. If two drivers have identical names for devices, then the string returned will be of the form driver+''+device.
static PStringArray PSoundChannel::GetDeviceNames | ( | Directions | direction, | |
PPluginManager * | pluginMgr = NULL | |||
) | [static] |
Get the list of all devices name for the default sound devices/driver that is on this platform. Note that a named device may not necessarily do both playing and recording so the arrays returned with the dir# parameter in each value is not necessarily the same.
direction | Direction for device (record or play) |
pluginMgr | Plug in manager, use default if NULL |
static PStringArray PSoundChannel::GetDeviceNames | ( | const PString & | driverName, | |
Directions | direction, | |||
PPluginManager * | pluginMgr = NULL | |||
) | [inline, static] |
static PStringArray PSoundChannel::GetDriverNames | ( | PPluginManager * | pluginMgr = NULL |
) | [static] |
Get the list of available sound drivers (plug-ins)
pluginMgr | Plug in manager, use default if NULL |
static PStringArray PSoundChannel::GetDriversDeviceNames | ( | const PString & | driverName, | |
Directions | direction, | |||
PPluginManager * | pluginMgr = NULL | |||
) | [static] |
Get sound devices that correspond to the specified driver name. If driverName is an empty string or the value "*" then GetAllDeviceNames() is used.
driverName | Name of driver |
direction | Direction for device (record or play) |
pluginMgr | Plug in manager, use default if NULL |
virtual int PSoundChannel::GetHandle | ( | ) | const [virtual] |
Get the OS specific handle for the PSoundChannel.
Reimplemented from PChannel.
PINDEX PSoundChannel::GetLastReadCount | ( | ) | const [virtual] |
Get the number of bytes read by the last Read() call. This will be from 0 to the maximum number of bytes as passed to the Read() call.
Note that the number of bytes read may often be less than that asked for. Aside from the most common case of being at end of file, which the applications semantics may regard as an exception, there are some cases where this is normal. For example, if a PTextFile channel on the MSDOS platform is read from, then the translation of CR/LF pairs to
characters will result in the number of bytes returned being less than the size of the buffer supplied.
Reimplemented from PChannel.
virtual PINDEX PSoundChannel::GetLastWriteCount | ( | ) | const [virtual] |
Get the number of bytes written by the last Write() call.
Note that the number of bytes written may often be less, or even more, than that asked for. A common case of it being less is where the disk is full. An example of where the bytes written is more is as follows. On a PTextFile# channel on the MSDOS platform, there is translation of
to CR/LF pairs. This will result in the number of bytes returned being more than that requested.
Reimplemented from PChannel.
virtual PString PSoundChannel::GetName | ( | ) | const [virtual] |
virtual unsigned PSoundChannel::GetSampleRate | ( | ) | const [virtual] |
Get the sample rate in samples per second.
virtual unsigned PSoundChannel::GetSampleSize | ( | ) | const [virtual] |
Get the sample size in bits per sample.
virtual PBoolean PSoundChannel::GetVolume | ( | unsigned & | volume | ) | [virtual] |
Get the volume of the play/read process. The volume range is 0 == quiet, 100 == LOUDEST. The volume is a logarithmic scale mapped from the lowest gain possible on the device to the highest gain.
volume | Variable to receive volume level. |
virtual PBoolean PSoundChannel::HasPlayCompleted | ( | ) | [virtual] |
Indicate if the sound play begun with PlayBuffer() or PlayFile() has completed.
virtual PBoolean PSoundChannel::IsOpen | ( | ) | const [virtual] |
Test if this instance of PSoundChannel is open.
Reimplemented from PChannel.
virtual PBoolean PSoundChannel::IsRecordBufferFull | ( | ) | [virtual] |
Determine if a record buffer has been filled, so that the next Read() call will not block. Provided that the amount of data read is less than the buffer size.
virtual PBoolean PSoundChannel::Open | ( | const PString & | device, | |
Directions | dir, | |||
unsigned | numChannels = 1 , |
|||
unsigned | sampleRate = 8000 , |
|||
unsigned | bitsPerSample = 16 | |||
) | [virtual] |
Open the specified device for playing or recording. The device name is platform specific and is as returned in the GetDevices() function.
device | Name of sound driver/device |
dir | Sound I/O direction |
numChannels | Number of channels eg mono/stereo |
sampleRate | Samples per second |
bitsPerSample | Number of bits per sample |
virtual PBoolean PSoundChannel::PlayFile | ( | const PFilePath & | file, | |
PBoolean | wait = PTrue | |||
) | [virtual] |
Play a sound file to the open device. If the wait# parameter is PTrue then the function does not return until the file has been played. If PFalse then the sound play is begun asynchronously and the function returns immediately.
Note if the driver is closed of the object destroyed then the sound play is aborted.
Also note that not all possible sounds and sound files are playable by this library. No format conversions between sound object and driver are performed.
file | Sound file to play. |
wait | Flag to play sound synchronously. |
Play a sound to the open device. If the wait# parameter is PTrue then the function does not return until the file has been played. If PFalse then the sound play is begun asynchronously and the function returns immediately.
Note if the driver is closed of the object destroyed then the sound play is aborted.
Also note that not all possible sounds and sound files are playable by this library. No format conversions between sound object and driver are performed.
sound | Sound to play. |
wait | Flag to play sound synchronously. |
virtual PBoolean PSoundChannel::Read | ( | void * | buf, | |
PINDEX | len | |||
) | [virtual] |
Low level read from the channel. This function may block until the requested number of characters were read or the read timeout was reached. The GetLastReadCount() function returns the actual number of bytes read.
The GetErrorCode() function should be consulted after Read() returns PFalse to determine what caused the failure.
buf | Pointer to a block of memory to receive the read bytes. |
len | Maximum number of bytes to read into the buffer. |
Reimplemented from PChannel.
Record into the platform dependent sound file all of the buffer's of sound data. Use the SetBuffers() function to determine how long the recording will be made.
Note that this function will block until all of the data is buffered. If you wish to do this asynchronously, use StartRecording() and AreAllrecordBuffersFull() to determine when you can call RecordSound() without blocking.
file | Sound file recorded |
Record into the sound object all of the buffer's of sound data. Use the SetBuffers() function to determine how long the recording will be made.
For the Win32 platform, the most efficient way to record a PSound is to use the SetBuffers() function to set a single buffer of the desired size and then do the recording. For Linux OSS this can cause problems as the buffers are rounded up to a power of two, so to gain more accuracy you need a number of smaller buffers.
Note that this function will block until all of the data is buffered. If you wish to do this asynchronously, use StartRecording() and AreAllrecordBuffersFull() to determine when you can call RecordSound() without blocking.
sound | Sound recorded |
virtual PBoolean PSoundChannel::SetBuffers | ( | PINDEX | size, | |
PINDEX | count = 2 | |||
) | [virtual] |
Set the internal buffers for the sound channel I/O.
Note that with Linux OSS, the size is always rounded up to the nearest power of two, so 20000 => 32768.
size | Size of each buffer |
count | Number of buffers |
virtual PBoolean PSoundChannel::SetFormat | ( | unsigned | numChannels = 1 , |
|
unsigned | sampleRate = 8000 , |
|||
unsigned | bitsPerSample = 16 | |||
) | [virtual] |
Set the format for play/record. Note that linear PCM data is the only one supported at this time.
Note that if the PlayFile() function is used, this may be overridden by information in the file being played.
numChannels | Number of channels eg mono/stereo |
sampleRate | Samples per second |
bitsPerSample | Number of bits per sample |
virtual PBoolean PSoundChannel::SetVolume | ( | unsigned | volume | ) | [virtual] |
Set the volume of the play/read process. The volume range is 0 == quiet, 100 == LOUDEST. The volume is a logarithmic scale mapped from the lowest gain possible on the device to the highest gain.
volume | New volume level |
virtual PBoolean PSoundChannel::StartRecording | ( | ) | [virtual] |
Start filling record buffers. The first call to Read() will also initiate the recording.
virtual PBoolean PSoundChannel::WaitForAllRecordBuffersFull | ( | ) | [virtual] |
Block the thread until all of the record buffer allocated has been filled. There is an implicit Abort() of the recording if this occurs and recording is stopped. The channel may need to be closed and opened again to start a new recording.
virtual PBoolean PSoundChannel::WaitForPlayCompletion | ( | ) | [virtual] |
Block the thread until the sound play begun with PlayBuffer() or PlayFile() has completed.
virtual PBoolean PSoundChannel::WaitForRecordBufferFull | ( | ) | [virtual] |
Block the thread until a record buffer has been filled, so that the next Read() call will not block. Provided that the amount of data read is less than the buffer size.
virtual PBoolean PSoundChannel::Write | ( | const void * | buf, | |
PINDEX | len | |||
) | [virtual] |
Low level write (or play) to the channel. This function will block until the requested number of characters are written or the write timeout is reached. The GetLastWriteCount() function returns the actual number of bytes written.
The GetErrorCode() function should be consulted after Write() returns PFalse to determine what caused the failure.
Reimplemented from PChannel.
PSoundChannel* PSoundChannel::baseChannel [protected] |