]> git.sesse.net Git - vlc/blob - modules/audio_mixer/fixed32.c
aout: premultiply gain before mixing
[vlc] / modules / audio_mixer / fixed32.c
1 /*****************************************************************************
2  * fixed32.c : fixed-point software volume
3  *****************************************************************************
4  * Copyright (C) 2011 RĂ©mi Denis-Courmont
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation; either version 2.1 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19  *****************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 #endif
24
25 #include <vlc_common.h>
26 #include <vlc_plugin.h>
27 #include <vlc_aout.h>
28 #include <vlc_aout_mixer.h>
29
30 static int Activate (vlc_object_t *);
31
32 vlc_module_begin ()
33     set_category (CAT_AUDIO)
34     set_subcategory (SUBCAT_AUDIO_MISC)
35     set_description (N_("Fixed-point audio mixer"))
36     set_capability ("audio mixer", 9)
37     set_callbacks (Activate, NULL)
38 vlc_module_end ()
39
40 static void FilterFI32 (aout_mixer_t *, block_t *, float);
41 static void FilterS16N (aout_mixer_t *, block_t *, float);
42
43 static int Activate (vlc_object_t *obj)
44 {
45     aout_mixer_t *mixer = (aout_mixer_t *)obj;
46
47     switch (mixer->fmt.i_format)
48     {
49         case VLC_CODEC_FI32:
50             mixer->mix = FilterFI32;
51             break;
52         case VLC_CODEC_S16N:
53             mixer->mix = FilterS16N;
54             break;
55         default:
56             return -1;
57     }
58     return 0;
59 }
60
61 static void FilterFI32 (aout_mixer_t *mixer, block_t *block, float volume)
62 {
63     const int64_t mult = volume * FIXED32_ONE;
64
65     if (mult == FIXED32_ONE)
66         return;
67
68     int32_t *p = (int32_t *)block->p_buffer;
69
70     for (size_t n = block->i_buffer / sizeof (*p); n > 0; n--)
71     {
72         *p = (*p * mult) >> FIXED32_FRACBITS;
73         p++;
74     }
75
76     (void) mixer;
77 }
78
79 static void FilterS16N (aout_mixer_t *mixer, block_t *block, float volume)
80 {
81     const int32_t mult = volume * 0x10000;
82
83     if (mult == 0x10000)
84         return;
85
86     int16_t *p = (int16_t *)block->p_buffer;
87
88     for (size_t n = block->i_buffer / sizeof (*p); n > 0; n--)
89     {
90         *p = (*p * mult) >> 16;
91         p++;
92     }
93
94     (void) mixer;
95 }