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_MIDIIN_H__ 21 #define __AGS_CORE_AUDIO_MIDIIN_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_MIDIIN (ags_core_audio_midiin_get_type()) 31 #define AGS_CORE_AUDIO_MIDIIN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), AGS_TYPE_CORE_AUDIO_MIDIIN, AgsCoreAudioMidiin)) 32 #define AGS_CORE_AUDIO_MIDIIN_CLASS(class) (G_TYPE_CHECK_CLASS_CAST(class, AGS_TYPE_CORE_AUDIO_MIDIIN, AgsCoreAudioMidiin)) 33 #define AGS_IS_CORE_AUDIO_MIDIIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), AGS_TYPE_CORE_AUDIO_MIDIIN)) 34 #define AGS_IS_CORE_AUDIO_MIDIIN_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), AGS_TYPE_CORE_AUDIO_MIDIIN)) 35 #define AGS_CORE_AUDIO_MIDIIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS(obj, AGS_TYPE_CORE_AUDIO_MIDIIN, AgsCoreAudioMidiinClass)) 36 37 #define AGS_CORE_AUDIO_MIDIIN_GET_OBJ_MUTEX(obj) (&(((AgsCoreAudioMidiin *) obj)->obj_mutex)) 38 39 #define AGS_CORE_AUDIO_MIDIIN_DEFAULT_BUFFER_SIZE (256) 40 41 typedef struct _AgsCoreAudioMidiin AgsCoreAudioMidiin; 42 typedef struct _AgsCoreAudioMidiinClass AgsCoreAudioMidiinClass; 43 44 /** 45 * AgsCoreAudioMidiinFlags: 46 * @AGS_CORE_AUDIO_MIDIIN_ADDED_TO_REGISTRY: the CoreAudio midiin was added to registry, see #AgsConnectable::add_to_registry() 47 * @AGS_CORE_AUDIO_MIDIIN_CONNECTED: indicates the CoreAudio midiin was connected by calling #AgsConnectable::connect() 48 * @AGS_CORE_AUDIO_MIDIIN_BUFFER0: ring-buffer 0 49 * @AGS_CORE_AUDIO_MIDIIN_BUFFER1: ring-buffer 1 50 * @AGS_CORE_AUDIO_MIDIIN_BUFFER2: ring-buffer 2 51 * @AGS_CORE_AUDIO_MIDIIN_BUFFER3: ring-buffer 3 52 * @AGS_CORE_AUDIO_MIDIIN_ATTACK_FIRST: use first attack, instead of second one 53 * @AGS_CORE_AUDIO_MIDIIN_RECORD: is recording 54 * @AGS_CORE_AUDIO_MIDIIN_SHUTDOWN: stop recording 55 * @AGS_CORE_AUDIO_MIDIIN_START_RECORD: just started recording 56 * @AGS_CORE_AUDIO_MIDIIN_NONBLOCKING: do non-blocking calls 57 * @AGS_CORE_AUDIO_MIDIIN_INITIALIZED: recording is initialized 58 * 59 * Enum values to control the behavior or indicate internal state of #AgsCoreAudioMidiin by 60 * enable/disable as flags. 61 */ 62 typedef enum 63 { 64 AGS_CORE_AUDIO_MIDIIN_ADDED_TO_REGISTRY = 1, 65 AGS_CORE_AUDIO_MIDIIN_CONNECTED = 1 << 1, 66 67 AGS_CORE_AUDIO_MIDIIN_BUFFER0 = 1 << 2, 68 AGS_CORE_AUDIO_MIDIIN_BUFFER1 = 1 << 3, 69 AGS_CORE_AUDIO_MIDIIN_BUFFER2 = 1 << 4, 70 AGS_CORE_AUDIO_MIDIIN_BUFFER3 = 1 << 5, 71 72 AGS_CORE_AUDIO_MIDIIN_ATTACK_FIRST = 1 << 6, 73 74 AGS_CORE_AUDIO_MIDIIN_RECORD = 1 << 7, 75 76 AGS_CORE_AUDIO_MIDIIN_SHUTDOWN = 1 << 8, 77 AGS_CORE_AUDIO_MIDIIN_START_RECORD = 1 << 9, 78 79 AGS_CORE_AUDIO_MIDIIN_NONBLOCKING = 1 << 10, 80 AGS_CORE_AUDIO_MIDIIN_INITIALIZED = 1 << 11, 81 }AgsCoreAudioMidiinFlags; 82 83 /** 84 * AgsCoreAudioMidiinSyncFlags: 85 * @AGS_CORE_AUDIO_MIDIIN_PASS_THROUGH: do not sync 86 * @AGS_CORE_AUDIO_MIDIIN_INITIAL_CALLBACK: initial callback 87 * @AGS_CORE_AUDIO_MIDIIN_CALLBACK_WAIT: sync wait, soundcard conditional lock 88 * @AGS_CORE_AUDIO_MIDIIN_CALLBACK_DONE: sync done, soundcard conditional lock 89 * @AGS_CORE_AUDIO_MIDIIN_CALLBACK_FINISH_WAIT: sync wait, client conditional lock 90 * @AGS_CORE_AUDIO_MIDIIN_CALLBACK_FINISH_DONE: sync done, client conditional lock 91 * @AGS_CORE_AUDIO_MIDIIN_DO_SYNC: do synchronize 92 * 93 * Enum values to control the synchronization between soundcard and client. 94 */ 95 typedef enum{ 96 AGS_CORE_AUDIO_MIDIIN_PASS_THROUGH = 1, 97 AGS_CORE_AUDIO_MIDIIN_INITIAL_CALLBACK = 1 << 1, 98 AGS_CORE_AUDIO_MIDIIN_CALLBACK_WAIT = 1 << 2, 99 AGS_CORE_AUDIO_MIDIIN_CALLBACK_DONE = 1 << 3, 100 AGS_CORE_AUDIO_MIDIIN_CALLBACK_FINISH_WAIT = 1 << 4, 101 AGS_CORE_AUDIO_MIDIIN_CALLBACK_FINISH_DONE = 1 << 5, 102 AGS_CORE_AUDIO_MIDIIN_DO_SYNC = 1 << 6, 103 }AgsCoreAudioMidiinSyncFlags; 104 105 #define AGS_CORE_AUDIO_MIDIIN_ERROR (ags_core_audio_midiin_error_quark()) 106 107 typedef enum{ 108 AGS_CORE_AUDIO_MIDIIN_ERROR_LOCKED_SOUNDCARD, 109 }AgsCoreAudioMidiinError; 110 111 struct _AgsCoreAudioMidiin 112 { 113 GObject gobject; 114 115 guint flags; 116 volatile guint sync_flags; 117 118 GRecMutex obj_mutex; 119 120 AgsUUID *uuid; 121 122 GRecMutex **buffer_mutex; 123 char **buffer; 124 guint buffer_size[4]; 125 126 double bpm; // beats per minute 127 128 gdouble delay; 129 gdouble delay_factor; 130 guint latency; 131 132 gdouble tact_counter; 133 gdouble delay_counter; // next time attack changeing when delay_counter == delay 134 guint tic_counter; // in the range of default period 135 136 guint start_note_offset; 137 guint note_offset; 138 guint note_offset_absolute; 139 140 gchar *card_uri; 141 GObject *core_audio_client; 142 143 gchar **port_name; 144 GList *core_audio_port; 145 146 GMutex callback_mutex; 147 GCond callback_cond; 148 149 GMutex callback_finish_mutex; 150 GCond callback_finish_cond; 151 }; 152 153 struct _AgsCoreAudioMidiinClass 154 { 155 GObjectClass gobject; 156 }; 157 158 GType ags_core_audio_midiin_get_type(); 159 160 GQuark ags_core_audio_midiin_error_quark(); 161 162 gboolean ags_core_audio_midiin_test_flags(AgsCoreAudioMidiin *core_audio_midiin, guint flags); 163 void ags_core_audio_midiin_set_flags(AgsCoreAudioMidiin *core_audio_midiin, guint flags); 164 void ags_core_audio_midiin_unset_flags(AgsCoreAudioMidiin *core_audio_midiin, guint flags); 165 166 void ags_core_audio_midiin_switch_buffer_flag(AgsCoreAudioMidiin *core_audio_midiin); 167 168 AgsCoreAudioMidiin* ags_core_audio_midiin_new(); 169 170 G_END_DECLS 171 172 #endif /*__AGS_CORE_AUDIO_MIDIIN_H__*/ 173