cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

mixeng.c (11894B)


      1/*
      2 * QEMU Mixing engine
      3 *
      4 * Copyright (c) 2004-2005 Vassili Karpov (malc)
      5 * Copyright (c) 1998 Fabrice Bellard
      6 *
      7 * Permission is hereby granted, free of charge, to any person obtaining a copy
      8 * of this software and associated documentation files (the "Software"), to deal
      9 * in the Software without restriction, including without limitation the rights
     10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     11 * copies of the Software, and to permit persons to whom the Software is
     12 * furnished to do so, subject to the following conditions:
     13 *
     14 * The above copyright notice and this permission notice shall be included in
     15 * all copies or substantial portions of the Software.
     16 *
     17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     23 * THE SOFTWARE.
     24 */
     25#include "qemu/osdep.h"
     26#include "qemu/bswap.h"
     27#include "qemu/error-report.h"
     28#include "audio.h"
     29
     30#define AUDIO_CAP "mixeng"
     31#include "audio_int.h"
     32
     33/* 8 bit */
     34#define ENDIAN_CONVERSION natural
     35#define ENDIAN_CONVERT(v) (v)
     36
     37/* Signed 8 bit */
     38#define BSIZE 8
     39#define ITYPE int
     40#define IN_MIN SCHAR_MIN
     41#define IN_MAX SCHAR_MAX
     42#define SIGNED
     43#define SHIFT 8
     44#include "mixeng_template.h"
     45#undef SIGNED
     46#undef IN_MAX
     47#undef IN_MIN
     48#undef BSIZE
     49#undef ITYPE
     50#undef SHIFT
     51
     52/* Unsigned 8 bit */
     53#define BSIZE 8
     54#define ITYPE uint
     55#define IN_MIN 0
     56#define IN_MAX UCHAR_MAX
     57#define SHIFT 8
     58#include "mixeng_template.h"
     59#undef IN_MAX
     60#undef IN_MIN
     61#undef BSIZE
     62#undef ITYPE
     63#undef SHIFT
     64
     65#undef ENDIAN_CONVERT
     66#undef ENDIAN_CONVERSION
     67
     68/* Signed 16 bit */
     69#define BSIZE 16
     70#define ITYPE int
     71#define IN_MIN SHRT_MIN
     72#define IN_MAX SHRT_MAX
     73#define SIGNED
     74#define SHIFT 16
     75#define ENDIAN_CONVERSION natural
     76#define ENDIAN_CONVERT(v) (v)
     77#include "mixeng_template.h"
     78#undef ENDIAN_CONVERT
     79#undef ENDIAN_CONVERSION
     80#define ENDIAN_CONVERSION swap
     81#define ENDIAN_CONVERT(v) bswap16 (v)
     82#include "mixeng_template.h"
     83#undef ENDIAN_CONVERT
     84#undef ENDIAN_CONVERSION
     85#undef SIGNED
     86#undef IN_MAX
     87#undef IN_MIN
     88#undef BSIZE
     89#undef ITYPE
     90#undef SHIFT
     91
     92/* Unsigned 16 bit */
     93#define BSIZE 16
     94#define ITYPE uint
     95#define IN_MIN 0
     96#define IN_MAX USHRT_MAX
     97#define SHIFT 16
     98#define ENDIAN_CONVERSION natural
     99#define ENDIAN_CONVERT(v) (v)
    100#include "mixeng_template.h"
    101#undef ENDIAN_CONVERT
    102#undef ENDIAN_CONVERSION
    103#define ENDIAN_CONVERSION swap
    104#define ENDIAN_CONVERT(v) bswap16 (v)
    105#include "mixeng_template.h"
    106#undef ENDIAN_CONVERT
    107#undef ENDIAN_CONVERSION
    108#undef IN_MAX
    109#undef IN_MIN
    110#undef BSIZE
    111#undef ITYPE
    112#undef SHIFT
    113
    114/* Signed 32 bit */
    115#define BSIZE 32
    116#define ITYPE int
    117#define IN_MIN INT32_MIN
    118#define IN_MAX INT32_MAX
    119#define SIGNED
    120#define SHIFT 32
    121#define ENDIAN_CONVERSION natural
    122#define ENDIAN_CONVERT(v) (v)
    123#include "mixeng_template.h"
    124#undef ENDIAN_CONVERT
    125#undef ENDIAN_CONVERSION
    126#define ENDIAN_CONVERSION swap
    127#define ENDIAN_CONVERT(v) bswap32 (v)
    128#include "mixeng_template.h"
    129#undef ENDIAN_CONVERT
    130#undef ENDIAN_CONVERSION
    131#undef SIGNED
    132#undef IN_MAX
    133#undef IN_MIN
    134#undef BSIZE
    135#undef ITYPE
    136#undef SHIFT
    137
    138/* Unsigned 32 bit */
    139#define BSIZE 32
    140#define ITYPE uint
    141#define IN_MIN 0
    142#define IN_MAX UINT32_MAX
    143#define SHIFT 32
    144#define ENDIAN_CONVERSION natural
    145#define ENDIAN_CONVERT(v) (v)
    146#include "mixeng_template.h"
    147#undef ENDIAN_CONVERT
    148#undef ENDIAN_CONVERSION
    149#define ENDIAN_CONVERSION swap
    150#define ENDIAN_CONVERT(v) bswap32 (v)
    151#include "mixeng_template.h"
    152#undef ENDIAN_CONVERT
    153#undef ENDIAN_CONVERSION
    154#undef IN_MAX
    155#undef IN_MIN
    156#undef BSIZE
    157#undef ITYPE
    158#undef SHIFT
    159
    160t_sample *mixeng_conv[2][2][2][3] = {
    161    {
    162        {
    163            {
    164                conv_natural_uint8_t_to_mono,
    165                conv_natural_uint16_t_to_mono,
    166                conv_natural_uint32_t_to_mono
    167            },
    168            {
    169                conv_natural_uint8_t_to_mono,
    170                conv_swap_uint16_t_to_mono,
    171                conv_swap_uint32_t_to_mono,
    172            }
    173        },
    174        {
    175            {
    176                conv_natural_int8_t_to_mono,
    177                conv_natural_int16_t_to_mono,
    178                conv_natural_int32_t_to_mono
    179            },
    180            {
    181                conv_natural_int8_t_to_mono,
    182                conv_swap_int16_t_to_mono,
    183                conv_swap_int32_t_to_mono
    184            }
    185        }
    186    },
    187    {
    188        {
    189            {
    190                conv_natural_uint8_t_to_stereo,
    191                conv_natural_uint16_t_to_stereo,
    192                conv_natural_uint32_t_to_stereo
    193            },
    194            {
    195                conv_natural_uint8_t_to_stereo,
    196                conv_swap_uint16_t_to_stereo,
    197                conv_swap_uint32_t_to_stereo
    198            }
    199        },
    200        {
    201            {
    202                conv_natural_int8_t_to_stereo,
    203                conv_natural_int16_t_to_stereo,
    204                conv_natural_int32_t_to_stereo
    205            },
    206            {
    207                conv_natural_int8_t_to_stereo,
    208                conv_swap_int16_t_to_stereo,
    209                conv_swap_int32_t_to_stereo,
    210            }
    211        }
    212    }
    213};
    214
    215f_sample *mixeng_clip[2][2][2][3] = {
    216    {
    217        {
    218            {
    219                clip_natural_uint8_t_from_mono,
    220                clip_natural_uint16_t_from_mono,
    221                clip_natural_uint32_t_from_mono
    222            },
    223            {
    224                clip_natural_uint8_t_from_mono,
    225                clip_swap_uint16_t_from_mono,
    226                clip_swap_uint32_t_from_mono
    227            }
    228        },
    229        {
    230            {
    231                clip_natural_int8_t_from_mono,
    232                clip_natural_int16_t_from_mono,
    233                clip_natural_int32_t_from_mono
    234            },
    235            {
    236                clip_natural_int8_t_from_mono,
    237                clip_swap_int16_t_from_mono,
    238                clip_swap_int32_t_from_mono
    239            }
    240        }
    241    },
    242    {
    243        {
    244            {
    245                clip_natural_uint8_t_from_stereo,
    246                clip_natural_uint16_t_from_stereo,
    247                clip_natural_uint32_t_from_stereo
    248            },
    249            {
    250                clip_natural_uint8_t_from_stereo,
    251                clip_swap_uint16_t_from_stereo,
    252                clip_swap_uint32_t_from_stereo
    253            }
    254        },
    255        {
    256            {
    257                clip_natural_int8_t_from_stereo,
    258                clip_natural_int16_t_from_stereo,
    259                clip_natural_int32_t_from_stereo
    260            },
    261            {
    262                clip_natural_int8_t_from_stereo,
    263                clip_swap_int16_t_from_stereo,
    264                clip_swap_int32_t_from_stereo
    265            }
    266        }
    267    }
    268};
    269
    270#ifdef FLOAT_MIXENG
    271#define CONV_NATURAL_FLOAT(x) (x)
    272#define CLIP_NATURAL_FLOAT(x) (x)
    273#else
    274/* macros to map [-1.f, 1.f] <-> [INT32_MIN, INT32_MAX + 1] */
    275static const float float_scale = (int64_t)INT32_MAX + 1;
    276#define CONV_NATURAL_FLOAT(x) ((x) * float_scale)
    277
    278#ifdef RECIPROCAL
    279static const float float_scale_reciprocal = 1.f / ((int64_t)INT32_MAX + 1);
    280#define CLIP_NATURAL_FLOAT(x) ((x) * float_scale_reciprocal)
    281#else
    282#define CLIP_NATURAL_FLOAT(x) ((x) / float_scale)
    283#endif
    284#endif
    285
    286static void conv_natural_float_to_mono(struct st_sample *dst, const void *src,
    287                                       int samples)
    288{
    289    float *in = (float *)src;
    290
    291    while (samples--) {
    292        dst->r = dst->l = CONV_NATURAL_FLOAT(*in++);
    293        dst++;
    294    }
    295}
    296
    297static void conv_natural_float_to_stereo(struct st_sample *dst, const void *src,
    298                                         int samples)
    299{
    300    float *in = (float *)src;
    301
    302    while (samples--) {
    303        dst->l = CONV_NATURAL_FLOAT(*in++);
    304        dst->r = CONV_NATURAL_FLOAT(*in++);
    305        dst++;
    306    }
    307}
    308
    309t_sample *mixeng_conv_float[2] = {
    310    conv_natural_float_to_mono,
    311    conv_natural_float_to_stereo,
    312};
    313
    314static void clip_natural_float_from_mono(void *dst, const struct st_sample *src,
    315                                         int samples)
    316{
    317    float *out = (float *)dst;
    318
    319    while (samples--) {
    320        *out++ = CLIP_NATURAL_FLOAT(src->l + src->r);
    321        src++;
    322    }
    323}
    324
    325static void clip_natural_float_from_stereo(
    326    void *dst, const struct st_sample *src, int samples)
    327{
    328    float *out = (float *)dst;
    329
    330    while (samples--) {
    331        *out++ = CLIP_NATURAL_FLOAT(src->l);
    332        *out++ = CLIP_NATURAL_FLOAT(src->r);
    333        src++;
    334    }
    335}
    336
    337f_sample *mixeng_clip_float[2] = {
    338    clip_natural_float_from_mono,
    339    clip_natural_float_from_stereo,
    340};
    341
    342void audio_sample_to_uint64(const void *samples, int pos,
    343                            uint64_t *left, uint64_t *right)
    344{
    345    const struct st_sample *sample = samples;
    346    sample += pos;
    347#ifdef FLOAT_MIXENG
    348    error_report(
    349        "Coreaudio and floating point samples are not supported by replay yet");
    350    abort();
    351#else
    352    *left = sample->l;
    353    *right = sample->r;
    354#endif
    355}
    356
    357void audio_sample_from_uint64(void *samples, int pos,
    358                            uint64_t left, uint64_t right)
    359{
    360    struct st_sample *sample = samples;
    361    sample += pos;
    362#ifdef FLOAT_MIXENG
    363    error_report(
    364        "Coreaudio and floating point samples are not supported by replay yet");
    365    abort();
    366#else
    367    sample->l = left;
    368    sample->r = right;
    369#endif
    370}
    371
    372/*
    373 * August 21, 1998
    374 * Copyright 1998 Fabrice Bellard.
    375 *
    376 * [Rewrote completely the code of Lance Norskog And Sundry
    377 * Contributors with a more efficient algorithm.]
    378 *
    379 * This source code is freely redistributable and may be used for
    380 * any purpose.  This copyright notice must be maintained.
    381 * Lance Norskog And Sundry Contributors are not responsible for
    382 * the consequences of using this software.
    383 */
    384
    385/*
    386 * Sound Tools rate change effect file.
    387 */
    388/*
    389 * Linear Interpolation.
    390 *
    391 * The use of fractional increment allows us to use no buffer. It
    392 * avoid the problems at the end of the buffer we had with the old
    393 * method which stored a possibly big buffer of size
    394 * lcm(in_rate,out_rate).
    395 *
    396 * Limited to 16 bit samples and sampling frequency <= 65535 Hz. If
    397 * the input & output frequencies are equal, a delay of one sample is
    398 * introduced.  Limited to processing 32-bit count worth of samples.
    399 *
    400 * 1 << FRAC_BITS evaluating to zero in several places.  Changed with
    401 * an (unsigned long) cast to make it safe.  MarkMLl 2/1/99
    402 */
    403
    404/* Private data */
    405struct rate {
    406    uint64_t opos;
    407    uint64_t opos_inc;
    408    uint32_t ipos;              /* position in the input stream (integer) */
    409    struct st_sample ilast;          /* last sample in the input stream */
    410};
    411
    412/*
    413 * Prepare processing.
    414 */
    415void *st_rate_start (int inrate, int outrate)
    416{
    417    struct rate *rate = audio_calloc(__func__, 1, sizeof(*rate));
    418
    419    if (!rate) {
    420        dolog ("Could not allocate resampler (%zu bytes)\n", sizeof (*rate));
    421        return NULL;
    422    }
    423
    424    rate->opos = 0;
    425
    426    /* increment */
    427    rate->opos_inc = ((uint64_t) inrate << 32) / outrate;
    428
    429    rate->ipos = 0;
    430    rate->ilast.l = 0;
    431    rate->ilast.r = 0;
    432    return rate;
    433}
    434
    435#define NAME st_rate_flow_mix
    436#define OP(a, b) a += b
    437#include "rate_template.h"
    438
    439#define NAME st_rate_flow
    440#define OP(a, b) a = b
    441#include "rate_template.h"
    442
    443void st_rate_stop (void *opaque)
    444{
    445    g_free (opaque);
    446}
    447
    448void mixeng_clear (struct st_sample *buf, int len)
    449{
    450    memset (buf, 0, len * sizeof (struct st_sample));
    451}
    452
    453void mixeng_volume (struct st_sample *buf, int len, struct mixeng_volume *vol)
    454{
    455    if (vol->mute) {
    456        mixeng_clear (buf, len);
    457        return;
    458    }
    459
    460    while (len--) {
    461#ifdef FLOAT_MIXENG
    462        buf->l = buf->l * vol->l;
    463        buf->r = buf->r * vol->r;
    464#else
    465        buf->l = (buf->l * vol->l) >> 32;
    466        buf->r = (buf->r * vol->r) >> 32;
    467#endif
    468        buf += 1;
    469    }
    470}