{{{ #!html
}}} = PJMEDIA Audio Device API = '''Table of Contents''' [[PageOutline(2-3,,inline)]] The '''PJMEDIA Audio Device API''' is a new sound device abstraction API/library in PJMEDIA, introduced in PJSIP version 1.1, deprecating the [http://www.pjsip.org/pjmedia/docs/html/group__PJMED__SND.htm existing sound device API]. [[BR]] == Background == The '''PJMEDIA Audio Device API''' was introduced as part of the implementation of [wiki:Nokia_APS_VAS_Direct APS-Direct] implementation in PJSIP version 1.1. During the design and implementation of [wiki:Nokia_APS_VAS_Direct APS-Direct] project, it was clear that the [http://www.pjsip.org/pjmedia/docs/html/group__PJMED__SND.htm existing sound device API] lacks many features that are needed to support the project. We had the choice to either patch the existing API with new features that are specific to Nokia APS, and potentially break existing applications anyway, or design a new sound device API to support all these new features as well as future enhancements, while providing some support for the old sound API and a clear migration path to the new API. [[BR]] == Features == The new audio device API contains the following major features. '''Forward compatibility:''' :: The new API has been designed to be extensible, it will support new API's as well as new features that may be introduced in the future without breaking compatibility with applications that use this API as well as compatibility with existing device implementations. '''Device capabilities:''' :: At the heart of the API is device capabilities management, where all possible audio capabilities of audio devices should be able to be handled in a generic manner. With this framework, new capabilities that may be discovered in the future can be handled in manner without breaking existing applications. '''Built-in features:''' :: The device capabilities framework enables applications to use audio features built-in in the device, such as echo cancellation, built-in codecs, audio routing, and volume control. '''Codec support:''' :: Some audio devices such as Nokia/Symbian Audio Proxy Server (APS) and Nokia VoIP Audio Services (VAS) support built-in hardware audio codecs (e.g. G.729, iLBC, and AMR), and this feature is supported by the new audio device API. '''Multiple backends:''' :: The new API supports multiple audio backends (may be called ''factories'' or ''drivers'' in the code) to be active simultaneously, and audio backends may be added or removed during run-time. [[BR]] == Migration Path == === Common Tasks === 1. The Audio Device API is implemented as a new (static) library called '''pjmedia-audiodev''', under '''pjmedia''' directory. Please add this library into link specifications of your application. === Ported Devices === The following audio device backends have been ported to the new API: - !PortAudio (previously pasound.c) - WMME (previously wmme_sound.c) - Null implementation (previously nullsound.c) - APS (previously symbian_sound_aps.cpp) === Compatibility settings === The following compile time settings/macros have introduced to manage compatibility between old and new API and to assist migration of application and/or sound device implementation to the new API. '''Setting 1) {{{PJMEDIA_AUDIO_API = PJMEDIA_AUDIO_API_NEW_ONLY}}}''' :: This setting will completely deprecate the use of old API, and inclusion of {{{}}} in the code will raise compilation error. Use this setting if: - you are accessing sound devices which have been implemented using the '''new''' API - you have completely ported your application to use the new API '''Setting 2) {{{PJMEDIA_AUDIO_API = PJMEDIA_AUDIO_API_HAS_OLD_API}}}''' :: With this setting (this is the default setting), application can use the old sound device API to access audio devices provided by the new audio device API. Use this setting if: - you are accessing sound devices which have been ported to the new API - you want to access the sound device using '''both''' old or new API's. What this setting does: - it creates a sound device implementation based on the old API, but the implementation uses/accesses the new audio device API. '''Setting 3) {{{PJMEDIA_AUDIO_API = PJMEDIA_AUDIO_API_HAS_OLD_DEVICE}}}''' :: This setting enables old sound device implementation to be accessed via '''both''' old and new API's. Use this setting if: - you have your own sound device implementation, using the old API - you want to access the sound device using '''both''' old or new API's. What this setting does: - the new audio device API will create a wrapper for the old sound device implementation, effectively enabling the sound device implementation to be accessed via old or new API. === Migration strategy === Use the following checklist to select which setting is appropriate for your build. 1. I use sound devices provided by PJMEDIA (I don't have my own sound device implementation), or I have ported my sound device implementation to the new API a. I haven't changed my application to use the new API - use setting 2 (the default) a. I have changed my application to use the new API - you may use setting 1 to make sure that everything has been ported to the new API, or otherwise use setting 2. 1. I have my own sound device implementation, based on old API a. I haven't changed my application to use the new API - use setting 3 a. I have changed my application to use the new API - also use setting 3 [[BR]] == Changes == As stated above, existing applications should build fine with the new changes. However, it will still be beneficial to port the application to use the new API since the old sound API has been deprecated, and also to make use of the new features in the new Audio Device API. === Default device convention === Old API:: Value -1 is used throughout to denote default device New API:: Default devices are encoded with the following constants: - PJMEDIA_AUD_DEFAULT_CAPTURE_DEV (-1) is not used to denote default capture device, and - PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV (-2) for default playback device. Applications using the old convention is expected to work with the new API. === Configuring AEC with the sound port === #ec Old API:: The echo cancellation is usually configured after the sound port is created, by using {{{pjmedia_snd_port_set_ec()}}}. New API:: The semantic of {{{pjmedia_snd_port_set_ec()}}} API has been changed to ''to change the settings of the AEC'' rather than ''to enable AEC''. With the new API, the best way to configure AEC is to set the EC parameters in the {{{pjmedia_aud_param}}} when creating the sound device or sound device port, e.g.: {{{ pjmedia_aud_param param; .. param.flags |= (PJMEDIA_AUD_DEV_CAP_EC | PJMEDIA_AUD_DEV_CAP_EC_TAIL); param.ec_enabled = PJ_TRUE; param.ec_tail_ms = ..; .. pjmedia_snd_port_create2(pool, ¶m, &snd_port); }}} If {{{pjmedia_snd_port_set_ec()}}} is called after the sound port is opened, the behavior is as follows: - if the device supports (hardware) AEC, as indicated by device capabilities, then the sound port will forward the change request to the device. The device may or may not support the request to change AEC parameters after the device is opened. - if software AEC is being used (for devices that don't support AEC), this will change the setting of the software AEC. Effectively this resembles the old behavior of the API. === PJSUA-LIB applications === PJSUA-LIB applications that only make use of the API in {{{}}} should require minimum changes. 1. Change in {{{pjsua_enum_snd_devs()}}} signature. Old API: {{{ PJ_DECL(pj_status_t) pjsua_enum_snd_devs(pjmedia_snd_dev_info info[], unsigned *count); }}} New API (notice the type difference in the ''info'' argument): {{{ PJ_DECL(pj_status_t) pjsua_enum_snd_devs(pjmedia_aud_dev_info info[], unsigned *count); }}} 2. Add '''pjmedia-audiodev''' library to the link specifications of your application. 3. '''Latency''' setting. Old code may set latency directly accessing PJMEDIA API: {{{ pjmedia_snd_set_latency(rec_latency, play_latency); }}} Now latency setting is part of PJSUA-LIB API: {{{ pjsua_media_config media_cfg; .. media_cfg.snd_rec_latency = ..; media_cfg.snd_play_latency = ..; }}} === PJMEDIA applications === Below are list of changes for applications that directly uses the old sound API as declared in {{{}}}. 1. Change the header file to include. Old code: {{{ #include }}} New code: {{{ #include }}} 2. Add '''pjmedia-audiodev''' library to the link specifications of your application. 3. Sound device subsystem startup and shutdown. Old code: {{{ pjmedia_snd_init(pf); ... pjmedia_snd_deinit(); }}} New code: {{{ pjmedia_aud_subsys_init(pf); ... pjmedia_aud_subsys_shutdown(); }}} 4. Device enumeration. Old code: {{{ unsigned i, dev_count; dev_count = pjmedia_snd_get_dev_count(); for (i=0; i
}}}