/* $Id$ */ /* * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) * Copyright (C) 2003-2008 Benny Prijono * * 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_STEREO_H__ #define __PJMEDIA_STEREO_H__ /** * @file stereo.h * @brief Monochannel and multichannel converter. */ #include #include #include #include /** * @defgroup PJMEDIA_STEREO Monochannel and multichannel audio frame converter * @ingroup PJMEDIA_FRAME_OP * @brief Mono - multi-channels audio conversion * @{ * */ PJ_BEGIN_DECL /** * Multichannel to monochannel conversion mixes samples from all channels * into the monochannel. */ #define PJMEDIA_STEREO_MIX PJ_TRUE /** * Multichannel to monochannel conversion, it has two operation mode specified * by param options, @see pjmedia_stereo_options. This function can work safely * using the same buffer (in place conversion). * * @param mono Output buffer to store the mono frame extracted * from the multichannels frame. * @param multi Input frame containing multichannels audio. * @param channel_count Number of channels in the input frame. * @param samples_per_frame Number of samples in the input frame. * @param mix If the value is PJ_TRUE then the input channels * will be mixed to produce output frame, otherwise * only frame from channel_src will be copied to the * output frame. * @param channel_src When mixing is disabled, the mono output frame * will be copied from this channel number. * * @return PJ_SUCCESS on success; */ PJ_INLINE(pj_status_t) pjmedia_convert_channel_nto1(pj_int16_t mono[], const pj_int16_t multi[], unsigned channel_count, unsigned samples_per_frame, pj_bool_t mix, unsigned channel_src) { unsigned i; PJ_ASSERT_RETURN(mono && multi && channel_count && samples_per_frame && channel_src < channel_count, PJ_EINVAL); if (mix==PJ_FALSE) { for (i = channel_src; i < samples_per_frame; i += channel_count) { *mono = multi[i]; ++mono; } } else { unsigned j; for (i = 0; i < samples_per_frame; i += channel_count) { int tmp = 0; for(j = 0; j < channel_count; ++j) tmp += multi[i+j]; if (tmp > 32767) tmp = 32767; else if (tmp < -32768) tmp = -32768; *mono = (pj_int16_t) tmp; ++mono; } } return PJ_SUCCESS; } /** * Monochannel to multichannel conversion, it will just duplicate the samples * from monochannel frame to all channels in the multichannel frame. * This function can work safely using the same buffer (in place conversion) * as long as the buffer is big enough for the multichannel samples. * * @param multi Output buffer to store the multichannels frame * mixed from the mono frame. * @param mono The input monochannel audio frame. * @param channel_count Desired number of channels in the output frame. * @param samples_per_frame Number of samples in the input frame. * @param options Options for conversion, currently must be zero. * * @return PJ_SUCCESS on success; */ PJ_INLINE(pj_status_t) pjmedia_convert_channel_1ton(pj_int16_t multi[], const pj_int16_t mono[], unsigned channel_count, unsigned samples_per_frame, unsigned options) { const pj_int16_t *src; PJ_ASSERT_RETURN(mono && multi && channel_count && samples_per_frame, PJ_EINVAL); PJ_ASSERT_RETURN(options == 0, PJ_EINVAL); PJ_UNUSED_ARG(options); src = mono + samples_per_frame - 1; samples_per_frame *= channel_count; while (samples_per_frame) { unsigned i; for (i=1; i<=channel_count; ++i) multi[samples_per_frame-i] = *src; samples_per_frame -= channel_count; --src; } return PJ_SUCCESS; } /** * Options for channel converter port. The #pjmedia_stereo_options is also * valid for this port options. */ typedef enum pjmedia_stereo_port_options { /** * Specifies whether this port should not destroy downstream port when * this port is destroyed. */ PJMEDIA_STEREO_DONT_DESTROY_DN = 4 } pjmedia_stereo_port_options; /** * Create a mono-multi channel converter port. This creates a converter session, * which will adjust the samples of audio frame to a different channel count * when the port's get_frame() and put_frame() is called. * * When the port's get_frame() is called, this port will get a frame from * the downstream port and convert the frame to the target channel count before * returning it to the caller. * * When the port's put_frame() is called, this port will convert the frame * to the downstream port's channel count before giving the frame to the * downstream port. * * @param pool Pool to allocate the structure and buffers. * @param dn_port The downstream port, which channel count is to * be converted to the target channel count. * @param channel_count This port channel count. * @param options Bitmask flags from #pjmedia_stereo_port_options * and also application may add PJMEDIA_STEREO_MIX * to mix channels. * When this flag is zero, the default behavior * is to use simple N-to-1 channel converter and * to destroy downstream port when this port is * destroyed. * @param p_port Pointer to receive the stereo port instance. * * @return PJ_SUCCESS on success. */ PJ_DECL(pj_status_t) pjmedia_stereo_port_create( pj_pool_t *pool, pjmedia_port *dn_port, unsigned channel_count, unsigned options, pjmedia_port **p_port ); PJ_END_DECL /** * @} */ #endif /* __PJMEDIA_STEREO_H__ */