1 /* GSequencer - Advanced GTK Sequencer
2  * Copyright (C) 2005-2021 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 #ifndef __AGS_AUDIO_SIGNAL_H__
21 #define __AGS_AUDIO_SIGNAL_H__
22 
23 #include <glib.h>
24 #include <glib-object.h>
25 
26 #include <ags/libags.h>
27 
28 #include <ags/audio/ags_note.h>
29 
30 G_BEGIN_DECLS
31 
32 #define AGS_TYPE_AUDIO_SIGNAL                (ags_audio_signal_get_type())
33 #define AGS_AUDIO_SIGNAL(obj)                (G_TYPE_CHECK_INSTANCE_CAST((obj), AGS_TYPE_AUDIO_SIGNAL, AgsAudioSignal))
34 #define AGS_AUDIO_SIGNAL_CLASS(class)        (G_TYPE_CHECK_CLASS_CAST((class), AGS_TYPE_AUDIO_SIGNAL, AgsAudioSignalClass))
35 #define AGS_IS_AUDIO_SIGNAL(obj)             (G_TYPE_CHECK_INSTANCE_TYPE ((obj), AGS_TYPE_AUDIO_SIGNAL))
36 #define AGS_IS_AUDIO_SIGNAL_CLASS(class)     (G_TYPE_CHECK_CLASS_TYPE ((class), AGS_TYPE_AUDIO_SIGNAL))
37 #define AGS_AUDIO_SIGNAL_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS ((obj), AGS_TYPE_AUDIO_SIGNAL, AgsAudioSignalClass))
38 
39 #define AGS_AUDIO_SIGNAL_GET_OBJ_MUTEX(obj) (&(((AgsAudioSignal *) obj)->obj_mutex))
40 #define AGS_AUDIO_SIGNAL_GET_STREAM_MUTEX(obj) (&(((AgsAudioSignal *) obj)->stream_mutex))
41 
42 typedef struct _AgsAudioSignal AgsAudioSignal;
43 typedef struct _AgsAudioSignalClass AgsAudioSignalClass;
44 
45 /**
46  * AgsAudioSignalFlags:
47  * @AGS_AUDIO_SIGNAL_ADDED_TO_REGISTRY: the audio signal was added to registry, see #AgsConnectable::add_to_registry()
48  * @AGS_AUDIO_SIGNAL_CONNECTED: indicates the audio signal was connected by calling #AgsConnectable::connect()
49  * @AGS_AUDIO_SIGNAL_TEMPLATE: the audio signal acts as a template
50  * @AGS_AUDIO_SIGNAL_RT_TEMPLATE: the audio signal acts as a realtime template
51  * @AGS_AUDIO_SIGNAL_MASTER: the audio signal needs master
52  * @AGS_AUDIO_SIGNAL_FEED: the audio signal needs feed
53  * @AGS_AUDIO_SIGNAL_RECYCLED: the audio signal is recycled
54  * @AGS_AUDIO_SIGNAL_STREAM: the audio signal needs stream
55  * @AGS_AUDIO_SIGNAL_SLICE_ALLOC: the audio signal allocates from slice
56  *
57  * Enum values to control the behavior or indicate internal state of #AgsAudioSignal by
58  * enable/disable as flags.
59  */
60 typedef enum{
61   AGS_AUDIO_SIGNAL_ADDED_TO_REGISTRY    = 1,
62   AGS_AUDIO_SIGNAL_CONNECTED            = 1 <<  1,
63   AGS_AUDIO_SIGNAL_TEMPLATE             = 1 <<  2,
64   AGS_AUDIO_SIGNAL_RT_TEMPLATE          = 1 <<  3,
65   AGS_AUDIO_SIGNAL_MASTER               = 1 <<  4,
66   AGS_AUDIO_SIGNAL_FEED                 = 1 <<  5,
67   AGS_AUDIO_SIGNAL_RECYCLED             = 1 <<  6,
68   AGS_AUDIO_SIGNAL_STREAM               = 1 <<  7,
69   AGS_AUDIO_SIGNAL_SLICE_ALLOC          = 1 <<  8,
70 }AgsAudioSignalFlags;
71 
72 struct _AgsAudioSignal
73 {
74   GObject gobject;
75 
76   guint flags;
77 
78   GRecMutex obj_mutex;
79 
80   AgsUUID *uuid;
81 
82   GObject *recycling;
83 
84   GObject *output_soundcard;
85   gint output_soundcard_channel;
86 
87   GObject *input_soundcard;
88   gint input_soundcard_channel;
89 
90   guint samplerate;
91   guint buffer_size;
92   guint format;
93   guint word_size;
94 
95   guint length;
96   guint first_frame;
97   guint last_frame; // the last frame at stream_end
98 
99   guint frame_count; // initial size
100   guint loop_start;
101   guint loop_end;
102 
103   gdouble delay;
104   guint attack;
105 
106   AgsComplex damping;
107   AgsComplex vibration;
108   guint timbre_start;
109   guint timbre_end;
110 
111   GObject *template;
112 
113   GObject *rt_template;
114   GList *note;
115 
116   GObject *recall_id; // AGS_TYPE_RECALL_ID to identify the AgsAudioSignal
117 
118   GRecMutex stream_mutex;
119 
120   GList *stream;
121   GList *stream_current;
122   GList *stream_end;
123 };
124 
125 struct _AgsAudioSignalClass
126 {
127   GObjectClass gobject;
128 
129   void (*add_note)(AgsAudioSignal *audio_signal,
130 		   GObject *note);
131   void (*remove_note)(AgsAudioSignal *audio_signal,
132 		      GObject *note);
133 
134   void (*refresh_data)(AgsAudioSignal *audio_signal);
135 };
136 
137 GType ags_audio_signal_get_type();
138 GType ags_audio_signal_flags_get_type();
139 
140 GRecMutex* ags_audio_signal_get_obj_mutex(AgsAudioSignal *audio_signal);
141 
142 void ags_audio_signal_stream_lock(AgsAudioSignal *audio_signal);
143 void ags_audio_signal_stream_unlock(AgsAudioSignal *audio_signal);
144 
145 gboolean ags_audio_signal_test_flags(AgsAudioSignal *audio_signal, guint flags);
146 void ags_audio_signal_set_flags(AgsAudioSignal *audio_signal, guint flags);
147 void ags_audio_signal_unset_flags(AgsAudioSignal *audio_signal, guint flags);
148 
149 void* ags_stream_alloc(guint buffer_size,
150 		       guint format);
151 void ags_stream_free(void *buffer);
152 
153 void* ags_stream_slice_alloc(guint buffer_size,
154 			     guint format);
155 void ags_stream_slice_free(guint buffer_size,
156 			   guint format,
157 			   void *buffer);
158 
159 /* parent */
160 GObject* ags_audio_signal_get_recycling(AgsAudioSignal *audio_signal);
161 void ags_audio_signal_set_recycling(AgsAudioSignal *audio_signal, GObject *recycling);
162 
163 /* soundcard */
164 GObject* ags_audio_signal_get_output_soundcard(AgsAudioSignal *audio_signal);
165 void ags_audio_signal_set_output_soundcard(AgsAudioSignal *audio_signal, GObject *output_soundcard);
166 
167 GObject* ags_audio_signal_get_input_soundcard(AgsAudioSignal *audio_signal);
168 void ags_audio_signal_set_input_soundcard(AgsAudioSignal *audio_signal, GObject *input_soundcard);
169 
170 /* presets */
171 guint ags_audio_signal_get_samplerate(AgsAudioSignal *audio_signal);
172 void ags_audio_signal_set_samplerate(AgsAudioSignal *audio_signal, guint samplerate);
173 
174 guint ags_audio_signal_get_buffer_size(AgsAudioSignal *audio_signal);
175 void ags_audio_signal_set_buffer_size(AgsAudioSignal *audio_signal, guint buffer_size);
176 
177 guint ags_audio_signal_get_format(AgsAudioSignal *audio_signal);
178 void ags_audio_signal_set_format(AgsAudioSignal *audio_signal, guint format);
179 
180 /* children */
181 GList* ags_audio_signal_get_note(AgsAudioSignal *audio_signal);
182 void ags_audio_signal_set_note(AgsAudioSignal *audio_signal, GList *note);
183 
184 void ags_audio_signal_add_note(AgsAudioSignal *audio_signal,
185 			       GObject *note);
186 void ags_audio_signal_remove_note(AgsAudioSignal *audio_signal,
187 				  GObject *note);
188 
189 GList* ags_audio_signal_get_stream(AgsAudioSignal *audio_signal);
190 void ags_audio_signal_set_stream(AgsAudioSignal *audio_signal, GList *stream);
191 
192 /* presets related */
193 void ags_audio_signal_refresh_data(AgsAudioSignal *audio_signal);
194 
195 /* control */
196 void ags_audio_signal_add_stream(AgsAudioSignal *audio_signal);
197 void ags_audio_signal_stream_resize(AgsAudioSignal *audio_signal, guint length);
198 void ags_audio_signal_stream_safe_resize(AgsAudioSignal *audio_signal, guint length);
199 
200 void ags_audio_signal_clear(AgsAudioSignal *audio_signal);
201 
202 void ags_audio_signal_duplicate_stream(AgsAudioSignal *audio_signal,
203 				       AgsAudioSignal *template);
204 
205 void ags_audio_signal_feed(AgsAudioSignal *audio_signal,
206 			   AgsAudioSignal *template,
207 			   guint frame_count);
208 void ags_audio_signal_feed_extended(AgsAudioSignal *audio_signal,
209 				    AgsAudioSignal *template,
210 				    guint frame_count, guint old_frame_count,
211 				    gboolean do_open, gboolean do_close);
212 
213 void ags_audio_signal_open_feed(AgsAudioSignal *audio_signal,
214 				AgsAudioSignal *template,
215 				guint frame_count, guint old_frame_count);
216 void ags_audio_signal_continue_feed(AgsAudioSignal *audio_signal,
217 				    AgsAudioSignal *template,
218 				    guint frame_count, guint old_frame_count);
219 void ags_audio_signal_close_feed(AgsAudioSignal *audio_signal,
220 				 AgsAudioSignal *template,
221 				 guint frame_count, guint old_frame_count);
222 
223 /* query */
224 guint ags_audio_signal_get_length_till_current(AgsAudioSignal *audio_signal);
225 gboolean ags_audio_signal_contains_note(AgsAudioSignal *audio_signal,
226 					AgsNote *note);
227 
228 AgsAudioSignal* ags_audio_signal_get_template(GList *audio_signal);
229 GList* ags_audio_signal_get_rt_template(GList *audio_signal);
230 
231 GList* ags_audio_signal_find_stream_current(GList *audio_signal,
232 					   GObject *recall_id);
233 GList* ags_audio_signal_find_by_recall_id(GList *audio_signal,
234 					  GObject *recall_id);
235 
236 gboolean ags_audio_signal_is_active(GList *audio_signal,
237 				    GObject *recall_id);
238 
239 /* instantiate */
240 AgsAudioSignal* ags_audio_signal_new(GObject *output_soundcard,
241 				     GObject *recycling,
242 				     GObject *recall_id);
243 
244 AgsAudioSignal* ags_audio_signal_new_with_length(GObject *output_soundcard,
245 						 GObject *recycling,
246 						 GObject *recall_id,
247 						 guint length);
248 
249 G_END_DECLS
250 
251 #endif /*__AGS_AUDIO_SIGNAL_H__*/
252