|
|
|
/* GSL - Generic Sound Layer
|
|
|
|
* Copyright (C) 2001 Tim Janik
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library 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
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General
|
|
|
|
* Public License along with this library; if not, write to the
|
|
|
|
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
#ifndef __GSL_COMMON_H__
|
|
|
|
#define __GSL_COMMON_H__
|
|
|
|
|
|
|
|
#include <gsl/gsldefs.h>
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif /* __cplusplus */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* --- global initialization --- */
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
const char *value_name;
|
|
|
|
double value;
|
|
|
|
} GslConfigValue;
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
guint n_processors;
|
|
|
|
/* # values to pad around wave chunk blocks per channel */
|
|
|
|
guint wave_chunk_padding;
|
|
|
|
guint wave_chunk_big_pad;
|
|
|
|
/* data (file) cache block size (aligned to power of 2) */
|
|
|
|
guint dcache_block_size;
|
|
|
|
/* amount of bytes to spare for memory cache */
|
|
|
|
guint dcache_cache_memory;
|
|
|
|
guint midi_kammer_note;
|
|
|
|
/* kammer frequency, normally 440Hz, historically 435Hz */
|
|
|
|
gfloat kammer_freq;
|
|
|
|
} GslConfig;
|
|
|
|
typedef struct _GslMutexTable GslMutexTable;
|
|
|
|
void gsl_init (const GslConfigValue values[],
|
|
|
|
GslMutexTable *mtable);
|
|
|
|
const GslConfig* gsl_get_config (void) G_GNUC_CONST;
|
|
|
|
#define GSL_CONFIG(value) ((gsl_get_config () [0]) . value)
|
|
|
|
|
|
|
|
|
|
|
|
/* --- memory allocation --- */
|
|
|
|
#define gsl_new_struct(type, n) ((type*) gsl_alloc_memblock (sizeof (type) * (n)))
|
|
|
|
#define gsl_new_struct0(type, n) ((type*) gsl_alloc_memblock0 (sizeof (type) * (n)))
|
|
|
|
#define gsl_delete_struct(type, mem) gsl_delete_structs (type, 1, (mem))
|
|
|
|
#ifndef __GNUC__
|
|
|
|
# define gsl_delete_structs(type, n, mem) (gsl_free_memblock (sizeof (type) * (n), (mem)))
|
|
|
|
#else /* provide typesafety if possible */
|
|
|
|
# define gsl_delete_structs(type, n, mem) do { \
|
|
|
|
type *__typed_pointer = (mem); \
|
|
|
|
gsl_free_memblock (sizeof (type) * (n), __typed_pointer); \
|
|
|
|
} while(0)
|
|
|
|
#endif
|
|
|
|
#define GSL_ALIGNED_SIZE(size,align) ((align) > 0 ? _GSL_INTERN_ALIGN (((gsize) (size)), ((gsize) (align))) : (gsize) (size))
|
|
|
|
#define _GSL_INTERN_ALIGN(s, a) (((s + (a - 1)) / a) * a)
|
|
|
|
#define GSL_STD_ALIGN (MAX (MAX (sizeof (float), sizeof (int)), sizeof (void*)))
|
|
|
|
|
|
|
|
|
|
|
|
/* --- ring (circular-list) --- */
|
|
|
|
struct _GslRing
|
|
|
|
{
|
|
|
|
GslRing *next;
|
|
|
|
GslRing *prev;
|
|
|
|
gpointer data;
|
|
|
|
};
|
|
|
|
GslRing* gsl_ring_prepend (GslRing *head,
|
|
|
|
gpointer data);
|
|
|
|
GslRing* gsl_ring_prepend_uniq (GslRing *head,
|
|
|
|
gpointer data);
|
|
|
|
GslRing* gsl_ring_append (GslRing *head,
|
|
|
|
gpointer data);
|
|
|
|
GslRing* gsl_ring_insert_sorted (GslRing *head,
|
|
|
|
gpointer data,
|
|
|
|
GCompareFunc func);
|
|
|
|
GslRing* gsl_ring_remove_node (GslRing *head,
|
|
|
|
GslRing *node);
|
|
|
|
GslRing* gsl_ring_remove (GslRing *head,
|
|
|
|
gpointer data);
|
|
|
|
guint gsl_ring_length (GslRing *head);
|
|
|
|
GslRing* gsl_ring_concat (GslRing *head1,
|
|
|
|
GslRing *head2);
|
|
|
|
GslRing* gsl_ring_find (GslRing *head,
|
|
|
|
gconstpointer data);
|
|
|
|
GslRing* gsl_ring_nth (GslRing *head,
|
|
|
|
guint n);
|
|
|
|
gpointer gsl_ring_nth_data (GslRing *head,
|
|
|
|
guint n);
|
|
|
|
gpointer gsl_ring_pop_head (GslRing **head);
|
|
|
|
gpointer gsl_ring_pop_tail (GslRing **head);
|
|
|
|
#define gsl_ring_push_head gsl_ring_prepend
|
|
|
|
#define gsl_ring_push_tail gsl_ring_append
|
|
|
|
void gsl_ring_free (GslRing *head);
|
|
|
|
#define gsl_ring_walk(head,node) ((node) != (head)->prev ? (node)->next : NULL)
|
|
|
|
|
|
|
|
|
|
|
|
/* --- GslMessage and debugging --- */
|
|
|
|
typedef enum /*< skip >*/
|
|
|
|
{
|
|
|
|
GSL_MSG_NOTIFY = 1 << 0,
|
|
|
|
GSL_MSG_DATA_CACHE = 1 << 1,
|
|
|
|
GSL_MSG_DATA_HANDLE = 1 << 2,
|
|
|
|
GSL_MSG_LOADER = 1 << 3,
|
|
|
|
GSL_MSG_OSC = 1 << 4,
|
|
|
|
GSL_MSG_ENGINE = 1 << 5,
|
|
|
|
GSL_MSG_JOBS = 1 << 6,
|
|
|
|
GSL_MSG_FJOBS = 1 << 7,
|
|
|
|
GSL_MSG_SCHED = 1 << 8,
|
|
|
|
GSL_MSG_MASTER = 1 << 9,
|
|
|
|
GSL_MSG_SLAVE = 1 << 10
|
|
|
|
} GslDebugFlags;
|
|
|
|
extern const GDebugKey *gsl_debug_keys;
|
|
|
|
extern const guint gsl_n_debug_keys;
|
|
|
|
void gsl_debug (GslDebugFlags reporter,
|
|
|
|
const gchar *section,
|
|
|
|
const gchar *format,
|
|
|
|
...) G_GNUC_PRINTF (3, 4);
|
|
|
|
void gsl_debug_enable (GslDebugFlags dbg_flags);
|
|
|
|
void gsl_debug_disable (GslDebugFlags dbg_flags);
|
|
|
|
gboolean gsl_debug_check (GslDebugFlags dbg_flags);
|
|
|
|
void gsl_message_send (GslDebugFlags reporter,
|
|
|
|
const gchar *section, /* maybe NULL */
|
|
|
|
GslErrorType error, /* maybe 0 */
|
|
|
|
const gchar *messagef,
|
|
|
|
...) G_GNUC_PRINTF (4, 5);
|
|
|
|
const gchar* gsl_strerror (GslErrorType error);
|
|
|
|
|
|
|
|
/* provide message/debugging macro templates, so custom messages
|
|
|
|
* are done as:
|
|
|
|
* #define FOO_DEBUG GSL_DEBUG_FUNCTION (GSL_MSG_LOADER, "FOO")
|
|
|
|
* FOO_DEBUG ("some debug message and number: %d", 5);
|
|
|
|
*/
|
|
|
|
#define GSL_DEBUG_FUNCTION(reporter, section) _GSL_DEBUG_MACRO_IMPL((reporter), (section))
|
|
|
|
#define GSL_MESSAGE_FUNCTION(reporter, section) _GSL_MESSAGE_MACRO_IMPL((reporter), (section))
|
|
|
|
|
|
|
|
|
|
|
|
/* --- GslThread --- */
|
|
|
|
typedef void (*GslThreadFunc) (gpointer user_data);
|
|
|
|
GslThread* gsl_thread_new (GslThreadFunc func,
|
|
|
|
gpointer user_data);
|
|
|
|
guint gsl_threads_get_count (void);
|
|
|
|
GslThread* gsl_thread_self (void);
|
|
|
|
GslThread* gsl_thread_main (void);
|
|
|
|
|
|
|
|
|
|
|
|
/* --- tick stamps --- */
|
|
|
|
typedef struct {
|
|
|
|
guint64 tick_stamp;
|
|
|
|
guint64 system_time;
|
|
|
|
} GslTickStampUpdate;
|
|
|
|
guint64 gsl_tick_stamp (void);
|
|
|
|
guint64 gsl_time_system (void);
|
|
|
|
GslTickStampUpdate gsl_tick_stamp_last (void);
|
|
|
|
#define GSL_TICK_STAMP (_GSL_TICK_STAMP_VAL ())
|
|
|
|
#define GSL_MAX_TICK_STAMP (G_MAXUINT64)
|
|
|
|
|
|
|
|
|
|
|
|
/* --- thread syncronization --- */
|
|
|
|
gboolean gsl_thread_sleep (glong max_msec);
|
|
|
|
gboolean gsl_thread_aborted (void);
|
|
|
|
void gsl_thread_queue_abort (GslThread *thread);
|
|
|
|
void gsl_thread_abort (GslThread *thread);
|
|
|
|
void gsl_thread_wakeup (GslThread *thread);
|
|
|
|
void gsl_thread_awake_after (guint64 tick_stamp);
|
|
|
|
void gsl_thread_awake_before (guint64 tick_stamp);
|
|
|
|
void gsl_thread_get_pollfd (GPollFD *pfd);
|
|
|
|
|
|
|
|
|
|
|
|
/* --- GslMutex --- */
|
|
|
|
#define gsl_mutex_init(mutex) (gsl_mutex_table.mutex_init (mutex))
|
|
|
|
#define GSL_SPIN_LOCK(mutex) (gsl_mutex_table.mutex_lock (mutex))
|
|
|
|
#define GSL_SPIN_UNLOCK(mutex) (gsl_mutex_table.mutex_unlock (mutex))
|
|
|
|
#define GSL_SYNC_LOCK(mutex) (gsl_mutex_table.mutex_lock (mutex))
|
|
|
|
#define GSL_SYNC_UNLOCK(mutex) (gsl_mutex_table.mutex_unlock (mutex))
|
|
|
|
#define gsl_mutex_trylock(mutex) (!gsl_mutex_table.mutex_trylock (mutex))
|
|
|
|
#define gsl_mutex_destroy(mutex) (gsl_mutex_table.mutex_destroy (mutex))
|
|
|
|
#define gsl_rec_mutex_init(rmutex) (gsl_mutex_table.rec_mutex_init (rmutex))
|
|
|
|
#define gsl_rec_mutex_lock(rmutex) (gsl_mutex_table.rec_mutex_lock (rmutex))
|
|
|
|
#define gsl_rec_mutex_unlock(rmutex) (gsl_mutex_table.rec_mutex_unlock (rmutex))
|
|
|
|
#define gsl_rec_mutex_trylock(rmutex) (!gsl_mutex_table.rec_mutex_trylock (rmutex))
|
|
|
|
#define gsl_rec_mutex_destroy(rmutex) (gsl_mutex_table.rec_mutex_destroy (rmutex))
|
|
|
|
#define gsl_cond_init(cond) (gsl_mutex_table.cond_init (cond))
|
|
|
|
#define gsl_cond_signal(cond) (gsl_mutex_table.cond_signal (cond))
|
|
|
|
#define gsl_cond_broadcast(cond) (gsl_mutex_table.cond_broadcast (cond))
|
|
|
|
#define gsl_cond_wait(cond, mutex) (gsl_mutex_table.cond_wait ((cond), (mutex)))
|
|
|
|
#define gsl_cond_destroy(cond) (gsl_mutex_table.cond_destroy (cond))
|
|
|
|
void gsl_cond_wait_timed (GslCond *cond,
|
|
|
|
GslMutex *mutex,
|
|
|
|
glong max_useconds);
|
|
|
|
struct _GslMutexTable
|
|
|
|
{
|
|
|
|
void (*mutex_init) (GslMutex *mutex);
|
|
|
|
void (*mutex_lock) (GslMutex *mutex);
|
|
|
|
int (*mutex_trylock) (GslMutex *mutex); /* 0==has_lock */
|
|
|
|
void (*mutex_unlock) (GslMutex *mutex);
|
|
|
|
void (*mutex_destroy) (GslMutex *mutex);
|
|
|
|
void (*rec_mutex_init) (GslRecMutex *mutex);
|
|
|
|
void (*rec_mutex_lock) (GslRecMutex *mutex);
|
|
|
|
int (*rec_mutex_trylock) (GslRecMutex *mutex); /* 0==has_lock */
|
|
|
|
void (*rec_mutex_unlock) (GslRecMutex *mutex);
|
|
|
|
void (*rec_mutex_destroy) (GslRecMutex *mutex);
|
|
|
|
void (*cond_init) (GslCond *cond);
|
|
|
|
void (*cond_signal) (GslCond *cond);
|
|
|
|
void (*cond_broadcast) (GslCond *cond);
|
|
|
|
void (*cond_wait) (GslCond *cond,
|
|
|
|
GslMutex *mutex);
|
|
|
|
void (*cond_wait_timed) (GslCond *cond,
|
|
|
|
GslMutex *mutex,
|
|
|
|
gulong abs_secs,
|
|
|
|
gulong abs_usecs);
|
|
|
|
void (*cond_destroy) (GslCond *cond);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* --- misc --- */
|
|
|
|
const gchar* gsl_byte_order_to_string (guint byte_order);
|
|
|
|
guint gsl_byte_order_from_string (const gchar *string);
|
|
|
|
GslErrorType gsl_error_from_errno (gint sys_errno,
|
|
|
|
GslErrorType fallback);
|
|
|
|
GslErrorType gsl_check_file (const gchar *file_name,
|
|
|
|
const gchar *mode);
|
|
|
|
|
|
|
|
|
|
|
|
/* --- implementation details --- */
|
|
|
|
gpointer gsl_alloc_memblock (gsize size);
|
|
|
|
gpointer gsl_alloc_memblock0 (gsize size);
|
|
|
|
void gsl_free_memblock (gsize size,
|
|
|
|
gpointer memblock);
|
|
|
|
void gsl_alloc_report (void);
|
|
|
|
const guint gsl_alloc_upper_power2 (const gulong number);
|
|
|
|
void _gsl_tick_stamp_inc (void);
|
|
|
|
void _gsl_tick_stamp_set_leap (guint ticks);
|
|
|
|
void _gsl_init_signal (void);
|
|
|
|
void _gsl_init_fd_pool (void);
|
|
|
|
void _gsl_init_data_caches (void);
|
|
|
|
void _gsl_init_engine_utils (void);
|
|
|
|
void _gsl_init_loader_gslwave (void);
|
|
|
|
void _gsl_init_loader_wav (void);
|
|
|
|
void _gsl_init_loader_oggvorbis (void);
|
|
|
|
void _gsl_init_loader_mad (void);
|
|
|
|
#define GSL_N_IO_RETRIES (5)
|
|
|
|
#define _GSL_TICK_STAMP_VAL() (gsl_externvar_tick_stamp + 0)
|
|
|
|
extern volatile guint64 gsl_externvar_tick_stamp;
|
|
|
|
extern GslMutexTable gsl_mutex_table;
|
|
|
|
|
|
|
|
/* we need to provide a REPORTER and SECTION string for the debugging
|
|
|
|
* and message generation functions. for GCC, we also want to make use
|
|
|
|
* of printf style format checking with G_GNUC_PRINTF(). for the non GCC
|
|
|
|
* case, we push REPORTER and SECTION as thread specific data before
|
|
|
|
* invoking the debugging/message generation function. for the GCC case
|
|
|
|
* we use GNUC varargs. (using ISO varargs wouldn't provide any benefit,
|
|
|
|
* for one, ISO vararg support is broken with gcc-2.95 and ansi/c++, and
|
|
|
|
* we only need the macro magic for GCC in the first place to make use
|
|
|
|
* of G_GNUC_PRINTF()).
|
|
|
|
*/
|
|
|
|
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
|
|
|
|
#define _GSL_DEBUG_MACRO_IMPL(reporter, section) gsl_debug ((reporter), (section), _GSL_DEBUG_GCCTAIL
|
|
|
|
#define _GSL_DEBUG_GCCTAIL(GCCARGS...) GCCARGS )
|
|
|
|
#define _GSL_MESSAGE_MACRO_IMPL(reporter, section) gsl_message_send ((reporter), (section), _GSL_MESSGAE_GCCTAIL
|
|
|
|
#define _GSL_MESSGAE_GCCTAIL(GCCARGS...) GCCARGS )
|
|
|
|
#else /* non GCC, push data and invoke function */
|
|
|
|
#define _GSL_DEBUG_MACRO_IMPL(reporter, section) (gsl_auxlog_push ((reporter), (section)), gsl_auxlog_debug)
|
|
|
|
#define _GSL_MESSAGE_MACRO_IMPL(reporter, section) (gsl_auxlog_push ((reporter), (section)), gsl_auxlog_message)
|
|
|
|
#endif
|
|
|
|
/* non-GCC message helpers */
|
|
|
|
void gsl_auxlog_push (GslDebugFlags reporter,
|
|
|
|
const gchar *section);
|
|
|
|
void gsl_auxlog_debug (const gchar *format,
|
|
|
|
...);
|
|
|
|
void gsl_auxlog_message (GslErrorType error,
|
|
|
|
const gchar *format,
|
|
|
|
...);
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif /* __cplusplus */
|
|
|
|
|
|
|
|
#endif /* __GSL_COMMON_H__ */
|