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