185571bc7Sbellard /* 285571bc7Sbellard * QEMU Mixing engine 385571bc7Sbellard * 41d14ffa9Sbellard * Copyright (c) 2004-2005 Vassili Karpov (malc) 585571bc7Sbellard * Copyright (c) 1998 Fabrice Bellard 685571bc7Sbellard * 785571bc7Sbellard * Permission is hereby granted, free of charge, to any person obtaining a copy 885571bc7Sbellard * of this software and associated documentation files (the "Software"), to deal 985571bc7Sbellard * in the Software without restriction, including without limitation the rights 1085571bc7Sbellard * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 1185571bc7Sbellard * copies of the Software, and to permit persons to whom the Software is 1285571bc7Sbellard * furnished to do so, subject to the following conditions: 1385571bc7Sbellard * 1485571bc7Sbellard * The above copyright notice and this permission notice shall be included in 1585571bc7Sbellard * all copies or substantial portions of the Software. 1685571bc7Sbellard * 1785571bc7Sbellard * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1885571bc7Sbellard * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1985571bc7Sbellard * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 2085571bc7Sbellard * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 2185571bc7Sbellard * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 2285571bc7Sbellard * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 2385571bc7Sbellard * THE SOFTWARE. 2485571bc7Sbellard */ 2587ecb68bSpbrook #include "qemu-common.h" 2687ecb68bSpbrook #include "audio.h" 2785571bc7Sbellard 281d14ffa9Sbellard #define AUDIO_CAP "mixeng" 291d14ffa9Sbellard #include "audio_int.h" 301d14ffa9Sbellard 311d14ffa9Sbellard /* 8 bit */ 321d14ffa9Sbellard #define ENDIAN_CONVERSION natural 331d14ffa9Sbellard #define ENDIAN_CONVERT(v) (v) 341d14ffa9Sbellard 351d14ffa9Sbellard /* Signed 8 bit */ 36*a2885387SRoger Pau Monne #define BSIZE 8 37*a2885387SRoger Pau Monne #define ITYPE int 381d14ffa9Sbellard #define IN_MIN SCHAR_MIN 391d14ffa9Sbellard #define IN_MAX SCHAR_MAX 4085571bc7Sbellard #define SIGNED 411d14ffa9Sbellard #define SHIFT 8 4285571bc7Sbellard #include "mixeng_template.h" 4385571bc7Sbellard #undef SIGNED 4485571bc7Sbellard #undef IN_MAX 4585571bc7Sbellard #undef IN_MIN 46*a2885387SRoger Pau Monne #undef BSIZE 47*a2885387SRoger Pau Monne #undef ITYPE 481d14ffa9Sbellard #undef SHIFT 4985571bc7Sbellard 501d14ffa9Sbellard /* Unsigned 8 bit */ 51*a2885387SRoger Pau Monne #define BSIZE 8 52*a2885387SRoger Pau Monne #define ITYPE uint 5385571bc7Sbellard #define IN_MIN 0 5485571bc7Sbellard #define IN_MAX UCHAR_MAX 551d14ffa9Sbellard #define SHIFT 8 5685571bc7Sbellard #include "mixeng_template.h" 5785571bc7Sbellard #undef IN_MAX 5885571bc7Sbellard #undef IN_MIN 59*a2885387SRoger Pau Monne #undef BSIZE 60*a2885387SRoger Pau Monne #undef ITYPE 611d14ffa9Sbellard #undef SHIFT 6285571bc7Sbellard 631d14ffa9Sbellard #undef ENDIAN_CONVERT 641d14ffa9Sbellard #undef ENDIAN_CONVERSION 651d14ffa9Sbellard 661d14ffa9Sbellard /* Signed 16 bit */ 67*a2885387SRoger Pau Monne #define BSIZE 16 68*a2885387SRoger Pau Monne #define ITYPE int 6985571bc7Sbellard #define IN_MIN SHRT_MIN 7085571bc7Sbellard #define IN_MAX SHRT_MAX 7185571bc7Sbellard #define SIGNED 721d14ffa9Sbellard #define SHIFT 16 731d14ffa9Sbellard #define ENDIAN_CONVERSION natural 741d14ffa9Sbellard #define ENDIAN_CONVERT(v) (v) 7585571bc7Sbellard #include "mixeng_template.h" 761d14ffa9Sbellard #undef ENDIAN_CONVERT 771d14ffa9Sbellard #undef ENDIAN_CONVERSION 781d14ffa9Sbellard #define ENDIAN_CONVERSION swap 791d14ffa9Sbellard #define ENDIAN_CONVERT(v) bswap16 (v) 801d14ffa9Sbellard #include "mixeng_template.h" 811d14ffa9Sbellard #undef ENDIAN_CONVERT 821d14ffa9Sbellard #undef ENDIAN_CONVERSION 8385571bc7Sbellard #undef SIGNED 8485571bc7Sbellard #undef IN_MAX 8585571bc7Sbellard #undef IN_MIN 86*a2885387SRoger Pau Monne #undef BSIZE 87*a2885387SRoger Pau Monne #undef ITYPE 881d14ffa9Sbellard #undef SHIFT 8985571bc7Sbellard 90f941aa25Sths /* Unsigned 16 bit */ 91*a2885387SRoger Pau Monne #define BSIZE 16 92*a2885387SRoger Pau Monne #define ITYPE uint 9385571bc7Sbellard #define IN_MIN 0 9485571bc7Sbellard #define IN_MAX USHRT_MAX 951d14ffa9Sbellard #define SHIFT 16 961d14ffa9Sbellard #define ENDIAN_CONVERSION natural 971d14ffa9Sbellard #define ENDIAN_CONVERT(v) (v) 9885571bc7Sbellard #include "mixeng_template.h" 991d14ffa9Sbellard #undef ENDIAN_CONVERT 1001d14ffa9Sbellard #undef ENDIAN_CONVERSION 1011d14ffa9Sbellard #define ENDIAN_CONVERSION swap 1021d14ffa9Sbellard #define ENDIAN_CONVERT(v) bswap16 (v) 1031d14ffa9Sbellard #include "mixeng_template.h" 1041d14ffa9Sbellard #undef ENDIAN_CONVERT 1051d14ffa9Sbellard #undef ENDIAN_CONVERSION 10685571bc7Sbellard #undef IN_MAX 10785571bc7Sbellard #undef IN_MIN 108*a2885387SRoger Pau Monne #undef BSIZE 109*a2885387SRoger Pau Monne #undef ITYPE 1101d14ffa9Sbellard #undef SHIFT 11185571bc7Sbellard 112f941aa25Sths /* Signed 32 bit */ 113*a2885387SRoger Pau Monne #define BSIZE 32 114*a2885387SRoger Pau Monne #define ITYPE int 115f941aa25Sths #define IN_MIN INT32_MIN 116f941aa25Sths #define IN_MAX INT32_MAX 117f941aa25Sths #define SIGNED 118f941aa25Sths #define SHIFT 32 119f941aa25Sths #define ENDIAN_CONVERSION natural 120f941aa25Sths #define ENDIAN_CONVERT(v) (v) 121f941aa25Sths #include "mixeng_template.h" 122f941aa25Sths #undef ENDIAN_CONVERT 123f941aa25Sths #undef ENDIAN_CONVERSION 124f941aa25Sths #define ENDIAN_CONVERSION swap 125f941aa25Sths #define ENDIAN_CONVERT(v) bswap32 (v) 126f941aa25Sths #include "mixeng_template.h" 127f941aa25Sths #undef ENDIAN_CONVERT 128f941aa25Sths #undef ENDIAN_CONVERSION 129f941aa25Sths #undef SIGNED 130f941aa25Sths #undef IN_MAX 131f941aa25Sths #undef IN_MIN 132*a2885387SRoger Pau Monne #undef BSIZE 133*a2885387SRoger Pau Monne #undef ITYPE 134f941aa25Sths #undef SHIFT 135f941aa25Sths 136ad483a51Smalc /* Unsigned 32 bit */ 137*a2885387SRoger Pau Monne #define BSIZE 32 138*a2885387SRoger Pau Monne #define ITYPE uint 139f941aa25Sths #define IN_MIN 0 140f941aa25Sths #define IN_MAX UINT32_MAX 141f941aa25Sths #define SHIFT 32 142f941aa25Sths #define ENDIAN_CONVERSION natural 143f941aa25Sths #define ENDIAN_CONVERT(v) (v) 144f941aa25Sths #include "mixeng_template.h" 145f941aa25Sths #undef ENDIAN_CONVERT 146f941aa25Sths #undef ENDIAN_CONVERSION 147f941aa25Sths #define ENDIAN_CONVERSION swap 148f941aa25Sths #define ENDIAN_CONVERT(v) bswap32 (v) 149f941aa25Sths #include "mixeng_template.h" 150f941aa25Sths #undef ENDIAN_CONVERT 151f941aa25Sths #undef ENDIAN_CONVERSION 152f941aa25Sths #undef IN_MAX 153f941aa25Sths #undef IN_MIN 154*a2885387SRoger Pau Monne #undef BSIZE 155*a2885387SRoger Pau Monne #undef ITYPE 156f941aa25Sths #undef SHIFT 157f941aa25Sths 158f941aa25Sths t_sample *mixeng_conv[2][2][2][3] = { 15985571bc7Sbellard { 16085571bc7Sbellard { 1611d14ffa9Sbellard { 1621d14ffa9Sbellard conv_natural_uint8_t_to_mono, 163f941aa25Sths conv_natural_uint16_t_to_mono, 164f941aa25Sths conv_natural_uint32_t_to_mono 16585571bc7Sbellard }, 16685571bc7Sbellard { 1671d14ffa9Sbellard conv_natural_uint8_t_to_mono, 168f941aa25Sths conv_swap_uint16_t_to_mono, 169f941aa25Sths conv_swap_uint32_t_to_mono, 17085571bc7Sbellard } 17185571bc7Sbellard }, 17285571bc7Sbellard { 17385571bc7Sbellard { 1741d14ffa9Sbellard conv_natural_int8_t_to_mono, 175f941aa25Sths conv_natural_int16_t_to_mono, 176f941aa25Sths conv_natural_int32_t_to_mono 17785571bc7Sbellard }, 17885571bc7Sbellard { 1791d14ffa9Sbellard conv_natural_int8_t_to_mono, 180f941aa25Sths conv_swap_int16_t_to_mono, 181f941aa25Sths conv_swap_int32_t_to_mono 1821d14ffa9Sbellard } 1831d14ffa9Sbellard } 1841d14ffa9Sbellard }, 1851d14ffa9Sbellard { 1861d14ffa9Sbellard { 1871d14ffa9Sbellard { 1881d14ffa9Sbellard conv_natural_uint8_t_to_stereo, 189f941aa25Sths conv_natural_uint16_t_to_stereo, 190f941aa25Sths conv_natural_uint32_t_to_stereo 1911d14ffa9Sbellard }, 1921d14ffa9Sbellard { 1931d14ffa9Sbellard conv_natural_uint8_t_to_stereo, 194f941aa25Sths conv_swap_uint16_t_to_stereo, 195f941aa25Sths conv_swap_uint32_t_to_stereo 1961d14ffa9Sbellard } 1971d14ffa9Sbellard }, 1981d14ffa9Sbellard { 1991d14ffa9Sbellard { 2001d14ffa9Sbellard conv_natural_int8_t_to_stereo, 201f941aa25Sths conv_natural_int16_t_to_stereo, 202f941aa25Sths conv_natural_int32_t_to_stereo 2031d14ffa9Sbellard }, 2041d14ffa9Sbellard { 2051d14ffa9Sbellard conv_natural_int8_t_to_stereo, 206f941aa25Sths conv_swap_int16_t_to_stereo, 207f941aa25Sths conv_swap_int32_t_to_stereo, 2081d14ffa9Sbellard } 20985571bc7Sbellard } 21085571bc7Sbellard } 21185571bc7Sbellard }; 21285571bc7Sbellard 213f941aa25Sths f_sample *mixeng_clip[2][2][2][3] = { 21485571bc7Sbellard { 21585571bc7Sbellard { 2161d14ffa9Sbellard { 2171d14ffa9Sbellard clip_natural_uint8_t_from_mono, 218f941aa25Sths clip_natural_uint16_t_from_mono, 219f941aa25Sths clip_natural_uint32_t_from_mono 22085571bc7Sbellard }, 22185571bc7Sbellard { 2221d14ffa9Sbellard clip_natural_uint8_t_from_mono, 223f941aa25Sths clip_swap_uint16_t_from_mono, 224f941aa25Sths clip_swap_uint32_t_from_mono 22585571bc7Sbellard } 22685571bc7Sbellard }, 22785571bc7Sbellard { 22885571bc7Sbellard { 2291d14ffa9Sbellard clip_natural_int8_t_from_mono, 230f941aa25Sths clip_natural_int16_t_from_mono, 231f941aa25Sths clip_natural_int32_t_from_mono 23285571bc7Sbellard }, 23385571bc7Sbellard { 2341d14ffa9Sbellard clip_natural_int8_t_from_mono, 235f941aa25Sths clip_swap_int16_t_from_mono, 236f941aa25Sths clip_swap_int32_t_from_mono 2371d14ffa9Sbellard } 2381d14ffa9Sbellard } 2391d14ffa9Sbellard }, 2401d14ffa9Sbellard { 2411d14ffa9Sbellard { 2421d14ffa9Sbellard { 2431d14ffa9Sbellard clip_natural_uint8_t_from_stereo, 244f941aa25Sths clip_natural_uint16_t_from_stereo, 245f941aa25Sths clip_natural_uint32_t_from_stereo 2461d14ffa9Sbellard }, 2471d14ffa9Sbellard { 2481d14ffa9Sbellard clip_natural_uint8_t_from_stereo, 249f941aa25Sths clip_swap_uint16_t_from_stereo, 250f941aa25Sths clip_swap_uint32_t_from_stereo 2511d14ffa9Sbellard } 2521d14ffa9Sbellard }, 2531d14ffa9Sbellard { 2541d14ffa9Sbellard { 2551d14ffa9Sbellard clip_natural_int8_t_from_stereo, 256f941aa25Sths clip_natural_int16_t_from_stereo, 257f941aa25Sths clip_natural_int32_t_from_stereo 2581d14ffa9Sbellard }, 2591d14ffa9Sbellard { 2601d14ffa9Sbellard clip_natural_int8_t_from_stereo, 261f941aa25Sths clip_swap_int16_t_from_stereo, 262f941aa25Sths clip_swap_int32_t_from_stereo 2631d14ffa9Sbellard } 26485571bc7Sbellard } 26585571bc7Sbellard } 26685571bc7Sbellard }; 26785571bc7Sbellard 26885571bc7Sbellard /* 26985571bc7Sbellard * August 21, 1998 27085571bc7Sbellard * Copyright 1998 Fabrice Bellard. 27185571bc7Sbellard * 27285571bc7Sbellard * [Rewrote completly the code of Lance Norskog And Sundry 27385571bc7Sbellard * Contributors with a more efficient algorithm.] 27485571bc7Sbellard * 27585571bc7Sbellard * This source code is freely redistributable and may be used for 27685571bc7Sbellard * any purpose. This copyright notice must be maintained. 27785571bc7Sbellard * Lance Norskog And Sundry Contributors are not responsible for 27885571bc7Sbellard * the consequences of using this software. 27985571bc7Sbellard */ 28085571bc7Sbellard 28185571bc7Sbellard /* 28285571bc7Sbellard * Sound Tools rate change effect file. 28385571bc7Sbellard */ 28485571bc7Sbellard /* 28585571bc7Sbellard * Linear Interpolation. 28685571bc7Sbellard * 28785571bc7Sbellard * The use of fractional increment allows us to use no buffer. It 28885571bc7Sbellard * avoid the problems at the end of the buffer we had with the old 28985571bc7Sbellard * method which stored a possibly big buffer of size 29085571bc7Sbellard * lcm(in_rate,out_rate). 29185571bc7Sbellard * 29285571bc7Sbellard * Limited to 16 bit samples and sampling frequency <= 65535 Hz. If 29385571bc7Sbellard * the input & output frequencies are equal, a delay of one sample is 29485571bc7Sbellard * introduced. Limited to processing 32-bit count worth of samples. 29585571bc7Sbellard * 29685571bc7Sbellard * 1 << FRAC_BITS evaluating to zero in several places. Changed with 29785571bc7Sbellard * an (unsigned long) cast to make it safe. MarkMLl 2/1/99 29885571bc7Sbellard */ 29985571bc7Sbellard 30085571bc7Sbellard /* Private data */ 301c0fe3827Sbellard struct rate { 30285571bc7Sbellard uint64_t opos; 30385571bc7Sbellard uint64_t opos_inc; 30485571bc7Sbellard uint32_t ipos; /* position in the input stream (integer) */ 3051ea879e5Smalc struct st_sample ilast; /* last sample in the input stream */ 306c0fe3827Sbellard }; 30785571bc7Sbellard 30885571bc7Sbellard /* 30985571bc7Sbellard * Prepare processing. 31085571bc7Sbellard */ 31185571bc7Sbellard void *st_rate_start (int inrate, int outrate) 31285571bc7Sbellard { 313c0fe3827Sbellard struct rate *rate = audio_calloc (AUDIO_FUNC, 1, sizeof (*rate)); 31485571bc7Sbellard 31585571bc7Sbellard if (!rate) { 316e7cad338Sbellard dolog ("Could not allocate resampler (%zu bytes)\n", sizeof (*rate)); 3171d14ffa9Sbellard return NULL; 31885571bc7Sbellard } 31985571bc7Sbellard 32085571bc7Sbellard rate->opos = 0; 32185571bc7Sbellard 32285571bc7Sbellard /* increment */ 3231d14ffa9Sbellard rate->opos_inc = ((uint64_t) inrate << 32) / outrate; 32485571bc7Sbellard 32585571bc7Sbellard rate->ipos = 0; 32685571bc7Sbellard rate->ilast.l = 0; 32785571bc7Sbellard rate->ilast.r = 0; 32885571bc7Sbellard return rate; 32985571bc7Sbellard } 33085571bc7Sbellard 3311d14ffa9Sbellard #define NAME st_rate_flow_mix 3321d14ffa9Sbellard #define OP(a, b) a += b 3331d14ffa9Sbellard #include "rate_template.h" 33485571bc7Sbellard 3351d14ffa9Sbellard #define NAME st_rate_flow 3361d14ffa9Sbellard #define OP(a, b) a = b 3371d14ffa9Sbellard #include "rate_template.h" 33885571bc7Sbellard 33985571bc7Sbellard void st_rate_stop (void *opaque) 34085571bc7Sbellard { 3417267c094SAnthony Liguori g_free (opaque); 34285571bc7Sbellard } 3431d14ffa9Sbellard 3441ea879e5Smalc void mixeng_clear (struct st_sample *buf, int len) 3451d14ffa9Sbellard { 3461ea879e5Smalc memset (buf, 0, len * sizeof (struct st_sample)); 3471d14ffa9Sbellard } 34800e07679SMichael Walle 34900e07679SMichael Walle void mixeng_volume (struct st_sample *buf, int len, struct mixeng_volume *vol) 35000e07679SMichael Walle { 35100e07679SMichael Walle #ifdef CONFIG_MIXEMU 35200e07679SMichael Walle if (vol->mute) { 35300e07679SMichael Walle mixeng_clear (buf, len); 35400e07679SMichael Walle return; 35500e07679SMichael Walle } 35600e07679SMichael Walle 35700e07679SMichael Walle while (len--) { 35800e07679SMichael Walle #ifdef FLOAT_MIXENG 35900e07679SMichael Walle buf->l = buf->l * vol->l; 36000e07679SMichael Walle buf->r = buf->r * vol->r; 36100e07679SMichael Walle #else 36200e07679SMichael Walle buf->l = (buf->l * vol->l) >> 32; 36300e07679SMichael Walle buf->r = (buf->r * vol->r) >> 32; 36400e07679SMichael Walle #endif 36500e07679SMichael Walle buf += 1; 36600e07679SMichael Walle } 36700e07679SMichael Walle #else 36800e07679SMichael Walle (void) buf; 36900e07679SMichael Walle (void) len; 37000e07679SMichael Walle (void) vol; 37100e07679SMichael Walle #endif 37200e07679SMichael Walle } 373