Coverage Report

Created: 2026-02-14 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gstreamer/subprojects/gst-plugins-base/gst-libs/gst/audio/streamvolume.c
Line
Count
Source
1
/* GStreamer Mixer
2
 * Copyright (C) 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
3
 *
4
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Library General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2 of the License, or (at your option) any later version.
8
 *
9
 * This library is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Library General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Library General Public
15
 * License along with this library; if not, write to the
16
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17
 * Boston, MA 02110-1301, USA.
18
 */
19
20
/**
21
 * SECTION:gststreamvolume
22
 * @title: GstStreamVolume
23
 * @short_description: Interface for elements that provide a stream volume
24
 *
25
 * This interface is implemented by elements that provide a stream volume. Examples for
26
 * such elements are #volume and #playbin.
27
 *
28
 * Applications can use this interface to get or set the current stream volume. For this
29
 * the "volume" #GObject property can be used or the helper functions gst_stream_volume_set_volume()
30
 * and gst_stream_volume_get_volume(). This volume is always a linear factor, i.e. 0.0 is muted
31
 * 1.0 is 100%. For showing the volume in a GUI it might make sense to convert it to
32
 * a different format by using gst_stream_volume_convert_volume(). Volume sliders should usually
33
 * use a cubic volume.
34
 *
35
 * Separate from the volume the stream can also be muted by the "mute" #GObject property or
36
 * gst_stream_volume_set_mute() and gst_stream_volume_get_mute().
37
 *
38
 * Elements that provide some kind of stream volume should implement the "volume" and
39
 * "mute" #GObject properties and handle setting and getting of them properly.
40
 * The volume property is defined to be a linear volume factor.
41
 *
42
 */
43
44
#ifdef HAVE_CONFIG_H
45
#include "config.h"
46
#endif
47
48
#include "streamvolume.h"
49
#include <math.h>
50
51
static void
52
gst_stream_volume_class_init (GstStreamVolumeInterface * iface)
53
2
{
54
2
  g_object_interface_install_property (iface,
55
2
      g_param_spec_double ("volume",
56
2
          "Volume",
57
2
          "Linear volume factor, 1.0=100%",
58
2
          0.0, G_MAXDOUBLE, 1.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
59
2
  g_object_interface_install_property (iface,
60
2
      g_param_spec_boolean ("mute",
61
2
          "Mute",
62
2
          "Mute the audio channel without changing the volume",
63
2
          FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
64
2
}
65
66
GType
67
gst_stream_volume_get_type (void)
68
8
{
69
8
  static gsize type = 0;
70
8
  if (g_once_init_enter (&type)) {
71
2
    GType tmp;
72
2
    static const GTypeInfo info = {
73
2
      sizeof (GstStreamVolumeInterface),
74
2
      NULL,                     /* base_init */
75
2
      NULL,                     /* base_finalize */
76
2
      (GClassInitFunc) gst_stream_volume_class_init,    /* class_init */
77
2
      NULL,                     /* class_finalize */
78
2
      NULL,                     /* class_data */
79
2
      0,
80
2
      0,                        /* n_preallocs */
81
      NULL                      /* instance_init */
82
2
    };
83
2
    tmp = g_type_register_static (G_TYPE_INTERFACE,
84
2
        "GstStreamVolume", &info, 0);
85
2
    g_type_interface_add_prerequisite (tmp, G_TYPE_OBJECT);
86
87
2
    g_once_init_leave (&type, tmp);
88
2
  }
89
8
  return type;
90
8
}
91
92
/**
93
 * gst_stream_volume_get_volume:
94
 * @volume: #GstStreamVolume that should be used
95
 * @format: #GstStreamVolumeFormat which should be returned
96
 *
97
 * Returns: The current stream volume as linear factor
98
 */
99
gdouble
100
gst_stream_volume_get_volume (GstStreamVolume * volume,
101
    GstStreamVolumeFormat format)
102
0
{
103
0
  gdouble val;
104
105
0
  g_return_val_if_fail (GST_IS_STREAM_VOLUME (volume), 1.0);
106
107
0
  g_object_get (volume, "volume", &val, NULL);
108
0
  if (format != GST_STREAM_VOLUME_FORMAT_LINEAR)
109
0
    val =
110
0
        gst_stream_volume_convert_volume (GST_STREAM_VOLUME_FORMAT_LINEAR,
111
0
        format, val);
112
0
  return val;
113
0
}
114
115
/**
116
 * gst_stream_volume_set_volume:
117
 * @volume: #GstStreamVolume that should be used
118
 * @format: #GstStreamVolumeFormat of @val
119
 * @val: Linear volume factor that should be set
120
 */
121
void
122
gst_stream_volume_set_volume (GstStreamVolume * volume,
123
    GstStreamVolumeFormat format, gdouble val)
124
0
{
125
0
  g_return_if_fail (GST_IS_STREAM_VOLUME (volume));
126
127
0
  if (format != GST_STREAM_VOLUME_FORMAT_LINEAR)
128
0
    val =
129
0
        gst_stream_volume_convert_volume (format,
130
0
        GST_STREAM_VOLUME_FORMAT_LINEAR, val);
131
0
  g_object_set (volume, "volume", val, NULL);
132
0
}
133
134
/**
135
 * gst_stream_volume_get_mute:
136
 * @volume: #GstStreamVolume that should be used
137
 *
138
 * Returns: Returns %TRUE if the stream is muted
139
 */
140
gboolean
141
gst_stream_volume_get_mute (GstStreamVolume * volume)
142
0
{
143
0
  gboolean val;
144
145
0
  g_return_val_if_fail (GST_IS_STREAM_VOLUME (volume), FALSE);
146
147
0
  g_object_get (volume, "mute", &val, NULL);
148
0
  return val;
149
0
}
150
151
/**
152
 * gst_stream_volume_set_mute:
153
 * @volume: #GstStreamVolume that should be used
154
 * @mute: Mute state that should be set
155
 */
156
void
157
gst_stream_volume_set_mute (GstStreamVolume * volume, gboolean mute)
158
0
{
159
0
  g_return_if_fail (GST_IS_STREAM_VOLUME (volume));
160
161
0
  g_object_set (volume, "mute", mute, NULL);
162
0
}
163
164
/**
165
 * gst_stream_volume_convert_volume:
166
 * @from: #GstStreamVolumeFormat to convert from
167
 * @to: #GstStreamVolumeFormat to convert to
168
 * @val: Volume in @from format that should be converted
169
 *
170
 * Returns: the converted volume
171
 */
172
gdouble
173
gst_stream_volume_convert_volume (GstStreamVolumeFormat from,
174
    GstStreamVolumeFormat to, gdouble val)
175
0
{
176
0
  switch (from) {
177
0
    case GST_STREAM_VOLUME_FORMAT_LINEAR:
178
0
      g_return_val_if_fail (val >= 0.0, 0.0);
179
0
      switch (to) {
180
0
        case GST_STREAM_VOLUME_FORMAT_LINEAR:
181
0
          return val;
182
0
        case GST_STREAM_VOLUME_FORMAT_CUBIC:
183
0
          return pow (val, 1 / 3.0);
184
0
        case GST_STREAM_VOLUME_FORMAT_DB:
185
0
          return 20.0 * log10 (val);
186
0
      }
187
0
      break;
188
0
    case GST_STREAM_VOLUME_FORMAT_CUBIC:
189
0
      g_return_val_if_fail (val >= 0.0, 0.0);
190
0
      switch (to) {
191
0
        case GST_STREAM_VOLUME_FORMAT_LINEAR:
192
0
          return val * val * val;
193
0
        case GST_STREAM_VOLUME_FORMAT_CUBIC:
194
0
          return val;
195
0
        case GST_STREAM_VOLUME_FORMAT_DB:
196
0
          return 3.0 * 20.0 * log10 (val);
197
0
      }
198
0
      break;
199
0
    case GST_STREAM_VOLUME_FORMAT_DB:
200
0
      switch (to) {
201
0
        case GST_STREAM_VOLUME_FORMAT_LINEAR:
202
0
          return pow (10.0, val / 20.0);
203
0
        case GST_STREAM_VOLUME_FORMAT_CUBIC:
204
0
          return pow (10.0, val / (3.0 * 20.0));
205
0
        case GST_STREAM_VOLUME_FORMAT_DB:
206
0
          return val;
207
0
      }
208
0
      break;
209
0
  }
210
0
  g_return_val_if_reached (0.0);
211
0
}