Change-Id: Ic0b9c377e111cb59ed4859819b810842347e8525 Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>pull/463/head
| @@ -107,7 +107,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| #endif /* _WIN32 && !__CYGWIN__ && !GNU_WIN32 */ | |||
| #if defined(__APPLE__) || defined(__linux__) || defined(__sun__) || defined(sun) || defined(__unix__) || defined(__CYGWIN__) || defined(GNU_WIN32) | |||
| #if defined(__APPLE__) || defined(__linux__) || defined(__sun__) || defined(sun) || defined(__unix__) || defined(__CYGWIN__) || defined(GNU_WIN32) || defined(__QNXNTO__) | |||
| #if defined(__CYGWIN__) || defined(GNU_WIN32) | |||
| #include <stdint.h> | |||
| @@ -0,0 +1,86 @@ | |||
| /* | |||
| Copyright (C) 2004-2008 Grame | |||
| This program 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.1 of the License, or | |||
| (at your option) any later version. | |||
| This program 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 program; if not, write to the Free Software | |||
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| */ | |||
| #ifndef __JackAtomic_linux__ | |||
| #define __JackAtomic_linux__ | |||
| #include "JackTypes.h" | |||
| #ifdef __PPC__ | |||
| static inline int CAS(register UInt32 value, register UInt32 newvalue, register volatile void* addr) | |||
| { | |||
| register int result; | |||
| register UInt32 tmp; | |||
| asm volatile ( | |||
| "# CAS \n" | |||
| " lwarx %4, 0, %1 \n" // creates a reservation on addr | |||
| " cmpw %4, %2 \n" // test value at addr | |||
| " bne- 1f \n" | |||
| " sync \n" // synchronize instructions | |||
| " stwcx. %3, 0, %1 \n" // if the reservation is not altered | |||
| // stores the new value at addr | |||
| " bne- 1f \n" | |||
| " li %0, 1 \n" | |||
| " b 2f \n" | |||
| "1: \n" | |||
| " li %0, 0 \n" | |||
| "2: \n" | |||
| : "=r" (result) | |||
| : "r" (addr), "r" (value), "r" (newvalue), "r" (tmp) | |||
| ); | |||
| return result; | |||
| } | |||
| #endif | |||
| #if defined(__i386__) || defined(__x86_64__) | |||
| #define LOCK "lock ; " | |||
| static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* addr) | |||
| { | |||
| register char ret; | |||
| __asm__ __volatile__ ( | |||
| "# CAS \n\t" | |||
| LOCK "cmpxchg %2, (%1) \n\t" | |||
| "sete %0 \n\t" | |||
| : "=a" (ret) | |||
| : "c" (addr), "d" (newvalue), "a" (value) | |||
| ); | |||
| return ret; | |||
| } | |||
| #endif | |||
| #if !defined(__i386__) && !defined(__x86_64__) && !defined(__PPC__) | |||
| static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* addr) | |||
| { | |||
| return __sync_bool_compare_and_swap ((UInt32*)addr, value, newvalue); | |||
| } | |||
| #endif | |||
| #endif | |||
| @@ -0,0 +1,215 @@ | |||
| /* | |||
| Copyright (C) 2001-2003 Paul Davis | |||
| Copyright (C) 2005 Jussi Laako | |||
| Copyright (C) 2004-2008 Grame | |||
| This program 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.1 of the License, or | |||
| (at your option) any later version. | |||
| This program 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 program; if not, write to the Free Software | |||
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| */ | |||
| #include "JackConstants.h" | |||
| #include "JackTime.h" | |||
| #include "JackTypes.h" | |||
| #include "JackError.h" | |||
| #include <stdint.h> | |||
| #include <stdio.h> | |||
| #include <sys/mman.h> | |||
| #include <sys/time.h> | |||
| #include <sys/types.h> | |||
| #include <sys/stat.h> | |||
| #include <fcntl.h> | |||
| #include <errno.h> | |||
| #include <string.h> | |||
| #include <unistd.h> | |||
| #include <stdlib.h> | |||
| #include <inttypes.h> | |||
| jack_time_t (*_jack_get_microseconds)(void) = 0; | |||
| #if defined(__gnu_linux__) && (defined(__i386__) || defined(__x86_64__)) | |||
| #define HPET_SUPPORT | |||
| #define HPET_MMAP_SIZE 1024 | |||
| #define HPET_CAPS 0x000 | |||
| #define HPET_PERIOD 0x004 | |||
| #define HPET_COUNTER 0x0f0 | |||
| #define HPET_CAPS_COUNTER_64BIT (1 << 13) | |||
| #if defined(__x86_64__) | |||
| typedef uint64_t hpet_counter_t; | |||
| #else | |||
| typedef uint32_t hpet_counter_t; | |||
| #endif | |||
| static int hpet_fd; | |||
| static unsigned char *hpet_ptr; | |||
| static uint32_t hpet_period; /* period length in femto secs */ | |||
| static uint64_t hpet_offset = 0; | |||
| static uint64_t hpet_wrap; | |||
| static hpet_counter_t hpet_previous = 0; | |||
| #endif /* defined(__gnu_linux__) && (__i386__ || __x86_64__) */ | |||
| #ifdef HPET_SUPPORT | |||
| static int jack_hpet_init () | |||
| { | |||
| uint32_t hpet_caps; | |||
| hpet_fd = open("/dev/hpet", O_RDONLY); | |||
| if (hpet_fd < 0) { | |||
| jack_error ("This system has no accessible HPET device (%s)", strerror (errno)); | |||
| return -1; | |||
| } | |||
| hpet_ptr = (unsigned char *) mmap(NULL, HPET_MMAP_SIZE, | |||
| PROT_READ, MAP_SHARED, hpet_fd, 0); | |||
| if (hpet_ptr == MAP_FAILED) { | |||
| jack_error ("This system has no mappable HPET device (%s)", strerror (errno)); | |||
| close (hpet_fd); | |||
| return -1; | |||
| } | |||
| /* this assumes period to be constant. if needed, | |||
| it can be moved to the clock access function | |||
| */ | |||
| hpet_period = *((uint32_t *) (hpet_ptr + HPET_PERIOD)); | |||
| hpet_caps = *((uint32_t *) (hpet_ptr + HPET_CAPS)); | |||
| hpet_wrap = ((hpet_caps & HPET_CAPS_COUNTER_64BIT) && | |||
| (sizeof(hpet_counter_t) == sizeof(uint64_t))) ? | |||
| 0 : ((uint64_t) 1 << 32); | |||
| return 0; | |||
| } | |||
| static jack_time_t jack_get_microseconds_from_hpet (void) | |||
| { | |||
| hpet_counter_t hpet_counter; | |||
| long double hpet_time; | |||
| hpet_counter = *((hpet_counter_t *) (hpet_ptr + HPET_COUNTER)); | |||
| if (hpet_counter < hpet_previous) | |||
| hpet_offset += hpet_wrap; | |||
| hpet_previous = hpet_counter; | |||
| hpet_time = (long double) (hpet_offset + hpet_counter) * | |||
| (long double) hpet_period * (long double) 1e-9; | |||
| return ((jack_time_t) (hpet_time + 0.5)); | |||
| } | |||
| #else | |||
| static int jack_hpet_init () | |||
| { | |||
| jack_error ("This version of JACK or this computer does not have HPET support.\n" | |||
| "Please choose a different clock source."); | |||
| return -1; | |||
| } | |||
| static jack_time_t jack_get_microseconds_from_hpet (void) | |||
| { | |||
| /* never called */ | |||
| return 0; | |||
| } | |||
| #endif /* HPET_SUPPORT */ | |||
| #define HAVE_CLOCK_GETTIME 1 | |||
| #ifndef HAVE_CLOCK_GETTIME | |||
| static jack_time_t jack_get_microseconds_from_system (void) | |||
| { | |||
| jack_time_t jackTime; | |||
| struct timeval tv; | |||
| gettimeofday (&tv, NULL); | |||
| jackTime = (jack_time_t) tv.tv_sec * 1000000 + (jack_time_t) tv.tv_usec; | |||
| return jackTime; | |||
| } | |||
| #else | |||
| static jack_time_t jack_get_microseconds_from_system (void) | |||
| { | |||
| jack_time_t jackTime; | |||
| struct timespec time; | |||
| clock_gettime(CLOCK_MONOTONIC, &time); | |||
| jackTime = (jack_time_t) time.tv_sec * 1e6 + | |||
| (jack_time_t) time.tv_nsec / 1e3; | |||
| return jackTime; | |||
| } | |||
| #endif /* HAVE_CLOCK_GETTIME */ | |||
| SERVER_EXPORT void JackSleep(long usec) | |||
| { | |||
| usleep(usec); | |||
| } | |||
| SERVER_EXPORT void InitTime() | |||
| { | |||
| /* nothing to do on a generic system - we use the system clock */ | |||
| } | |||
| SERVER_EXPORT void EndTime() | |||
| {} | |||
| void SetClockSource(jack_timer_type_t source) | |||
| { | |||
| jack_log("Clock source : %s", ClockSourceName(source)); | |||
| switch (source) | |||
| { | |||
| case JACK_TIMER_HPET: | |||
| if (jack_hpet_init () == 0) { | |||
| _jack_get_microseconds = jack_get_microseconds_from_hpet; | |||
| } else { | |||
| _jack_get_microseconds = jack_get_microseconds_from_system; | |||
| } | |||
| break; | |||
| case JACK_TIMER_SYSTEM_CLOCK: | |||
| default: | |||
| _jack_get_microseconds = jack_get_microseconds_from_system; | |||
| break; | |||
| } | |||
| } | |||
| const char* ClockSourceName(jack_timer_type_t source) | |||
| { | |||
| switch (source) { | |||
| case JACK_TIMER_HPET: | |||
| return "hpet"; | |||
| case JACK_TIMER_SYSTEM_CLOCK: | |||
| #ifdef HAVE_CLOCK_GETTIME | |||
| return "system clock via clock_gettime"; | |||
| #else | |||
| return "system clock via gettimeofday"; | |||
| #endif | |||
| } | |||
| /* what is wrong with gcc ? */ | |||
| return "unknown"; | |||
| } | |||
| SERVER_EXPORT jack_time_t GetMicroSeconds() | |||
| { | |||
| return _jack_get_microseconds(); | |||
| } | |||
| SERVER_EXPORT jack_time_t jack_get_microseconds() | |||
| { | |||
| return _jack_get_microseconds(); | |||
| } | |||
| @@ -0,0 +1,85 @@ | |||
| /* | |||
| Copyright (C) 2004-2008 Grame | |||
| This program 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.1 of the License, or | |||
| (at your option) any later version. | |||
| This program 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 program; if not, write to the Free Software | |||
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| */ | |||
| #ifndef __JackPlatformPlug_linux__ | |||
| #define __JackPlatformPlug_linux__ | |||
| #define jack_server_dir "/dev/shm" | |||
| #define jack_client_dir "/dev/shm" | |||
| #define JACK_DEFAULT_DRIVER "alsa" | |||
| namespace Jack | |||
| { | |||
| struct JackRequest; | |||
| struct JackResult; | |||
| class JackPosixMutex; | |||
| class JackPosixThread; | |||
| class JackFifo; | |||
| class JackSocketServerChannel; | |||
| class JackSocketClientChannel; | |||
| class JackSocketServerNotifyChannel; | |||
| class JackSocketNotifyChannel; | |||
| class JackClientSocket; | |||
| class JackNetUnixSocket; | |||
| } | |||
| /* __JackPlatformMutex__ */ | |||
| #include "JackPosixMutex.h" | |||
| namespace Jack {typedef JackPosixMutex JackMutex; } | |||
| /* __JackPlatformThread__ */ | |||
| #include "JackPosixThread.h" | |||
| namespace Jack { typedef JackPosixThread JackThread; } | |||
| #include "JackFifo.h" | |||
| namespace Jack { typedef JackFifo JackSynchro; } | |||
| /* __JackPlatformChannelTransaction__ */ | |||
| /* | |||
| #include "JackSocket.h" | |||
| namespace Jack { typedef JackClientSocket JackChannelTransaction; } | |||
| */ | |||
| /* __JackPlatformProcessSync__ */ | |||
| #include "JackPosixProcessSync.h" | |||
| namespace Jack { typedef JackPosixProcessSync JackProcessSync; } | |||
| /* __JackPlatformServerChannel__ */ | |||
| #include "JackSocketServerChannel.h" | |||
| namespace Jack { typedef JackSocketServerChannel JackServerChannel; } | |||
| /* __JackPlatformClientChannel__ */ | |||
| #include "JackSocketClientChannel.h" | |||
| namespace Jack { typedef JackSocketClientChannel JackClientChannel; } | |||
| /* __JackPlatformServerNotifyChannel__ */ | |||
| #include "JackSocketServerNotifyChannel.h" | |||
| namespace Jack { typedef JackSocketServerNotifyChannel JackServerNotifyChannel; } | |||
| /* __JackPlatformNotifyChannel__ */ | |||
| #include "JackSocketNotifyChannel.h" | |||
| namespace Jack { typedef JackSocketNotifyChannel JackNotifyChannel; } | |||
| /* __JackPlatformNetSocket__ */ | |||
| #include "JackNetUnixSocket.h" | |||
| namespace Jack { typedef JackNetUnixSocket JackNetSocket; } | |||
| #endif | |||
| @@ -0,0 +1,300 @@ | |||
| /* | |||
| Copyright (C) 2001 Paul Davis | |||
| This program 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 2 of the License, or | |||
| (at your option) any later version. | |||
| This program 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 this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| $Id: driver.h,v 1.2 2005/11/23 11:24:29 letz Exp $ | |||
| */ | |||
| #ifndef __jack_driver_h__ | |||
| #define __jack_driver_h__ | |||
| #include <pthread.h> | |||
| #include "types.h" | |||
| #include "jslist.h" | |||
| #include "driver_interface.h" | |||
| typedef float gain_t; | |||
| typedef long channel_t; | |||
| typedef enum { | |||
| Lock = 0x1, | |||
| NoLock = 0x2, | |||
| Sync = 0x4, | |||
| NoSync = 0x8 | |||
| } ClockSyncStatus; | |||
| typedef void (*ClockSyncListenerFunction)(channel_t, ClockSyncStatus, void*); | |||
| typedef struct | |||
| { | |||
| unsigned long id; | |||
| ClockSyncListenerFunction function; | |||
| void *arg; | |||
| } | |||
| ClockSyncListener; | |||
| struct _jack_engine; | |||
| struct _jack_driver; | |||
| typedef int (*JackDriverAttachFunction)(struct _jack_driver *, | |||
| struct _jack_engine *); | |||
| typedef int (*JackDriverDetachFunction)(struct _jack_driver *, | |||
| struct _jack_engine *); | |||
| typedef int (*JackDriverReadFunction)(struct _jack_driver *, | |||
| jack_nframes_t nframes); | |||
| typedef int (*JackDriverWriteFunction)(struct _jack_driver *, | |||
| jack_nframes_t nframes); | |||
| typedef int (*JackDriverNullCycleFunction)(struct _jack_driver *, | |||
| jack_nframes_t nframes); | |||
| typedef int (*JackDriverStopFunction)(struct _jack_driver *); | |||
| typedef int (*JackDriverStartFunction)(struct _jack_driver *); | |||
| typedef int (*JackDriverBufSizeFunction)(struct _jack_driver *, | |||
| jack_nframes_t nframes); | |||
| /* | |||
| Call sequence summary: | |||
| 1) engine loads driver via runtime dynamic linking | |||
| - calls jack_driver_load | |||
| - we call dlsym for "driver_initialize" and execute it | |||
| 2) engine attaches to driver | |||
| 3) engine starts driver | |||
| 4) driver runs its own thread, calling | |||
| while () { | |||
| driver->wait (); | |||
| driver->engine->run_cycle () | |||
| } | |||
| 5) engine stops driver | |||
| 6) engine detaches from driver | |||
| 7) engine calls driver `finish' routine | |||
| Note that stop/start may be called multiple times in the event of an | |||
| error return from the `wait' function. | |||
| */ | |||
| typedef struct _jack_driver | |||
| { | |||
| /* The _jack_driver structure fields are included at the beginning of | |||
| each driver-specific structure using the JACK_DRIVER_DECL macro, | |||
| which is defined below. The comments that follow describe each | |||
| common field. | |||
| The driver should set this to be the interval it expects to elapse | |||
| between returning from the `wait' function. if set to zero, it | |||
| implies that the driver does not expect regular periodic wakeups. | |||
| jack_time_t period_usecs; | |||
| The driver should set this within its "wait" function to indicate | |||
| the UST of the most recent determination that the engine cycle | |||
| should run. it should not be set if the "extra_fd" argument of | |||
| the wait function is set to a non-zero value. | |||
| jack_time_t last_wait_ust; | |||
| These are not used by the driver. They should not be written to or | |||
| modified in any way | |||
| void *handle; | |||
| struct _jack_internal_client *internal_client; | |||
| This should perform any cleanup associated with the driver. it will | |||
| be called when jack server process decides to get rid of the | |||
| driver. in some systems, it may not be called at all, so the driver | |||
| should never rely on a call to this. it can set it to NULL if | |||
| it has nothing do do. | |||
| void (*finish)(struct _jack_driver *); | |||
| The JACK engine will call this when it wishes to attach itself to | |||
| the driver. the engine will pass a pointer to itself, which the driver | |||
| may use in anyway it wishes to. the driver may assume that this | |||
| is the same engine object that will make `wait' calls until a | |||
| `detach' call is made. | |||
| JackDriverAttachFunction attach; | |||
| The JACK engine will call this when it is finished using a driver. | |||
| JackDriverDetachFunction detach; | |||
| The JACK engine will call this when it wants to wait until the | |||
| driver decides that its time to process some data. the driver returns | |||
| a count of the number of audioframes that can be processed. | |||
| it should set the variable pointed to by `status' as follows: | |||
| zero: the wait completed normally, processing may begin | |||
| negative: the wait failed, and recovery is not possible | |||
| positive: the wait failed, and the driver stopped itself. | |||
| a call to `start' will return the driver to | |||
| a correct and known state. | |||
| the driver should also fill out the `delayed_usecs' variable to | |||
| indicate any delay in its expected periodic execution. for example, | |||
| if it discovers that its return from poll(2) is later than it | |||
| expects it to be, it would place an estimate of the delay | |||
| in this variable. the engine will use this to decide if it | |||
| plans to continue execution. | |||
| JackDriverWaitFunction wait; | |||
| The JACK engine will call this to ask the driver to move | |||
| data from its inputs to its output port buffers. it should | |||
| return 0 to indicate successful completion, negative otherwise. | |||
| This function will always be called after the wait function (above). | |||
| JackDriverReadFunction read; | |||
| The JACK engine will call this to ask the driver to move | |||
| data from its input port buffers to its outputs. it should | |||
| return 0 to indicate successful completion, negative otherwise. | |||
| this function will always be called after the read function (above). | |||
| JackDriverWriteFunction write; | |||
| The JACK engine will call this after the wait function (above) has | |||
| been called, but for some reason the engine is unable to execute | |||
| a full "cycle". the driver should do whatever is necessary to | |||
| keep itself running correctly, but cannot reference ports | |||
| or other JACK data structures in any way. | |||
| JackDriverNullCycleFunction null_cycle; | |||
| The engine will call this when it plans to stop calling the `wait' | |||
| function for some period of time. the driver should take | |||
| appropriate steps to handle this (possibly no steps at all). | |||
| NOTE: the driver must silence its capture buffers (if any) | |||
| from within this function or the function that actually | |||
| implements the change in state. | |||
| JackDriverStopFunction stop; | |||
| The engine will call this to let the driver know that it plans | |||
| to start calling the `wait' function on a regular basis. the driver | |||
| should take any appropriate steps to handle this (possibly no steps | |||
| at all). NOTE: The driver may wish to silence its playback buffers | |||
| (if any) from within this function or the function that actually | |||
| implements the change in state. | |||
| JackDriverStartFunction start; | |||
| The engine will call this to let the driver know that some client | |||
| has requested a new buffer size. The stop function will be called | |||
| prior to this, and the start function after this one has returned. | |||
| JackDriverBufSizeFunction bufsize; | |||
| */ | |||
| /* define the fields here... */ | |||
| #define JACK_DRIVER_DECL \ | |||
| jack_time_t period_usecs; \ | |||
| jack_time_t last_wait_ust; \ | |||
| void *handle; \ | |||
| struct _jack_client_internal * internal_client; \ | |||
| void (*finish)(struct _jack_driver *);\ | |||
| JackDriverAttachFunction attach; \ | |||
| JackDriverDetachFunction detach; \ | |||
| JackDriverReadFunction read; \ | |||
| JackDriverWriteFunction write; \ | |||
| JackDriverNullCycleFunction null_cycle; \ | |||
| JackDriverStopFunction stop; \ | |||
| JackDriverStartFunction start; \ | |||
| JackDriverBufSizeFunction bufsize; | |||
| JACK_DRIVER_DECL /* expand the macro */ | |||
| } | |||
| jack_driver_t; | |||
| void jack_driver_init (jack_driver_t *); | |||
| void jack_driver_release (jack_driver_t *); | |||
| jack_driver_t *jack_driver_load (int argc, char **argv); | |||
| void jack_driver_unload (jack_driver_t *); | |||
| /**************************** | |||
| *** Non-Threaded Drivers *** | |||
| ****************************/ | |||
| /* | |||
| Call sequence summary: | |||
| 1) engine loads driver via runtime dynamic linking | |||
| - calls jack_driver_load | |||
| - we call dlsym for "driver_initialize" and execute it | |||
| - driver_initialize calls jack_driver_nt_init | |||
| 2) nt layer attaches to driver | |||
| 3) nt layer starts driver | |||
| 4) nt layer runs a thread, calling | |||
| while () { | |||
| driver->nt_run_ctcle(); | |||
| } | |||
| 5) nt layer stops driver | |||
| 6) nt layer detaches driver | |||
| 7) engine calls driver `finish' routine which calls jack_driver_nt_finish | |||
| Note that stop/start may be called multiple times in the event of an | |||
| error return from the `wait' function. | |||
| */ | |||
| struct _jack_driver_nt; | |||
| typedef int (*JackDriverNTAttachFunction)(struct _jack_driver_nt *); | |||
| typedef int (*JackDriverNTDetachFunction)(struct _jack_driver_nt *); | |||
| typedef int (*JackDriverNTStopFunction)(struct _jack_driver_nt *); | |||
| typedef int (*JackDriverNTStartFunction)(struct _jack_driver_nt *); | |||
| typedef int (*JackDriverNTBufSizeFunction)(struct _jack_driver_nt *, | |||
| jack_nframes_t nframes); | |||
| typedef int (*JackDriverNTRunCycleFunction)(struct _jack_driver_nt *); | |||
| typedef struct _jack_driver_nt | |||
| { | |||
| #define JACK_DRIVER_NT_DECL \ | |||
| JACK_DRIVER_DECL \ | |||
| struct _jack_engine * engine; \ | |||
| volatile int nt_run; \ | |||
| pthread_t nt_thread; \ | |||
| pthread_mutex_t nt_run_lock; \ | |||
| JackDriverNTAttachFunction nt_attach; \ | |||
| JackDriverNTDetachFunction nt_detach; \ | |||
| JackDriverNTStopFunction nt_stop; \ | |||
| JackDriverNTStartFunction nt_start; \ | |||
| JackDriverNTBufSizeFunction nt_bufsize; \ | |||
| JackDriverNTRunCycleFunction nt_run_cycle; | |||
| #define nt_read read | |||
| #define nt_write write | |||
| #define nt_null_cycle null_cycle | |||
| JACK_DRIVER_NT_DECL | |||
| } | |||
| jack_driver_nt_t; | |||
| void jack_driver_nt_init (jack_driver_nt_t * driver); | |||
| void jack_driver_nt_finish (jack_driver_nt_t * driver); | |||
| #endif /* __jack_driver_h__ */ | |||