1 /* GSequencer - Advanced GTK Sequencer
2 * Copyright (C) 2005-2019 Joël Krähemann
3 *
4 * This file is part of GSequencer.
5 *
6 * GSequencer is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * GSequencer 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 General Public License
17 * along with GSequencer. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <ags/audio/recall/ags_peak_audio_signal.h>
21
22 #include <ags/audio/recall/ags_peak_channel.h>
23 #include <ags/audio/recall/ags_peak_channel_run.h>
24 #include <ags/audio/recall/ags_peak_recycling.h>
25
26 #include <ags/i18n.h>
27
28 void ags_peak_audio_signal_class_init(AgsPeakAudioSignalClass *peak_audio_signal);
29 void ags_peak_audio_signal_init(AgsPeakAudioSignal *peak_audio_signal);
30 void ags_peak_audio_signal_set_property(GObject *gobject,
31 guint prop_id,
32 const GValue *value,
33 GParamSpec *param_spec);
34 void ags_peak_audio_signal_get_property(GObject *gobject,
35 guint prop_id,
36 GValue *value,
37 GParamSpec *param_spec);
38 void ags_peak_audio_signal_finalize(GObject *gobject);
39
40 void ags_peak_audio_signal_run_inter(AgsRecall *recall);
41 AgsRecall* ags_peak_audio_signal_duplicate(AgsRecall *recall,
42 AgsRecallID *recall_id,
43 guint *n_params, GParameter *parameter);
44
45 /**
46 * SECTION:ags_peak_audio_signal
47 * @short_description: peaks audio signal
48 * @title: AgsPeakAudioSignal
49 * @section_id:
50 * @include: ags/audio/recall/ags_peak_audio_signal.h
51 *
52 * The #AgsPeakAudioSignal class peaks the audio signal.
53 */
54
55 enum{
56 PROP_0,
57 PROP_PEAK,
58 };
59
60 static gpointer ags_peak_audio_signal_parent_class = NULL;
61
62 GType
ags_peak_audio_signal_get_type()63 ags_peak_audio_signal_get_type()
64 {
65 static volatile gsize g_define_type_id__volatile = 0;
66
67 if(g_once_init_enter (&g_define_type_id__volatile)){
68 GType ags_type_peak_audio_signal = 0;
69
70 static const GTypeInfo ags_peak_audio_signal_info = {
71 sizeof (AgsPeakAudioSignalClass),
72 NULL, /* base_init */
73 NULL, /* base_finalize */
74 (GClassInitFunc) ags_peak_audio_signal_class_init,
75 NULL, /* class_finalize */
76 NULL, /* class_data */
77 sizeof (AgsPeakAudioSignal),
78 0, /* n_preallocs */
79 (GInstanceInitFunc) ags_peak_audio_signal_init,
80 };
81
82 ags_type_peak_audio_signal = g_type_register_static(AGS_TYPE_RECALL_AUDIO_SIGNAL,
83 "AgsPeakAudioSignal",
84 &ags_peak_audio_signal_info,
85 0);
86
87 g_once_init_leave(&g_define_type_id__volatile, ags_type_peak_audio_signal);
88 }
89
90 return g_define_type_id__volatile;
91 }
92
93 void
ags_peak_audio_signal_class_init(AgsPeakAudioSignalClass * peak_audio_signal)94 ags_peak_audio_signal_class_init(AgsPeakAudioSignalClass *peak_audio_signal)
95 {
96 GObjectClass *gobject;
97 AgsRecallClass *recall;
98
99 GParamSpec *param_spec;
100
101 ags_peak_audio_signal_parent_class = g_type_class_peek_parent(peak_audio_signal);
102
103 /* GObjectClass */
104 gobject = (GObjectClass *) peak_audio_signal;
105
106 gobject->set_property = ags_peak_audio_signal_set_property;
107 gobject->get_property = ags_peak_audio_signal_get_property;
108
109 gobject->finalize = ags_peak_audio_signal_finalize;
110
111 /* properties */
112 /**
113 * AgsPeakAudioSignal:peak:
114 *
115 * The peak.
116 *
117 * Since: 3.0.0
118 */
119 param_spec = g_param_spec_double("peak",
120 i18n_pspec("resulting peak"),
121 i18n_pspec("The peak resulted"),
122 0.0,
123 1.0,
124 0.0,
125 G_PARAM_READABLE | G_PARAM_WRITABLE);
126 g_object_class_install_property(gobject,
127 PROP_PEAK,
128 param_spec);
129
130 /* AgsRecallClass */
131 recall = (AgsRecallClass *) peak_audio_signal;
132
133 recall->run_inter = ags_peak_audio_signal_run_inter;
134 }
135
136 void
ags_peak_audio_signal_init(AgsPeakAudioSignal * peak_audio_signal)137 ags_peak_audio_signal_init(AgsPeakAudioSignal *peak_audio_signal)
138 {
139 AGS_RECALL(peak_audio_signal)->child_type = G_TYPE_NONE;
140
141 peak_audio_signal->peak = 0.0;
142 }
143
144 void
ags_peak_audio_signal_set_property(GObject * gobject,guint prop_id,const GValue * value,GParamSpec * param_spec)145 ags_peak_audio_signal_set_property(GObject *gobject,
146 guint prop_id,
147 const GValue *value,
148 GParamSpec *param_spec)
149 {
150 AgsPeakAudioSignal *peak_audio_signal;
151
152 GRecMutex *recall_mutex;
153
154 peak_audio_signal = AGS_PEAK_AUDIO_SIGNAL(gobject);
155
156 /* get recall mutex */
157 recall_mutex = AGS_RECALL_GET_OBJ_MUTEX(peak_audio_signal);
158
159 switch(prop_id){
160 case PROP_PEAK:
161 {
162 gdouble peak;
163
164 peak = g_value_get_double(value);
165
166 g_rec_mutex_lock(recall_mutex);
167
168 peak_audio_signal->peak = peak;
169
170 g_rec_mutex_unlock(recall_mutex);
171 }
172 break;
173 default:
174 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
175 break;
176 }
177 }
178
179 void
ags_peak_audio_signal_get_property(GObject * gobject,guint prop_id,GValue * value,GParamSpec * param_spec)180 ags_peak_audio_signal_get_property(GObject *gobject,
181 guint prop_id,
182 GValue *value,
183 GParamSpec *param_spec)
184 {
185 AgsPeakAudioSignal *peak_audio_signal;
186
187 GRecMutex *recall_mutex;
188
189 peak_audio_signal = AGS_PEAK_AUDIO_SIGNAL(gobject);
190
191 /* get recall mutex */
192 recall_mutex = AGS_RECALL_GET_OBJ_MUTEX(peak_audio_signal);
193
194 switch(prop_id){
195 case PROP_PEAK:
196 {
197 g_rec_mutex_lock(recall_mutex);
198
199 g_value_set_double(value, peak_audio_signal->peak);
200
201 g_rec_mutex_unlock(recall_mutex);
202 }
203 break;
204 default:
205 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
206 break;
207 }
208 }
209
210 void
ags_peak_audio_signal_finalize(GObject * gobject)211 ags_peak_audio_signal_finalize(GObject *gobject)
212 {
213 /* call parent */
214 G_OBJECT_CLASS(ags_peak_audio_signal_parent_class)->finalize(gobject);
215 }
216
217 void
ags_peak_audio_signal_run_inter(AgsRecall * recall)218 ags_peak_audio_signal_run_inter(AgsRecall *recall)
219 {
220 AgsAudioSignal *source;
221 AgsPeakChannel *peak_channel;
222 AgsPeakChannelRun *peak_channel_run;
223 AgsPeakRecycling *peak_recycling;
224 AgsPeakAudioSignal *peak_audio_signal;
225
226 guint samplerate;
227 guint buffer_size;
228 guint format;
229
230 void (*parent_class_run_inter)(AgsRecall *recall);
231
232 peak_audio_signal = (AgsPeakAudioSignal *) recall;
233
234 /* get parent class */
235 parent_class_run_inter = AGS_RECALL_CLASS(ags_peak_audio_signal_parent_class)->run_inter;
236
237 /* call parent */
238 parent_class_run_inter(recall);
239
240 /* get some fields */
241 g_object_get(peak_audio_signal,
242 "source", &source,
243 NULL);
244
245 if(source->stream_current != NULL){
246 g_object_get(peak_audio_signal,
247 "parent", &peak_recycling,
248 NULL);
249
250 g_object_get(peak_recycling,
251 "parent", &peak_channel_run,
252 NULL);
253
254 g_object_get(peak_channel_run,
255 "recall-channel", &peak_channel,
256 NULL);
257
258 g_object_get(source,
259 "samplerate", &samplerate,
260 "buffer-size", &buffer_size,
261 "format", &format,
262 NULL);
263
264 ags_peak_channel_buffer_add(peak_channel,
265 source->stream_current->data,
266 samplerate,
267 buffer_size,
268 format);
269
270 g_object_unref(peak_recycling);
271
272 g_object_unref(peak_channel_run);
273 g_object_unref(peak_channel);
274 }else{
275 ags_recall_done(recall);
276 }
277
278 g_object_unref(source);
279 }
280
281 /**
282 * ags_peak_audio_signal_new:
283 * @source: the #AgsAudioSignal
284 *
285 * Create a new instance of #AgsPeakAudioSignal
286 *
287 * Returns: the new #AgsPeakAudioSignal
288 *
289 * Since: 3.0.0
290 */
291 AgsPeakAudioSignal*
ags_peak_audio_signal_new(AgsAudioSignal * source)292 ags_peak_audio_signal_new(AgsAudioSignal *source)
293 {
294 AgsPeakAudioSignal *peak_audio_signal;
295
296 peak_audio_signal = (AgsPeakAudioSignal *) g_object_new(AGS_TYPE_PEAK_AUDIO_SIGNAL,
297 "source", source,
298 NULL);
299
300 return(peak_audio_signal);
301 }
302