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 #ifndef __AGS_CORE_AUDIO_DEVIN_H__ 21 #define __AGS_CORE_AUDIO_DEVIN_H__ 22 23 #include <glib.h> 24 #include <glib-object.h> 25 26 #include <ags/libags.h> 27 28 G_BEGIN_DECLS 29 30 #define AGS_TYPE_CORE_AUDIO_DEVIN (ags_core_audio_devin_get_type()) 31 #define AGS_CORE_AUDIO_DEVIN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), AGS_TYPE_CORE_AUDIO_DEVIN, AgsCoreAudioDevin)) 32 #define AGS_CORE_AUDIO_DEVIN_CLASS(class) (G_TYPE_CHECK_CLASS_CAST(class, AGS_TYPE_CORE_AUDIO_DEVIN, AgsCoreAudioDevin)) 33 #define AGS_IS_CORE_AUDIO_DEVIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), AGS_TYPE_CORE_AUDIO_DEVIN)) 34 #define AGS_IS_CORE_AUDIO_DEVIN_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), AGS_TYPE_CORE_AUDIO_DEVIN)) 35 #define AGS_CORE_AUDIO_DEVIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS(obj, AGS_TYPE_CORE_AUDIO_DEVIN, AgsCoreAudioDevinClass)) 36 37 #define AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(obj) (&(((AgsCoreAudioDevin *) obj)->obj_mutex)) 38 39 typedef struct _AgsCoreAudioDevin AgsCoreAudioDevin; 40 typedef struct _AgsCoreAudioDevinClass AgsCoreAudioDevinClass; 41 42 /** 43 * AgsCoreAudioDevinFlags: 44 * @AGS_CORE_AUDIO_DEVIN_ADDED_TO_REGISTRY: the core-audio devin was added to registry, see #AgsConnectable::add_to_registry() 45 * @AGS_CORE_AUDIO_DEVIN_CONNECTED: indicates the core-audio devin was connected by calling #AgsConnectable::connect() 46 * @AGS_CORE_AUDIO_DEVIN_BUFFER0: ring-buffer 0 47 * @AGS_CORE_AUDIO_DEVIN_BUFFER1: ring-buffer 1 48 * @AGS_CORE_AUDIO_DEVIN_BUFFER2: ring-buffer 2 49 * @AGS_CORE_AUDIO_DEVIN_BUFFER3: ring-buffer 3 50 * @AGS_CORE_AUDIO_DEVIN_BUFFER4: ring-buffer 4 51 * @AGS_CORE_AUDIO_DEVIN_BUFFER5: ring-buffer 5 52 * @AGS_CORE_AUDIO_DEVIN_BUFFER6: ring-buffer 6 53 * @AGS_CORE_AUDIO_DEVIN_BUFFER7: ring-buffer 7 54 * @AGS_CORE_AUDIO_DEVIN_ATTACK_FIRST: use first attack, instead of second one 55 * @AGS_CORE_AUDIO_DEVIN_RECORD: do capture 56 * @AGS_CORE_AUDIO_DEVIN_SHUTDOWN: stop capture 57 * @AGS_CORE_AUDIO_DEVIN_START_RECORD: capture starting 58 * @AGS_CORE_AUDIO_DEVIN_NONBLOCKING: do non-blocking calls 59 * @AGS_CORE_AUDIO_DEVIN_INITIALIZED: the soundcard was initialized 60 * 61 * Enum values to control the behavior or indicate internal state of #AgsCoreAudioDevin by 62 * enable/disable as flags. 63 */ 64 typedef enum{ 65 AGS_CORE_AUDIO_DEVIN_ADDED_TO_REGISTRY = 1, 66 AGS_CORE_AUDIO_DEVIN_CONNECTED = 1 << 1, 67 68 AGS_CORE_AUDIO_DEVIN_BUFFER0 = 1 << 2, 69 AGS_CORE_AUDIO_DEVIN_BUFFER1 = 1 << 3, 70 AGS_CORE_AUDIO_DEVIN_BUFFER2 = 1 << 4, 71 AGS_CORE_AUDIO_DEVIN_BUFFER3 = 1 << 5, 72 AGS_CORE_AUDIO_DEVIN_BUFFER4 = 1 << 6, 73 AGS_CORE_AUDIO_DEVIN_BUFFER5 = 1 << 7, 74 AGS_CORE_AUDIO_DEVIN_BUFFER6 = 1 << 8, 75 AGS_CORE_AUDIO_DEVIN_BUFFER7 = 1 << 9, 76 77 AGS_CORE_AUDIO_DEVIN_ATTACK_FIRST = 1 << 10, 78 79 AGS_CORE_AUDIO_DEVIN_RECORD = 1 << 11, 80 AGS_CORE_AUDIO_DEVIN_SHUTDOWN = 1 << 12, 81 AGS_CORE_AUDIO_DEVIN_START_RECORD = 1 << 13, 82 83 AGS_CORE_AUDIO_DEVIN_NONBLOCKING = 1 << 14, 84 AGS_CORE_AUDIO_DEVIN_INITIALIZED = 1 << 15, 85 }AgsCoreAudioDevinFlags; 86 87 /** 88 * AgsCoreAudioDevinSyncFlags: 89 * @AGS_CORE_AUDIO_DEVIN_PASS_THROUGH: do not sync 90 * @AGS_CORE_AUDIO_DEVIN_INITIAL_CALLBACK: initial callback 91 * @AGS_CORE_AUDIO_DEVIN_CALLBACK_WAIT: sync wait, soundcard conditional lock 92 * @AGS_CORE_AUDIO_DEVIN_CALLBACK_DONE: sync done, soundcard conditional lock 93 * @AGS_CORE_AUDIO_DEVIN_CALLBACK_FINISH_WAIT: sync wait, client conditional lock 94 * @AGS_CORE_AUDIO_DEVIN_CALLBACK_FINISH_DONE: sync done, client conditional lock 95 * 96 * Enum values to control the synchronization between soundcard and client. 97 */ 98 typedef enum{ 99 AGS_CORE_AUDIO_DEVIN_PASS_THROUGH = 1, 100 AGS_CORE_AUDIO_DEVIN_INITIAL_CALLBACK = 1 << 1, 101 AGS_CORE_AUDIO_DEVIN_CALLBACK_WAIT = 1 << 2, 102 AGS_CORE_AUDIO_DEVIN_CALLBACK_DONE = 1 << 3, 103 AGS_CORE_AUDIO_DEVIN_CALLBACK_FINISH_WAIT = 1 << 4, 104 AGS_CORE_AUDIO_DEVIN_CALLBACK_FINISH_DONE = 1 << 5, 105 }AgsCoreAudioDevinSyncFlags; 106 107 #define AGS_CORE_AUDIO_DEVIN_ERROR (ags_core_audio_devin_error_quark()) 108 109 typedef enum{ 110 AGS_CORE_AUDIO_DEVIN_ERROR_LOCKED_SOUNDCARD, 111 }AgsCoreAudioDevinError; 112 113 struct _AgsCoreAudioDevin 114 { 115 GObject gobject; 116 117 guint flags; 118 volatile guint sync_flags; 119 120 GRecMutex obj_mutex; 121 122 AgsUUID *uuid; 123 124 guint dsp_channels; 125 guint pcm_channels; 126 guint format; 127 guint buffer_size; 128 guint samplerate; 129 130 GRecMutex **buffer_mutex; 131 void** buffer; 132 133 double bpm; // beats per minute 134 gdouble delay_factor; 135 136 gdouble *delay; // count of tics within buffer size 137 guint *attack; // where currently tic resides in the stream's offset, measured in 1/64 of bpm 138 139 gdouble tact_counter; 140 gdouble delay_counter; // next time attack changeing when delay_counter == delay 141 guint tic_counter; // in the range of default period 142 143 guint start_note_offset; 144 guint note_offset; 145 guint note_offset_absolute; 146 147 guint loop_left; 148 guint loop_right; 149 gboolean do_loop; 150 151 guint loop_offset; 152 153 gchar *card_uri; 154 GObject *core_audio_client; 155 156 gchar **port_name; 157 GList *core_audio_port; 158 159 GMutex callback_mutex; 160 GCond callback_cond; 161 162 GMutex callback_finish_mutex; 163 GCond callback_finish_cond; 164 }; 165 166 struct _AgsCoreAudioDevinClass 167 { 168 GObjectClass gobject; 169 }; 170 171 GType ags_core_audio_devin_get_type(); 172 173 GQuark ags_core_audio_devin_error_quark(); 174 175 gboolean ags_core_audio_devin_test_flags(AgsCoreAudioDevin *core_audio_devin, guint flags); 176 void ags_core_audio_devin_set_flags(AgsCoreAudioDevin *core_audio_devin, guint flags); 177 void ags_core_audio_devin_unset_flags(AgsCoreAudioDevin *core_audio_devin, guint flags); 178 179 void ags_core_audio_devin_switch_buffer_flag(AgsCoreAudioDevin *core_audio_devin); 180 181 void ags_core_audio_devin_adjust_delay_and_attack(AgsCoreAudioDevin *core_audio_devin); 182 void ags_core_audio_devin_realloc_buffer(AgsCoreAudioDevin *core_audio_devin); 183 184 AgsCoreAudioDevin* ags_core_audio_devin_new(); 185 186 G_END_DECLS 187 188 #endif /*__AGS_CORE_AUDIO_DEVIN_H__*/ 189