1 /*
2  * sound.h
3  *
4  * Sound interface class.
5  *
6  * Portable Windows Library
7  *
8  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * The Original Code is Portable Windows Library.
21  *
22  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23  *
24  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
25  * All Rights Reserved.
26  *
27  * Contributor(s): ______________________________________.
28  *
29  * $Revision: 28275 $
30  * $Author: rjongbloed $
31  * $Date: 2012-08-29 21:42:35 -0500 (Wed, 29 Aug 2012) $
32  */
33 
34 
35 #ifndef PTLIB_SOUND_H
36 #define PTLIB_SOUND_H
37 
38 #ifdef P_USE_PRAGMA
39 #pragma interface
40 #endif
41 
42 #include <ptlib/plugin.h>
43 #include <ptlib/pluginmgr.h>
44 
45 /** A class representing a sound. A sound is a highly platform dependent
46    entity that is abstracted for use here. Very little manipulation of the
47    sounds are possible.
48 
49    The most common sound to use is the static function <code>Beep()</code> which
50    emits the system standard "warning" or "attention" sound.
51  */
52 class PSound : public PBYTEArray
53 {
54   PCLASSINFO(PSound, PBYTEArray);
55 
56   public:
57   /**@name Construction */
58   //@{
59     /**Create a new sound, using the parameters provided.
60        It is expected that the "lowest common denominator" encoding, linear PCM,
61        is used.
62 
63        All other values for the encoding are platform dependent.
64      */
65     PSound(
66       unsigned numChannels = 1,    ///< Number of channels eg mono/stereo
67       unsigned sampleRate = 8000,  ///< Samples per second
68       unsigned bitsPerSample = 16, ///< Number of bits per sample
69       PINDEX   bufferSize = 0,     ///< Size of data
70       const BYTE * data = NULL     ///< Pointer to initial data
71     );
72 
73     /**Create a new sound, reading from a platform dependent file.
74      */
75     PSound(
76       const PFilePath & filename   ///< Sound file to load.
77     );
78 
79     /**Set new data bytes for the sound.
80      */
81     PSound & operator=(
82       const PBYTEArray & data  ///< New data for sound
83     );
84   //@}
85 
86   /**@name File functions */
87   //@{
88     /**Load a platform dependent sound file (eg .WAV file for Win32) into the
89        object. Note the whole file must able to be loaded into memory.
90 
91        Also note that not all possible files are playable by this library. No
92        format conversions between file and driver are performed.
93 
94        @return
95        true if the sound is loaded successfully.
96      */
97     PBoolean Load(
98       const PFilePath & filename   ///< Sound file to load.
99     );
100 
101     /**Save a platform dependent sound file (eg .WAV file for Win32) from the
102        object.
103 
104        @return
105        true if the sound is saved successfully.
106      */
107     PBoolean Save(
108       const PFilePath & filename   ///< Sound file to load.
109     );
110   //@}
111 
112   /**@name Access functions */
113   //@{
114     /// Play the sound on the default sound device.
115     PBoolean Play();
116 
117     /// Play the sound to the specified sound device.
118     PBoolean Play(const PString & device);
119 
120     /**Set the internal sound format to linear PCM at the specification in
121        the parameters.
122      */
123     void SetFormat(
124       unsigned numChannels,   ///< Number of channels eg mono/stereo
125       unsigned sampleRate,    ///< Samples per second
126       unsigned bitsPerSample  ///< Number of bits per sample
127     );
128 
129     /**Get the current encoding. A value of 0 indicates linear PCM, any other
130        value is platform dependent.
131      */
GetEncoding()132     unsigned GetEncoding()   const { return encoding; }
133 
134     /// Get  the number of channels (mono/stereo) in the sound.
GetChannels()135     unsigned GetChannels()   const { return numChannels; }
136 
137     /// Get the sample rate in samples per second.
GetSampleRate()138     unsigned GetSampleRate() const { return sampleRate; }
139 
140     /// Get the sample size in bits per sample.
GetSampleSize()141     unsigned GetSampleSize() const { return sampleSize; }
142 
143     /// Get the platform dependent error code from the last file load.
GetErrorCode()144     DWORD    GetErrorCode()  const { return dwLastError; }
145 
146     /// Get the size of the platform dependent format info.
GetFormatInfoSize()147     PINDEX   GetFormatInfoSize()  const { return formatInfo.GetSize(); }
148 
149     /// Get pointer to the platform dependent format info.
GetFormatInfoData()150     const void * GetFormatInfoData() const { return (const BYTE *)formatInfo; }
151   //@}
152 
153   /**@name Miscellaneous functions */
154   //@{
155     /**Play a sound file to the default device. If the <code>wait</code>
156        parameter is true then the function does not return until the file has
157        been played. If false then the sound play is begun asynchronously and
158        the function returns immediately.
159 
160        @return
161        true if the sound is playing or has played.
162      */
163     static PBoolean PlayFile(
164       const PFilePath & file, ///< Sound file to play.
165       PBoolean wait = true        ///< Flag to play sound synchronously.
166     );
167 
168     /// Play the "standard" warning beep for the platform.
169     static void Beep();
170   //@}
171 
172   protected:
173     /// Format code
174     unsigned   encoding;
175     /// Number of channels eg mono/stereo
176     unsigned   numChannels;
177     /// Samples per second
178     unsigned   sampleRate;
179     /// Number of bits per sample
180     unsigned   sampleSize;
181     /// Last error code for Load()/Save() functions
182     DWORD      dwLastError;
183     /// Full info on the format (platform dependent)
184     PBYTEArray formatInfo;
185 };
186 
187 
188 /**
189    Abstract class for a generalised sound channel, and an implementation of
190    PSoundChannel for old code that is not plugin-aware.
191    When instantiated, it selects the first plugin of the base class
192    "PSoundChannel"
193 
194    As an abstract class, this represents a sound channel. Drivers for real,
195    platform dependent sound hardware will be ancestors of this class and
196    can be found in the plugins section of PTLib.
197 
198    A sound channel is either playing or recording. If simultaneous
199    playing and recording is desired, two instances of PSoundChannel
200    must be created. It is an error for the same thread to attempt to
201    both read and write audio data to once instance of a PSoundChannel
202    class.
203 
204    PSoundChannel instances are designed to be reentrant. The actual
205    usage model employed is left to the developer. One model could be
206    where one thread is responsible for construction, setup, opening and
207    read/write operations. After creating and eventually opening the channel
208    this thread is responsible for handling read/writes fast enough to avoid
209    gaps in the generated audio stream.
210 
211    Remaining operations may beinvoked from other threads.
212    This includes Close() and actually gathering the necessary data to
213    be sent to the device.
214 
215    Besides the basic I/O task, the Read()/Write(() functions have well
216    defined timing characteristics. When a PSoundChannel instance is
217    used from Opal, the read/write operations are designed to also act
218    as timers so as to nicely space the generated network packets of
219    audio/ sound packets to the speaker.
220 
221 
222    Read and Writes of audio data to a PSoundChannel are blocking. The
223    length of time required to read/write a block of audio from/to a
224    PSoundChannel instance is equal to the time required for that block
225    of audio to record/play. So for a sound rate of 8khz, 240 samples,
226    it is going to take 30ms to do a read/write.
227 
228    Since the Read()/Write(() functions have well defined
229    timing characteristics; they are designed to also act as timers in a loop
230    involving data transfers to/from the codecs.
231 
232    The sound is buffered and the size and number of buffers should be set
233    before playing/recording. Each call to Write() will use one buffer, so care
234    needs to be taken not to use a large number of small writes but tailor the
235    buffers to the size of each write you make.
236 
237    Similarly for reading, an entire buffer must be read before any of it is
238    available to a Read() call. Note that once a buffer is filled you can read
239    it a byte at a time if desired, but as soon as all the data in the buffer
240    is used, the next read will wait until the entire next buffer is
241    read from the hardware. So again, tailor the number and size of buffers to
242    the application. To avoid being blocked until the buffer fills, you can use
243    the StartRecording() function to initiate the buffer filling, and the
244    IsRecordingBufferFull() function to determine when the Read() function will
245    no longer block.
246 
247    Note that this sound channel is implicitly a linear PCM channel. No data
248    conversion is performed on data to/from the channel.
249 
250  */
251 class PSoundChannel : public PChannel
252 {
253   PCLASSINFO(PSoundChannel, PChannel);
254 
255   public:
256   /**@name Construction */
257   //@{
258     enum Directions {
259       Closed = -1,
260       Recorder,
261       Player
262     };
263 
264     /// Create a sound channel.
265     PSoundChannel();
266 
267     /** Create a sound channel.
268         Create a reference to the sound drivers for the platform.
269       */
270     PSoundChannel(
271       const PString & device,       ///< Name of sound driver/device
272       Directions dir,               ///< Sound I/O direction
273       unsigned numChannels = 1,     ///< Number of channels eg mono/stereo
274       unsigned sampleRate = 8000,   ///< Samples per second
275       unsigned bitsPerSample = 16   ///< Number of bits per sample
276     );
277     //
278 
279     virtual ~PSoundChannel();
280     // Destroy and close the sound driver
281   //@}
282 
283   /**@name Open functions */
284   //@{
285     /**Get the list of available sound drivers (plug-ins)
286      */
287     static PStringArray GetDriverNames(
288       PPluginManager * pluginMgr = NULL   ///< Plug in manager, use default if NULL
289     );
290 
291     /**Get sound devices that correspond to the specified driver name.
292        If driverName is an empty string or the value "*" then GetAllDeviceNames()
293        is used.
294      */
295     static PStringArray GetDriversDeviceNames(
296       const PString & driverName,         ///< Name of driver
297       Directions direction,               ///< Direction for device (record or play)
298       PPluginManager * pluginMgr = NULL   ///< Plug in manager, use default if NULL
299     );
300 
301     // For backward compatibility
302     static inline PStringArray GetDeviceNames(
303       const PString & driverName,
304       Directions direction,
305       PPluginManager * pluginMgr = NULL
306     ) { return GetDriversDeviceNames(driverName, direction, pluginMgr); }
307 
308     /**Create the sound channel that corresponds to the specified driver name.
309      */
310     static PSoundChannel * CreateChannel (
311       const PString & driverName,         ///< Name of driver
312       PPluginManager * pluginMgr = NULL   ///< Plug in manager, use default if NULL
313     );
314 
315     /* Create the matching sound channel that corresponds to the device name.
316        So, for "fake" return a device that will generate fake video.
317        For "Phillips 680 webcam" (eg) will return appropriate grabber.
318        Note that Phillips will return the appropriate grabber also.
319 
320        This is typically used with the return values from GetDeviceNames().
321      */
322     static PSoundChannel * CreateChannelByName(
323       const PString & deviceName,         ///< Name of device
324       Directions direction,               ///< Direction for device (record or play)
325       PPluginManager * pluginMgr = NULL   ///< Plug in manager, use default if NULL
326     );
327 
328     /**Create an opened sound channel that corresponds to the specified names.
329        If the driverName parameter is an empty string or "*" then CreateChannelByName
330        is used with the deviceName parameter which is assumed to be a value returned
331        from GetAllDeviceNames().
332      */
333     static PSoundChannel * CreateOpenedChannel(
334       const PString & driverName,         ///< Name of driver
335       const PString & deviceName,         ///< Name of device
336       Directions direction,               ///< Direction for device (record or play)
337       unsigned numChannels = 1,           ///< Number of channels 1=mon, 2=stereo
338       unsigned sampleRate = 8000,         ///< Sample rate
339       unsigned bitsPerSample = 16,        ///< Bits per sample
340       PPluginManager * pluginMgr = NULL   ///< Plug in manager, use default if NULL
341     );
342 
343     /**Get the name for the default sound devices/driver that is on this
344        platform. Note that a named device may not necessarily do both
345        playing and recording so the string returned with the <code>dir</code>
346        parameter in each value is not necessarily the same.
347 
348        @return
349        A platform dependent string for the sound player/recorder.
350      */
351     static PString GetDefaultDevice(
352       Directions dir    // Sound I/O direction
353     );
354 
355     /**Get the list of all devices name for the default sound devices/driver that is on this
356        platform. Note that a named device may not necessarily do both
357        playing and recording so the arrays returned with the <code>dir</code>
358        parameter in each value is not necessarily the same.
359 
360        This will return a list of unique device names across all of the available
361        drivers. If two drivers have identical names for devices, then the string
362        returned will be of the form driver+'\\t'+device.
363 
364        @return
365        Platform dependent strings for the sound player/recorder.
366      */
367     static PStringArray GetDeviceNames(
368       Directions direction,               ///< Direction for device (record or play)
369       PPluginManager * pluginMgr = NULL   ///< Plug in manager, use default if NULL
370     );
371 
372     /**Open the specified device for playing or recording. The device name is
373        platform specific and is as returned in the GetDevices() function.
374 
375        @return
376        true if the sound device is valid for playing/recording.
377      */
378     virtual PBoolean Open(
379       const PString & device,       ///< Name of sound driver/device
380       Directions dir,               ///< Sound I/O direction
381       unsigned numChannels = 1,     ///< Number of channels eg mono/stereo
382       unsigned sampleRate = 8000,   ///< Samples per second
383       unsigned bitsPerSample = 16   ///< Number of bits per sample
384     );
385 
386     /**Test if this instance of PSoundChannel is open.
387 
388        @return
389        true if this instance is open.
390      */
391     virtual PBoolean IsOpen() const;
392 
393     /** Close the channel, shutting down the link to the data source.
394 
395        @return true if the channel successfully closed.
396      */
397     virtual PBoolean Close();
398 
399     /**Get the OS specific handle for the PSoundChannel.
400 
401        @return
402        integer value of the handle.
403      */
404     virtual int GetHandle() const;
405 
406     /// Get the name of the open channel
407     virtual PString GetName() const;
408 
409     /// Get the direction of the channel
GetDirection()410     Directions GetDirection() const
411     {
412       return activeDirection;
413     }
414 
415     /// Get text representing the direction of the channel
416     static const char * GetDirectionText(Directions dir);
417 
GetDirectionText()418     virtual const char * GetDirectionText() const
419     {
420       return GetDirectionText(activeDirection);
421     }
422 
423     /** Abort the background playing/recording of the sound channel.
424         There will be a logic assertion if you attempt to Abort a
425         sound channel operation, when the device is currently closed.
426 
427        @return
428        true if the sound has successfully been aborted.
429      */
430     virtual PBoolean Abort();
431   //@}
432 
433   /**@name Channel set up functions */
434   //@{
435     /**Set the format for play/record. Note that linear PCM data is the only
436        one supported at this time.
437 
438        Note that if the PlayFile() function is used, this may be overridden
439        by information in the file being played.
440 
441        @return
442        true if the format is valid.
443      */
444     virtual PBoolean SetFormat(
445       unsigned numChannels = 1,     ///< Number of channels eg mono/stereo
446       unsigned sampleRate = 8000,   ///< Samples per second
447       unsigned bitsPerSample = 16   ///< Number of bits per sample
448     );
449 
450     /// Get  the number of channels (mono/stereo) in the sound.
451     virtual unsigned GetChannels() const;
452 
453     /// Get the sample rate in samples per second.
454     virtual unsigned GetSampleRate() const;
455 
456     /// Get the sample size in bits per sample.
457     virtual unsigned GetSampleSize() const;
458 
459     /**Set the internal buffers for the sound channel I/O.
460 
461        Note that with Linux OSS, the size is always rounded up to the nearest
462        power of two, so 20000 => 32768.
463 
464        @return
465        true if the sound device is valid for playing/recording.
466      */
467     virtual PBoolean SetBuffers(
468       PINDEX size,      ///< Size of each buffer
469       PINDEX count = 2  ///< Number of buffers
470     );
471 
472     /**Get the internal buffers for the sound channel I/O.
473 
474        @return
475        true if the buffer size were obtained.
476      */
477     virtual PBoolean GetBuffers(
478       PINDEX & size,    // Size of each buffer
479       PINDEX & count    // Number of buffers
480     );
481 
482     enum {
483       MaxVolume = 100
484     };
485 
486     /**Set the volume of the play/read process.
487        The volume range is 0 == muted, 100 == LOUDEST. The volume is a
488        logarithmic scale mapped from the lowest gain possible on the device to
489        the highest gain.
490 
491        @return
492        true if there were no errors.
493     */
494     virtual PBoolean SetVolume(
495       unsigned volume   ///< New volume level
496     );
497 
498     /**Get the volume of the play/read process.
499        The volume range is 0 == muted, 100 == LOUDEST. The volume is a
500        logarithmic scale mapped from the lowest gain possible on the device to
501        the highest gain.
502 
503        @return
504        true if there were no errors.
505     */
506     virtual PBoolean GetVolume(
507       unsigned & volume   ///< Variable to receive volume level.
508     );
509 
510     /**Set the mute state of the play/read process.
511 
512        @return
513        true if there were no errors.
514     */
515     virtual bool SetMute(
516       bool mute   ///< New mute state
517     );
518 
519     /**Get the mute state of the play/read process.
520 
521        @return
522        true if there were no errors.
523     */
524     virtual bool GetMute(
525       bool & mute   ///< Variable to receive mute state.
526     );
527 
528   //@}
529 
530   /**@name Play functions */
531   //@{
532 
533     /** Low level write (or play) to the channel.
534 
535         It will generate a logical assertion if you attempt write to a
536         channel set up for recording.
537 
538         @param buf is a pointer to the data to be written to the
539         channel.  It is an error for this pointer to be NULL. A logical
540         assert will be generated when buf is NULL.
541 
542         @param len Nr of bytes to send. If len equals the buffer size
543         set by SetBuffers() it will block for
544         (1000*len)/(samplesize*samplerate) ms. Typically, the sample
545         size is 2 bytes.  If len == 0, this will return immediately,
546         where the return value is equal to the value of IsOpen().
547 
548         @return true if len bytes were written to the channel,
549         otherwise false. The GetErrorCode() function should be
550         consulted after Write() returns false to determine what
551         caused the failure.
552      */
553     virtual PBoolean Write(const void * buf, PINDEX len);
554 
555 
556     /** Low level write (or play) with watermark to the channel.
557 
558         It will generate a logical assertion if you attempt write to a
559         channel set up for recording.
560 
561         @param buf is a pointer to the data to be written to the
562         channel.  It is an error for this pointer to be NULL. A logical
563         assert will be generated when buf is NULL.
564 
565         @param len Nr of bytes to send. If len equals the buffer size
566         set by SetBuffers() it will block for
567         (1000*len)/(samplesize*samplerate) ms. Typically, the sample
568         size is 2 bytes.  If len == 0, this will return immediately,
569         where the return value is equal to the value of IsOpen().
570 
571         @param mark Unique identifer to identify the write
572 
573         @return PTrue if len bytes were written to the channel,
574         otherwise PFalse. The GetErrorCode() function should be
575         consulted after Write() returns PFalse to determine what
576         caused the failure.
577      */
578     virtual PBoolean Write(
579       const void * buf,         ///< Pointer to a block of memory to write.
580       PINDEX len,               ///< Number of bytes to write.
581       const void * mark         ///< Unique Marker to identify write
582     );
583 
584     /** Get number of bytes written in last Write() operation. */
585     virtual PINDEX GetLastWriteCount() const;
586 
587     /**Play a sound to the open device. If the <code>wait</code> parameter is
588        true then the function does not return until the file has been played.
589        If false then the sound play is begun asynchronously and the function
590        returns immediately.
591 
592        Note:  if the driver is closed while playing the sound, the play
593        operation stops immediately.
594 
595        Also note that not all possible sounds and sound files are playable by
596        this library. No format conversions between sound object and driver are
597        performed.
598 
599        @return
600        true if the sound is playing or has played.
601      */
602 
603     virtual PBoolean PlaySound(
604       const PSound & sound,   ///< Sound to play.
605       PBoolean wait = true        ///< Flag to play sound synchronously.
606     );
607 
608     /**Play a sound file to the open device. If the <code>wait</code>
609        parameter is true then the function does not return until the file has
610        been played. If false then the sound play is begun asynchronously and
611        the function returns immediately.
612 
613        Note if the driver is closed of the object destroyed then the sound
614        play is aborted.
615 
616        Also note that not all possible sounds and sound files are playable by
617        this library. No format conversions between sound object and driver are
618        performed.
619 
620        @return
621        true if the sound is playing or has played.
622      */
623     virtual PBoolean PlayFile(
624       const PFilePath & file, ///< Sound file to play.
625       PBoolean wait = true        ///< Flag to play sound synchronously.
626     );
627 
628     /**Indicate if the sound play begun with PlayBuffer() or PlayFile() has
629        completed.
630 
631        @return
632        true if the sound has completed playing.
633      */
634     virtual PBoolean HasPlayCompleted();
635 
636     /**Block calling thread until the sound play begun with PlaySound() or
637        PlayFile() has completed.
638 
639        @return
640        true if the sound has successfully completed playing.
641      */
642     virtual PBoolean WaitForPlayCompletion();
643 
644   //@}
645 
646   /**@name Record functions */
647   //@{
648     /** Low level read from the channel. This function may block until the
649        requested number of characters were read or the read timeout was
650        reached. The GetLastReadCount() function returns the actual number
651        of bytes read.
652 
653        It will generate a logical assertion if you attempt to read
654        from a PSoundChannel that is setup for playing.
655 
656        The GetErrorCode() function should be consulted after Read() returns
657        false to determine what caused the failure.
658 
659        @param len Nr of bytes to endeaveour to read from the sound
660        device. If len equals the buffer size set by SetBuffers() it
661        will block for (1000*len)/(samplesize*samplerate)
662        ms. Typically, the sample size is 2 bytes.  If len == 0, this
663        will return immediately, where the return value is equal to
664        the value of IsOpen().
665 
666        @param buf is a pointer to the empty data area, which will
667        contain the data collected from the sound device.  It is an
668        error for this pointer to be NULL. A logical assert will be
669        generated when buf is NULL.
670 
671        @return true indicates that at least one character was read
672        from the channel.  false means no bytes were read due to some
673        I/O error, (which includes timeout or some other thread closed
674        the device).
675      */
676     virtual PBoolean Read(
677       void * buf,   ///< Pointer to a block of memory to receive the read bytes.
678       PINDEX len    ///< Maximum number of bytes to read into the buffer.
679     );
680 
681     /** Return number of bytes read in last Read() call. */
682     PINDEX GetLastReadCount() const;
683 
684     /**Record into the sound object all of the buffer's of sound data. Use the
685        SetBuffers() function to determine how long the recording will be made.
686 
687        For the Win32 platform, the most efficient way to record a PSound is to
688        use the SetBuffers() function to set a single buffer of the desired
689        size and then do the recording. For Linux OSS this can cause problems
690        as the buffers are rounded up to a power of two, so to gain more
691        accuracy you need a number of smaller buffers.
692 
693        Note that this function will block until all of the data is buffered.
694        If you wish to do this asynchronously, use StartRecording() and
695        AreAllrecordBuffersFull() to determine when you can call RecordSound()
696        without blocking.
697 
698        @return
699        true if the sound has been recorded.
700      */
701     virtual PBoolean RecordSound(
702       PSound & sound ///< Sound recorded
703     );
704 
705     /**Record into the platform dependent sound file all of the buffer's of
706        sound data. Use the SetBuffers() function to determine how long the
707        recording will be made.
708 
709        Note that this function will block until all of the data is buffered.
710        If you wish to do this asynchronously, use StartRecording() and
711        AreAllrecordBuffersFull() to determine when you can call RecordSound()
712        without blocking.
713 
714        @return
715        true if the sound has been recorded.
716      */
717     virtual PBoolean RecordFile(
718       const PFilePath & file ///< Sound file recorded
719     );
720 
721     /**Start filling record buffers. The first call to Read() will also
722        initiate the recording.
723 
724        @return
725        true if the sound driver has successfully started recording.
726      */
727     virtual PBoolean StartRecording();
728 
729     /**Determine if a record buffer has been filled, so that the next Read()
730        call will not block. Provided that the amount of data read is less than
731        the buffer size.
732 
733        @return
734        true if the sound driver has filled a buffer.
735      */
736     virtual PBoolean IsRecordBufferFull();
737 
738     /**Determine if all of the record buffer allocated has been filled. There
739        is an implicit Abort() of the recording if this occurs and recording is
740        stopped. The channel may need to be closed and opened again to start
741        a new recording.
742 
743        @return
744        true if the sound driver has filled a buffer.
745      */
746     virtual PBoolean AreAllRecordBuffersFull();
747 
748     /**Block the thread until a record buffer has been filled, so that the
749        next Read() call will not block. Provided that the amount of data read
750        is less than the buffer size.
751 
752        @return
753        true if the sound driver has filled a buffer.
754      */
755     virtual PBoolean WaitForRecordBufferFull();
756 
757     /**Block the thread until all of the record buffer allocated has been
758        filled. There is an implicit Abort() of the recording if this occurs
759        and recording is stopped. The channel may need to be closed and opened
760        again to start a new recording.
761 
762        @return
763        true if the sound driver has filled a buffer.
764      */
765     virtual PBoolean WaitForAllRecordBuffersFull();
766   //@}
767 
768   protected:
769     PSoundChannel * m_baseChannel;
770     PReadWriteMutex m_baseMutex;
771 
772     /**This is the direction that this sound channel is opened for use
773        in.  Should the user attempt to used this opened class instance
774        in a direction opposite to that specified in activeDirection,
775        an assert happens. */
776     Directions      activeDirection;
777 };
778 
779 
780 /////////////////////////////////////////////////////////////////////////
781 
782 // define the sound plugin service descriptor
783 
784 template <class className> class PSoundChannelPluginServiceDescriptor : public PDevicePluginServiceDescriptor
785 {
786   public:
CreateInstance(int)787     virtual PObject *    CreateInstance(int /*userData*/) const { return new className; }
GetDeviceNames(int userData)788     virtual PStringArray GetDeviceNames(int userData) const { return className::GetDeviceNames((PSoundChannel::Directions)userData); }
789 };
790 
791 #define PCREATE_SOUND_PLUGIN(name, className) \
792   static PSoundChannelPluginServiceDescriptor<className> className##_descriptor; \
793   PCREATE_PLUGIN(name, PSoundChannel, &className##_descriptor)
794 
795 #ifdef _WIN32
796   PPLUGIN_STATIC_LOAD(WindowsMultimedia, PSoundChannel);
797 #elif defined(__BEOS__)
798   PPLUGIN_STATIC_LOAD(BeOS, PSoundChannel);
799 #endif
800 
801 #if defined(P_DIRECTSOUND)
802   PPLUGIN_STATIC_LOAD(DirectSound, PSoundChannel);
803 #endif
804 
805 #if defined(P_WAVFILE)
806   PPLUGIN_STATIC_LOAD(WAVFile, PSoundChannel)
807 #endif
808 
809 
810 #endif // PTLIB_SOUND_H
811 
812 
813 // End Of File ///////////////////////////////////////////////////////////////
814