diff options
Diffstat (limited to 'pjmedia/include/pjmedia-audiodev')
-rw-r--r-- | pjmedia/include/pjmedia-audiodev/audiodev.h | 667 | ||||
-rw-r--r-- | pjmedia/include/pjmedia-audiodev/audiodev_imp.h | 181 | ||||
-rw-r--r-- | pjmedia/include/pjmedia-audiodev/audiotest.h | 116 | ||||
-rw-r--r-- | pjmedia/include/pjmedia-audiodev/config.h | 368 | ||||
-rw-r--r-- | pjmedia/include/pjmedia-audiodev/errno.h | 198 |
5 files changed, 1530 insertions, 0 deletions
diff --git a/pjmedia/include/pjmedia-audiodev/audiodev.h b/pjmedia/include/pjmedia-audiodev/audiodev.h new file mode 100644 index 00000000..8f2ab783 --- /dev/null +++ b/pjmedia/include/pjmedia-audiodev/audiodev.h @@ -0,0 +1,667 @@ +/* $Id$ */ +/* + * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com) + * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __PJMEDIA_AUDIODEV_AUDIODEV_H__ +#define __PJMEDIA_AUDIODEV_AUDIODEV_H__ + +/** + * @file audiodev.h + * @brief Audio device API. + */ +#include <pjmedia-audiodev/config.h> +#include <pjmedia-audiodev/errno.h> +#include <pjmedia/types.h> +#include <pj/pool.h> + + +PJ_BEGIN_DECL + +/** + * @defgroup s2_audio_device_reference Audio Device API Reference + * @ingroup audio_device_api + * @brief API Reference + * @{ + */ + +/** + * Type for device index. + */ +typedef pj_int32_t pjmedia_aud_dev_index; + +/** + * Device index constants. + */ +enum +{ + /** + * Constant to denote default capture device + */ + PJMEDIA_AUD_DEFAULT_CAPTURE_DEV = -1, + + /** + * Constant to denote default playback device + */ + PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV = -2, + + /** + * Constant to denote invalid device index. + */ + PJMEDIA_AUD_INVALID_DEV = -3 +}; + + +/** + * This enumeration identifies various audio device capabilities. These audio + * capabilities indicates what features are supported by the underlying + * audio device implementation. + * + * Applications get these capabilities in the #pjmedia_aud_dev_info structure. + * + * Application can also set the specific features/capabilities when opening + * the audio stream by setting the \a flags member of #pjmedia_aud_param + * structure. + * + * Once audio stream is running, application can also retrieve or set some + * specific audio capability, by using #pjmedia_aud_stream_get_cap() and + * #pjmedia_aud_stream_set_cap() and specifying the desired capability. The + * value of the capability is specified as pointer, and application needs to + * supply the pointer with the correct value, according to the documentation + * of each of the capability. + */ +typedef enum pjmedia_aud_dev_cap +{ + /** + * Support for audio formats other than PCM. The value of this capability + * is represented by #pjmedia_format structure. + */ + PJMEDIA_AUD_DEV_CAP_EXT_FORMAT = 1, + + /** + * Support for audio input latency control or query. The value of this + * capability is an unsigned integer containing milliseconds value of + * the latency. + */ + PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY = 2, + + /** + * Support for audio output latency control or query. The value of this + * capability is an unsigned integer containing milliseconds value of + * the latency. + */ + PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY = 4, + + /** + * Support for setting/retrieving the audio input device volume level. + * The value of this capability is an unsigned integer representing + * the input audio volume setting in percent. + */ + PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING = 8, + + /** + * Support for setting/retrieving the audio output device volume level. + * The value of this capability is an unsigned integer representing + * the output audio volume setting in percent. + */ + PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING = 16, + + /** + * Support for monitoring the current audio input signal volume. + * The value of this capability is an unsigned integer representing + * the audio volume in percent. + */ + PJMEDIA_AUD_DEV_CAP_INPUT_SIGNAL_METER = 32, + + /** + * Support for monitoring the current audio output signal volume. + * The value of this capability is an unsigned integer representing + * the audio volume in percent. + */ + PJMEDIA_AUD_DEV_CAP_OUTPUT_SIGNAL_METER = 64, + + /** + * Support for audio input routing. The value of this capability is an + * integer containing #pjmedia_aud_dev_route enumeration. + */ + PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE = 128, + + /** + * Support for audio output routing (e.g. loudspeaker vs earpiece). The + * value of this capability is an integer containing #pjmedia_aud_dev_route + * enumeration. + */ + PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE = 256, + + /** + * The audio device has echo cancellation feature. The value of this + * capability is a pj_bool_t containing boolean PJ_TRUE or PJ_FALSE. + */ + PJMEDIA_AUD_DEV_CAP_EC = 512, + + /** + * The audio device supports setting echo cancellation fail length. The + * value of this capability is an unsigned integer representing the + * echo tail in milliseconds. + */ + PJMEDIA_AUD_DEV_CAP_EC_TAIL = 1024, + + /** + * The audio device has voice activity detection feature. The value + * of this capability is a pj_bool_t containing boolean PJ_TRUE or + * PJ_FALSE. + */ + PJMEDIA_AUD_DEV_CAP_VAD = 2048, + + /** + * The audio device has comfort noise generation feature. The value + * of this capability is a pj_bool_t containing boolean PJ_TRUE or + * PJ_FALSE. + */ + PJMEDIA_AUD_DEV_CAP_CNG = 4096, + + /** + * The audio device has packet loss concealment feature. The value + * of this capability is a pj_bool_t containing boolean PJ_TRUE or + * PJ_FALSE. + */ + PJMEDIA_AUD_DEV_CAP_PLC = 8192, + + /** + * End of capability + */ + PJMEDIA_AUD_DEV_CAP_MAX = 16384 + +} pjmedia_aud_dev_cap; + + +/** + * This enumeration describes audio routing setting. + */ +typedef enum pjmedia_aud_dev_route +{ + /** Default route. */ + PJMEDIA_AUD_DEV_ROUTE_DEFAULT = 0, + + /** Route to loudspeaker */ + PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER = 1, + + /** Route to earpiece */ + PJMEDIA_AUD_DEV_ROUTE_EARPIECE = 2 + +} pjmedia_aud_dev_route; + + +/** + * Device information structure returned by #pjmedia_aud_dev_get_info(). + */ +typedef struct pjmedia_aud_dev_info +{ + /** + * The device name + */ + char name[64]; + + /** + * Maximum number of input channels supported by this device. If the + * value is zero, the device does not support input operation (i.e. + * it is a playback only device). + */ + unsigned input_count; + + /** + * Maximum number of output channels supported by this device. If the + * value is zero, the device does not support output operation (i.e. + * it is an input only device). + */ + unsigned output_count; + + /** + * Default sampling rate. + */ + unsigned default_samples_per_sec; + + /** + * The underlying driver name + */ + char driver[32]; + + /** + * Device capabilities, as bitmask combination of #pjmedia_aud_dev_cap. + */ + unsigned caps; + + /** + * Supported audio device routes, as bitmask combination of + * #pjmedia_aud_dev_route. The value may be zero if the device + * does not support audio routing. + */ + unsigned routes; + + /** + * Number of audio formats supported by this device. The value may be + * zero if the device does not support non-PCM format. + */ + unsigned ext_fmt_cnt; + + /** + * Array of supported extended audio formats + */ + pjmedia_format ext_fmt[8]; + + +} pjmedia_aud_dev_info; + + +/** + * This callback is called by player stream when it needs additional data + * to be played by the device. Application must fill in the whole of output + * buffer with audio samples. + * + * The frame argument contains the following values: + * - timestamp Playback timestamp, in samples. + * - buf Buffer to be filled out by application. + * - size The size requested in bytes, which will be equal to + * the size of one whole packet. + * + * @param user_data User data associated with the stream. + * @param frame Audio frame, which buffer is to be filled in by + * the application. + * + * @return Returning non-PJ_SUCCESS will cause the audio stream + * to stop + */ +typedef pj_status_t (*pjmedia_aud_play_cb)(void *user_data, + pjmedia_frame *frame); + +/** + * This callback is called by recorder stream when it has captured the whole + * packet worth of audio samples. + * + * @param user_data User data associated with the stream. + * @param frame Captured frame. + * + * @return Returning non-PJ_SUCCESS will cause the audio stream + * to stop + */ +typedef pj_status_t (*pjmedia_aud_rec_cb)(void *user_data, + pjmedia_frame *frame); + +/** + * This structure specifies the parameters to open the audio stream. + */ +typedef struct pjmedia_aud_param +{ + /** + * The audio direction. This setting is mandatory. + */ + pjmedia_dir dir; + + /** + * The audio recorder device ID. This setting is mandatory if the audio + * direction includes input/capture direction. + */ + pjmedia_aud_dev_index rec_id; + + /** + * The audio playback device ID. This setting is mandatory if the audio + * direction includes output/playback direction. + */ + pjmedia_aud_dev_index play_id; + + /** + * Clock rate/sampling rate. This setting is mandatory. + */ + unsigned clock_rate; + + /** + * Number of channels. This setting is mandatory. + */ + unsigned channel_count; + + /** + * Number of samples per frame. This setting is mandatory. + */ + unsigned samples_per_frame; + + /** + * Number of bits per sample. This setting is mandatory. + */ + unsigned bits_per_sample; + + /** + * This flags specifies which of the optional settings are valid in this + * structure. The flags is bitmask combination of pjmedia_aud_dev_cap. + */ + unsigned flags; + + /** + * Set the audio format. This setting is optional, and will only be used + * if PJMEDIA_AUD_DEV_CAP_EXT_FORMAT is set in the flags. + */ + pjmedia_format ext_fmt; + + /** + * Input latency, in milliseconds. This setting is optional, and will + * only be used if PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY is set in the flags. + */ + unsigned input_latency_ms; + + /** + * Input latency, in milliseconds. This setting is optional, and will + * only be used if PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY is set in the flags. + */ + unsigned output_latency_ms; + + /** + * Input volume setting, in percent. This setting is optional, and will + * only be used if PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING is set in + * the flags. + */ + unsigned input_vol; + + /** + * Output volume setting, in percent. This setting is optional, and will + * only be used if PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING is set in + * the flags. + */ + unsigned output_vol; + + /** + * Set the audio input route. This setting is optional, and will only be + * used if PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE is set in the flags. + */ + pjmedia_aud_dev_route input_route; + + /** + * Set the audio output route. This setting is optional, and will only be + * used if PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE is set in the flags. + */ + pjmedia_aud_dev_route output_route; + + /** + * Enable/disable echo canceller, if the device supports it. This setting + * is optional, and will only be used if PJMEDIA_AUD_DEV_CAP_EC is set in + * the flags. + */ + pj_bool_t ec_enabled; + + /** + * Set echo canceller tail length in milliseconds, if the device supports + * it. This setting is optional, and will only be used if + * PJMEDIA_AUD_DEV_CAP_EC_TAIL is set in the flags. + */ + unsigned ec_tail_ms; + + /** + * Enable/disable PLC. This setting is optional, and will only be used + * if PJMEDIA_AUD_DEV_CAP_PLC is set in the flags. + */ + pj_bool_t plc_enabled; + + /** + * Enable/disable CNG. This setting is optional, and will only be used + * if PJMEDIA_AUD_DEV_CAP_CNG is set in the flags. + */ + pj_bool_t cng_enabled; + +} pjmedia_aud_param; + + +/** Forward declaration for pjmedia_aud_stream */ +typedef struct pjmedia_aud_stream pjmedia_aud_stream; + +/** Forward declaration for audio device factory */ +typedef struct pjmedia_aud_dev_factory pjmedia_aud_dev_factory; + +/** + * Get string info for the specified capability. + * + * @param cap The capability ID. + * @param p_desc Optional pointer which will be filled with longer + * description about the capability. + * + * @return Capability name. + */ +PJ_DECL(const char*) pjmedia_aud_dev_cap_name(pjmedia_aud_dev_cap cap, + const char **p_desc); + + +/** + * Set a capability field value in #pjmedia_aud_param structure. This will + * also set the flags field for the specified capability in the structure. + * + * @param param The structure. + * @param cap The audio capability which value is to be set. + * @param value Pointer to value. Please see the type of value to + * be supplied in the pjmedia_aud_dev_cap documentation. + * + * @return PJ_SUCCESS on successful operation or the appropriate + * error code. + */ +PJ_DECL(pj_status_t) pjmedia_aud_param_set_cap(pjmedia_aud_param *param, + pjmedia_aud_dev_cap cap, + const void *pval); + + +/** + * Get a capability field value from #pjmedia_aud_param structure. This + * function will return PJMEDIA_EAUD_INVCAP error if the flag for that + * capability is not set in the flags field in the structure. + * + * @param param The structure. + * @param cap The audio capability which value is to be retrieved. + * @param value Pointer to value. Please see the type of value to + * be supplied in the pjmedia_aud_dev_cap documentation. + * + * @return PJ_SUCCESS on successful operation or the appropriate + * error code. + */ +PJ_DECL(pj_status_t) pjmedia_aud_param_get_cap(const pjmedia_aud_param *param, + pjmedia_aud_dev_cap cap, + void *pval); + +/** + * Initialize the audio subsystem. This will register all supported audio + * device factories to the audio subsystem. This function may be called + * more than once, but each call to this function must have the + * corresponding #pjmedia_aud_subsys_shutdown() call. + * + * @param pf The pool factory. + * + * @return PJ_SUCCESS on successful operation or the appropriate + * error code. + */ +PJ_DECL(pj_status_t) pjmedia_aud_subsys_init(pj_pool_factory *pf); + + +/** + * Get the pool factory registered to the audio subsystem. + * + * @return The pool factory. + */ +PJ_DECL(pj_pool_factory*) pjmedia_aud_subsys_get_pool_factory(void); + + +/** + * Shutdown the audio subsystem. This will destroy all audio device factories + * registered in the audio subsystem. Note that currently opened audio streams + * may or may not be closed, depending on the implementation of the audio + * device factories. + * + * @return PJ_SUCCESS on successful operation or the appropriate + * error code. + */ +PJ_DECL(pj_status_t) pjmedia_aud_subsys_shutdown(void); + + +/** + * Get the number of sound devices installed in the system. + * + * @return The number of sound devices installed in the system. + */ +PJ_DECL(unsigned) pjmedia_aud_dev_count(void); + + +/** + * Get device information. + * + * @param id The audio device ID. + * @param info The device information which will be filled in by this + * function once it returns successfully. + * + * @return PJ_SUCCESS on successful operation or the appropriate + * error code. + */ +PJ_DECL(pj_status_t) pjmedia_aud_dev_get_info(pjmedia_aud_dev_index id, + pjmedia_aud_dev_info *info); + + +/** + * Lookup device index based on the driver and device name. + * + * @param drv_name The driver name. + * @param dev_name The device name. + * @param id Pointer to store the returned device ID. + * + * @return PJ_SUCCESS if the device can be found. + */ +PJ_DECL(pj_status_t) pjmedia_aud_dev_lookup(const char *drv_name, + const char *dev_name, + pjmedia_aud_dev_index *id); + + +/** + * Initialize the audio device parameters with default values for the + * specified device. + * + * @param id The audio device ID. + * @param param The audio device parameters which will be initialized + * by this function once it returns successfully. + * + * @return PJ_SUCCESS on successful operation or the appropriate + * error code. + */ +PJ_DECL(pj_status_t) pjmedia_aud_dev_default_param(pjmedia_aud_dev_index id, + pjmedia_aud_param *param); + + +/** + * Open audio stream object using the specified parameters. + * + * @param param Sound device parameters to be used for the stream. + * @param rec_cb Callback to be called on every input frame captured. + * @param play_cb Callback to be called everytime the sound device needs + * audio frames to be played back. + * @param user_data Arbitrary user data, which will be given back in the + * callbacks. + * @param p_strm Pointer to receive the audio stream. + * + * @return PJ_SUCCESS on successful operation or the appropriate + * error code. + */ +PJ_DECL(pj_status_t) pjmedia_aud_stream_create(const pjmedia_aud_param *param, + pjmedia_aud_rec_cb rec_cb, + pjmedia_aud_play_cb play_cb, + void *user_data, + pjmedia_aud_stream **p_strm); + +/** + * Get the running parameters for the specified audio stream. + * + * @param strm The audio stream. + * @param param Audio stream parameters to be filled in by this + * function once it returns successfully. + * + * @return PJ_SUCCESS on successful operation or the appropriate + * error code. + */ +PJ_DECL(pj_status_t) pjmedia_aud_stream_get_param(pjmedia_aud_stream *strm, + pjmedia_aud_param *param); + +/** + * Get the value of a specific capability of the audio stream. + * + * @param strm The audio stream. + * @param cap The audio capability which value is to be retrieved. + * @param value Pointer to value to be filled in by this function + * once it returns successfully. Please see the type + * of value to be supplied in the pjmedia_aud_dev_cap + * documentation. + * + * @return PJ_SUCCESS on successful operation or the appropriate + * error code. + */ +PJ_DECL(pj_status_t) pjmedia_aud_stream_get_cap(pjmedia_aud_stream *strm, + pjmedia_aud_dev_cap cap, + void *value); + +/** + * Set the value of a specific capability of the audio stream. + * + * @param strm The audio stream. + * @param cap The audio capability which value is to be set. + * @param value Pointer to value. Please see the type of value to + * be supplied in the pjmedia_aud_dev_cap documentation. + * + * @return PJ_SUCCESS on successful operation or the appropriate + * error code. + */ +PJ_DECL(pj_status_t) pjmedia_aud_stream_set_cap(pjmedia_aud_stream *strm, + pjmedia_aud_dev_cap cap, + const void *value); + +/** + * Start the stream. + * + * @param strm The audio stream. + * + * @return PJ_SUCCESS on successful operation or the appropriate + * error code. + */ +PJ_DECL(pj_status_t) pjmedia_aud_stream_start(pjmedia_aud_stream *strm); + +/** + * Stop the stream. + * + * @param strm The audio stream. + * + * @return PJ_SUCCESS on successful operation or the appropriate + * error code. + */ +PJ_DECL(pj_status_t) pjmedia_aud_stream_stop(pjmedia_aud_stream *strm); + +/** + * Destroy the stream. + * + * @param strm The audio stream. + * + * @return PJ_SUCCESS on successful operation or the appropriate + * error code. + */ +PJ_DECL(pj_status_t) pjmedia_aud_stream_destroy(pjmedia_aud_stream *strm); + + +/** + * @} + */ + +PJ_END_DECL + + +#endif /* __PJMEDIA_AUDIODEV_AUDIODEV_H__ */ + diff --git a/pjmedia/include/pjmedia-audiodev/audiodev_imp.h b/pjmedia/include/pjmedia-audiodev/audiodev_imp.h new file mode 100644 index 00000000..e12c0f21 --- /dev/null +++ b/pjmedia/include/pjmedia-audiodev/audiodev_imp.h @@ -0,0 +1,181 @@ +/* $Id$ */ +/* + * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com) + * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __AUDIODEV_IMP_H__ +#define __AUDIODEV_IMP_H__ + +#include <pjmedia-audiodev/audiodev.h> + +/** + * @defgroup s8_audio_device_implementors_api Audio Device Implementors API + * @ingroup audio_device_api + * @brief API for audio device implementors + * @{ + */ + +/** + * Sound device factory operations. + */ +typedef struct pjmedia_aud_dev_factory_op +{ + /** + * Initialize the audio device factory. + * + * @param f The audio device factory. + */ + pj_status_t (*init)(pjmedia_aud_dev_factory *f); + + /** + * Close this audio device factory and release all resources back to the + * operating system. + * + * @param f The audio device factory. + */ + pj_status_t (*destroy)(pjmedia_aud_dev_factory *f); + + /** + * Get the number of audio devices installed in the system. + * + * @param f The audio device factory. + */ + unsigned (*get_dev_count)(pjmedia_aud_dev_factory *f); + + /** + * Get the audio device information and capabilities. + * + * @param f The audio device factory. + * @param index Device index. + * @param info The audio device information structure which will be + * initialized by this function once it returns + * successfully. + */ + pj_status_t (*get_dev_info)(pjmedia_aud_dev_factory *f, + unsigned index, + pjmedia_aud_dev_info *info); + + /** + * Initialize the specified audio device parameter with the default + * values for the specified device. + * + * @param f The audio device factory. + * @param index Device index. + * @param param The audio device parameter. + */ + pj_status_t (*default_param)(pjmedia_aud_dev_factory *f, + unsigned index, + pjmedia_aud_param *param); + + /** + * Open the audio device and create audio stream. See + * #pjmedia_aud_stream_create() + */ + pj_status_t (*create_stream)(pjmedia_aud_dev_factory *f, + const pjmedia_aud_param *param, + pjmedia_aud_rec_cb rec_cb, + pjmedia_aud_play_cb play_cb, + void *user_data, + pjmedia_aud_stream **p_aud_strm); + +} pjmedia_aud_dev_factory_op; + + +/** + * This structure describes an audio device factory. + */ +struct pjmedia_aud_dev_factory +{ + /** Internal data to be initialized by audio subsystem. */ + struct { + /** Driver index */ + unsigned drv_idx; + } sys; + + /** Operations */ + pjmedia_aud_dev_factory_op *op; +}; + + +/** + * Sound stream operations. + */ +typedef struct pjmedia_aud_stream_op +{ + /** + * See #pjmedia_aud_stream_get_param() + */ + pj_status_t (*get_param)(pjmedia_aud_stream *strm, + pjmedia_aud_param *param); + + /** + * See #pjmedia_aud_stream_get_cap() + */ + pj_status_t (*get_cap)(pjmedia_aud_stream *strm, + pjmedia_aud_dev_cap cap, + void *value); + + /** + * See #pjmedia_aud_stream_set_cap() + */ + pj_status_t (*set_cap)(pjmedia_aud_stream *strm, + pjmedia_aud_dev_cap cap, + const void *value); + + /** + * See #pjmedia_aud_stream_start() + */ + pj_status_t (*start)(pjmedia_aud_stream *strm); + + /** + * See #pjmedia_aud_stream_stop(). + */ + pj_status_t (*stop)(pjmedia_aud_stream *strm); + + /** + * See #pjmedia_aud_stream_destroy(). + */ + pj_status_t (*destroy)(pjmedia_aud_stream *strm); + +} pjmedia_aud_stream_op; + + +/** + * This structure describes the audio device stream. + */ +struct pjmedia_aud_stream +{ + /** Internal data to be initialized by audio subsystem */ + struct { + /** Driver index */ + unsigned drv_idx; + } sys; + + /** Operations */ + pjmedia_aud_stream_op *op; +}; + + + + +/** + * @} + */ + + + +#endif /* __AUDIODEV_IMP_H__ */ diff --git a/pjmedia/include/pjmedia-audiodev/audiotest.h b/pjmedia/include/pjmedia-audiodev/audiotest.h new file mode 100644 index 00000000..8da3cc14 --- /dev/null +++ b/pjmedia/include/pjmedia-audiodev/audiotest.h @@ -0,0 +1,116 @@ +/* $Id$ */ +/* + * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com) + * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __PJMEDIA_AUDIODEV_AUDIOTEST_H__ +#define __PJMEDIA_AUDIODEV_AUDIOTEST_H__ + +/** + * @file audiotest.h + * @brief Audio test utility. + */ +#include <pjmedia-audiodev/audiodev.h> + + +PJ_BEGIN_DECL + +/** + * @defgroup s30_audio_test_utility Audio tests utility. + * @ingroup audio_device_api + * @brief Audio test utility. + * @{ + */ + +/** + * Statistic for each direction. + */ +typedef struct pjmedia_aud_test_stat +{ + /** + * Number of frames processed during the test. + */ + unsigned frame_cnt; + + /** + * Minimum inter-frame arrival time, in milliseconds + */ + unsigned min_interval; + + /** + * Maximum inter-frame arrival time, in milliseconds + */ + unsigned max_interval; + + /** + * Average inter-frame arrival time, in milliseconds + */ + unsigned avg_interval; + + /** + * Standard deviation of inter-frame arrival time, in milliseconds + */ + unsigned dev_interval; + + /** + * Maximum number of frame burst + */ + unsigned max_burst; + +} pjmedia_aud_test_stat; + + +/** + * Test results. + */ +typedef struct pjmedia_aud_test_results +{ + /** + * Recording statistic. + */ + pjmedia_aud_test_stat rec; + + /** + * Playback statistic. + */ + pjmedia_aud_test_stat play; + + /** + * Clock drifts per second, in samples. Positive number indicates rec + * device is running faster than playback device. + */ + pj_int32_t rec_drift_per_sec; + +} pjmedia_aud_test_results; + + +/** + * Perform audio device testing. + */ +PJ_DECL(pj_status_t) pjmedia_aud_test(const pjmedia_aud_param *param, + pjmedia_aud_test_results *result); + +/** + * @} + */ + +PJ_END_DECL + + +#endif /* __PJMEDIA_AUDIODEV_AUDIOTEST_H__ */ + + diff --git a/pjmedia/include/pjmedia-audiodev/config.h b/pjmedia/include/pjmedia-audiodev/config.h new file mode 100644 index 00000000..b4603c15 --- /dev/null +++ b/pjmedia/include/pjmedia-audiodev/config.h @@ -0,0 +1,368 @@ +/* $Id$ */ +/* + * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com) + * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __PJMEDIA_AUDIODEV_CONFIG_H__ +#define __PJMEDIA_AUDIODEV_CONFIG_H__ + +/** + * @file audiodev.h + * @brief Audio device API. + */ +#include <pjmedia/types.h> +#include <pj/pool.h> + + +PJ_BEGIN_DECL + +/** + * @defgroup audio_device_api Audio Device API + * @brief PJMEDIA audio device abstraction API. + */ + +/** + * @defgroup s1_audio_device_config Compile time configurations + * @ingroup audio_device_api + * @brief Compile time configurations + * @{ + */ + +/** + * This setting controls whether PortAudio support should be included. + */ +#ifndef PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO +# define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO 1 +#endif + + +/** + * This setting controls whether WMME support should be included. + */ +#ifndef PJMEDIA_AUDIO_DEV_HAS_WMME +# define PJMEDIA_AUDIO_DEV_HAS_WMME 1 +#endif + + +/** + * This setting controls whether Symbian APS support should be included. + */ +#ifndef PJMEDIA_AUDIO_DEV_HAS_SYMB_APS +# define PJMEDIA_AUDIO_DEV_HAS_SYMB_APS 0 +#endif + + +/** + * This setting controls whether Symbian audio (using built-in multimedia + * framework) support should be included. + */ +#ifndef PJMEDIA_AUDIO_DEV_HAS_SYMB_MDA +# define PJMEDIA_AUDIO_DEV_HAS_SYMB_MDA PJ_SYMBIAN +#endif + + +/** + * This setting controls whether the Audio Device API should support + * device implementation that is based on the old sound device API + * (sound.h). + * + * Enable this API if: + * - you have implemented your own sound device using the old sound + * device API (sound.h), and + * - you wish to be able to use your sound device implementation + * using the new Audio Device API. + * + * Please see http://trac.pjsip.org/repos/wiki/Audio_Dev_API for more + * info. + */ +#ifndef PJMEDIA_AUDIO_DEV_HAS_LEGACY_DEVICE +# define PJMEDIA_AUDIO_DEV_HAS_LEGACY_DEVICE 0 +#endif + + +/** + * @} + */ + +PJ_END_DECL + + +#endif /* __PJMEDIA_AUDIODEV_CONFIG_H__ */ + +/* + --------------------- DOCUMENTATION FOLLOWS --------------------------- + */ + +/** + * @addtogroup audio_device_api Audio Device API + * @{ + +PJMEDIA Audio Device API is a cross-platform audio API appropriate for use with +VoIP applications and many other types of audio streaming applications. + +The API abstracts many different audio API's on various platforms, such as: + - PortAudio back-end for Win32, Windows Mobile, Linux, Unix, dan MacOS X. + - native WMME audio for Win32 and Windows Mobile devices + - native Symbian audio streaming/multimedia framework (MMF) implementation + - native Nokia Audio Proxy Server (APS) implementation + - null-audio implementation + - and more to be implemented in the future + +The Audio Device API/library is an evolution from PJMEDIA @ref PJMED_SND and +contains many enhancements: + + - Forward compatibility: +\n + 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: +\n + 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: +\n + The device capabilities framework enables applications to use and control + audio features built-in in the device, such as: + - echo cancellation, + - built-in codecs, + - audio routing (e.g. to earpiece or loudspeaker), + - volume control, + - etc. + + - Codec support: +\n + 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 application can use the sound device in encoded mode to + make use of these hardware codecs. + + - Multiple backends: +\n + The new API supports multiple audio backends (called factories or drivers in + the code) to be active simultaneously, and audio backends may be added or + removed during run-time. + + +@section using Overview on using the API + +@subsection getting_started Getting started + + -# <b>Configure the application's project settings</b>.\n + Add the following + include: + \code + #include <pjmedia_audiodev.h>\endcode\n + And add <b>pjmedia-audiodev</b> library to your application link + specifications.\n + -# <b>Compile time settings</b>.\n + Use the compile time settings to enable or + disable specific audio drivers. For more information, please see + \ref s1_audio_device_config. + -# <b>API initialization and cleaning up</b>.\n + Before anything else, application must initialize the API by calling: + \code + pjmedia_aud_subsys_init(pf);\endcode\n + And add this in the application cleanup sequence + \code + pjmedia_aud_subsys_shutdown();\endcode + +@subsection devices Working with devices + + -# The following code prints the list of audio devices detected + in the system. + \code + int dev_count; + pjmedia_aud_dev_index dev_idx; + pj_status_t status; + + dev_count = pjmedia_aud_dev_count(); + printf("Got %d audio devices\n", dev_count); + + for (dev_idx=0; dev_idx<dev_count; ++i) { + pjmedia_aud_dev_info info; + + status = pjmedia_aud_dev_get_info(dev_idx, &info); + printf("%d. %s (in=%d, out=%d)\n", + dev_idx, info.name, + info.input_count, info.output_count); + } + \endcode\n + -# Info: The #PJMEDIA_AUD_DEFAULT_CAPTURE_DEV and #PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV + constants are used to denote default capture and playback devices + respectively. + -# Info: You may save the device and driver's name in your application + setting, for example to specify the prefered devices to be + used by your application. You can then retrieve the device index + for the device by calling: + \code + const char *drv_name = "WMME"; + const char *dev_name = "Wave mapper"; + pjmedia_aud_dev_index dev_idx; + + status = pjmedia_aud_dev_lookup(drv_name, dev_name, &dev_idx); + if (status==PJ_SUCCESS) + printf("Device index is %d\n", dev_idx); + \endcode + +@subsection caps Device capabilities + +Capabilities are encoded as #pjmedia_aud_dev_cap enumeration. Please see +#pjmedia_aud_dev_cap enumeration for more information. + + -# The following snippet prints the capabilities supported by the device: + \code + pjmedia_aud_dev_info info; + pj_status_t status; + + status = pjmedia_aud_dev_get_info(PJMEDIA_AUD_DEFAULT_CAPTURE_DEV, &info); + if (status == PJ_SUCCESS) { + unsigned i; + // Enumerate capability bits + printf("Device capabilities: "); + for (i=0; i<32; ++i) { + if (info.caps & (1 << i)) + printf("%s ", pjmedia_aud_dev_cap_name(1 << i, NULL)); + } + } + \endcode\n + -# Info: You can set the device settings when opening audio stream by setting + the flags and the appropriate setting in #pjmedia_aud_param when calling + #pjmedia_aud_stream_create()\n + -# Info: Once the audio stream is running, you can retrieve or change the stream + setting by specifying the capability in #pjmedia_aud_stream_get_cap() + and #pjmedia_aud_stream_set_cap() respectively. + + +@subsection creating_stream Creating audio streams + +The audio stream enables audio streaming to capture device, playback device, +or both. + + -# It is recommended to initialize the #pjmedia_aud_param with its default + values before using it: + \code + pjmedia_aud_param param; + pjmedia_aud_dev_index dev_idx; + pj_status_t status; + + dev_idx = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV; + status = pjmedia_aud_dev_default_param(dev_idx, ¶m); + \endcode\n + -# Configure the mandatory parameters: + \code + param.dir = PJMEDIA_DIR_CAPTURE_PLAYBACK; + param.rec_id = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV; + param.play_id = PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV; + param.clock_rate = 8000; + param.channel_count = 1; + param.samples_per_frame = 160; + param.bits_per_sample = 16; + \endcode\n + -# If you want the audio stream to use the device's built-in codec, specify + the codec in the #pjmedia_aud_param. You must make sure that the codec + is supported by the device, by looking at its supported format list in + the #pjmedia_aud_dev_info.\n + The snippet below sets the audio stream to use G.711 ULAW encoding: + \code + unsigned i; + + // Make sure Ulaw is supported + if ((info.caps & PJMEDIA_AUD_DEV_CAP_EXT_FORMAT) == 0) + error("Device does not support extended formats"); + for (i = 0; i < info.ext_fmt_cnt; ++i) { + if (info.ext_fmt[i].id == PJMEDIA_FORMAT_ULAW) + break; + } + if (i == info.ext_fmt_cnt) + error("Device does not support Ulaw format"); + + // Set Ulaw format + param.flags |= PJMEDIA_AUD_DEV_CAP_EXT_FORMAT; + param.ext_fmt.id = PJMEDIA_FORMAT_ULAW; + param.ext_fmt.bitrate = 64000; + param.ext_fmt.vad = PJ_FALSE; + \endcode\n + -# Note that if non-PCM format is configured on the audio stream, the + capture and/or playback functions (#pjmedia_aud_rec_cb and + #pjmedia_aud_play_cb respectively) will report the audio frame as + #pjmedia_frame_ext structure instead of the #pjmedia_frame. + -# Optionally configure other device's capabilities. The following snippet + shows how to enable echo cancellation on the device (note that this + snippet may not be necessary since the setting may have been enabled + when calling #pjmedia_aud_dev_default_param() above): + \code + if (info.caps & PJMEDIA_AUD_DEV_CAP_EC) { + param.flags |= PJMEDIA_AUD_DEV_CAP_EC; + param.ec_enabled = PJ_TRUE; + } + \endcode + -# Open the audio stream, specifying the capture and/or playback callback + functions: + \code + pjmedia_aud_stream *stream; + + status = pjmedia_aud_stream_create(¶m, &rec_cb, &play_cb, + user_data, &stream); + \endcode + +@subsection working_with_stream Working with audio streams + + -# To start the audio stream: + \code + status = pjmedia_aud_stream_start(stream); + \endcode\n + To stop the stream: + \code + status = pjmedia_aud_stream_stop(stream); + \endcode\n + And to destroy the stream: + \code + status = pjmedia_aud_stream_destroy(stream); + \endcode\n + -# Info: The following shows how to retrieve the capability value of the + stream (in this case, the current output volume setting). + \code + // Volume setting is an unsigned integer showing the level in percent. + unsigned vol; + status = pjmedia_aud_stream_get_cap(stream, + PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING, + &vol); + \endcode + -# Info: And following shows how to modify the capability value of the + stream (in this case, the current output volume setting). + \code + // Volume setting is an unsigned integer showing the level in percent. + unsigned vol = 50; + status = pjmedia_aud_stream_set_cap(stream, + PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING, + &vol); + \endcode + + +*/ + + +/** + * @} + */ + diff --git a/pjmedia/include/pjmedia-audiodev/errno.h b/pjmedia/include/pjmedia-audiodev/errno.h new file mode 100644 index 00000000..12830354 --- /dev/null +++ b/pjmedia/include/pjmedia-audiodev/errno.h @@ -0,0 +1,198 @@ +/* $Id$ */ +/* + * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __PJMEDIA_AUDIODEV_AUDIODEV_ERRNO_H__ +#define __PJMEDIA_AUDIODEV_AUDIODEV_ERRNO_H__ + +/** + * @file errno.h Error Codes + * @brief Audiodev specific error codes. + */ + +#include <pjmedia-audiodev/config.h> +#include <pj/errno.h> + +/** + * @defgroup error_codes Error Codes + * @ingroup audio_device_api + * @brief Audio devive library specific error codes. + * @{ + */ + + +PJ_BEGIN_DECL + + +/** + * Start of error code relative to PJ_ERRNO_START_USER. + * This value is 420000. + */ +#define PJMEDIA_AUDIODEV_ERRNO_START \ + (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*5) +#define PJMEDIA_AUDIODEV_ERRNO_END \ + (PJMEDIA_AUDIODEV_ERRNO_START + PJ_ERRNO_SPACE_SIZE - 1) + + +/** + * Mapping from PortAudio error codes to pjmedia error space. + */ +#define PJMEDIA_AUDIODEV_PORTAUDIO_ERRNO_START \ + (PJMEDIA_AUDIODEV_ERRNO_END-10000) +#define PJMEDIA_AUDIODEV_PORTAUDIO_ERRNO_END \ + (PJMEDIA_AUDIODEV_PORTAUDIO_ERRNO_START + 10000 -1) +/** + * Convert PortAudio error code to PJLIB error code. + * PortAudio error code range: 0 >= err >= -10000 + */ +#define PJMEDIA_AUDIODEV_ERRNO_FROM_PORTAUDIO(err) \ + ((int)PJMEDIA_AUDIODEV_PORTAUDIO_ERRNO_START-err) + +/** + * Mapping from Windows multimedia WaveIn error codes. + */ +#define PJMEDIA_AUDIODEV_WMME_IN_ERROR_START \ + (PJMEDIA_AUDIODEV_ERRNO_START + 30000) +#define PJMEDIA_AUDIODEV_WMME_IN_ERROR_END \ + (PJMEDIA_AUDIODEV_WMME_IN_ERROR_START + 1000 - 1) +/** + * Convert WaveIn operation error codes to PJLIB error space. + */ +#define PJMEDIA_AUDIODEV_ERRNO_FROM_WMME_IN(err) \ + ((int)PJMEDIA_AUDIODEV_WMME_IN_ERROR_START+err) + + +/** + * Mapping from Windows multimedia WaveOut error codes. + */ +#define PJMEDIA_AUDIODEV_WMME_OUT_ERROR_START \ + (PJMEDIA_AUDIODEV_WMME_IN_ERROR_END + 1000) +#define PJMEDIA_AUDIODEV_WMME_OUT_ERROR_END \ + (PJMEDIA_AUDIODEV_WMME_OUT_ERROR_START + 1000) +/** + * Convert WaveOut operation error codes to PJLIB error space. + */ +#define PJMEDIA_AUDIODEV_ERRNO_FROM_WMME_OUT(err) \ + ((int)PJMEDIA_AUDIODEV_WMME_OUT_ERROR_START+err) + + +/************************************************************ + * Audio Device API error codes + ***********************************************************/ +/** + * @hideinitializer + * General/unknown error. + */ +#define PJMEDIA_EAUD_ERR (PJMEDIA_AUDIODEV_ERRNO_START+1) /* 420001 */ + +/** + * @hideinitializer + * Unknown error from audio driver + */ +#define PJMEDIA_EAUD_SYSERR (PJMEDIA_AUDIODEV_ERRNO_START+2) /* 420002 */ + +/** + * @hideinitializer + * Audio subsystem not initialized + */ +#define PJMEDIA_EAUD_INIT (PJMEDIA_AUDIODEV_ERRNO_START+3) /* 420003 */ + +/** + * @hideinitializer + * Invalid audio device + */ +#define PJMEDIA_EAUD_INVDEV (PJMEDIA_AUDIODEV_ERRNO_START+4) /* 420004 */ + +/** + * @hideinitializer + * Found no devices + */ +#define PJMEDIA_EAUD_NODEV (PJMEDIA_AUDIODEV_ERRNO_START+5) /* 420005 */ + +/** + * @hideinitializer + * Unable to find default device + */ +#define PJMEDIA_EAUD_NODEFDEV (PJMEDIA_AUDIODEV_ERRNO_START+6) /* 420006 */ + +/** + * @hideinitializer + * Device not ready + */ +#define PJMEDIA_EAUD_NOTREADY (PJMEDIA_AUDIODEV_ERRNO_START+7) /* 420007 */ + +/** + * @hideinitializer + * The audio capability is invalid or not supported + */ +#define PJMEDIA_EAUD_INVCAP (PJMEDIA_AUDIODEV_ERRNO_START+8) /* 420008 */ + +/** + * @hideinitializer + * The operation is invalid or not supported + */ +#define PJMEDIA_EAUD_INVOP (PJMEDIA_AUDIODEV_ERRNO_START+9) /* 420009 */ + +/** + * @hideinitializer + * Bad or invalid audio device format + */ +#define PJMEDIA_EAUD_BADFORMAT (PJMEDIA_AUDIODEV_ERRNO_START+10) /* 4200010 */ + +/** + * @hideinitializer + * Invalid audio device sample format + */ +#define PJMEDIA_EAUD_SAMPFORMAT (PJMEDIA_AUDIODEV_ERRNO_START+11) /* 4200011 */ + +/** + * @hideinitializer + * Bad latency setting + */ +#define PJMEDIA_EAUD_BADLATENCY (PJMEDIA_AUDIODEV_ERRNO_START+12) /* 4200012 */ + + + + + +/** + * Get error message for the specified error code. Note that this + * function is only able to decode PJMEDIA Audiodev specific error code. + * Application should use pj_strerror(), which should be able to + * decode all error codes belonging to all subsystems (e.g. pjlib, + * pjmedia, pjsip, etc). + * + * @param status The error code. + * @param buffer The buffer where to put the error message. + * @param bufsize Size of the buffer. + * + * @return The error message as NULL terminated string, + * wrapped with pj_str_t. + */ +PJ_DECL(pj_str_t) pjmedia_audiodev_strerror(pj_status_t status, char *buffer, + pj_size_t bufsize); + + +PJ_END_DECL + +/** + * @} + */ + + +#endif /* __PJMEDIA_AUDIODEV_AUDIODEV_ERRNO_H__ */ + |