1 /* 2 * pcss.h 3 * 4 * PC Sound System support. 5 * 6 * Open Phone Abstraction Library (OPAL) 7 * Formally known as the Open H323 project. 8 * 9 * Copyright (c) 2001 Equivalence Pty. Ltd. 10 * 11 * The contents of this file are subject to the Mozilla Public License 12 * Version 1.0 (the "License"); you may not use this file except in 13 * compliance with the License. You may obtain a copy of the License at 14 * http://www.mozilla.org/MPL/ 15 * 16 * Software distributed under the License is distributed on an "AS IS" 17 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 18 * the License for the specific language governing rights and limitations 19 * under the License. 20 * 21 * The Original Code is Open Phone Abstraction Library. 22 * 23 * The Initial Developer of the Original Code is Equivalence Pty. Ltd. 24 * 25 * Contributor(s): ______________________________________. 26 * 27 * $Revision: 28276 $ 28 * $Author: rjongbloed $ 29 * $Date: 2012-08-29 21:50:30 -0500 (Wed, 29 Aug 2012) $ 30 */ 31 32 #ifndef OPAL_OPAL_PCSS_H 33 #define OPAL_OPAL_PCSS_H 34 35 #ifdef P_USE_PRAGMA 36 #pragma interface 37 #endif 38 39 40 #include <opal/buildopts.h> 41 42 #if OPAL_HAS_PCSS 43 44 #include <ptlib/sound.h> 45 #include <opal/localep.h> 46 47 48 class OpalPCSSConnection; 49 50 51 /** PC Sound System endpoint. 52 */ 53 class OpalPCSSEndPoint : public OpalLocalEndPoint 54 { 55 PCLASSINFO(OpalPCSSEndPoint, OpalLocalEndPoint); 56 public: 57 /**@name Construction */ 58 //@{ 59 /**Create a new endpoint. 60 */ 61 OpalPCSSEndPoint( 62 OpalManager & manager, ///< Manager of all endpoints. 63 const char * prefix = "pc" ///< Prefix for URL style address strings 64 ); 65 66 /**Destroy endpoint. 67 */ 68 ~OpalPCSSEndPoint(); 69 //@} 70 71 /**@name Overrides from OpalEndPoint */ 72 //@{ 73 /**Set up a connection to a remote party. 74 This is called from the OpalManager::MakeConnection() function once 75 it has determined that this is the endpoint for the protocol. 76 77 The general form for this party parameter is: 78 79 [proto:][alias@][transport$]address[:port] 80 81 where the various fields will have meanings specific to the endpoint 82 type. For example, with H.323 it could be "h323:Fred@site.com" which 83 indicates a user Fred at gatekeeper size.com. Whereas for the PSTN 84 endpoint it could be "pstn:5551234" which is to call 5551234 on the 85 first available PSTN line. 86 87 The proto field is optional when passed to a specific endpoint. If it 88 is present, however, it must agree with the endpoints protocol name or 89 false is returned. 90 91 This function usually returns almost immediately with the connection 92 continuing to occur in a new background thread. 93 94 If false is returned then the connection could not be established. For 95 example if a PSTN endpoint is used and the assiciated line is engaged 96 then it may return immediately. Returning a non-NULL value does not 97 mean that the connection will succeed, only that an attempt is being 98 made. 99 100 The default behaviour is pure. 101 */ 102 virtual PSafePtr<OpalConnection> MakeConnection( 103 OpalCall & call, ///< Owner of connection 104 const PString & party, ///< Remote party to call 105 void * userData = NULL, ///< Arbitrary data to pass to connection 106 unsigned options = 0, ///< Option bit map to be passed to connection 107 OpalConnection::StringOptions * stringOptions = NULL ///< Options to be passed to connection 108 ); 109 //@} 110 111 /**@name Overrides from OpalLocalEndPoint */ 112 //@{ 113 /**Call back to indicate that remote is ringing. 114 If false is returned the call is aborted. 115 116 The default implementation does nothing. 117 */ 118 virtual bool OnOutgoingCall( 119 const OpalLocalConnection & connection ///< Connection having event 120 ); 121 122 /**Call back to indicate that there is an incoming call. 123 Note this function should not block or it will impede the operation of 124 the stack. 125 126 The default implementation returns true; 127 128 @return false is returned the call is aborted with status of EndedByLocalBusy. 129 130 */ 131 virtual bool OnIncomingCall( 132 OpalLocalConnection & connection ///< Connection having event 133 ); 134 135 /**Call back to indicate that the remote user has indicated something. 136 If false is returned the call is aborted. 137 138 The default implementation does nothing. 139 */ 140 virtual bool OnUserInput( 141 const OpalLocalConnection & connection, ///< Connection having event 142 const PString & indication ///< Received user input indications 143 ); 144 //@} 145 146 /**@name Customisation call backs */ 147 //@{ 148 /**Create a connection for the PCSS endpoint. 149 The default implementation is to create a OpalPCSSConnection. 150 */ 151 virtual OpalPCSSConnection * CreateConnection( 152 OpalCall & call, ///< Owner of connection 153 const PString & playDevice, ///< Sound channel play device 154 const PString & recordDevice, ///< Sound channel record device 155 void * userData, ///< Arbitrary data to pass to connection 156 unsigned options, ///< Option bit map to be passed to connection 157 OpalConnection::StringOptions * stringOptions ///< Options to be passed to connection 158 ); 159 160 /**Create an PSoundChannel based media stream. 161 */ 162 virtual PSoundChannel * CreateSoundChannel( 163 const OpalPCSSConnection & connection, ///< Connection needing created sound channel 164 const OpalMediaFormat & mediaFormat, ///< Media format for the connection 165 PBoolean isSource ///< Direction for channel 166 ); 167 //@} 168 169 /**@name User Interface operations */ 170 //@{ 171 /**Find a connection that uses the specified token. 172 This searches the endpoint for the connection that contains the token 173 as provided by functions such as MakeConnection(). If not then it 174 attempts to use the token as a OpalCall token and find a connection 175 of the same class. 176 */ 177 PSafePtr<OpalPCSSConnection> GetPCSSConnectionWithLock( 178 const PString & token, ///< Token to identify connection 179 PSafetyMode mode = PSafeReadWrite ///< Lock mode 180 ) { return GetConnectionWithLockAs<OpalPCSSConnection>(token, mode); } 181 182 /**Call back to indicate that there is an incoming call. 183 Note this function should not block or it will impede the operation of 184 the stack. 185 186 The default implementation is pure. 187 188 @return false is returned the call is aborted with status of EndedByLocalBusy. 189 */ 190 virtual PBoolean OnShowIncoming( 191 const OpalPCSSConnection & connection ///< Connection having event 192 ) = 0; 193 194 /**Accept the incoming connection. 195 Returns false if the connection token does not correspond to a valid 196 connection. 197 */ 198 virtual PBoolean AcceptIncomingConnection( 199 const PString & connectionToken ///< Token of connection to accept call 200 ); 201 202 /**Reject the incoming connection. 203 Returns false if the connection token does not correspond to a valid 204 connection. 205 */ 206 virtual PBoolean RejectIncomingConnection( 207 const PString & connectionToken, ///< Token of connection to accept call 208 const OpalConnection::CallEndReason & reason = OpalConnection::EndedByAnswerDenied ///< Reason for rejecting the call 209 ); 210 211 /**Call back to indicate that remote is ringing. 212 If false is returned the call is aborted. 213 214 The default implementation is pure. 215 */ 216 virtual PBoolean OnShowOutgoing( 217 const OpalPCSSConnection & connection ///< Connection having event 218 ) = 0; 219 220 /**Call back to indicate that the remote user has indicated something. 221 If false is returned the call is aborted. 222 223 The default implementation does nothing. 224 */ 225 virtual PBoolean OnShowUserInput( 226 const OpalPCSSConnection & connection, ///< Connection having event 227 const PString & indication ///< Received user input indications 228 ); 229 //@} 230 231 /**@name Member variable access */ 232 //@{ 233 /**Set the name for the sound channel to be used for output. 234 If the name is not suitable for use with the PSoundChannel class then 235 the function will return false and not change the device. 236 237 This defaults to the value of the PSoundChannel::GetDefaultDevice() 238 function. 239 */ 240 virtual PBoolean SetSoundChannelPlayDevice(const PString & name); 241 242 /**Get the name for the sound channel to be used for output. 243 This defaults to the value of the PSoundChannel::GetDefaultDevice() 244 function. 245 */ GetSoundChannelPlayDevice()246 const PString & GetSoundChannelPlayDevice() const { return soundChannelPlayDevice; } 247 248 /**Set the name for the sound channel to be used for input. 249 If the name is not suitable for use with the PSoundChannel class then 250 the function will return false and not change the device. 251 252 This defaults to the value of the PSoundChannel::GetDefaultDevice() 253 function. 254 */ 255 virtual PBoolean SetSoundChannelRecordDevice(const PString & name); 256 257 /**Get the name for the sound channel to be used for input. 258 This defaults to the value of the PSoundChannel::GetDefaultDevice() 259 function. 260 */ GetSoundChannelRecordDevice()261 const PString & GetSoundChannelRecordDevice() const { return soundChannelRecordDevice; } 262 263 /**Get default the sound channel buffer depth. 264 Note the largest of the depth in frames and the depth in milliseconds 265 as returned by GetSoundBufferTime() is used. 266 */ GetSoundChannelBufferDepth()267 unsigned GetSoundChannelBufferDepth() const { return soundChannelBuffers; } 268 269 /**Set the default sound channel buffer depth. 270 Note the largest of the depth in frames and the depth in milliseconds 271 as returned by GetSoundBufferTime() is used. 272 */ 273 void SetSoundChannelBufferDepth( 274 unsigned depth ///< New depth 275 ); 276 277 /**Get default the sound channel buffer time in milliseconds. 278 Note the largest of the depth in frames and the depth in milliseconds 279 as returned by GetSoundBufferTime() is used. 280 */ GetSoundChannelBufferTime()281 unsigned GetSoundChannelBufferTime() const { return m_soundChannelBufferTime; } 282 283 /**Set the default sound channel buffer time in milliseconds. 284 Note the largest of the depth in frames and the depth in milliseconds 285 as returned by GetSoundBufferTime() is used. 286 */ 287 void SetSoundChannelBufferTime( 288 unsigned depth ///< New depth in milliseconds 289 ); 290 //@} 291 292 protected: 293 PString soundChannelPlayDevice; 294 PString soundChannelRecordDevice; 295 unsigned soundChannelBuffers; 296 unsigned m_soundChannelBufferTime; 297 298 private: 299 P_REMOVE_VIRTUAL(OpalPCSSConnection *, CreateConnection(OpalCall &, const PString &, const PString &, void *), 0) 300 }; 301 302 303 /** PC Sound System connection. 304 */ 305 class OpalPCSSConnection : public OpalLocalConnection 306 { 307 PCLASSINFO(OpalPCSSConnection, OpalLocalConnection); 308 public: 309 /**@name Construction */ 310 //@{ 311 /**Create a new endpoint. 312 */ 313 OpalPCSSConnection( 314 OpalCall & call, ///< Owner calll for connection 315 OpalPCSSEndPoint & endpoint, ///< Owner endpoint for connection 316 const PString & playDevice, ///< Sound channel play device 317 const PString & recordDevice, ///< Sound channel record device 318 unsigned options = 0, ///< Option bit map to be passed to connection 319 OpalConnection::StringOptions * stringOptions = NULL ///< Options to be passed to connection 320 ); 321 322 /**Destroy endpoint. 323 */ 324 ~OpalPCSSConnection(); 325 //@} 326 327 /**@name Overrides from OpalConnection */ 328 //@{ 329 /**Initiate the transfer of an existing call (connection) to a new remote 330 party. 331 332 If remoteParty is a valid call token, then the remote party is transferred 333 to that party (consultation transfer) and both calls are cleared. 334 */ 335 virtual bool TransferConnection( 336 const PString & remoteParty ///< Remote party to transfer the existing call to 337 ); 338 339 /**Open a new media stream. 340 This will create a media stream of an appropriate subclass as required 341 by the underlying connection protocol. For instance H.323 would create 342 an OpalRTPStream. 343 344 The sessionID parameter may not be needed by a particular media stream 345 and may be ignored. In the case of an OpalRTPStream it us used. 346 347 Note that media streams may be created internally to the underlying 348 protocol. This function is not the only way a stream can come into 349 existance. 350 351 The default behaviour is pure. 352 */ 353 virtual OpalMediaStream * CreateMediaStream( 354 const OpalMediaFormat & mediaFormat, ///< Media format for stream 355 unsigned sessionID, ///< Session number for stream 356 PBoolean isSource ///< Is a source stream 357 ); 358 359 /**Set the volume (gain) for the audio media channel. 360 The volume range is 0 == muted, 100 == LOUDEST. 361 */ 362 virtual PBoolean SetAudioVolume( 363 PBoolean source, ///< true for source (microphone), false for sink (speaker) 364 unsigned percentage ///< Gain, 0=silent, 100=maximun 365 ); 366 367 /**Get the volume (gain) for the audio media channel. 368 The volume range is 0 == muted, 100 == LOUDEST. 369 */ 370 virtual PBoolean GetAudioVolume( 371 PBoolean source, ///< true for source (microphone), false for sink (speaker) 372 unsigned & percentage ///< Gain, 0=silent, 100=maximun 373 ); 374 375 /**Set the mute state for the audio media channel. 376 */ 377 virtual bool SetAudioMute( 378 bool source, ///< true for source (microphone), false for sink (speaker) 379 bool mute ///< Flag for muted audio 380 ); 381 382 /**Get the mute state for the audio media channel. 383 */ 384 virtual bool GetAudioMute( 385 bool source, ///< true for source (microphone), false for sink (speaker) 386 bool & mute ///< Flag for muted audio 387 ); 388 389 /**Get the average signal level (0..32767) for the audio media channel. 390 A return value of UINT_MAX indicates no valid signal, eg no audio channel opened. 391 */ 392 virtual unsigned GetAudioSignalLevel( 393 PBoolean source ///< true for source (microphone), false for sink (speaker) 394 ); 395 //@} 396 397 /**@name New operations */ 398 //@{ 399 /**Create an PSoundChannel based media stream. 400 */ 401 virtual PSoundChannel * CreateSoundChannel( 402 const OpalMediaFormat & mediaFormat, ///< Media format for the connection 403 PBoolean isSource ///< Direction for channel 404 ); 405 //@} 406 407 /**@name Member variable access */ 408 //@{ 409 /**Get the name for the sound channel to be used for output. 410 This defaults to the value of the PSoundChannel::GetDefaultDevice() 411 function. 412 */ GetSoundChannelPlayDevice()413 const PString & GetSoundChannelPlayDevice() const { return soundChannelPlayDevice; } 414 415 /**Get the name for the sound channel to be used for input. 416 This defaults to the value of the PSoundChannel::GetDefaultDevice() 417 function. 418 */ GetSoundChannelRecordDevice()419 const PString & GetSoundChannelRecordDevice() const { return soundChannelRecordDevice; } 420 421 /**Get default the sound channel buffer depth. 422 Note the largest of the depth in frames and the depth in milliseconds 423 as returned by GetSoundBufferTime() is used. 424 */ GetSoundChannelBufferDepth()425 unsigned GetSoundChannelBufferDepth() const { return soundChannelBuffers; } 426 427 /**Get default the sound channel buffer time in milliseconds. 428 Note the largest of the depth in frames and the depth in milliseconds 429 as returned by GetSoundBufferTime() is used. 430 */ GetSoundChannelBufferTime()431 unsigned GetSoundChannelBufferTime() const { return m_soundChannelBufferTime; } 432 //@} 433 434 435 protected: 436 OpalPCSSEndPoint & endpoint; 437 PString soundChannelPlayDevice; 438 PString soundChannelRecordDevice; 439 unsigned soundChannelBuffers; 440 unsigned m_soundChannelBufferTime; 441 }; 442 443 #else 444 445 #ifdef _MSC_VER 446 #pragma message("PTLib soundcard support not available") 447 #else 448 #warning "PTLib soundcard support not available" 449 #endif 450 451 452 #endif // OPAL_HAS_PCSS 453 454 #endif // OPAL_OPAL_PCSS_H 455 456 457 // End of File /////////////////////////////////////////////////////////////// 458