/* GSequencer - Advanced GTK Sequencer * Copyright (C) 2005-2019 Joël Krähemann * * This file is part of GSequencer. * * GSequencer is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GSequencer is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GSequencer. If not, see . */ #ifndef __AGS_CORE_AUDIO_DEVOUT_H__ #define __AGS_CORE_AUDIO_DEVOUT_H__ #include #include #include G_BEGIN_DECLS #define AGS_TYPE_CORE_AUDIO_DEVOUT (ags_core_audio_devout_get_type()) #define AGS_CORE_AUDIO_DEVOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), AGS_TYPE_CORE_AUDIO_DEVOUT, AgsCoreAudioDevout)) #define AGS_CORE_AUDIO_DEVOUT_CLASS(class) (G_TYPE_CHECK_CLASS_CAST(class, AGS_TYPE_CORE_AUDIO_DEVOUT, AgsCoreAudioDevout)) #define AGS_IS_CORE_AUDIO_DEVOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), AGS_TYPE_CORE_AUDIO_DEVOUT)) #define AGS_IS_CORE_AUDIO_DEVOUT_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), AGS_TYPE_CORE_AUDIO_DEVOUT)) #define AGS_CORE_AUDIO_DEVOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS(obj, AGS_TYPE_CORE_AUDIO_DEVOUT, AgsCoreAudioDevoutClass)) #define AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(obj) (&(((AgsCoreAudioDevout *) obj)->obj_mutex)) typedef struct _AgsCoreAudioDevout AgsCoreAudioDevout; typedef struct _AgsCoreAudioDevoutClass AgsCoreAudioDevoutClass; /** * AgsCoreAudioDevoutFlags: * @AGS_CORE_AUDIO_DEVOUT_ADDED_TO_REGISTRY: the core-audio devout was added to registry, see #AgsConnectable::add_to_registry() * @AGS_CORE_AUDIO_DEVOUT_CONNECTED: indicates the core-audio devout was connected by calling #AgsConnectable::connect() * @AGS_CORE_AUDIO_DEVOUT_BUFFER0: ring-buffer 0 * @AGS_CORE_AUDIO_DEVOUT_BUFFER1: ring-buffer 1 * @AGS_CORE_AUDIO_DEVOUT_BUFFER2: ring-buffer 2 * @AGS_CORE_AUDIO_DEVOUT_BUFFER3: ring-buffer 3 * @AGS_CORE_AUDIO_DEVOUT_BUFFER4: ring-buffer 4 * @AGS_CORE_AUDIO_DEVOUT_BUFFER5: ring-buffer 5 * @AGS_CORE_AUDIO_DEVOUT_BUFFER6: ring-buffer 6 * @AGS_CORE_AUDIO_DEVOUT_BUFFER7: ring-buffer 7 * @AGS_CORE_AUDIO_DEVOUT_ATTACK_FIRST: use first attack, instead of second one * @AGS_CORE_AUDIO_DEVOUT_PLAY: do playback * @AGS_CORE_AUDIO_DEVOUT_SHUTDOWN: stop playback * @AGS_CORE_AUDIO_DEVOUT_START_PLAY: playback starting * @AGS_CORE_AUDIO_DEVOUT_NONBLOCKING: do non-blocking calls * @AGS_CORE_AUDIO_DEVOUT_INITIALIZED: the soundcard was initialized * * Enum values to control the behavior or indicate internal state of #AgsCoreAudioDevout by * enable/disable as flags. */ typedef enum{ AGS_CORE_AUDIO_DEVOUT_ADDED_TO_REGISTRY = 1, AGS_CORE_AUDIO_DEVOUT_CONNECTED = 1 << 1, AGS_CORE_AUDIO_DEVOUT_BUFFER0 = 1 << 2, AGS_CORE_AUDIO_DEVOUT_BUFFER1 = 1 << 3, AGS_CORE_AUDIO_DEVOUT_BUFFER2 = 1 << 4, AGS_CORE_AUDIO_DEVOUT_BUFFER3 = 1 << 5, AGS_CORE_AUDIO_DEVOUT_BUFFER4 = 1 << 6, AGS_CORE_AUDIO_DEVOUT_BUFFER5 = 1 << 7, AGS_CORE_AUDIO_DEVOUT_BUFFER6 = 1 << 8, AGS_CORE_AUDIO_DEVOUT_BUFFER7 = 1 << 9, AGS_CORE_AUDIO_DEVOUT_ATTACK_FIRST = 1 << 10, AGS_CORE_AUDIO_DEVOUT_PLAY = 1 << 11, AGS_CORE_AUDIO_DEVOUT_SHUTDOWN = 1 << 12, AGS_CORE_AUDIO_DEVOUT_START_PLAY = 1 << 13, AGS_CORE_AUDIO_DEVOUT_NONBLOCKING = 1 << 14, AGS_CORE_AUDIO_DEVOUT_INITIALIZED = 1 << 15, }AgsCoreAudioDevoutFlags; /** * AgsCoreAudioDevoutSyncFlags: * @AGS_CORE_AUDIO_DEVOUT_PASS_THROUGH: do not sync * @AGS_CORE_AUDIO_DEVOUT_INITIAL_CALLBACK: initial callback * @AGS_CORE_AUDIO_DEVOUT_CALLBACK_WAIT: sync wait, soundcard conditional lock * @AGS_CORE_AUDIO_DEVOUT_CALLBACK_DONE: sync done, soundcard conditional lock * @AGS_CORE_AUDIO_DEVOUT_CALLBACK_FINISH_WAIT: sync wait, client conditional lock * @AGS_CORE_AUDIO_DEVOUT_CALLBACK_FINISH_DONE: sync done, client conditional lock * * Enum values to control the synchronization between soundcard and client. */ typedef enum{ AGS_CORE_AUDIO_DEVOUT_PASS_THROUGH = 1, AGS_CORE_AUDIO_DEVOUT_INITIAL_CALLBACK = 1 << 1, AGS_CORE_AUDIO_DEVOUT_CALLBACK_WAIT = 1 << 2, AGS_CORE_AUDIO_DEVOUT_CALLBACK_DONE = 1 << 3, AGS_CORE_AUDIO_DEVOUT_CALLBACK_FINISH_WAIT = 1 << 4, AGS_CORE_AUDIO_DEVOUT_CALLBACK_FINISH_DONE = 1 << 5, }AgsCoreAudioDevoutSyncFlags; #define AGS_CORE_AUDIO_DEVOUT_ERROR (ags_core_audio_devout_error_quark()) typedef enum{ AGS_CORE_AUDIO_DEVOUT_ERROR_LOCKED_SOUNDCARD, }AgsCoreAudioDevoutError; struct _AgsCoreAudioDevout { GObject gobject; guint flags; volatile guint sync_flags; GRecMutex obj_mutex; AgsUUID *uuid; guint dsp_channels; guint pcm_channels; guint format; guint buffer_size; guint samplerate; GRecMutex **buffer_mutex; guint sub_block_count; GRecMutex **sub_block_mutex; void** buffer; double bpm; // beats per minute gdouble delay_factor; gdouble *delay; // count of tics within buffer size guint *attack; // where currently tic resides in the stream's offset, measured in 1/64 of bpm gdouble tact_counter; gdouble delay_counter; // next time attack changeing when delay_counter == delay guint tic_counter; // in the range of default period guint start_note_offset; guint note_offset; guint note_offset_absolute; guint loop_left; guint loop_right; gboolean do_loop; guint loop_offset; gchar *card_uri; GObject *core_audio_client; gchar **port_name; GList *core_audio_port; GMutex callback_mutex; GCond callback_cond; GMutex callback_finish_mutex; GCond callback_finish_cond; }; struct _AgsCoreAudioDevoutClass { GObjectClass gobject; }; GType ags_core_audio_devout_get_type(); GQuark ags_core_audio_devout_error_quark(); gboolean ags_core_audio_devout_test_flags(AgsCoreAudioDevout *core_audio_devout, guint flags); void ags_core_audio_devout_set_flags(AgsCoreAudioDevout *core_audio_devout, guint flags); void ags_core_audio_devout_unset_flags(AgsCoreAudioDevout *core_audio_devout, guint flags); void ags_core_audio_devout_switch_buffer_flag(AgsCoreAudioDevout *core_audio_devout); void ags_core_audio_devout_adjust_delay_and_attack(AgsCoreAudioDevout *core_audio_devout); void ags_core_audio_devout_realloc_buffer(AgsCoreAudioDevout *core_audio_devout); AgsCoreAudioDevout* ags_core_audio_devout_new(); G_END_DECLS #endif /*__AGS_CORE_AUDIO_DEVOUT_H__*/