stereo.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  3. * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. */
  19. #ifndef __PJMEDIA_STEREO_H__
  20. #define __PJMEDIA_STEREO_H__
  21. /**
  22. * @file stereo.h
  23. * @brief Monochannel and multichannel converter.
  24. */
  25. #include <pjmedia/errno.h>
  26. #include <pjmedia/port.h>
  27. #include <pjmedia/types.h>
  28. #include <pj/assert.h>
  29. /**
  30. * @defgroup PJMEDIA_STEREO Monochannel and multichannel audio frame converter
  31. * @ingroup PJMEDIA_FRAME_OP
  32. * @brief Mono - multi-channels audio conversion
  33. * @{
  34. *
  35. */
  36. PJ_BEGIN_DECL
  37. /**
  38. * Multichannel to monochannel conversion mixes samples from all channels
  39. * into the monochannel.
  40. */
  41. #define PJMEDIA_STEREO_MIX PJ_TRUE
  42. /**
  43. * Multichannel to monochannel conversion. This function can work safely
  44. * using the same buffer (in place conversion).
  45. *
  46. * @param mono Output buffer to store the mono frame extracted
  47. * from the multichannels frame.
  48. * @param multi Input frame containing multichannels audio.
  49. * @param channel_count Number of channels in the input frame.
  50. * @param samples_per_frame Number of samples in the input frame.
  51. * @param mix If the value is PJ_TRUE then the input channels
  52. * will be mixed to produce output frame, otherwise
  53. * only frame from channel_src will be copied to the
  54. * output frame.
  55. * @param channel_src When mixing is disabled, the mono output frame
  56. * will be copied from this channel number.
  57. *
  58. * @return PJ_SUCCESS on success;
  59. */
  60. PJ_INLINE(pj_status_t) pjmedia_convert_channel_nto1(pj_int16_t mono[],
  61. const pj_int16_t multi[],
  62. unsigned channel_count,
  63. unsigned samples_per_frame,
  64. pj_bool_t mix,
  65. unsigned channel_src)
  66. {
  67. unsigned i;
  68. PJ_ASSERT_RETURN(mono && multi && channel_count && samples_per_frame &&
  69. channel_src < channel_count, PJ_EINVAL);
  70. if (mix==PJ_FALSE) {
  71. for (i = channel_src; i < samples_per_frame; i += channel_count) {
  72. *mono = multi[i];
  73. ++mono;
  74. }
  75. } else {
  76. unsigned j;
  77. for (i = 0; i < samples_per_frame; i += channel_count) {
  78. int tmp = 0;
  79. for(j = 0; j < channel_count; ++j)
  80. tmp += multi[i+j];
  81. if (tmp > 32767) tmp = 32767;
  82. else if (tmp < -32768) tmp = -32768;
  83. *mono = (pj_int16_t) tmp;
  84. ++mono;
  85. }
  86. }
  87. return PJ_SUCCESS;
  88. }
  89. /**
  90. * Monochannel to multichannel conversion, it will just duplicate the samples
  91. * from monochannel frame to all channels in the multichannel frame.
  92. * This function can work safely using the same buffer (in place conversion)
  93. * as long as the buffer is big enough for the multichannel samples.
  94. *
  95. * @param multi Output buffer to store the multichannels frame
  96. * mixed from the mono frame.
  97. * @param mono The input monochannel audio frame.
  98. * @param channel_count Desired number of channels in the output frame.
  99. * @param samples_per_frame Number of samples in the input frame.
  100. * @param options Options for conversion, currently must be zero.
  101. *
  102. * @return PJ_SUCCESS on success;
  103. */
  104. PJ_INLINE(pj_status_t) pjmedia_convert_channel_1ton(pj_int16_t multi[],
  105. const pj_int16_t mono[],
  106. unsigned channel_count,
  107. unsigned samples_per_frame,
  108. unsigned options)
  109. {
  110. const pj_int16_t *src;
  111. PJ_ASSERT_RETURN(mono && multi && channel_count && samples_per_frame,
  112. PJ_EINVAL);
  113. PJ_ASSERT_RETURN(options == 0, PJ_EINVAL);
  114. PJ_UNUSED_ARG(options);
  115. src = mono + samples_per_frame - 1;
  116. samples_per_frame *= channel_count;
  117. while (samples_per_frame) {
  118. unsigned i;
  119. for (i=1; i<=channel_count; ++i)
  120. multi[samples_per_frame-i] = *src;
  121. samples_per_frame -= channel_count;
  122. --src;
  123. }
  124. return PJ_SUCCESS;
  125. }
  126. /**
  127. * Options for channel converter port.
  128. */
  129. typedef enum pjmedia_stereo_port_options
  130. {
  131. /**
  132. * Specifies whether this port should not destroy downstream port when
  133. * this port is destroyed.
  134. */
  135. PJMEDIA_STEREO_DONT_DESTROY_DN = 4
  136. } pjmedia_stereo_port_options;
  137. /**
  138. * Create a mono-multi channel converter port. This creates a converter session,
  139. * which will adjust the samples of audio frame to a different channel count
  140. * when the port's get_frame() and put_frame() is called.
  141. *
  142. * When the port's get_frame() is called, this port will get a frame from
  143. * the downstream port and convert the frame to the target channel count before
  144. * returning it to the caller.
  145. *
  146. * When the port's put_frame() is called, this port will convert the frame
  147. * to the downstream port's channel count before giving the frame to the
  148. * downstream port.
  149. *
  150. * @param pool Pool to allocate the structure and buffers.
  151. * @param dn_port The downstream port, which channel count is to
  152. * be converted to the target channel count.
  153. * @param channel_count This port channel count.
  154. * @param options Bitmask flags from #pjmedia_stereo_port_options
  155. * and also application may add PJMEDIA_STEREO_MIX
  156. * to mix channels.
  157. * When this flag is zero, the default behavior
  158. * is to use simple N-to-1 channel converter and
  159. * to destroy downstream port when this port is
  160. * destroyed.
  161. * @param p_port Pointer to receive the stereo port instance.
  162. *
  163. * @return PJ_SUCCESS on success.
  164. */
  165. PJ_DECL(pj_status_t) pjmedia_stereo_port_create( pj_pool_t *pool,
  166. pjmedia_port *dn_port,
  167. unsigned channel_count,
  168. unsigned options,
  169. pjmedia_port **p_port );
  170. PJ_END_DECL
  171. /**
  172. * @}
  173. */
  174. #endif /* __PJMEDIA_STEREO_H__ */