153a5a1b3Sopenharmony_ci#  This file is part of PulseAudio.
253a5a1b3Sopenharmony_ci#
353a5a1b3Sopenharmony_ci#  Copyright 2010 Lennart Poettering
453a5a1b3Sopenharmony_ci#  Copyright 2010 Wim Taymans <wim.taymans@collabora.co.uk>
553a5a1b3Sopenharmony_ci#  Copyright 2010 Arun Raghavan <arun.raghavan@collabora.co.uk>
653a5a1b3Sopenharmony_ci#
753a5a1b3Sopenharmony_ci#  PulseAudio is free software; you can redistribute it and/or modify
853a5a1b3Sopenharmony_ci#  it under the terms of the GNU Lesser General Public License as published
953a5a1b3Sopenharmony_ci#  by the Free Software Foundation; either version 2.1 of the License,
1053a5a1b3Sopenharmony_ci#  or (at your option) any later version.
1153a5a1b3Sopenharmony_ci#
1253a5a1b3Sopenharmony_ci#  PulseAudio is distributed in the hope that it will be useful, but
1353a5a1b3Sopenharmony_ci#  WITHOUT ANY WARRANTY; without even the implied warranty of
1453a5a1b3Sopenharmony_ci#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1553a5a1b3Sopenharmony_ci#  General Public License for more details.
1653a5a1b3Sopenharmony_ci#
1753a5a1b3Sopenharmony_ci#  You should have received a copy of the GNU Lesser General Public License
1853a5a1b3Sopenharmony_ci#  along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
1953a5a1b3Sopenharmony_ci
2053a5a1b3Sopenharmony_ci# S16NE 1- and 2-channel volume scaling work as follows:
2153a5a1b3Sopenharmony_ci#
2253a5a1b3Sopenharmony_ci#     params: samples s (signed 16-bit), volume v (signed 32-bit < 2^31)
2353a5a1b3Sopenharmony_ci#
2453a5a1b3Sopenharmony_ci#                  32           16                 0 (type of operation)
2553a5a1b3Sopenharmony_ci#         sample =               |      sample     | (signed)
2653a5a1b3Sopenharmony_ci#              s = |      0      |      sample     | (unsigned)
2753a5a1b3Sopenharmony_ci#
2853a5a1b3Sopenharmony_ci#     if (sample < 0)
2953a5a1b3Sopenharmony_ci#          signc = |      0      |      0xffff     | (unsigned)
3053a5a1b3Sopenharmony_ci#     else
3153a5a1b3Sopenharmony_ci#          signc = |      0      |        0        | (unsigned)
3253a5a1b3Sopenharmony_ci#
3353a5a1b3Sopenharmony_ci#     if (sample < 0)
3453a5a1b3Sopenharmony_ci#             ml = |      0      | -((s*vl) >> 16) | (unsigned)
3553a5a1b3Sopenharmony_ci#     else
3653a5a1b3Sopenharmony_ci#             ml = |      0      |   (s*vl) >> 16  | (unsigned)
3753a5a1b3Sopenharmony_ci#
3853a5a1b3Sopenharmony_ci#             vh =               |      v >> 16    | (signed, but sign bit is always zero
3953a5a1b3Sopenharmony_ci#                                                     since PA_VOLUME_MAX is 0x0fffffff)
4053a5a1b3Sopenharmony_ci#             mh = |         (s * vh) >> 16        | (signed)
4153a5a1b3Sopenharmony_ci#             ml = |           ml + mh             | (signed)
4253a5a1b3Sopenharmony_ci#         sample =               |    (ml >> 16)   | (signed, saturated)
4353a5a1b3Sopenharmony_ci
4453a5a1b3Sopenharmony_ci.function pa_volume_s16ne_orc_1ch
4553a5a1b3Sopenharmony_ci.dest 2 samples int16_t
4653a5a1b3Sopenharmony_ci.param 4 vols int32_t
4753a5a1b3Sopenharmony_ci.temp 4 v
4853a5a1b3Sopenharmony_ci.temp 2 vh
4953a5a1b3Sopenharmony_ci.temp 4 s
5053a5a1b3Sopenharmony_ci.temp 4 mh
5153a5a1b3Sopenharmony_ci.temp 4 ml
5253a5a1b3Sopenharmony_ci.temp 4 signc
5353a5a1b3Sopenharmony_ci
5453a5a1b3Sopenharmony_ciloadpl v, vols
5553a5a1b3Sopenharmony_ciconvuwl s, samples
5653a5a1b3Sopenharmony_cix2 cmpgtsw signc, 0, s
5753a5a1b3Sopenharmony_cix2 andw signc, signc, v
5853a5a1b3Sopenharmony_cix2 mulhuw ml, s, v
5953a5a1b3Sopenharmony_cisubl ml, ml, signc
6053a5a1b3Sopenharmony_ciconvhlw vh, v
6153a5a1b3Sopenharmony_cimulswl mh, samples, vh
6253a5a1b3Sopenharmony_ciaddl ml, ml, mh
6353a5a1b3Sopenharmony_ciconvssslw samples, ml
6453a5a1b3Sopenharmony_ci
6553a5a1b3Sopenharmony_ci.function pa_volume_s16ne_orc_2ch
6653a5a1b3Sopenharmony_ci.dest 4 samples int16_t
6753a5a1b3Sopenharmony_ci.longparam 8 vols
6853a5a1b3Sopenharmony_ci.temp 8 v
6953a5a1b3Sopenharmony_ci.temp 4 vh
7053a5a1b3Sopenharmony_ci.temp 8 s
7153a5a1b3Sopenharmony_ci.temp 8 mh
7253a5a1b3Sopenharmony_ci.temp 8 ml
7353a5a1b3Sopenharmony_ci.temp 8 signc
7453a5a1b3Sopenharmony_ci
7553a5a1b3Sopenharmony_ciloadpq v, vols
7653a5a1b3Sopenharmony_cix2 convuwl s, samples
7753a5a1b3Sopenharmony_cix4 cmpgtsw signc, 0, s
7853a5a1b3Sopenharmony_cix4 andw signc, signc, v
7953a5a1b3Sopenharmony_cix4 mulhuw ml, s, v
8053a5a1b3Sopenharmony_cix2 subl ml, ml, signc
8153a5a1b3Sopenharmony_cix2 convhlw vh, v
8253a5a1b3Sopenharmony_cix2 mulswl mh, samples, vh
8353a5a1b3Sopenharmony_cix2 addl ml, ml, mh
8453a5a1b3Sopenharmony_cix2 convssslw samples, ml
85