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_DEVOUT_H__ 21 #define __AGS_CORE_AUDIO_DEVOUT_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_DEVOUT (ags_core_audio_devout_get_type()) 31 #define AGS_CORE_AUDIO_DEVOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), AGS_TYPE_CORE_AUDIO_DEVOUT, AgsCoreAudioDevout)) 32 #define AGS_CORE_AUDIO_DEVOUT_CLASS(class) (G_TYPE_CHECK_CLASS_CAST(class, AGS_TYPE_CORE_AUDIO_DEVOUT, AgsCoreAudioDevout)) 33 #define AGS_IS_CORE_AUDIO_DEVOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), AGS_TYPE_CORE_AUDIO_DEVOUT)) 34 #define AGS_IS_CORE_AUDIO_DEVOUT_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), AGS_TYPE_CORE_AUDIO_DEVOUT)) 35 #define AGS_CORE_AUDIO_DEVOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS(obj, AGS_TYPE_CORE_AUDIO_DEVOUT, AgsCoreAudioDevoutClass)) 36 37 #define AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(obj) (&(((AgsCoreAudioDevout *) obj)->obj_mutex)) 38 39 typedef struct _AgsCoreAudioDevout AgsCoreAudioDevout; 40 typedef struct _AgsCoreAudioDevoutClass AgsCoreAudioDevoutClass; 41 42 /** 43 * AgsCoreAudioDevoutFlags: 44 * @AGS_CORE_AUDIO_DEVOUT_ADDED_TO_REGISTRY: the core-audio devout was added to registry, see #AgsConnectable::add_to_registry() 45 * @AGS_CORE_AUDIO_DEVOUT_CONNECTED: indicates the core-audio devout was connected by calling #AgsConnectable::connect() 46 * @AGS_CORE_AUDIO_DEVOUT_BUFFER0: ring-buffer 0 47 * @AGS_CORE_AUDIO_DEVOUT_BUFFER1: ring-buffer 1 48 * @AGS_CORE_AUDIO_DEVOUT_BUFFER2: ring-buffer 2 49 * @AGS_CORE_AUDIO_DEVOUT_BUFFER3: ring-buffer 3 50 * @AGS_CORE_AUDIO_DEVOUT_BUFFER4: ring-buffer 4 51 * @AGS_CORE_AUDIO_DEVOUT_BUFFER5: ring-buffer 5 52 * @AGS_CORE_AUDIO_DEVOUT_BUFFER6: ring-buffer 6 53 * @AGS_CORE_AUDIO_DEVOUT_BUFFER7: ring-buffer 7 54 * @AGS_CORE_AUDIO_DEVOUT_ATTACK_FIRST: use first attack, instead of second one 55 * @AGS_CORE_AUDIO_DEVOUT_PLAY: do playback 56 * @AGS_CORE_AUDIO_DEVOUT_SHUTDOWN: stop playback 57 * @AGS_CORE_AUDIO_DEVOUT_START_PLAY: playback starting 58 * @AGS_CORE_AUDIO_DEVOUT_NONBLOCKING: do non-blocking calls 59 * @AGS_CORE_AUDIO_DEVOUT_INITIALIZED: the soundcard was initialized 60 * 61 * Enum values to control the behavior or indicate internal state of #AgsCoreAudioDevout by 62 * enable/disable as flags. 63 */ 64 typedef enum{ 65 AGS_CORE_AUDIO_DEVOUT_ADDED_TO_REGISTRY = 1, 66 AGS_CORE_AUDIO_DEVOUT_CONNECTED = 1 << 1, 67 68 AGS_CORE_AUDIO_DEVOUT_BUFFER0 = 1 << 2, 69 AGS_CORE_AUDIO_DEVOUT_BUFFER1 = 1 << 3, 70 AGS_CORE_AUDIO_DEVOUT_BUFFER2 = 1 << 4, 71 AGS_CORE_AUDIO_DEVOUT_BUFFER3 = 1 << 5, 72 AGS_CORE_AUDIO_DEVOUT_BUFFER4 = 1 << 6, 73 AGS_CORE_AUDIO_DEVOUT_BUFFER5 = 1 << 7, 74 AGS_CORE_AUDIO_DEVOUT_BUFFER6 = 1 << 8, 75 AGS_CORE_AUDIO_DEVOUT_BUFFER7 = 1 << 9, 76 77 AGS_CORE_AUDIO_DEVOUT_ATTACK_FIRST = 1 << 10, 78 79 AGS_CORE_AUDIO_DEVOUT_PLAY = 1 << 11, 80 AGS_CORE_AUDIO_DEVOUT_SHUTDOWN = 1 << 12, 81 AGS_CORE_AUDIO_DEVOUT_START_PLAY = 1 << 13, 82 83 AGS_CORE_AUDIO_DEVOUT_NONBLOCKING = 1 << 14, 84 AGS_CORE_AUDIO_DEVOUT_INITIALIZED = 1 << 15, 85 }AgsCoreAudioDevoutFlags; 86 87 /** 88 * AgsCoreAudioDevoutSyncFlags: 89 * @AGS_CORE_AUDIO_DEVOUT_PASS_THROUGH: do not sync 90 * @AGS_CORE_AUDIO_DEVOUT_INITIAL_CALLBACK: initial callback 91 * @AGS_CORE_AUDIO_DEVOUT_CALLBACK_WAIT: sync wait, soundcard conditional lock 92 * @AGS_CORE_AUDIO_DEVOUT_CALLBACK_DONE: sync done, soundcard conditional lock 93 * @AGS_CORE_AUDIO_DEVOUT_CALLBACK_FINISH_WAIT: sync wait, client conditional lock 94 * @AGS_CORE_AUDIO_DEVOUT_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_DEVOUT_PASS_THROUGH = 1, 100 AGS_CORE_AUDIO_DEVOUT_INITIAL_CALLBACK = 1 << 1, 101 AGS_CORE_AUDIO_DEVOUT_CALLBACK_WAIT = 1 << 2, 102 AGS_CORE_AUDIO_DEVOUT_CALLBACK_DONE = 1 << 3, 103 AGS_CORE_AUDIO_DEVOUT_CALLBACK_FINISH_WAIT = 1 << 4, 104 AGS_CORE_AUDIO_DEVOUT_CALLBACK_FINISH_DONE = 1 << 5, 105 }AgsCoreAudioDevoutSyncFlags; 106 107 #define AGS_CORE_AUDIO_DEVOUT_ERROR (ags_core_audio_devout_error_quark()) 108 109 typedef enum{ 110 AGS_CORE_AUDIO_DEVOUT_ERROR_LOCKED_SOUNDCARD, 111 }AgsCoreAudioDevoutError; 112 113 struct _AgsCoreAudioDevout 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 132 guint sub_block_count; 133 GRecMutex **sub_block_mutex; 134 135 void** buffer; 136 137 double bpm; // beats per minute 138 gdouble delay_factor; 139 140 gdouble *delay; // count of tics within buffer size 141 guint *attack; // where currently tic resides in the stream's offset, measured in 1/64 of bpm 142 143 gdouble tact_counter; 144 gdouble delay_counter; // next time attack changeing when delay_counter == delay 145 guint tic_counter; // in the range of default period 146 147 guint start_note_offset; 148 guint note_offset; 149 guint note_offset_absolute; 150 151 guint loop_left; 152 guint loop_right; 153 gboolean do_loop; 154 155 guint loop_offset; 156 157 gchar *card_uri; 158 GObject *core_audio_client; 159 160 gchar **port_name; 161 GList *core_audio_port; 162 163 GMutex callback_mutex; 164 GCond callback_cond; 165 166 GMutex callback_finish_mutex; 167 GCond callback_finish_cond; 168 }; 169 170 struct _AgsCoreAudioDevoutClass 171 { 172 GObjectClass gobject; 173 }; 174 175 GType ags_core_audio_devout_get_type(); 176 177 GQuark ags_core_audio_devout_error_quark(); 178 179 gboolean ags_core_audio_devout_test_flags(AgsCoreAudioDevout *core_audio_devout, guint flags); 180 void ags_core_audio_devout_set_flags(AgsCoreAudioDevout *core_audio_devout, guint flags); 181 void ags_core_audio_devout_unset_flags(AgsCoreAudioDevout *core_audio_devout, guint flags); 182 183 void ags_core_audio_devout_switch_buffer_flag(AgsCoreAudioDevout *core_audio_devout); 184 185 void ags_core_audio_devout_adjust_delay_and_attack(AgsCoreAudioDevout *core_audio_devout); 186 void ags_core_audio_devout_realloc_buffer(AgsCoreAudioDevout *core_audio_devout); 187 188 AgsCoreAudioDevout* ags_core_audio_devout_new(); 189 190 G_END_DECLS 191 192 #endif /*__AGS_CORE_AUDIO_DEVOUT_H__*/ 193