| @@ -28,7 +28,7 @@ | |||
| // the GNU General Public License. | |||
| #ifndef _GLIBCXX_ATOMICITY_H | |||
| #define _GLIBCXX_ATOMICITY_H 1 | |||
| #define _GLIBCXX_ATOMICITY_H 1 | |||
| /* @@@ With gas we can play nice .subsection games to get the | |||
| non-predicted branch pointing forward. But Digital assemblers | |||
| @@ -39,38 +39,38 @@ typedef int _Atomic_word; | |||
| static inline _Atomic_word | |||
| __attribute__ ((__unused__)) | |||
| __exchange_and_add(volatile _Atomic_word* __mem, int __val) | |||
| __exchange_and_add (volatile _Atomic_word* __mem, int __val) | |||
| { | |||
| register int __result, __tmp; | |||
| register int __result, __tmp; | |||
| __asm__ __volatile__ ( | |||
| "\n$Lxadd_%=:\n\t" | |||
| "ldl_l %0,%3\n\t" | |||
| "addl %0,%4,%1\n\t" | |||
| "stl_c %1,%2\n\t" | |||
| "beq %1,$Lxadd_%=\n\t" | |||
| "mb" | |||
| : "=&r"(__result), "=&r"(__tmp), "=m"(*__mem) | |||
| : "m" (*__mem), "r"(__val)); | |||
| __asm__ __volatile__ ( | |||
| "\n$Lxadd_%=:\n\t" | |||
| "ldl_l %0,%3\n\t" | |||
| "addl %0,%4,%1\n\t" | |||
| "stl_c %1,%2\n\t" | |||
| "beq %1,$Lxadd_%=\n\t" | |||
| "mb" | |||
| : "=&r" (__result), "=&r" (__tmp), "=m" (*__mem) | |||
| : "m" (*__mem), "r" (__val)); | |||
| return __result; | |||
| return __result; | |||
| } | |||
| static inline void | |||
| __attribute__ ((__unused__)) | |||
| __atomic_add(volatile _Atomic_word* __mem, int __val) | |||
| __atomic_add (volatile _Atomic_word* __mem, int __val) | |||
| { | |||
| register _Atomic_word __result; | |||
| register _Atomic_word __result; | |||
| __asm__ __volatile__ ( | |||
| "\n$Ladd_%=:\n\t" | |||
| "ldl_l %0,%2\n\t" | |||
| "addl %0,%3,%0\n\t" | |||
| "stl_c %0,%1\n\t" | |||
| "beq %0,$Ladd_%=\n\t" | |||
| "mb" | |||
| : "=&r"(__result), "=m"(*__mem) | |||
| : "m" (*__mem), "r"(__val)); | |||
| __asm__ __volatile__ ( | |||
| "\n$Ladd_%=:\n\t" | |||
| "ldl_l %0,%2\n\t" | |||
| "addl %0,%3,%0\n\t" | |||
| "stl_c %0,%1\n\t" | |||
| "beq %0,$Ladd_%=\n\t" | |||
| "mb" | |||
| : "=&r" (__result), "=m" (*__mem) | |||
| : "m" (*__mem), "r" (__val)); | |||
| } | |||
| #endif /* atomicity.h */ | |||
| @@ -1,7 +1,7 @@ | |||
| /* | |||
| Copyright (C) 2001 Paul Davis | |||
| Code derived from various headers from the Linux kernel | |||
| 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 | |||
| @@ -16,7 +16,7 @@ | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| */ | |||
| #ifndef __jack_cycles_h__ | |||
| #define __jack_cycles_h__ | |||
| @@ -27,7 +27,8 @@ typedef unsigned int cycles_t; | |||
| static inline cycles_t get_cycles (void) | |||
| { | |||
| cycles_t ret; | |||
| __asm__ __volatile__ ("rpcc %0" : "=r"(ret)); | |||
| __asm__ __volatile__ ("rpcc %0" : "=r" (ret)); | |||
| return ret; | |||
| } | |||
| @@ -28,51 +28,51 @@ | |||
| // the GNU General Public License. | |||
| #ifndef _GLIBCXX_ATOMICITY_H | |||
| #define _GLIBCXX_ATOMICITY_H 1 | |||
| #define _GLIBCXX_ATOMICITY_H 1 | |||
| // This entity must not cross a page boundary. | |||
| typedef int _Atomic_word __attribute__ ((__aligned__ (4))); | |||
| static inline _Atomic_word | |||
| __attribute__ ((__unused__)) | |||
| __exchange_and_add(_Atomic_word* __mem, int __val) | |||
| __exchange_and_add (_Atomic_word* __mem, int __val) | |||
| { | |||
| int __tmp; | |||
| _Atomic_word __result; | |||
| int __tmp; | |||
| _Atomic_word __result; | |||
| #if (__CRIS_arch_version >= 10) | |||
| __asm__ __volatile__ (" clearf \n" | |||
| "0: \n" | |||
| " move.d %4,%2 \n" | |||
| " move.d [%3],%0 \n" | |||
| " add.d %0,%2 \n" | |||
| " ax \n" | |||
| " move.d %2,[%3] \n" | |||
| " bwf 0b \n" | |||
| " clearf \n" | |||
| : "=&r" (__result), "=m" (*__mem), "=&r" (__tmp) | |||
| : "r" (__mem), "g" (__val), "m" (*__mem)); | |||
| __asm__ __volatile__ (" clearf \n" | |||
| "0: \n" | |||
| " move.d %4,%2 \n" | |||
| " move.d [%3],%0 \n" | |||
| " add.d %0,%2 \n" | |||
| " ax \n" | |||
| " move.d %2,[%3] \n" | |||
| " bwf 0b \n" | |||
| " clearf \n" | |||
| : "=&r" (__result), "=m" (*__mem), "=&r" (__tmp) | |||
| : "r" (__mem), "g" (__val), "m" (*__mem)); | |||
| #else | |||
| __asm__ __volatile__ (" move $ccr,$r9 \n" | |||
| " di \n" | |||
| " move.d %4,%2 \n" | |||
| " move.d [%3],%0 \n" | |||
| " add.d %0,%2 \n" | |||
| " move.d %2,[%3] \n" | |||
| " move $r9,$ccr \n" | |||
| : "=&r" (__result), "=m" (*__mem), "=&r" (__tmp) | |||
| : "r" (__mem), "g" (__val), "m" (*__mem) | |||
| : "r9"); | |||
| __asm__ __volatile__ (" move $ccr,$r9 \n" | |||
| " di \n" | |||
| " move.d %4,%2 \n" | |||
| " move.d [%3],%0 \n" | |||
| " add.d %0,%2 \n" | |||
| " move.d %2,[%3] \n" | |||
| " move $r9,$ccr \n" | |||
| : "=&r" (__result), "=m" (*__mem), "=&r" (__tmp) | |||
| : "r" (__mem), "g" (__val), "m" (*__mem) | |||
| : "r9"); | |||
| #endif | |||
| return __result; | |||
| return __result; | |||
| } | |||
| static inline void | |||
| __attribute__ ((__unused__)) | |||
| __atomic_add(_Atomic_word* __mem, int __val) | |||
| __atomic_add (_Atomic_word* __mem, int __val) | |||
| { | |||
| __exchange_and_add(__mem, __val); | |||
| __exchange_and_add (__mem, __val); | |||
| } | |||
| #endif /* atomicity.h */ | |||
| @@ -18,22 +18,22 @@ | |||
| 02111-1307 USA. */ | |||
| #ifndef _ATOMICITY_H | |||
| #define _ATOMICITY_H 1 | |||
| #define _ATOMICITY_H 1 | |||
| typedef int _Atomic_word; | |||
| static inline _Atomic_word | |||
| static inline _Atomic_word | |||
| __attribute__ ((__unused__)) | |||
| __exchange_and_add(volatile _Atomic_word* mem, int val) | |||
| __exchange_and_add (volatile _Atomic_word* mem, int val) | |||
| { | |||
| return __sync_fetch_and_add(mem, val); | |||
| return __sync_fetch_and_add (mem, val); | |||
| } | |||
| static inline void | |||
| __attribute__ ((__unused__)) | |||
| __atomic_add(volatile _Atomic_word* mem, int val) | |||
| __atomic_add (volatile _Atomic_word* mem, int val) | |||
| { | |||
| __sync_add_and_fetch(mem, val); | |||
| __sync_add_and_fetch (mem, val); | |||
| } | |||
| #endif /* atomicity.h */ | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| 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 | |||
| @@ -15,7 +15,7 @@ | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| */ | |||
| #ifndef __jack_cycles_h__ | |||
| #define __jack_cycles_h__ | |||
| @@ -26,12 +26,13 @@ | |||
| typedef long cycles_t; | |||
| static inline cycles_t get_cycles(void) | |||
| static inline cycles_t get_cycles (void) | |||
| { | |||
| struct timespec time; | |||
| clock_gettime(CLOCK_REALTIME, &time); | |||
| struct timespec time; | |||
| clock_gettime (CLOCK_REALTIME, &time); | |||
| return ((cycles_t) time.tv_sec * 1000000) + time.tv_nsec*1000; | |||
| return ((cycles_t)time.tv_sec * 1000000) + time.tv_nsec * 1000; | |||
| } | |||
| #endif /* __jack_cycles_h__ */ | |||
| @@ -26,27 +26,28 @@ | |||
| // the GNU General Public License. | |||
| #ifndef _GLIBCXX_ATOMICITY_H | |||
| #define _GLIBCXX_ATOMICITY_H 1 | |||
| #define _GLIBCXX_ATOMICITY_H 1 | |||
| typedef int _Atomic_word; | |||
| static inline _Atomic_word | |||
| static inline _Atomic_word | |||
| __attribute__ ((__unused__)) | |||
| __exchange_and_add(volatile _Atomic_word* __mem, int __val) | |||
| __exchange_and_add (volatile _Atomic_word* __mem, int __val) | |||
| { | |||
| register _Atomic_word __result; | |||
| __asm__ __volatile__ ("lock; xaddl %0,%1" | |||
| : "=r" (__result), "=m" (*__mem) | |||
| : "0" (__val), "m" (*__mem)); | |||
| return __result; | |||
| register _Atomic_word __result; | |||
| __asm__ __volatile__ ("lock; xaddl %0,%1" | |||
| : "=r" (__result), "=m" (*__mem) | |||
| : "0" (__val), "m" (*__mem)); | |||
| return __result; | |||
| } | |||
| static inline void | |||
| __attribute__ ((__unused__)) | |||
| __atomic_add(volatile _Atomic_word* __mem, int __val) | |||
| __atomic_add (volatile _Atomic_word* __mem, int __val) | |||
| { | |||
| __asm__ __volatile__ ("lock; addl %1,%0" | |||
| : "=m" (*__mem) : "ir" (__val), "m" (*__mem)); | |||
| __asm__ __volatile__ ("lock; addl %1,%0" | |||
| : "=m" (*__mem) : "ir" (__val), "m" (*__mem)); | |||
| } | |||
| #endif /* atomicity.h */ | |||
| @@ -1,7 +1,7 @@ | |||
| /* | |||
| Copyright (C) 2001 Paul Davis | |||
| Code derived from various headers from the Linux kernel | |||
| 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 | |||
| @@ -16,7 +16,7 @@ | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| */ | |||
| #ifndef __jack_cycles_h__ | |||
| #define __jack_cycles_h__ | |||
| @@ -26,7 +26,8 @@ typedef unsigned long long cycles_t; | |||
| static inline cycles_t get_cycles (void) | |||
| { | |||
| unsigned long long ret; | |||
| __asm__ __volatile__("rdtsc" : "=A" (ret)); | |||
| __asm__ __volatile__ ("rdtsc" : "=A" (ret)); | |||
| return ret; | |||
| } | |||
| @@ -34,18 +34,18 @@ | |||
| typedef int _Atomic_word; | |||
| static inline _Atomic_word | |||
| static inline _Atomic_word | |||
| __attribute__ ((__unused__)) | |||
| __exchange_and_add(volatile _Atomic_word* __mem, int __val) | |||
| __exchange_and_add (volatile _Atomic_word* __mem, int __val) | |||
| { | |||
| return __sync_fetch_and_add(__mem, __val); | |||
| return __sync_fetch_and_add (__mem, __val); | |||
| } | |||
| static inline void | |||
| __attribute__ ((__unused__)) | |||
| __atomic_add(volatile _Atomic_word* __mem, int __val) | |||
| __atomic_add (volatile _Atomic_word* __mem, int __val) | |||
| { | |||
| __sync_fetch_and_add(__mem, __val); | |||
| __sync_fetch_and_add (__mem, __val); | |||
| } | |||
| #endif /* atomicity.h */ | |||
| @@ -1,7 +1,7 @@ | |||
| /* | |||
| Copyright (C) 2001 Paul Davis | |||
| Code derived from various headers from the Linux kernel | |||
| 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 | |||
| @@ -16,7 +16,7 @@ | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| */ | |||
| #ifndef __jack_cycles_h__ | |||
| #define __jack_cycles_h__ | |||
| @@ -28,7 +28,8 @@ static inline cycles_t | |||
| get_cycles (void) | |||
| { | |||
| cycles_t ret; | |||
| __asm__ __volatile__ ("mov %0=ar.itc" : "=r"(ret)); | |||
| __asm__ __volatile__ ("mov %0=ar.itc" : "=r" (ret)); | |||
| return ret; | |||
| } | |||
| @@ -7,121 +7,121 @@ | |||
| extern "C" { | |||
| #endif | |||
| extern void __sync_synchronize (void); | |||
| extern void __sync_synchronize(void); | |||
| extern int __sync_val_compare_and_swap_si (int *, int, int); | |||
| extern long __sync_val_compare_and_swap_di (long *, long, long); | |||
| extern int __sync_val_compare_and_swap_si(int *, int, int); | |||
| extern long __sync_val_compare_and_swap_di(long *, long, long); | |||
| #define __sync_val_compare_and_swap(PTR, OLD, NEW) \ | |||
| ((sizeof (*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR))) \ | |||
| __sync_val_compare_and_swap_si((int *)(PTR),(int)(OLD),(int)(NEW)) \ | |||
| : (__typeof__(*(PTR))) \ | |||
| __sync_val_compare_and_swap_di((long *)(PTR),(long)(OLD),(long)(NEW))) | |||
| extern int __sync_bool_compare_and_swap_si (int *, int, int); | |||
| extern int __sync_bool_compare_and_swap_di (long *, long, long); | |||
| ((sizeof(*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR))) \ | |||
| __sync_val_compare_and_swap_si ((int*)(PTR), (int)(OLD), (int)(NEW)) \ | |||
| : (__typeof__(*(PTR))) \ | |||
| __sync_val_compare_and_swap_di ((long*)(PTR), (long)(OLD), (long)(NEW))) | |||
| extern int __sync_bool_compare_and_swap_si(int *, int, int); | |||
| extern int __sync_bool_compare_and_swap_di(long *, long, long); | |||
| #define __sync_bool_compare_and_swap(PTR, OLD, NEW) \ | |||
| ((sizeof (*(PTR)) == sizeof(int)) \ | |||
| ? __sync_bool_compare_and_swap_si((int *)(PTR),(int)(OLD),(int)(NEW)) \ | |||
| : __sync_bool_compare_and_swap_di((long *)(PTR),(long)(OLD),(long)(NEW))) | |||
| ((sizeof(*(PTR)) == sizeof(int)) \ | |||
| ? __sync_bool_compare_and_swap_si ((int*)(PTR), (int)(OLD), (int)(NEW)) \ | |||
| : __sync_bool_compare_and_swap_di ((long*)(PTR), (long)(OLD), (long)(NEW))) | |||
| extern void __sync_lock_release_si (int *); | |||
| extern void __sync_lock_release_di (long *); | |||
| extern void __sync_lock_release_si(int *); | |||
| extern void __sync_lock_release_di(long *); | |||
| #define __sync_lock_release(PTR) \ | |||
| ((sizeof (*(PTR)) == sizeof(int)) \ | |||
| ? __sync_lock_release_si((int *)(PTR)) \ | |||
| : __sync_lock_release_di((long *)(PTR))) | |||
| extern int __sync_lock_test_and_set_si (int *, int); | |||
| extern long __sync_lock_test_and_set_di (long *, long); | |||
| #define __sync_lock_test_and_set(PTR,VAL) \ | |||
| ((sizeof (*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR))) __sync_lock_test_and_set_si((int *)(PTR),(int)(VAL)) \ | |||
| : (__typeof__(*(PTR))) __sync_lock_test_and_set_di((long *)(PTR),(long)(VAL))) | |||
| extern int __sync_fetch_and_add_si (int *, int); | |||
| extern long __sync_fetch_and_add_di (long *, long); | |||
| #define __sync_fetch_and_add(PTR,VAL) \ | |||
| ((sizeof (*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR))) __sync_fetch_and_add_si((int *)(PTR),(int)(VAL)) \ | |||
| : (__typeof__(*(PTR))) __sync_fetch_and_add_di((long *)(PTR),(long)(VAL))) | |||
| extern int __sync_fetch_and_sub_si (int *, int); | |||
| extern long __sync_fetch_and_sub_di (long *, long); | |||
| #define __sync_fetch_and_sub(PTR,VAL) \ | |||
| ((sizeof (*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR))) __sync_fetch_and_sub_si((int *)(PTR),(int)(VAL)) \ | |||
| : (__typeof__(*(PTR))) __sync_fetch_and_sub_di((long *)(PTR),(long)(VAL))) | |||
| extern int __sync_fetch_and_and_si (int *, int); | |||
| extern long __sync_fetch_and_and_di (long *, long); | |||
| #define __sync_fetch_and_and(PTR,VAL) \ | |||
| ((sizeof (*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR))) __sync_fetch_and_and_si((int *)(PTR),(int)(VAL)) \ | |||
| : (__typeof__(*(PTR))) __sync_fetch_and_and_di((long *)(PTR),(long)(VAL))) | |||
| extern int __sync_fetch_and_or_si (int *, int); | |||
| extern long __sync_fetch_and_or_di (long *, long); | |||
| #define __sync_fetch_and_or(PTR,VAL) \ | |||
| ((sizeof (*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR))) __sync_fetch_and_or_si((int *)(PTR),(int)(VAL)) \ | |||
| : (__typeof__(*(PTR))) __sync_fetch_and_or_di((long *)(PTR),(long)(VAL))) | |||
| extern int __sync_fetch_and_xor_si (int *, int); | |||
| extern long __sync_fetch_and_xor_di (long *, long); | |||
| #define __sync_fetch_and_xor(PTR,VAL) \ | |||
| ((sizeof (*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR))) __sync_fetch_and_xor_si((int *)(PTR),(int)(VAL)) \ | |||
| : (__typeof__(*(PTR))) __sync_fetch_and_xor_di((long *)(PTR),(long)(VAL))) | |||
| extern int __sync_fetch_and_nand_si (int *, int); | |||
| extern long __sync_fetch_and_nand_di (long *, long); | |||
| #define __sync_fetch_and_nand(PTR,VAL) \ | |||
| ((sizeof (*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR))) __sync_fetch_and_nand_si((int *)(PTR),(int)(VAL)) \ | |||
| : (__typeof__(*(PTR))) __sync_fetch_and_nand_di((long *)(PTR),(long)(VAL))) | |||
| extern int __sync_add_and_fetch_si (int *, int); | |||
| extern long __sync_add_and_fetch_di (long *, long); | |||
| #define __sync_add_and_fetch(PTR,VAL) \ | |||
| ((sizeof (*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR))) __sync_add_and_fetch_si((int *)(PTR),(int)(VAL)) \ | |||
| : (__typeof__(*(PTR))) __sync_add_and_fetch_di((long *)(PTR),(long)(VAL))) | |||
| extern int __sync_sub_and_fetch_si (int *, int); | |||
| extern long __sync_sub_and_fetch_di (long *, long); | |||
| #define __sync_sub_and_fetch(PTR,VAL) \ | |||
| ((sizeof (*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR))) __sync_sub_and_fetch_si((int *)(PTR),(int)(VAL)) \ | |||
| : (__typeof__(*(PTR))) __sync_sub_and_fetch_di((long *)(PTR),(long)(VAL))) | |||
| extern int __sync_and_and_fetch_si (int *, int); | |||
| extern long __sync_and_and_fetch_di (long *, long); | |||
| #define __sync_and_and_fetch(PTR,VAL) \ | |||
| ((sizeof (*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR))) __sync_and_and_fetch_si((int *)(PTR),(int)(VAL)) \ | |||
| : (__typeof__(*(PTR))) __sync_and_and_fetch_di((long *)(PTR),(long)(VAL))) | |||
| extern int __sync_or_and_fetch_si (int *, int); | |||
| extern long __sync_or_and_fetch_di (long *, long); | |||
| #define __sync_or_and_fetch(PTR,VAL) \ | |||
| ((sizeof (*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR))) __sync_or_and_fetch_si((int *)(PTR),(int)(VAL)) \ | |||
| : (__typeof__(*(PTR))) __sync_or_and_fetch_di((long *)(PTR),(long)(VAL))) | |||
| extern int __sync_xor_and_fetch_si (int *, int); | |||
| extern long __sync_xor_and_fetch_di (long *, long); | |||
| #define __sync_xor_and_fetch(PTR,VAL) \ | |||
| ((sizeof (*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR))) __sync_xor_and_fetch_si((int *)(PTR),(int)(VAL)) \ | |||
| : (__typeof__(*(PTR))) __sync_xor_and_fetch_di((long *)(PTR),(long)(VAL))) | |||
| extern int __sync_nand_and_fetch_si (int *, int); | |||
| extern long __sync_nand_and_fetch_di (long *, long); | |||
| #define __sync_nand_and_fetch(PTR,VAL) \ | |||
| ((sizeof (*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR))) __sync_nand_and_fetch_si((int *)(PTR),(int)(VAL)) \ | |||
| : (__typeof__(*(PTR))) __sync_nand_and_fetch_di((long *)(PTR),(long)(VAL))) | |||
| ((sizeof(*(PTR)) == sizeof(int)) \ | |||
| ? __sync_lock_release_si ((int*)(PTR)) \ | |||
| : __sync_lock_release_di ((long*)(PTR))) | |||
| extern int __sync_lock_test_and_set_si(int *, int); | |||
| extern long __sync_lock_test_and_set_di(long *, long); | |||
| #define __sync_lock_test_and_set(PTR, VAL) \ | |||
| ((sizeof(*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR)))__sync_lock_test_and_set_si ((int*)(PTR), (int)(VAL)) \ | |||
| : (__typeof__(*(PTR)))__sync_lock_test_and_set_di ((long*)(PTR), (long)(VAL))) | |||
| extern int __sync_fetch_and_add_si(int *, int); | |||
| extern long __sync_fetch_and_add_di(long *, long); | |||
| #define __sync_fetch_and_add(PTR, VAL) \ | |||
| ((sizeof(*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR)))__sync_fetch_and_add_si ((int*)(PTR), (int)(VAL)) \ | |||
| : (__typeof__(*(PTR)))__sync_fetch_and_add_di ((long*)(PTR), (long)(VAL))) | |||
| extern int __sync_fetch_and_sub_si(int *, int); | |||
| extern long __sync_fetch_and_sub_di(long *, long); | |||
| #define __sync_fetch_and_sub(PTR, VAL) \ | |||
| ((sizeof(*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR)))__sync_fetch_and_sub_si ((int*)(PTR), (int)(VAL)) \ | |||
| : (__typeof__(*(PTR)))__sync_fetch_and_sub_di ((long*)(PTR), (long)(VAL))) | |||
| extern int __sync_fetch_and_and_si(int *, int); | |||
| extern long __sync_fetch_and_and_di(long *, long); | |||
| #define __sync_fetch_and_and(PTR, VAL) \ | |||
| ((sizeof(*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR)))__sync_fetch_and_and_si ((int*)(PTR), (int)(VAL)) \ | |||
| : (__typeof__(*(PTR)))__sync_fetch_and_and_di ((long*)(PTR), (long)(VAL))) | |||
| extern int __sync_fetch_and_or_si(int *, int); | |||
| extern long __sync_fetch_and_or_di(long *, long); | |||
| #define __sync_fetch_and_or(PTR, VAL) \ | |||
| ((sizeof(*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR)))__sync_fetch_and_or_si ((int*)(PTR), (int)(VAL)) \ | |||
| : (__typeof__(*(PTR)))__sync_fetch_and_or_di ((long*)(PTR), (long)(VAL))) | |||
| extern int __sync_fetch_and_xor_si(int *, int); | |||
| extern long __sync_fetch_and_xor_di(long *, long); | |||
| #define __sync_fetch_and_xor(PTR, VAL) \ | |||
| ((sizeof(*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR)))__sync_fetch_and_xor_si ((int*)(PTR), (int)(VAL)) \ | |||
| : (__typeof__(*(PTR)))__sync_fetch_and_xor_di ((long*)(PTR), (long)(VAL))) | |||
| extern int __sync_fetch_and_nand_si(int *, int); | |||
| extern long __sync_fetch_and_nand_di(long *, long); | |||
| #define __sync_fetch_and_nand(PTR, VAL) \ | |||
| ((sizeof(*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR)))__sync_fetch_and_nand_si ((int*)(PTR), (int)(VAL)) \ | |||
| : (__typeof__(*(PTR)))__sync_fetch_and_nand_di ((long*)(PTR), (long)(VAL))) | |||
| extern int __sync_add_and_fetch_si(int *, int); | |||
| extern long __sync_add_and_fetch_di(long *, long); | |||
| #define __sync_add_and_fetch(PTR, VAL) \ | |||
| ((sizeof(*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR)))__sync_add_and_fetch_si ((int*)(PTR), (int)(VAL)) \ | |||
| : (__typeof__(*(PTR)))__sync_add_and_fetch_di ((long*)(PTR), (long)(VAL))) | |||
| extern int __sync_sub_and_fetch_si(int *, int); | |||
| extern long __sync_sub_and_fetch_di(long *, long); | |||
| #define __sync_sub_and_fetch(PTR, VAL) \ | |||
| ((sizeof(*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR)))__sync_sub_and_fetch_si ((int*)(PTR), (int)(VAL)) \ | |||
| : (__typeof__(*(PTR)))__sync_sub_and_fetch_di ((long*)(PTR), (long)(VAL))) | |||
| extern int __sync_and_and_fetch_si(int *, int); | |||
| extern long __sync_and_and_fetch_di(long *, long); | |||
| #define __sync_and_and_fetch(PTR, VAL) \ | |||
| ((sizeof(*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR)))__sync_and_and_fetch_si ((int*)(PTR), (int)(VAL)) \ | |||
| : (__typeof__(*(PTR)))__sync_and_and_fetch_di ((long*)(PTR), (long)(VAL))) | |||
| extern int __sync_or_and_fetch_si(int *, int); | |||
| extern long __sync_or_and_fetch_di(long *, long); | |||
| #define __sync_or_and_fetch(PTR, VAL) \ | |||
| ((sizeof(*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR)))__sync_or_and_fetch_si ((int*)(PTR), (int)(VAL)) \ | |||
| : (__typeof__(*(PTR)))__sync_or_and_fetch_di ((long*)(PTR), (long)(VAL))) | |||
| extern int __sync_xor_and_fetch_si(int *, int); | |||
| extern long __sync_xor_and_fetch_di(long *, long); | |||
| #define __sync_xor_and_fetch(PTR, VAL) \ | |||
| ((sizeof(*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR)))__sync_xor_and_fetch_si ((int*)(PTR), (int)(VAL)) \ | |||
| : (__typeof__(*(PTR)))__sync_xor_and_fetch_di ((long*)(PTR), (long)(VAL))) | |||
| extern int __sync_nand_and_fetch_si(int *, int); | |||
| extern long __sync_nand_and_fetch_di(long *, long); | |||
| #define __sync_nand_and_fetch(PTR, VAL) \ | |||
| ((sizeof(*(PTR)) == sizeof(int)) \ | |||
| ? (__typeof__(*(PTR)))__sync_nand_and_fetch_si ((int*)(PTR), (int)(VAL)) \ | |||
| : (__typeof__(*(PTR)))__sync_nand_and_fetch_di ((long*)(PTR), (long)(VAL))) | |||
| #ifdef __cplusplus | |||
| } | |||
| @@ -28,112 +28,113 @@ | |||
| // the GNU General Public License. | |||
| #ifndef _GLIBCXX_ATOMICITY_H | |||
| #define _GLIBCXX_ATOMICITY_H 1 | |||
| #define _GLIBCXX_ATOMICITY_H 1 | |||
| typedef int _Atomic_word; | |||
| #if ( defined(__mc68020__) || defined(__mc68030__) \ | |||
| || defined(__mc68040__) || defined(__mc68060__) ) \ | |||
| && !defined(__mcpu32__) | |||
| || defined(__mc68040__) || defined(__mc68060__) ) \ | |||
| && !defined(__mcpu32__) | |||
| // These variants support compare-and-swap. | |||
| static inline _Atomic_word | |||
| static inline _Atomic_word | |||
| __attribute__ ((__unused__)) | |||
| __exchange_and_add(volatile _Atomic_word* __mem, int __val) | |||
| __exchange_and_add (volatile _Atomic_word* __mem, int __val) | |||
| { | |||
| register _Atomic_word __result = *__mem; | |||
| register _Atomic_word __temp; | |||
| __asm__ __volatile__ ("1: move%.l %0,%1\n\t" | |||
| "add%.l %3,%1\n\t" | |||
| "cas%.l %0,%1,%2\n\t" | |||
| "jne 1b" | |||
| : "=d" (__result), "=&d" (__temp), "=m" (*__mem) | |||
| : "d" (__val), "0" (__result), "m" (*__mem)); | |||
| return __result; | |||
| register _Atomic_word __result = *__mem; | |||
| register _Atomic_word __temp; | |||
| __asm__ __volatile__ ("1: move%.l %0,%1\n\t" | |||
| "add%.l %3,%1\n\t" | |||
| "cas%.l %0,%1,%2\n\t" | |||
| "jne 1b" | |||
| : "=d" (__result), "=&d" (__temp), "=m" (*__mem) | |||
| : "d" (__val), "0" (__result), "m" (*__mem)); | |||
| return __result; | |||
| } | |||
| #elif defined(__rtems__) | |||
| /* | |||
| * TAS/JBNE is unsafe on systems with strict priority-based scheduling. | |||
| * Disable interrupts, which we can do only from supervisor mode. | |||
| */ | |||
| /* | |||
| * TAS/JBNE is unsafe on systems with strict priority-based scheduling. | |||
| * Disable interrupts, which we can do only from supervisor mode. | |||
| */ | |||
| static inline _Atomic_word | |||
| __attribute__ ((__unused__)) | |||
| __exchange_and_add(volatile _Atomic_word* __mem, int __val) | |||
| __exchange_and_add (volatile _Atomic_word* __mem, int __val) | |||
| { | |||
| _Atomic_word __result; | |||
| short __level, __tmpsr; | |||
| __asm__ __volatile__ ("move%.w %%sr,%0\n\tor%.l %0,%1\n\tmove%.w %1,%%sr" | |||
| : "=d"(__level), "=d"(__tmpsr) : "1"(0x700)); | |||
| _Atomic_word __result; | |||
| short __level, __tmpsr; | |||
| __asm__ __volatile__ ("move%.w %%sr,%0\n\tor%.l %0,%1\n\tmove%.w %1,%%sr" | |||
| : "=d" (__level), "=d" (__tmpsr) : "1" (0x700)); | |||
| __result = *__mem; | |||
| *__mem = __result + __val; | |||
| __result = *__mem; | |||
| *__mem = __result + __val; | |||
| __asm__ __volatile__ ("move%.w %0,%%sr" : : "d"(__level)); | |||
| __asm__ __volatile__ ("move%.w %0,%%sr" : : "d" (__level)); | |||
| return __result; | |||
| return __result; | |||
| } | |||
| #else | |||
| template<int __inst> | |||
| struct __Atomicity_lock | |||
| { | |||
| static volatile unsigned char _S_atomicity_lock; | |||
| }; | |||
| struct __Atomicity_lock { | |||
| static volatile unsigned char _S_atomicity_lock; | |||
| }; | |||
| template<int __inst> | |||
| volatile unsigned char __Atomicity_lock<__inst>::_S_atomicity_lock = 0; | |||
| template volatile unsigned char __Atomicity_lock<0>::_S_atomicity_lock; | |||
| static inline _Atomic_word | |||
| static inline _Atomic_word | |||
| __attribute__ ((__unused__)) | |||
| __exchange_and_add(volatile _Atomic_word* __mem, int __val) | |||
| __exchange_and_add (volatile _Atomic_word* __mem, int __val) | |||
| { | |||
| _Atomic_word __result; | |||
| _Atomic_word __result; | |||
| // bset with no immediate addressing (not SMP-safe) | |||
| #if defined(__mcf5200__) || defined(__mcf5300__) | |||
| __asm__ __volatile__("1: bset.b #7,%0@\n\tjbne 1b" | |||
| : /* no outputs */ | |||
| : "a"(&__Atomicity_lock<0>::_S_atomicity_lock) | |||
| : "cc", "memory"); | |||
| __asm__ __volatile__ ("1: bset.b #7,%0@\n\tjbne 1b" | |||
| : /* no outputs */ | |||
| : "a" (&__Atomicity_lock<0>::_S_atomicity_lock) | |||
| : "cc", "memory"); | |||
| // CPU32 and MCF5400 support test-and-set (SMP-safe). | |||
| #elif defined(__mcpu32__) || defined(__mcf5400__) | |||
| __asm__ __volatile__("1: tas %0\n\tjbne 1b" | |||
| : "+m"(__Atomicity_lock<0>::_S_atomicity_lock) | |||
| : /* none */ | |||
| : "cc"); | |||
| __asm__ __volatile__ ("1: tas %0\n\tjbne 1b" | |||
| : "+m" (__Atomicity_lock<0>::_S_atomicity_lock) | |||
| : /* none */ | |||
| : "cc"); | |||
| // Use bset with immediate addressing for 68000/68010 (not SMP-safe) | |||
| // NOTE: TAS is available on the 68000, but unsupported by some Amiga | |||
| // memory controllers. | |||
| #else | |||
| __asm__ __volatile__("1: bset.b #7,%0\n\tjbne 1b" | |||
| : "+m"(__Atomicity_lock<0>::_S_atomicity_lock) | |||
| : /* none */ | |||
| : "cc"); | |||
| __asm__ __volatile__ ("1: bset.b #7,%0\n\tjbne 1b" | |||
| : "+m" (__Atomicity_lock<0>::_S_atomicity_lock) | |||
| : /* none */ | |||
| : "cc"); | |||
| #endif | |||
| __result = *__mem; | |||
| *__mem = __result + __val; | |||
| __result = *__mem; | |||
| *__mem = __result + __val; | |||
| __Atomicity_lock<0>::_S_atomicity_lock = 0; | |||
| __Atomicity_lock<0>::_S_atomicity_lock = 0; | |||
| return __result; | |||
| return __result; | |||
| } | |||
| #endif /* TAS / BSET */ | |||
| static inline void | |||
| __attribute__ ((__unused__)) | |||
| __atomic_add(volatile _Atomic_word* __mem, int __val) | |||
| __atomic_add (volatile _Atomic_word* __mem, int __val) | |||
| { | |||
| // Careful: using add.l with a memory destination is not | |||
| // architecturally guaranteed to be atomic. | |||
| (void) __exchange_and_add(__mem, __val); | |||
| // Careful: using add.l with a memory destination is not | |||
| // architecturally guaranteed to be atomic. | |||
| (void)__exchange_and_add (__mem, __val); | |||
| } | |||
| #endif /* !_GLIBCXX_ATOMICITY_H */ | |||
| @@ -34,50 +34,50 @@ typedef int _Atomic_word; | |||
| static inline int | |||
| __attribute__ ((__unused__)) | |||
| __exchange_and_add(volatile _Atomic_word* __mem, int __val) | |||
| __exchange_and_add (volatile _Atomic_word* __mem, int __val) | |||
| { | |||
| int __result, __tmp; | |||
| int __result, __tmp; | |||
| __asm__ __volatile__ | |||
| ("/* Inline exchange & add */\n\t" | |||
| "1:\n\t" | |||
| ".set push\n\t" | |||
| __asm__ __volatile__ | |||
| ("/* Inline exchange & add */\n\t" | |||
| "1:\n\t" | |||
| ".set push\n\t" | |||
| #if _MIPS_SIM == _ABIO32 | |||
| ".set mips2\n\t" | |||
| ".set mips2\n\t" | |||
| #endif | |||
| "ll %0,%3\n\t" | |||
| "addu %1,%4,%0\n\t" | |||
| "sc %1,%2\n\t" | |||
| ".set pop\n\t" | |||
| "beqz %1,1b\n\t" | |||
| "/* End exchange & add */" | |||
| : "=&r"(__result), "=&r"(__tmp), "=m"(*__mem) | |||
| : "m" (*__mem), "r"(__val)); | |||
| "ll %0,%3\n\t" | |||
| "addu %1,%4,%0\n\t" | |||
| "sc %1,%2\n\t" | |||
| ".set pop\n\t" | |||
| "beqz %1,1b\n\t" | |||
| "/* End exchange & add */" | |||
| : "=&r" (__result), "=&r" (__tmp), "=m" (*__mem) | |||
| : "m" (*__mem), "r" (__val)); | |||
| return __result; | |||
| return __result; | |||
| } | |||
| static inline void | |||
| __attribute__ ((__unused__)) | |||
| __atomic_add(volatile _Atomic_word* __mem, int __val) | |||
| __atomic_add (volatile _Atomic_word* __mem, int __val) | |||
| { | |||
| int __result; | |||
| int __result; | |||
| __asm__ __volatile__ | |||
| ("/* Inline atomic add */\n\t" | |||
| "1:\n\t" | |||
| ".set push\n\t" | |||
| __asm__ __volatile__ | |||
| ("/* Inline atomic add */\n\t" | |||
| "1:\n\t" | |||
| ".set push\n\t" | |||
| #if _MIPS_SIM == _ABIO32 | |||
| ".set mips2\n\t" | |||
| ".set mips2\n\t" | |||
| #endif | |||
| "ll %0,%2\n\t" | |||
| "addu %0,%3,%0\n\t" | |||
| "sc %0,%1\n\t" | |||
| ".set pop\n\t" | |||
| "beqz %0,1b\n\t" | |||
| "/* End atomic add */" | |||
| : "=&r"(__result), "=m"(*__mem) | |||
| : "m" (*__mem), "r"(__val)); | |||
| "ll %0,%2\n\t" | |||
| "addu %0,%3,%0\n\t" | |||
| "sc %0,%1\n\t" | |||
| ".set pop\n\t" | |||
| "beqz %0,1b\n\t" | |||
| "/* End atomic add */" | |||
| : "=&r" (__result), "=m" (*__mem) | |||
| : "m" (*__mem), "r" (__val)); | |||
| } | |||
| #endif /* atomicity.h */ | |||
| @@ -28,7 +28,7 @@ | |||
| // the GNU General Public License. | |||
| #ifndef _GLIBCXX_ATOMICITY_H | |||
| #define _GLIBCXX_ATOMICITY_H 1 | |||
| #define _GLIBCXX_ATOMICITY_H 1 | |||
| #ifdef __PPC405__ | |||
| #define _STWCX "sync \n\tstwcx. " | |||
| @@ -40,39 +40,41 @@ typedef int _Atomic_word; | |||
| static inline _Atomic_word | |||
| __attribute__ ((__unused__)) | |||
| __exchange_and_add(volatile _Atomic_word* __mem, int __val) | |||
| __exchange_and_add (volatile _Atomic_word* __mem, int __val) | |||
| { | |||
| _Atomic_word __tmp, __res; | |||
| __asm__ __volatile__ ( | |||
| "/* Inline exchange & add */\n" | |||
| "0:\t" | |||
| "lwarx %0,0,%3 \n\t" | |||
| "add%I4 %1,%0,%4 \n\t" | |||
| _STWCX " %1,0,%3 \n\t" | |||
| "bne- 0b \n\t" | |||
| "/* End exchange & add */" | |||
| : "=&b"(__res), "=&r"(__tmp), "=m" (*__mem) | |||
| : "r" (__mem), "Ir"(__val), "m" (*__mem) | |||
| : "cr0"); | |||
| return __res; | |||
| _Atomic_word __tmp, __res; | |||
| __asm__ __volatile__ ( | |||
| "/* Inline exchange & add */\n" | |||
| "0:\t" | |||
| "lwarx %0,0,%3 \n\t" | |||
| "add%I4 %1,%0,%4 \n\t" | |||
| _STWCX " %1,0,%3 \n\t" | |||
| "bne- 0b \n\t" | |||
| "/* End exchange & add */" | |||
| : "=&b" (__res), "=&r" (__tmp), "=m" (*__mem) | |||
| : "r" (__mem), "Ir" (__val), "m" (*__mem) | |||
| : "cr0"); | |||
| return __res; | |||
| } | |||
| static inline void | |||
| __attribute__ ((__unused__)) | |||
| __atomic_add(volatile _Atomic_word* __mem, int __val) | |||
| __atomic_add (volatile _Atomic_word* __mem, int __val) | |||
| { | |||
| _Atomic_word __tmp; | |||
| __asm__ __volatile__ ( | |||
| "/* Inline atomic add */\n" | |||
| "0:\t" | |||
| "lwarx %0,0,%2 \n\t" | |||
| "add%I3 %0,%0,%3 \n\t" | |||
| _STWCX " %0,0,%2 \n\t" | |||
| "bne- 0b \n\t" | |||
| "/* End atomic add */" | |||
| : "=&b"(__tmp), "=m" (*__mem) | |||
| : "r" (__mem), "Ir"(__val), "m" (*__mem) | |||
| : "cr0"); | |||
| _Atomic_word __tmp; | |||
| __asm__ __volatile__ ( | |||
| "/* Inline atomic add */\n" | |||
| "0:\t" | |||
| "lwarx %0,0,%2 \n\t" | |||
| "add%I3 %0,%0,%3 \n\t" | |||
| _STWCX " %0,0,%2 \n\t" | |||
| "bne- 0b \n\t" | |||
| "/* End atomic add */" | |||
| : "=&b" (__tmp), "=m" (*__mem) | |||
| : "r" (__mem), "Ir" (__val), "m" (*__mem) | |||
| : "cr0"); | |||
| } | |||
| #endif /* atomicity.h */ | |||
| @@ -1,7 +1,7 @@ | |||
| /* | |||
| Copyright (C) 2001 Paul Davis | |||
| Code derived from various headers from the Linux kernel | |||
| 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 | |||
| @@ -16,16 +16,16 @@ | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| */ | |||
| #ifndef __jack_cycles_h__ | |||
| #define __jack_cycles_h__ | |||
| /* PowerPC */ | |||
| #define CPU_FTR_601 0x00000100 | |||
| #define CPU_FTR_601 0x00000100 | |||
| #ifdef __powerpc64__ | |||
| #define CPU_FTR_CELL_TB_BUG 0x0000800000000000UL | |||
| #define CPU_FTR_CELL_TB_BUG 0x0000800000000000UL | |||
| #endif /* __powerpc64__ */ | |||
| typedef unsigned long cycles_t; | |||
| @@ -34,13 +34,13 @@ typedef unsigned long cycles_t; | |||
| extern cycles_t cacheflush_time; | |||
| static inline cycles_t get_cycles(void) | |||
| static inline cycles_t get_cycles (void) | |||
| { | |||
| cycles_t ret = 0; | |||
| #ifdef __powerpc64__ | |||
| #ifdef ENABLE_CELLBE | |||
| asm volatile( \ | |||
| asm volatile ( \ | |||
| "90: mftb %0;\n" \ | |||
| "97: cmpwi %0,0;\n" \ | |||
| " beq- 90b;\n" \ | |||
| @@ -54,11 +54,11 @@ static inline cycles_t get_cycles(void) | |||
| " .llong 99b-98b\n" \ | |||
| ".previous" \ | |||
| : "=r" (ret) : "i" (CPU_FTR_CELL_TB_BUG)); | |||
| #else /* !ENABLE_CELLBE */ | |||
| __asm__ __volatile__("mftb %0" : "=r" (ret)); | |||
| #else /* !ENABLE_CELLBE */ | |||
| __asm__ __volatile__ ("mftb %0" : "=r" (ret)); | |||
| #endif /* !ENABLE_CELLBE */ | |||
| #else /* !__powerpc64__ */ | |||
| __asm__ __volatile__( | |||
| #else /* !__powerpc64__ */ | |||
| __asm__ __volatile__ ( | |||
| "98: mftb %0\n" | |||
| "99:\n" | |||
| ".section __ftr_fixup,\"a\"\n" | |||
| @@ -68,7 +68,7 @@ static inline cycles_t get_cycles(void) | |||
| " .long 99b\n" | |||
| ".previous" | |||
| : "=r" (ret) : "i" (CPU_FTR_601)); | |||
| #endif /* !__powerpc64__ */ | |||
| #endif /* !__powerpc64__ */ | |||
| return ret; | |||
| } | |||
| @@ -28,31 +28,31 @@ | |||
| // the GNU General Public License. | |||
| #ifndef _GLIBCXX_ATOMICITY_H | |||
| #define _GLIBCXX_ATOMICITY_H 1 | |||
| #define _GLIBCXX_ATOMICITY_H 1 | |||
| typedef int _Atomic_word; | |||
| static inline _Atomic_word | |||
| static inline _Atomic_word | |||
| __attribute__ ((__unused__)) | |||
| __exchange_and_add(volatile _Atomic_word* __mem, int __val) | |||
| __exchange_and_add (volatile _Atomic_word* __mem, int __val) | |||
| { | |||
| register _Atomic_word __old_val, __new_val; | |||
| __asm__ __volatile__ (" l %0,0(%3)\n" | |||
| "0: lr %1,%0\n" | |||
| " ar %1,%4\n" | |||
| " cs %0,%1,0(%3)\n" | |||
| " jl 0b" | |||
| : "=&d" (__old_val), "=&d" (__new_val), "=m" (*__mem) | |||
| : "a" (__mem), "d" (__val), "m" (*__mem) : "cc"); | |||
| return __old_val; | |||
| register _Atomic_word __old_val, __new_val; | |||
| __asm__ __volatile__ (" l %0,0(%3)\n" | |||
| "0: lr %1,%0\n" | |||
| " ar %1,%4\n" | |||
| " cs %0,%1,0(%3)\n" | |||
| " jl 0b" | |||
| : "=&d" (__old_val), "=&d" (__new_val), "=m" (*__mem) | |||
| : "a" (__mem), "d" (__val), "m" (*__mem) : "cc"); | |||
| return __old_val; | |||
| } | |||
| static inline void | |||
| __attribute__ ((__unused__)) | |||
| __atomic_add(volatile _Atomic_word* __mem, int __val) | |||
| __atomic_add (volatile _Atomic_word* __mem, int __val) | |||
| { | |||
| __exchange_and_add(__mem, __val); | |||
| __exchange_and_add (__mem, __val); | |||
| } | |||
| #endif /* atomicity.h */ | |||
| @@ -2,22 +2,22 @@ | |||
| Copyright (C) 2004 Jack O'Quin | |||
| Generic version, overridden by OS-specific defines when needed. | |||
| 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 | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| */ | |||
| */ | |||
| #ifndef _jack_sys_ipc | |||
| #define _jack_sys_ipc 1 | |||
| @@ -2,22 +2,22 @@ | |||
| Copyright (C) 2004 Jack O'Quin | |||
| Generic version, overridden by OS-specific defines when needed. | |||
| 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 | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| */ | |||
| */ | |||
| #ifndef _jack_sys_poll | |||
| #define _jack_sys_poll 1 | |||
| @@ -2,28 +2,28 @@ | |||
| Copyright (C) 2001-2004 Paul Davis, Tilman Linneweh | |||
| Generic version, overridden by OS-specific definition when needed. | |||
| 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 | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| */ | |||
| */ | |||
| void jack_init_time () | |||
| { | |||
| /* nothing to do on a generic system - we use the system clock */ | |||
| } | |||
| void jack_set_clock_source (jack_timer_type_t clocksrc) | |||
| void jack_set_clock_source (jack_timer_type_t clocksrc) | |||
| { | |||
| /* only one clock source on a generic system */ | |||
| } | |||
| @@ -2,36 +2,37 @@ | |||
| Copyright (C) 2001-2004 Paul Davis, Tilman Linneweh | |||
| Generic version, overridden by OS-specific definition when needed. | |||
| 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 | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| */ | |||
| */ | |||
| #ifndef __jack_time_h__ | |||
| #define __jack_time_h__ | |||
| #include <jack/types.h> | |||
| extern jack_time_t jack_get_microseconds_from_system (void); | |||
| extern jack_time_t jack_get_microseconds_from_system(void); | |||
| static inline jack_time_t | |||
| jack_get_microseconds (void) { | |||
| jack_get_microseconds (void) | |||
| { | |||
| return jack_get_microseconds_from_system (); | |||
| } | |||
| typedef jack_time_t (*jack_get_microseconds_t)(void); | |||
| static inline jack_get_microseconds_t jack_get_microseconds_pointer(void) | |||
| static inline jack_get_microseconds_t jack_get_microseconds_pointer (void) | |||
| { | |||
| return jack_get_microseconds_from_system; | |||
| } | |||
| @@ -1,5 +1,5 @@ | |||
| /** | |||
| * | |||
| * | |||
| * 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 | |||
| @@ -22,64 +22,64 @@ | |||
| #include "systemtest.h" | |||
| #include "sanitycheck.h" | |||
| int sanitycheck (int care_about_realtime, | |||
| int care_about_freqscaling) | |||
| int sanitycheck (int care_about_realtime, | |||
| int care_about_freqscaling) | |||
| { | |||
| int errors = 0; | |||
| int warnings = 0; | |||
| int relogin = 0; | |||
| int errors = 0; | |||
| int warnings = 0; | |||
| int relogin = 0; | |||
| if (care_about_realtime && !system_user_can_rtprio ()) { | |||
| errors++; | |||
| relogin++; | |||
| fprintf (stderr, "\nJACK is running in realtime mode, but you are not allowed to use realtime scheduling.\n"); | |||
| if (!system_has_rtprio_limits_conf ()) { | |||
| errors++; | |||
| relogin++; | |||
| fprintf (stderr, "Please check your /etc/security/limits.conf for the following line\n"); | |||
| fprintf (stderr, "and correct/add it if necessary:\n\n"); | |||
| fprintf (stderr, " @audio - rtprio 99\n"); | |||
| } else if (!system_has_audiogroup ()) { | |||
| errors++; | |||
| relogin++; | |||
| fprintf (stderr, "\nYour system has no audio group. Please add it by executing (as root):\n"); | |||
| fprintf (stderr, " groupadd -r audio\n"); | |||
| fprintf (stderr, " usermod -a -G audio %s\n", system_get_username ()); | |||
| } else if (!system_user_in_audiogroup ()) { | |||
| errors++; | |||
| relogin++; | |||
| fprintf (stderr, "\nYour system has an audio group, but you are not a member of it.\n"); | |||
| fprintf (stderr, "Please add yourself to the audio group by executing (as root):\n"); | |||
| fprintf (stderr, " usermod -a -G audio %s\n", system_get_username ()); | |||
| } | |||
| } | |||
| if (care_about_freqscaling && system_has_frequencyscaling () && system_uses_frequencyscaling ()) { | |||
| warnings++; | |||
| fprintf (stderr, "\n--------------------------------------------------------------------------------\n"); | |||
| fprintf (stderr, "WARNING: Your system seems to use frequency scaling.\n\n"); | |||
| fprintf (stderr, " This can have a serious impact on audio latency. You have two choices:\n"); | |||
| fprintf (stderr, "\t(1)turn it off, e.g. by chosing the 'performance' governor.\n"); | |||
| fprintf (stderr, "\t(2)Use the HPET clocksource by passing \"-c h\" to JACK\n"); | |||
| fprintf (stderr, "\t (this second option only works on relatively recent computers)\n"); | |||
| fprintf (stderr, "--------------------------------------------------------------------------------\n\n"); | |||
| } | |||
| if (0 == system_memlock_amount ()) { | |||
| errors++; | |||
| relogin++; | |||
| fprintf (stderr, "\nYou are not allowed to lock memory. Please add a line\n"); | |||
| fprintf (stderr, " @audio - memlock %llu\n", (system_available_physical_mem () * 3) / 4096); | |||
| fprintf (stderr, "in your /etc/limits.conf.\n"); | |||
| } | |||
| if (0 < relogin) { | |||
| fprintf (stderr, "\nAfter applying these changes, please re-login in order for them to take effect.\n"); | |||
| } | |||
| if (0 < errors) { | |||
| fprintf (stderr, "\nYou don't appear to have a sane system configuration. It is very likely that you\n"); | |||
| fprintf (stderr, "encounter xruns. Please apply all the above mentioned changes and start jack again!\n"); | |||
| } | |||
| if (care_about_realtime && !system_user_can_rtprio()) { | |||
| errors++; | |||
| relogin++; | |||
| fprintf(stderr, "\nJACK is running in realtime mode, but you are not allowed to use realtime scheduling.\n"); | |||
| if (!system_has_rtprio_limits_conf()) { | |||
| errors++; | |||
| relogin++; | |||
| fprintf (stderr, "Please check your /etc/security/limits.conf for the following line\n"); | |||
| fprintf (stderr, "and correct/add it if necessary:\n\n"); | |||
| fprintf(stderr, " @audio - rtprio 99\n"); | |||
| } else if (!system_has_audiogroup()) { | |||
| errors++; | |||
| relogin++; | |||
| fprintf(stderr, "\nYour system has no audio group. Please add it by executing (as root):\n"); | |||
| fprintf(stderr, " groupadd -r audio\n"); | |||
| fprintf(stderr, " usermod -a -G audio %s\n", system_get_username()); | |||
| } else if (!system_user_in_audiogroup()) { | |||
| errors++; | |||
| relogin++; | |||
| fprintf(stderr, "\nYour system has an audio group, but you are not a member of it.\n"); | |||
| fprintf(stderr, "Please add yourself to the audio group by executing (as root):\n"); | |||
| fprintf(stderr, " usermod -a -G audio %s\n", system_get_username()); | |||
| } | |||
| } | |||
| if (care_about_freqscaling && system_has_frequencyscaling() && system_uses_frequencyscaling()) { | |||
| warnings++; | |||
| fprintf(stderr, "\n--------------------------------------------------------------------------------\n"); | |||
| fprintf(stderr, "WARNING: Your system seems to use frequency scaling.\n\n"); | |||
| fprintf(stderr, " This can have a serious impact on audio latency. You have two choices:\n"); | |||
| fprintf(stderr, "\t(1)turn it off, e.g. by chosing the 'performance' governor.\n"); | |||
| fprintf(stderr, "\t(2)Use the HPET clocksource by passing \"-c h\" to JACK\n"); | |||
| fprintf(stderr, "\t (this second option only works on relatively recent computers)\n"); | |||
| fprintf(stderr, "--------------------------------------------------------------------------------\n\n"); | |||
| } | |||
| if (0==system_memlock_amount()) { | |||
| errors++; | |||
| relogin++; | |||
| fprintf(stderr, "\nYou are not allowed to lock memory. Please add a line\n"); | |||
| fprintf(stderr, " @audio - memlock %llu\n", (system_available_physical_mem()*3)/4096); | |||
| fprintf(stderr, "in your /etc/limits.conf.\n"); | |||
| } | |||
| if (0<relogin) { | |||
| fprintf(stderr, "\nAfter applying these changes, please re-login in order for them to take effect.\n"); | |||
| } | |||
| if (0<errors) { | |||
| fprintf(stderr, "\nYou don't appear to have a sane system configuration. It is very likely that you\n"); | |||
| fprintf(stderr, "encounter xruns. Please apply all the above mentioned changes and start jack again!\n"); | |||
| } | |||
| return errors; | |||
| return errors; | |||
| } | |||
| @@ -14,7 +14,7 @@ | |||
| * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| * | |||
| * Set of functions to gather system information for the jack setup wizard. | |||
| * | |||
| * | |||
| * TODO: Test for rt prio availability | |||
| * | |||
| * @author Florian Faber, faber@faberman.de | |||
| @@ -43,112 +43,117 @@ | |||
| #include "systemtest.h" | |||
| /** | |||
| * This function checks for the existence of known frequency scaling mechanisms | |||
| * This function checks for the existence of known frequency scaling mechanisms | |||
| * in this system by testing for the availability of scaling governors/ | |||
| * | |||
| * @returns 0 if the system has no frequency scaling capabilities non-0 otherwise. | |||
| **/ | |||
| int system_has_frequencyscaling() { | |||
| int fd; | |||
| int system_has_frequencyscaling () | |||
| { | |||
| int fd; | |||
| fd = open("/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors", O_RDONLY); | |||
| fd = open ("/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors", O_RDONLY); | |||
| if (-1==fd) { | |||
| return 0; | |||
| } | |||
| if (-1 == fd) { | |||
| return 0; | |||
| } | |||
| (void) close(fd); | |||
| (void)close (fd); | |||
| return 1; | |||
| return 1; | |||
| } | |||
| static int read_string(char* filename, char* buf, size_t buflen) { | |||
| int fd; | |||
| ssize_t r=-1; | |||
| memset (buf, 0, buflen); | |||
| fd = open (filename, O_RDONLY); | |||
| if (-1<fd) { | |||
| r = read (fd, buf, buflen-1); | |||
| (void) close(fd); | |||
| if (-1==r) { | |||
| fprintf(stderr, "Error while reading \"%s\": %s\n", filename, strerror(errno)); | |||
| exit(EXIT_FAILURE); | |||
| } | |||
| } | |||
| return (int) r; | |||
| static int read_string (char* filename, char* buf, size_t buflen) | |||
| { | |||
| int fd; | |||
| ssize_t r = -1; | |||
| memset (buf, 0, buflen); | |||
| fd = open (filename, O_RDONLY); | |||
| if (-1 < fd) { | |||
| r = read (fd, buf, buflen - 1); | |||
| (void)close (fd); | |||
| if (-1 == r) { | |||
| fprintf (stderr, "Error while reading \"%s\": %s\n", filename, strerror (errno)); | |||
| exit (EXIT_FAILURE); | |||
| } | |||
| } | |||
| return (int)r; | |||
| } | |||
| static int read_int(char* filename, int* value) { | |||
| char buf[20]; | |||
| static int read_int (char* filename, int* value) | |||
| { | |||
| char buf[20]; | |||
| if (0<read_string(filename, buf, 20)) { | |||
| return (1==sscanf(buf, "%d", value)); | |||
| } | |||
| if (0 < read_string (filename, buf, 20)) { | |||
| return 1 == sscanf (buf, "%d", value); | |||
| } | |||
| return 0; | |||
| return 0; | |||
| } | |||
| /** | |||
| * This function determines wether any CPU core uses a variable clock speed if frequency | |||
| * This function determines wether any CPU core uses a variable clock speed if frequency | |||
| * scaling is available. If the governor for all cores is either "powersave" or | |||
| * "performance", the CPU frequency can be assumed to be static. This is also the case | |||
| * if scaling_min_freq and scaling_max_freq are set to the same value. | |||
| * | |||
| * @returns 0 if system doesn't use frequency scaling at the moment, non-0 otherwise | |||
| **/ | |||
| int system_uses_frequencyscaling() { | |||
| int cpu=0, done=0, min, max; | |||
| char filename[256], buf[256]; | |||
| while (!done) { | |||
| (void) snprintf(filename, 256, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor", cpu); | |||
| if (0<read_string(filename, buf, 256)) { | |||
| if ((0!=strncmp("performance", buf,11)) && | |||
| (0!=strncmp("powersafe", buf,9))) { | |||
| int system_uses_frequencyscaling () | |||
| { | |||
| int cpu = 0, done = 0, min, max; | |||
| char filename[256], buf[256]; | |||
| while (!done) { | |||
| (void)snprintf (filename, 256, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor", cpu); | |||
| if (0 < read_string (filename, buf, 256)) { | |||
| if ((0 != strncmp ("performance", buf, 11)) && | |||
| (0 != strncmp ("powersafe", buf, 9))) { | |||
| // So it's neither the "performance" nor the "powersafe" governor | |||
| (void) snprintf(filename, 256, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq", cpu); | |||
| if (read_int(filename, &min)) { | |||
| (void) snprintf(filename, 256, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq", cpu); | |||
| if (read_int(filename, &max)) { | |||
| if (min!=max) { | |||
| (void)snprintf (filename, 256, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq", cpu); | |||
| if (read_int (filename, &min)) { | |||
| (void)snprintf (filename, 256, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq", cpu); | |||
| if (read_int (filename, &max)) { | |||
| if (min != max) { | |||
| // wrong governor AND different frequency limits -> scaling | |||
| return 1; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } else { | |||
| // couldn't open file -> no more cores | |||
| done = 1; | |||
| } | |||
| cpu++; | |||
| } | |||
| // couldn't find anything that points to scaling | |||
| return 0; | |||
| } | |||
| } else { | |||
| // couldn't open file -> no more cores | |||
| done = 1; | |||
| } | |||
| cpu++; | |||
| } | |||
| // couldn't find anything that points to scaling | |||
| return 0; | |||
| } | |||
| static gid_t get_group_by_name(const char* name) { | |||
| struct group* grp; | |||
| static gid_t get_group_by_name (const char* name) | |||
| { | |||
| struct group* grp; | |||
| gid_t res = 0; | |||
| while ((0==res) && (NULL != (grp = getgrent()))) { | |||
| if (0==strcmp(name, grp->gr_name)) { | |||
| res = grp->gr_gid; | |||
| } | |||
| } | |||
| while ((0 == res) && (NULL != (grp = getgrent ()))) { | |||
| if (0 == strcmp (name, grp->gr_name)) { | |||
| res = grp->gr_gid; | |||
| } | |||
| } | |||
| endgrent(); | |||
| endgrent (); | |||
| return res; | |||
| return res; | |||
| } | |||
| /*** | |||
| @@ -162,7 +167,7 @@ int system_has_rtprio_limits_conf () | |||
| const char* limits = "/etc/security/limits.conf"; | |||
| char cmd[100]; | |||
| snprintf (cmd, sizeof (cmd), "grep -q 'rtprio *[0-9][0-9]*' %s", limits); | |||
| snprintf (cmd, sizeof(cmd), "grep -q 'rtprio *[0-9][0-9]*' %s", limits); | |||
| if (system (cmd) == 0) { | |||
| return 1; | |||
| } | |||
| @@ -175,8 +180,9 @@ int system_has_rtprio_limits_conf () | |||
| * | |||
| * @returns 0 is there is no 'audio' group, the group id otherwise | |||
| **/ | |||
| int system_has_audiogroup() { | |||
| return get_group_by_name("audio") || get_group_by_name ("jackuser"); | |||
| int system_has_audiogroup () | |||
| { | |||
| return get_group_by_name ("audio") || get_group_by_name ("jackuser"); | |||
| } | |||
| @@ -185,36 +191,37 @@ int system_has_audiogroup() { | |||
| * | |||
| * @returns 0 if the owner of this process is not in the audio group, non-0 otherwise | |||
| **/ | |||
| int system_user_in_audiogroup() { | |||
| gid_t* list = (gid_t*) malloc(MAX_GROUPS * sizeof(gid_t)); | |||
| int num_groups, i=0, found=0; | |||
| int system_user_in_audiogroup () | |||
| { | |||
| gid_t* list = (gid_t*)malloc (MAX_GROUPS * sizeof(gid_t)); | |||
| int num_groups, i = 0, found = 0; | |||
| unsigned int gid; | |||
| if (NULL==list) { | |||
| perror("Cannot allocate group list structure"); | |||
| exit(EXIT_FAILURE); | |||
| } | |||
| gid = get_group_by_name("audio"); | |||
| if (0==gid) { | |||
| fprintf(stderr, "No audio group found\n"); | |||
| exit(EXIT_FAILURE); | |||
| } | |||
| num_groups = getgroups(MAX_GROUPS, list); | |||
| while (i<num_groups) { | |||
| if (list[i]==gid) { | |||
| found = 1; | |||
| i = num_groups; | |||
| } | |||
| i++; | |||
| } | |||
| free(list); | |||
| return found; | |||
| if (NULL == list) { | |||
| perror ("Cannot allocate group list structure"); | |||
| exit (EXIT_FAILURE); | |||
| } | |||
| gid = get_group_by_name ("audio"); | |||
| if (0 == gid) { | |||
| fprintf (stderr, "No audio group found\n"); | |||
| exit (EXIT_FAILURE); | |||
| } | |||
| num_groups = getgroups (MAX_GROUPS, list); | |||
| while (i < num_groups) { | |||
| if (list[i] == gid) { | |||
| found = 1; | |||
| i = num_groups; | |||
| } | |||
| i++; | |||
| } | |||
| free (list); | |||
| return found; | |||
| } | |||
| @@ -223,38 +230,40 @@ int system_user_in_audiogroup() { | |||
| * | |||
| * @returns 0 if this process can not be switched to rt prio, non-0 otherwise | |||
| **/ | |||
| int system_user_can_rtprio() { | |||
| int min_prio; | |||
| struct sched_param schparam; | |||
| memset(&schparam, 0, sizeof(struct sched_param)); | |||
| if (-1 == (min_prio = sched_get_priority_min(SCHED_FIFO))) { | |||
| perror("sched_get_priority"); | |||
| exit(EXIT_FAILURE); | |||
| } | |||
| schparam.sched_priority = min_prio; | |||
| if (0 == sched_setscheduler(0, SCHED_FIFO, &schparam)) { | |||
| // TODO: restore previous state | |||
| schparam.sched_priority = 0; | |||
| if (0 != sched_setscheduler(0, SCHED_OTHER, &schparam)) { | |||
| perror("sched_setscheduler"); | |||
| exit(EXIT_FAILURE); | |||
| } | |||
| return 1; | |||
| } | |||
| return 0; | |||
| int system_user_can_rtprio () | |||
| { | |||
| int min_prio; | |||
| struct sched_param schparam; | |||
| memset (&schparam, 0, sizeof(struct sched_param)); | |||
| if (-1 == (min_prio = sched_get_priority_min (SCHED_FIFO))) { | |||
| perror ("sched_get_priority"); | |||
| exit (EXIT_FAILURE); | |||
| } | |||
| schparam.sched_priority = min_prio; | |||
| if (0 == sched_setscheduler (0, SCHED_FIFO, &schparam)) { | |||
| // TODO: restore previous state | |||
| schparam.sched_priority = 0; | |||
| if (0 != sched_setscheduler (0, SCHED_OTHER, &schparam)) { | |||
| perror ("sched_setscheduler"); | |||
| exit (EXIT_FAILURE); | |||
| } | |||
| return 1; | |||
| } | |||
| return 0; | |||
| } | |||
| long long unsigned int system_memlock_amount() { | |||
| long long unsigned int system_memlock_amount () | |||
| { | |||
| struct rlimit limits; | |||
| if (-1==getrlimit(RLIMIT_MEMLOCK, &limits)) { | |||
| perror("getrlimit on RLIMIT_MEMLOCK"); | |||
| exit(EXIT_FAILURE); | |||
| if (-1 == getrlimit (RLIMIT_MEMLOCK, &limits)) { | |||
| perror ("getrlimit on RLIMIT_MEMLOCK"); | |||
| exit (EXIT_FAILURE); | |||
| } | |||
| return limits.rlim_max; | |||
| @@ -266,26 +275,28 @@ long long unsigned int system_memlock_amount() { | |||
| * | |||
| * @returns - 0 if the memlock limit is limited, non-0 otherwise | |||
| **/ | |||
| int system_memlock_is_unlimited() { | |||
| return ((RLIM_INFINITY==system_memlock_amount())?1:0); | |||
| int system_memlock_is_unlimited () | |||
| { | |||
| return (RLIM_INFINITY == system_memlock_amount ()) ? 1 : 0; | |||
| } | |||
| long long unsigned int system_available_physical_mem() { | |||
| long long unsigned int system_available_physical_mem () | |||
| { | |||
| char buf[256]; | |||
| long long unsigned int res = 0; | |||
| if (0<read_string("/proc/meminfo", buf, sizeof (buf))) { | |||
| if (0 < read_string ("/proc/meminfo", buf, sizeof(buf))) { | |||
| if (strncmp (buf, "MemTotal:", 9) == 0) { | |||
| if (sscanf (buf, "%*s %llu", &res) != 1) { | |||
| perror ("parse error in /proc/meminfo"); | |||
| } | |||
| } | |||
| } | |||
| } else { | |||
| perror("read from /proc/meminfo"); | |||
| perror ("read from /proc/meminfo"); | |||
| } | |||
| return res*1024; | |||
| return res * 1024; | |||
| } | |||
| @@ -295,19 +306,21 @@ long long unsigned int system_available_physical_mem() { | |||
| * | |||
| * @returns String with the full version of the kernel | |||
| **/ | |||
| char* system_kernel_version() { | |||
| return NULL; | |||
| char* system_kernel_version () | |||
| { | |||
| return NULL; | |||
| } | |||
| char* system_get_username() { | |||
| char* res = NULL; | |||
| char* name = NULL; | |||
| char* system_get_username () | |||
| { | |||
| char* res = NULL; | |||
| char* name = NULL; | |||
| if ((name = getlogin())) { | |||
| res = strdup(name); | |||
| } | |||
| if ((name = getlogin ())) { | |||
| res = strdup (name); | |||
| } | |||
| return res; | |||
| return res; | |||
| } | |||
| @@ -2,22 +2,22 @@ | |||
| /* | |||
| Copyright (C) 2001-2003 Paul Davis | |||
| Copyright (C) 2005 Jussi Laako | |||
| 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 | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| */ | |||
| */ | |||
| #include <config.h> | |||
| @@ -27,11 +27,11 @@ 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) | |||
| #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 | |||
| @@ -51,14 +51,14 @@ jack_hpet_init () | |||
| { | |||
| uint32_t hpet_caps; | |||
| hpet_fd = open("/dev/hpet", O_RDONLY); | |||
| 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); | |||
| 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); | |||
| @@ -66,30 +66,31 @@ jack_hpet_init () | |||
| } | |||
| /* 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)); | |||
| 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); | |||
| (sizeof(hpet_counter_t) == sizeof(uint64_t))) ? | |||
| 0 : ((uint64_t)1 << 32); | |||
| return 0; | |||
| } | |||
| static jack_time_t | |||
| jack_get_microseconds_from_hpet (void) | |||
| 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 (unlikely(hpet_counter < hpet_previous)) | |||
| hpet_counter = *((hpet_counter_t*)(hpet_ptr + HPET_COUNTER)); | |||
| if (unlikely (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)); | |||
| 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 | |||
| @@ -103,7 +104,7 @@ jack_hpet_init () | |||
| } | |||
| static jack_time_t | |||
| jack_get_microseconds_from_hpet (void) | |||
| jack_get_microseconds_from_hpet (void) | |||
| { | |||
| /* never called */ | |||
| return 0; | |||
| @@ -121,8 +122,7 @@ jack_init_time () | |||
| void | |||
| jack_set_clock_source (jack_timer_type_t clocksrc) | |||
| { | |||
| switch (clocksrc) | |||
| { | |||
| switch (clocksrc) { | |||
| case JACK_TIMER_HPET: | |||
| if (jack_hpet_init () == 0) { | |||
| _jack_get_microseconds = jack_get_microseconds_from_hpet; | |||
| @@ -3,22 +3,22 @@ | |||
| Copyright (C) 2005 Jussi Laako | |||
| This is the GNU/Linux version. | |||
| 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 | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| */ | |||
| */ | |||
| #ifndef __jack_time_h__ | |||
| #define __jack_time_h__ | |||
| @@ -28,15 +28,15 @@ | |||
| extern jack_time_t (*_jack_get_microseconds)(void); | |||
| static inline jack_time_t | |||
| jack_get_microseconds (void) | |||
| jack_get_microseconds (void) | |||
| { | |||
| return _jack_get_microseconds (); | |||
| } | |||
| typedef jack_time_t (*jack_get_microseconds_t)(void); | |||
| static inline jack_get_microseconds_t jack_get_microseconds_pointer(void) | |||
| static inline jack_get_microseconds_t jack_get_microseconds_pointer (void) | |||
| { | |||
| return _jack_get_microseconds; | |||
| return _jack_get_microseconds; | |||
| } | |||
| #endif /* __jack_time_h__ */ | |||
| @@ -14,9 +14,9 @@ | |||
| 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. | |||
| Grame Research Laboratory, 9, rue du Garet 69001 Lyon - France | |||
| grame@rd.grame.fr | |||
| */ | |||
| */ | |||
| #include "/Developer/SDKs/MacOSX10.3.0.sdk/usr/include/getopt.h" | |||
| @@ -14,10 +14,10 @@ | |||
| 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. | |||
| Grame Research Laboratory, 9, rue du Garet 69001 Lyon - France | |||
| grame@rd.grame.fr | |||
| */ | |||
| */ | |||
| #ifndef __ipc__ | |||
| #define __ipc__ | |||
| @@ -26,140 +26,142 @@ | |||
| #include <servers/bootstrap.h> | |||
| #include "internal.h" | |||
| #include "engine.h" | |||
| #include "libjack/local.h" /* JOQ: fix me */ | |||
| #include "libjack/local.h" /* JOQ: fix me */ | |||
| /* | |||
| RPC without time out can put the jack server in a blocked state | |||
| (waiting for the client answer) when a client is killed. The | |||
| mach_msg function does not return any error in this case. Using | |||
| time out solve the problem but does not seems really satisfactory. | |||
| */ | |||
| */ | |||
| #define WAIT 2500 /* in millisecond */ | |||
| static inline int | |||
| jack_client_resume(jack_client_internal_t *client) | |||
| static inline int | |||
| jack_client_resume (jack_client_internal_t *client) | |||
| { | |||
| mach_msg_header_t *head = &client->message.header; | |||
| int err; | |||
| if (!client->running) { | |||
| err = mach_msg (head, MACH_RCV_MSG, 0, sizeof(client->message), | |||
| client->serverport, 0, MACH_PORT_NULL); | |||
| if (err) { | |||
| jack_error("jack_client_resume: priming receive error: %s\n", | |||
| mach_error_string(err)); | |||
| return -1; | |||
| } | |||
| client->running = TRUE; | |||
| }else { | |||
| /* remote port is already the send-once he sent us */ | |||
| head->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, 0); | |||
| head->msgh_local_port = MACH_PORT_NULL; | |||
| head->msgh_size = sizeof(mach_msg_header_t); | |||
| err = mach_msg(head, (MACH_SEND_MSG|MACH_RCV_MSG| | |||
| MACH_SEND_TIMEOUT|MACH_RCV_TIMEOUT), | |||
| sizeof(*head), sizeof(client->message), | |||
| client->serverport, WAIT, MACH_PORT_NULL); | |||
| if (err) { | |||
| /* | |||
| switch(err) { | |||
| case MACH_SEND_TIMED_OUT: | |||
| jack_error("MACH_SEND_TIMED_OUT %s\n", | |||
| client->control->name); | |||
| break; | |||
| case MACH_RCV_TIMED_OUT: | |||
| jack_error("MACH_RCV_TIMED_OUT %s\n", | |||
| client->control->name); | |||
| break; | |||
| case MACH_SEND_INVALID_DEST: | |||
| jack_error("MACH_SEND_INVALID_DEST %s\n", | |||
| client->control->name); | |||
| break; | |||
| } | |||
| */ | |||
| jack_error("jack_client_resume: send error for %s\n", | |||
| mach_error_string(err)); | |||
| return err; | |||
| } | |||
| } | |||
| return 0; | |||
| mach_msg_header_t *head = &client->message.header; | |||
| int err; | |||
| if (!client->running) { | |||
| err = mach_msg (head, MACH_RCV_MSG, 0, sizeof(client->message), | |||
| client->serverport, 0, MACH_PORT_NULL); | |||
| if (err) { | |||
| jack_error ("jack_client_resume: priming receive error: %s\n", | |||
| mach_error_string (err)); | |||
| return -1; | |||
| } | |||
| client->running = TRUE; | |||
| } else { | |||
| /* remote port is already the send-once he sent us */ | |||
| head->msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_MOVE_SEND_ONCE, 0); | |||
| head->msgh_local_port = MACH_PORT_NULL; | |||
| head->msgh_size = sizeof(mach_msg_header_t); | |||
| err = mach_msg (head, (MACH_SEND_MSG | MACH_RCV_MSG | | |||
| MACH_SEND_TIMEOUT | MACH_RCV_TIMEOUT), | |||
| sizeof(*head), sizeof(client->message), | |||
| client->serverport, WAIT, MACH_PORT_NULL); | |||
| if (err) { | |||
| /* | |||
| switch(err) { | |||
| case MACH_SEND_TIMED_OUT: | |||
| jack_error("MACH_SEND_TIMED_OUT %s\n", | |||
| client->control->name); | |||
| break; | |||
| case MACH_RCV_TIMED_OUT: | |||
| jack_error("MACH_RCV_TIMED_OUT %s\n", | |||
| client->control->name); | |||
| break; | |||
| case MACH_SEND_INVALID_DEST: | |||
| jack_error("MACH_SEND_INVALID_DEST %s\n", | |||
| client->control->name); | |||
| break; | |||
| } | |||
| */ | |||
| jack_error ("jack_client_resume: send error for %s\n", | |||
| mach_error_string (err)); | |||
| return err; | |||
| } | |||
| } | |||
| return 0; | |||
| } | |||
| static inline int | |||
| jack_client_suspend(jack_client_t * client) | |||
| static inline int | |||
| jack_client_suspend (jack_client_t * client) | |||
| { | |||
| int err = 0; | |||
| mach_msg_header_t * head = &client->message.header; | |||
| head->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, | |||
| MACH_MSG_TYPE_MAKE_SEND_ONCE); | |||
| head->msgh_remote_port = client->serverport; | |||
| int err = 0; | |||
| mach_msg_header_t * head = &client->message.header; | |||
| head->msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, | |||
| MACH_MSG_TYPE_MAKE_SEND_ONCE); | |||
| head->msgh_remote_port = client->serverport; | |||
| head->msgh_local_port = client->replyport; | |||
| head->msgh_size = sizeof(mach_msg_header_t); | |||
| err = mach_msg(head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_SEND_TIMEOUT, | |||
| sizeof(mach_msg_header_t), sizeof(client->message), | |||
| client->replyport, WAIT, MACH_PORT_NULL); | |||
| if (err) { | |||
| jack_error("jack_client_suspend: RPC error: %s\n", | |||
| mach_error_string(err)); | |||
| return -1; | |||
| } | |||
| return 0; | |||
| err = mach_msg (head, MACH_SEND_MSG | MACH_RCV_MSG | MACH_SEND_TIMEOUT, | |||
| sizeof(mach_msg_header_t), sizeof(client->message), | |||
| client->replyport, WAIT, MACH_PORT_NULL); | |||
| if (err) { | |||
| jack_error ("jack_client_suspend: RPC error: %s\n", | |||
| mach_error_string (err)); | |||
| return -1; | |||
| } | |||
| return 0; | |||
| } | |||
| static inline void | |||
| allocate_mach_serverport(jack_engine_t * engine, jack_client_internal_t *client) | |||
| static inline void | |||
| allocate_mach_serverport (jack_engine_t * engine, jack_client_internal_t *client) | |||
| { | |||
| char buf[256]; | |||
| snprintf(buf, 256, "JackMachPort_%d", engine->portnum); | |||
| if (mach_port_allocate(engine->servertask, MACH_PORT_RIGHT_RECEIVE, | |||
| &client->serverport)){ | |||
| jack_error("allocate_mach_serverport: can't allocate mach port"); | |||
| } | |||
| if (mach_port_insert_right(engine->servertask, client->serverport, | |||
| client->serverport, MACH_MSG_TYPE_MAKE_SEND)){ | |||
| jack_error("allocate_mach_serverport: error inserting mach rights"); | |||
| } | |||
| if (bootstrap_register(engine->bp, buf, client->serverport)){ | |||
| jack_error("allocate_mach_serverport: can't check in mach port"); | |||
| } | |||
| client->portnum = engine->portnum; | |||
| engine->portnum++; | |||
| char buf[256]; | |||
| snprintf (buf, 256, "JackMachPort_%d", engine->portnum); | |||
| if (mach_port_allocate (engine->servertask, MACH_PORT_RIGHT_RECEIVE, | |||
| &client->serverport)) { | |||
| jack_error ("allocate_mach_serverport: can't allocate mach port"); | |||
| } | |||
| if (mach_port_insert_right (engine->servertask, client->serverport, | |||
| client->serverport, MACH_MSG_TYPE_MAKE_SEND)) { | |||
| jack_error ("allocate_mach_serverport: error inserting mach rights"); | |||
| } | |||
| if (bootstrap_register (engine->bp, buf, client->serverport)) { | |||
| jack_error ("allocate_mach_serverport: can't check in mach port"); | |||
| } | |||
| client->portnum = engine->portnum; | |||
| engine->portnum++; | |||
| } | |||
| static inline int | |||
| allocate_mach_clientport(jack_client_t * client, int portnum) | |||
| static inline int | |||
| allocate_mach_clientport (jack_client_t * client, int portnum) | |||
| { | |||
| char buf[256]; | |||
| snprintf(buf, 256, "JackMachPort_%d", portnum); | |||
| if (bootstrap_look_up(client->bp, buf, &client->serverport)){ | |||
| jack_error ("allocate_mach_clientport: can't find mach server port"); | |||
| return -1; | |||
| } | |||
| if (mach_port_allocate(client->clienttask, MACH_PORT_RIGHT_RECEIVE, | |||
| &client->replyport)){ | |||
| jack_error("allocate_mach_clientport: can't allocate mach port"); | |||
| return -1; | |||
| } | |||
| return 0; | |||
| char buf[256]; | |||
| snprintf (buf, 256, "JackMachPort_%d", portnum); | |||
| if (bootstrap_look_up (client->bp, buf, &client->serverport)) { | |||
| jack_error ("allocate_mach_clientport: can't find mach server port"); | |||
| return -1; | |||
| } | |||
| if (mach_port_allocate (client->clienttask, MACH_PORT_RIGHT_RECEIVE, | |||
| &client->replyport)) { | |||
| jack_error ("allocate_mach_clientport: can't allocate mach port"); | |||
| return -1; | |||
| } | |||
| return 0; | |||
| } | |||
| #endif /* __ipc__ */ | |||
| @@ -14,22 +14,22 @@ | |||
| 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. | |||
| Grame Research Laboratory, 9, rue du Garet 69001 Lyon - France | |||
| grame@rd.grame.fr | |||
| */ | |||
| */ | |||
| #ifndef __mach_port__ | |||
| #define __mach_port__ | |||
| #include <mach/mach.h> | |||
| #include <mach/mach.h> | |||
| #include <mach/mach_types.h> | |||
| #include <mach/message.h> | |||
| /* specific ressources for server/client real-time thread communication */ | |||
| typedef struct { | |||
| mach_msg_header_t header; | |||
| mach_msg_trailer_t trailer; | |||
| mach_msg_header_t header; | |||
| mach_msg_trailer_t trailer; | |||
| } trivial_message; | |||
| #endif | |||
| @@ -1,65 +1,65 @@ | |||
| /* | |||
| Copyright: © Copyright 2002 Apple Computer, Inc. All rights | |||
| reserved. | |||
| Disclaimer: IMPORTANT: This Apple software is supplied to | |||
| you by Apple Computer, Inc. ("Apple") in | |||
| consideration of your agreement to the | |||
| following terms, and your use, installation, | |||
| modification or redistribution of this Apple | |||
| software constitutes acceptance of these | |||
| terms. If you do not agree with these terms, | |||
| please do not use, install, modify or | |||
| redistribute this Apple software. | |||
| In consideration of your agreement to abide by | |||
| the following terms, and subject to these | |||
| terms, Apple grants you a personal, | |||
| non-exclusive license, under AppleÕs | |||
| copyrights in this original Apple software | |||
| (the "Apple Software"), to use, reproduce, | |||
| modify and redistribute the Apple Software, | |||
| with or without modifications, in source | |||
| and/or binary forms; provided that if you | |||
| redistribute the Apple Software in its | |||
| entirety and without modifications, you must | |||
| retain this notice and the following text and | |||
| disclaimers in all such redistributions of the | |||
| Apple Software. Neither the name, trademarks, | |||
| service marks or logos of Apple Computer, | |||
| Inc. may be used to endorse or promote | |||
| products derived from the Apple Software | |||
| without specific prior written permission from | |||
| Apple. Except as expressly stated in this | |||
| notice, no other rights or licenses, express | |||
| or implied, are granted by Apple herein, | |||
| including but not limited to any patent rights | |||
| that may be infringed by your derivative works | |||
| or by other works in which the Apple Software | |||
| may be incorporated. | |||
| The Apple Software is provided by Apple on an | |||
| "AS IS" basis. APPLE MAKES NO WARRANTIES, | |||
| EXPRESS OR IMPLIED, INCLUDING WITHOUT | |||
| LIMITATION THE IMPLIED WARRANTIES OF | |||
| NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE | |||
| SOFTWARE OR ITS USE AND OPERATION ALONE OR IN | |||
| COMBINATION WITH YOUR PRODUCTS. | |||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY | |||
| SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL | |||
| DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE | |||
| USE, REPRODUCTION, MODIFICATION AND/OR | |||
| DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER | |||
| CAUSED AND WHETHER UNDER THEORY OF CONTRACT, | |||
| TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY | |||
| OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED | |||
| OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| Copyright: © Copyright 2002 Apple Computer, Inc. All rights | |||
| reserved. | |||
| Disclaimer: IMPORTANT: This Apple software is supplied to | |||
| you by Apple Computer, Inc. ("Apple") in | |||
| consideration of your agreement to the | |||
| following terms, and your use, installation, | |||
| modification or redistribution of this Apple | |||
| software constitutes acceptance of these | |||
| terms. If you do not agree with these terms, | |||
| please do not use, install, modify or | |||
| redistribute this Apple software. | |||
| In consideration of your agreement to abide by | |||
| the following terms, and subject to these | |||
| terms, Apple grants you a personal, | |||
| non-exclusive license, under AppleÕs | |||
| copyrights in this original Apple software | |||
| (the "Apple Software"), to use, reproduce, | |||
| modify and redistribute the Apple Software, | |||
| with or without modifications, in source | |||
| and/or binary forms; provided that if you | |||
| redistribute the Apple Software in its | |||
| entirety and without modifications, you must | |||
| retain this notice and the following text and | |||
| disclaimers in all such redistributions of the | |||
| Apple Software. Neither the name, trademarks, | |||
| service marks or logos of Apple Computer, | |||
| Inc. may be used to endorse or promote | |||
| products derived from the Apple Software | |||
| without specific prior written permission from | |||
| Apple. Except as expressly stated in this | |||
| notice, no other rights or licenses, express | |||
| or implied, are granted by Apple herein, | |||
| including but not limited to any patent rights | |||
| that may be infringed by your derivative works | |||
| or by other works in which the Apple Software | |||
| may be incorporated. | |||
| The Apple Software is provided by Apple on an | |||
| "AS IS" basis. APPLE MAKES NO WARRANTIES, | |||
| EXPRESS OR IMPLIED, INCLUDING WITHOUT | |||
| LIMITATION THE IMPLIED WARRANTIES OF | |||
| NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE | |||
| SOFTWARE OR ITS USE AND OPERATION ALONE OR IN | |||
| COMBINATION WITH YOUR PRODUCTS. | |||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY | |||
| SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL | |||
| DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE | |||
| USE, REPRODUCTION, MODIFICATION AND/OR | |||
| DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER | |||
| CAUSED AND WHETHER UNDER THEORY OF CONTRACT, | |||
| TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY | |||
| OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED | |||
| OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| /* pThreadUtilities.h */ | |||
| #ifndef __PTHREADUTILITIES_H__ | |||
| @@ -68,8 +68,8 @@ | |||
| #import "pthread.h" | |||
| #import <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h> | |||
| #define THREAD_SET_PRIORITY 0 | |||
| #define THREAD_SCHEDULED_PRIORITY 1 | |||
| #define THREAD_SET_PRIORITY 0 | |||
| #define THREAD_SCHEDULED_PRIORITY 1 | |||
| #include <mach/mach_error.h> | |||
| #include <mach/thread_policy.h> | |||
| @@ -77,127 +77,126 @@ | |||
| #include <CoreAudio/HostTime.h> | |||
| static inline UInt32 | |||
| _getThreadPriority(pthread_t inThread, int inWhichPriority) | |||
| _getThreadPriority (pthread_t inThread, int inWhichPriority) | |||
| { | |||
| thread_basic_info_data_t threadInfo; | |||
| policy_info_data_t thePolicyInfo; | |||
| unsigned int count; | |||
| // get basic info | |||
| count = THREAD_BASIC_INFO_COUNT; | |||
| thread_info (pthread_mach_thread_np (inThread), THREAD_BASIC_INFO, | |||
| (thread_info_t)&threadInfo, &count); | |||
| switch (threadInfo.policy) { | |||
| case POLICY_TIMESHARE: | |||
| count = POLICY_TIMESHARE_INFO_COUNT; | |||
| thread_info(pthread_mach_thread_np (inThread), | |||
| THREAD_SCHED_TIMESHARE_INFO, | |||
| (thread_info_t)&(thePolicyInfo.ts), &count); | |||
| if (inWhichPriority == THREAD_SCHEDULED_PRIORITY) { | |||
| return thePolicyInfo.ts.cur_priority; | |||
| } else { | |||
| return thePolicyInfo.ts.base_priority; | |||
| } | |||
| break; | |||
| case POLICY_FIFO: | |||
| count = POLICY_FIFO_INFO_COUNT; | |||
| thread_info(pthread_mach_thread_np (inThread), | |||
| THREAD_SCHED_FIFO_INFO, | |||
| (thread_info_t)&(thePolicyInfo.fifo), &count); | |||
| if ( (thePolicyInfo.fifo.depressed) | |||
| && (inWhichPriority == THREAD_SCHEDULED_PRIORITY) ) { | |||
| return thePolicyInfo.fifo.depress_priority; | |||
| } | |||
| return thePolicyInfo.fifo.base_priority; | |||
| break; | |||
| case POLICY_RR: | |||
| count = POLICY_RR_INFO_COUNT; | |||
| thread_info(pthread_mach_thread_np (inThread), | |||
| THREAD_SCHED_RR_INFO, | |||
| (thread_info_t)&(thePolicyInfo.rr), &count); | |||
| if ( (thePolicyInfo.rr.depressed) | |||
| && (inWhichPriority == THREAD_SCHEDULED_PRIORITY) ) { | |||
| return thePolicyInfo.rr.depress_priority; | |||
| } | |||
| return thePolicyInfo.rr.base_priority; | |||
| break; | |||
| } | |||
| return 0; | |||
| thread_basic_info_data_t threadInfo; | |||
| policy_info_data_t thePolicyInfo; | |||
| unsigned int count; | |||
| // get basic info | |||
| count = THREAD_BASIC_INFO_COUNT; | |||
| thread_info (pthread_mach_thread_np (inThread), THREAD_BASIC_INFO, | |||
| (thread_info_t)&threadInfo, &count); | |||
| switch (threadInfo.policy) { | |||
| case POLICY_TIMESHARE: | |||
| count = POLICY_TIMESHARE_INFO_COUNT; | |||
| thread_info (pthread_mach_thread_np (inThread), | |||
| THREAD_SCHED_TIMESHARE_INFO, | |||
| (thread_info_t)&(thePolicyInfo.ts), &count); | |||
| if (inWhichPriority == THREAD_SCHEDULED_PRIORITY) { | |||
| return thePolicyInfo.ts.cur_priority; | |||
| } else { | |||
| return thePolicyInfo.ts.base_priority; | |||
| } | |||
| break; | |||
| case POLICY_FIFO: | |||
| count = POLICY_FIFO_INFO_COUNT; | |||
| thread_info (pthread_mach_thread_np (inThread), | |||
| THREAD_SCHED_FIFO_INFO, | |||
| (thread_info_t)&(thePolicyInfo.fifo), &count); | |||
| if ( (thePolicyInfo.fifo.depressed) | |||
| && (inWhichPriority == THREAD_SCHEDULED_PRIORITY) ) { | |||
| return thePolicyInfo.fifo.depress_priority; | |||
| } | |||
| return thePolicyInfo.fifo.base_priority; | |||
| break; | |||
| case POLICY_RR: | |||
| count = POLICY_RR_INFO_COUNT; | |||
| thread_info (pthread_mach_thread_np (inThread), | |||
| THREAD_SCHED_RR_INFO, | |||
| (thread_info_t)&(thePolicyInfo.rr), &count); | |||
| if ( (thePolicyInfo.rr.depressed) | |||
| && (inWhichPriority == THREAD_SCHEDULED_PRIORITY) ) { | |||
| return thePolicyInfo.rr.depress_priority; | |||
| } | |||
| return thePolicyInfo.rr.base_priority; | |||
| break; | |||
| } | |||
| return 0; | |||
| } | |||
| // returns the thread's priority as it was last set by the API | |||
| static inline UInt32 | |||
| getThreadSetPriority(pthread_t inThread) | |||
| getThreadSetPriority (pthread_t inThread) | |||
| { | |||
| return _getThreadPriority (inThread, THREAD_SET_PRIORITY); | |||
| return _getThreadPriority (inThread, THREAD_SET_PRIORITY); | |||
| } | |||
| // returns the thread's priority as it was last scheduled by the Kernel | |||
| static inline UInt32 | |||
| getThreadScheduledPriority(pthread_t inThread) | |||
| getThreadScheduledPriority (pthread_t inThread) | |||
| { | |||
| return _getThreadPriority (inThread, THREAD_SCHEDULED_PRIORITY); | |||
| return _getThreadPriority (inThread, THREAD_SCHEDULED_PRIORITY); | |||
| } | |||
| static inline void | |||
| setThreadToPriority(pthread_t inThread, UInt32 inPriority, Boolean inIsFixed, | |||
| UInt64 inHALIOProcCycleDurationInNanoseconds) | |||
| setThreadToPriority (pthread_t inThread, UInt32 inPriority, Boolean inIsFixed, | |||
| UInt64 inHALIOProcCycleDurationInNanoseconds) | |||
| { | |||
| if (inPriority == 96) | |||
| { | |||
| // REAL-TIME / TIME-CONSTRAINT THREAD | |||
| thread_time_constraint_policy_data_t theTCPolicy; | |||
| UInt64 theComputeQuanta; | |||
| UInt64 thePeriod; | |||
| UInt64 thePeriodNanos; | |||
| thePeriodNanos = inHALIOProcCycleDurationInNanoseconds; | |||
| theComputeQuanta = AudioConvertNanosToHostTime ( thePeriodNanos * 0.15 ); | |||
| thePeriod = AudioConvertNanosToHostTime (thePeriodNanos); | |||
| theTCPolicy.period = thePeriod; | |||
| theTCPolicy.computation = theComputeQuanta; | |||
| theTCPolicy.constraint = thePeriod; | |||
| theTCPolicy.preemptible = true; | |||
| thread_policy_set (pthread_mach_thread_np(inThread), | |||
| THREAD_TIME_CONSTRAINT_POLICY, | |||
| (thread_policy_t)&theTCPolicy, | |||
| THREAD_TIME_CONSTRAINT_POLICY_COUNT); | |||
| if (inPriority == 96) { | |||
| // REAL-TIME / TIME-CONSTRAINT THREAD | |||
| thread_time_constraint_policy_data_t theTCPolicy; | |||
| UInt64 theComputeQuanta; | |||
| UInt64 thePeriod; | |||
| UInt64 thePeriodNanos; | |||
| thePeriodNanos = inHALIOProcCycleDurationInNanoseconds; | |||
| theComputeQuanta = AudioConvertNanosToHostTime ( thePeriodNanos * 0.15 ); | |||
| thePeriod = AudioConvertNanosToHostTime (thePeriodNanos); | |||
| theTCPolicy.period = thePeriod; | |||
| theTCPolicy.computation = theComputeQuanta; | |||
| theTCPolicy.constraint = thePeriod; | |||
| theTCPolicy.preemptible = true; | |||
| thread_policy_set (pthread_mach_thread_np (inThread), | |||
| THREAD_TIME_CONSTRAINT_POLICY, | |||
| (thread_policy_t)&theTCPolicy, | |||
| THREAD_TIME_CONSTRAINT_POLICY_COUNT); | |||
| } else { | |||
| // OTHER THREADS | |||
| thread_extended_policy_data_t theFixedPolicy; | |||
| thread_precedence_policy_data_t thePrecedencePolicy; | |||
| SInt32 relativePriority; | |||
| // [1] SET FIXED / NOT FIXED | |||
| theFixedPolicy.timeshare = !inIsFixed; | |||
| thread_policy_set (pthread_mach_thread_np(inThread), | |||
| THREAD_EXTENDED_POLICY, | |||
| (thread_policy_t)&theFixedPolicy, | |||
| THREAD_EXTENDED_POLICY_COUNT); | |||
| // [2] SET PRECEDENCE N.B.: We expect that if thread A | |||
| // created thread B, and the program wishes to change the | |||
| // priority of thread B, then the call to change the | |||
| // priority of thread B must be made by thread A. This | |||
| // assumption allows us to use pthread_self() to correctly | |||
| // calculate the priority of the feeder thread (since | |||
| // precedency policy's importance is relative to the | |||
| // spawning thread's priority.) | |||
| relativePriority = inPriority - | |||
| getThreadSetPriority (pthread_self()); | |||
| thePrecedencePolicy.importance = relativePriority; | |||
| thread_policy_set (pthread_mach_thread_np(inThread), | |||
| THREAD_PRECEDENCE_POLICY, | |||
| (thread_policy_t)&thePrecedencePolicy, | |||
| THREAD_PRECEDENCE_POLICY_COUNT); | |||
| // OTHER THREADS | |||
| thread_extended_policy_data_t theFixedPolicy; | |||
| thread_precedence_policy_data_t thePrecedencePolicy; | |||
| SInt32 relativePriority; | |||
| // [1] SET FIXED / NOT FIXED | |||
| theFixedPolicy.timeshare = !inIsFixed; | |||
| thread_policy_set (pthread_mach_thread_np (inThread), | |||
| THREAD_EXTENDED_POLICY, | |||
| (thread_policy_t)&theFixedPolicy, | |||
| THREAD_EXTENDED_POLICY_COUNT); | |||
| // [2] SET PRECEDENCE N.B.: We expect that if thread A | |||
| // created thread B, and the program wishes to change the | |||
| // priority of thread B, then the call to change the | |||
| // priority of thread B must be made by thread A. This | |||
| // assumption allows us to use pthread_self() to correctly | |||
| // calculate the priority of the feeder thread (since | |||
| // precedency policy's importance is relative to the | |||
| // spawning thread's priority.) | |||
| relativePriority = inPriority - | |||
| getThreadSetPriority (pthread_self ()); | |||
| thePrecedencePolicy.importance = relativePriority; | |||
| thread_policy_set (pthread_mach_thread_np (inThread), | |||
| THREAD_PRECEDENCE_POLICY, | |||
| (thread_policy_t)&thePrecedencePolicy, | |||
| THREAD_PRECEDENCE_POLICY_COUNT); | |||
| } | |||
| } | |||
| #endif /* __PTHREADUTILITIES_H__ */ | |||
| #endif /* __PTHREADUTILITIES_H__ */ | |||
| @@ -4,13 +4,13 @@ | |||
| // Warning: a call to this poll() takes about 4K of stack space. | |||
| // Greg Parker gparker-web@sealiesoftware.com December 2000 | |||
| // This code is in the public domain and may be copied or modified without | |||
| // permission. | |||
| // This code is in the public domain and may be copied or modified without | |||
| // permission. | |||
| // Updated May 2002: | |||
| // Updated May 2002: | |||
| // * fix crash when an fd is less than 0 | |||
| // * set errno=EINVAL if an fd is greater or equal to FD_SETSIZE | |||
| // * don't set POLLIN or POLLOUT in revents if it wasn't requested | |||
| // * don't set POLLIN or POLLOUT in revents if it wasn't requested | |||
| // in events (only happens when an fd is in the poll set twice) | |||
| #ifndef _FAKE_POLL_H | |||
| @@ -24,9 +24,9 @@ | |||
| #include <errno.h> | |||
| typedef struct pollfd { | |||
| int fd; /* file desc to poll */ | |||
| short events; /* events of interest on fd */ | |||
| short revents; /* events that occurred on fd */ | |||
| int fd; /* file desc to poll */ | |||
| short events; /* events of interest on fd */ | |||
| short revents; /* events that occurred on fd */ | |||
| } pollfd_t; | |||
| @@ -47,116 +47,119 @@ typedef struct pollfd { | |||
| #define POLLHUP 0x0010 | |||
| #define POLLNVAL 0x0020 | |||
| static inline int | |||
| poll(struct pollfd *pollSet, int pollCount, int pollTimeout) | |||
| static inline int | |||
| poll (struct pollfd *pollSet, int pollCount, int pollTimeout) | |||
| { | |||
| struct timeval tv; | |||
| struct timeval *tvp; | |||
| fd_set readFDs, writeFDs, exceptFDs; | |||
| fd_set *readp, *writep, *exceptp; | |||
| struct pollfd *pollEnd, *p; | |||
| int selected; | |||
| int result; | |||
| int maxFD; | |||
| if (!pollSet) { | |||
| pollEnd = NULL; | |||
| readp = NULL; | |||
| writep = NULL; | |||
| exceptp = NULL; | |||
| maxFD = 0; | |||
| } | |||
| else { | |||
| pollEnd = pollSet + pollCount; | |||
| readp = &readFDs; | |||
| writep = &writeFDs; | |||
| exceptp = &exceptFDs; | |||
| FD_ZERO(readp); | |||
| FD_ZERO(writep); | |||
| FD_ZERO(exceptp); | |||
| // Find the biggest fd in the poll set | |||
| maxFD = 0; | |||
| for (p = pollSet; p < pollEnd; p++) { | |||
| if (p->fd > maxFD) maxFD = p->fd; | |||
| } | |||
| if (maxFD >= FD_SETSIZE) { | |||
| // At least one fd is too big | |||
| errno = EINVAL; | |||
| return -1; | |||
| } | |||
| // Transcribe flags from the poll set to the fd sets | |||
| for (p = pollSet; p < pollEnd; p++) { | |||
| if (p->fd < 0) { | |||
| // Negative fd checks nothing and always reports zero | |||
| } else { | |||
| if (p->events & POLLIN) FD_SET(p->fd, readp); | |||
| if (p->events & POLLOUT) FD_SET(p->fd, writep); | |||
| if (p->events != 0) { | |||
| FD_SET(p->fd, exceptp); | |||
| } | |||
| // POLLERR is never set coming in; poll() always reports errors | |||
| // But don't report if we're not listening to anything at all. | |||
| } | |||
| } | |||
| } | |||
| // poll timeout is in milliseconds. Convert to struct timeval. | |||
| // poll timeout == -1 : wait forever : select timeout of NULL | |||
| // poll timeout == 0 : return immediately : select timeout of zero | |||
| if (pollTimeout >= 0) { | |||
| tv.tv_sec = pollTimeout / 1000; | |||
| tv.tv_usec = (pollTimeout % 1000) * 1000; | |||
| tvp = &tv; | |||
| } else { | |||
| tvp = NULL; | |||
| } | |||
| selected = select(maxFD+1, readp, writep, exceptp, tvp); | |||
| if (selected < 0) { | |||
| // Error during select | |||
| result = -1; | |||
| } | |||
| else if (selected > 0) { | |||
| // Select found something | |||
| // Transcribe result from fd sets to poll set. | |||
| // Also count the number of selected fds. poll returns the | |||
| // number of ready fds; select returns the number of bits set. | |||
| int polled = 0; | |||
| for (p = pollSet; p < pollEnd; p++) { | |||
| p->revents = 0; | |||
| if (p->fd < 0) { | |||
| // Negative fd always reports zero | |||
| } else { | |||
| if ((p->events & POLLIN) && FD_ISSET(p->fd, readp)) { | |||
| p->revents |= POLLIN; | |||
| } | |||
| if ((p->events & POLLOUT) && FD_ISSET(p->fd, writep)) { | |||
| p->revents |= POLLOUT; | |||
| } | |||
| if ((p->events != 0) && FD_ISSET(p->fd, exceptp)) { | |||
| p->revents |= POLLERR; | |||
| } | |||
| if (p->revents) polled++; | |||
| } | |||
| struct timeval tv; | |||
| struct timeval *tvp; | |||
| fd_set readFDs, writeFDs, exceptFDs; | |||
| fd_set *readp, *writep, *exceptp; | |||
| struct pollfd *pollEnd, *p; | |||
| int selected; | |||
| int result; | |||
| int maxFD; | |||
| if (!pollSet) { | |||
| pollEnd = NULL; | |||
| readp = NULL; | |||
| writep = NULL; | |||
| exceptp = NULL; | |||
| maxFD = 0; | |||
| } else { | |||
| pollEnd = pollSet + pollCount; | |||
| readp = &readFDs; | |||
| writep = &writeFDs; | |||
| exceptp = &exceptFDs; | |||
| FD_ZERO (readp); | |||
| FD_ZERO (writep); | |||
| FD_ZERO (exceptp); | |||
| // Find the biggest fd in the poll set | |||
| maxFD = 0; | |||
| for (p = pollSet; p < pollEnd; p++) | |||
| if (p->fd > maxFD) { | |||
| maxFD = p->fd; | |||
| } | |||
| if (maxFD >= FD_SETSIZE) { | |||
| // At least one fd is too big | |||
| errno = EINVAL; | |||
| return -1; | |||
| } | |||
| // Transcribe flags from the poll set to the fd sets | |||
| for (p = pollSet; p < pollEnd; p++) { | |||
| if (p->fd < 0) { | |||
| // Negative fd checks nothing and always reports zero | |||
| } else { | |||
| if (p->events & POLLIN) { | |||
| FD_SET (p->fd, readp); | |||
| } | |||
| if (p->events & POLLOUT) { | |||
| FD_SET (p->fd, writep); | |||
| } | |||
| if (p->events != 0) { | |||
| FD_SET (p->fd, exceptp); | |||
| } | |||
| // POLLERR is never set coming in; poll() always reports errors | |||
| // But don't report if we're not listening to anything at all. | |||
| } | |||
| } | |||
| } | |||
| result = polled; | |||
| } | |||
| else { | |||
| // selected == 0, select timed out before anything happened | |||
| // Clear all result bits and return zero. | |||
| for (p = pollSet; p < pollEnd; p++) { | |||
| p->revents = 0; | |||
| } | |||
| result = 0; | |||
| } | |||
| return result; | |||
| // poll timeout is in milliseconds. Convert to struct timeval. | |||
| // poll timeout == -1 : wait forever : select timeout of NULL | |||
| // poll timeout == 0 : return immediately : select timeout of zero | |||
| if (pollTimeout >= 0) { | |||
| tv.tv_sec = pollTimeout / 1000; | |||
| tv.tv_usec = (pollTimeout % 1000) * 1000; | |||
| tvp = &tv; | |||
| } else { | |||
| tvp = NULL; | |||
| } | |||
| selected = select (maxFD + 1, readp, writep, exceptp, tvp); | |||
| if (selected < 0) { | |||
| // Error during select | |||
| result = -1; | |||
| } else if (selected > 0) { | |||
| // Select found something | |||
| // Transcribe result from fd sets to poll set. | |||
| // Also count the number of selected fds. poll returns the | |||
| // number of ready fds; select returns the number of bits set. | |||
| int polled = 0; | |||
| for (p = pollSet; p < pollEnd; p++) { | |||
| p->revents = 0; | |||
| if (p->fd < 0) { | |||
| // Negative fd always reports zero | |||
| } else { | |||
| if ((p->events & POLLIN) && FD_ISSET (p->fd, readp)) { | |||
| p->revents |= POLLIN; | |||
| } | |||
| if ((p->events & POLLOUT) && FD_ISSET (p->fd, writep)) { | |||
| p->revents |= POLLOUT; | |||
| } | |||
| if ((p->events != 0) && FD_ISSET (p->fd, exceptp)) { | |||
| p->revents |= POLLERR; | |||
| } | |||
| if (p->revents) { | |||
| polled++; | |||
| } | |||
| } | |||
| } | |||
| result = polled; | |||
| } else { | |||
| // selected == 0, select timed out before anything happened | |||
| // Clear all result bits and return zero. | |||
| for (p = pollSet; p < pollEnd; p++) | |||
| p->revents = 0; | |||
| result = 0; | |||
| } | |||
| return result; | |||
| } | |||
| #endif | |||
| @@ -1,21 +1,21 @@ | |||
| /* | |||
| Copyright (C) 2001-2003 Paul Davis | |||
| 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 | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| */ | |||
| */ | |||
| #ifndef __jack_time_c__ | |||
| #define __jack_time_c__ | |||
| @@ -25,12 +25,13 @@ | |||
| double __jack_time_ratio; | |||
| void | |||
| void | |||
| jack_init_time () | |||
| { | |||
| mach_timebase_info_data_t info; | |||
| mach_timebase_info(&info); | |||
| __jack_time_ratio = ((float)info.numer/info.denom) / 1000; | |||
| mach_timebase_info_data_t info; | |||
| mach_timebase_info (&info); | |||
| __jack_time_ratio = ((float)info.numer / info.denom) / 1000; | |||
| } | |||
| void jack_set_clock_source (jack_timer_type_t clocksrc) | |||
| @@ -38,9 +39,9 @@ void jack_set_clock_source (jack_timer_type_t clocksrc) | |||
| /* only one clock source for os x */ | |||
| } | |||
| jack_time_t | |||
| jack_get_microseconds_symbol(void) | |||
| { | |||
| return (jack_time_t) mach_absolute_time () * __jack_time_ratio; | |||
| jack_time_t | |||
| jack_get_microseconds_symbol (void) | |||
| { | |||
| return (jack_time_t)mach_absolute_time () * __jack_time_ratio; | |||
| } | |||
| #endif /* __jack_time_c__ */ | |||
| @@ -1,21 +1,21 @@ | |||
| /* | |||
| Copyright (C) 2001-2003 Paul Davis | |||
| 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 | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| */ | |||
| */ | |||
| #ifndef __jack_time_h__ | |||
| #define __jack_time_h__ | |||
| @@ -25,16 +25,16 @@ | |||
| extern double __jack_time_ratio; | |||
| static inline jack_time_t | |||
| jack_get_microseconds(void) | |||
| { | |||
| return (jack_time_t) mach_absolute_time () * __jack_time_ratio; | |||
| static inline jack_time_t | |||
| jack_get_microseconds (void) | |||
| { | |||
| return (jack_time_t)mach_absolute_time () * __jack_time_ratio; | |||
| } | |||
| extern jack_time_t jack_get_microseconds_symbol(void); | |||
| typedef jack_time_t (*jack_get_microseconds_t)(void); | |||
| static inline jack_get_microseconds_t jack_get_microseconds_pointer(void) | |||
| static inline jack_get_microseconds_t jack_get_microseconds_pointer (void) | |||
| { | |||
| return jack_get_microseconds_symbol; | |||
| } | |||
| @@ -19,6 +19,6 @@ | |||
| #include <config/cpu/generic/atomicity.h> | |||
| #endif /* processor selection */ | |||
| #endif /* processor selection */ | |||
| #endif /* _jack_sysdep_atomicity_h_ */ | |||
| #endif /* _jack_sysdep_atomicity_h_ */ | |||
| @@ -2,12 +2,12 @@ | |||
| #define _jack_sysdep_cycles_h_ | |||
| #if defined(__i386__) | |||
| /* technically, i386 doesn't have a cycle counter, but | |||
| running JACK on a real i386 seems like a ridiculuous | |||
| target and gcc defines this for the entire x86 family | |||
| including the [456]86 that do have the counter. | |||
| */ | |||
| */ | |||
| #include <config/cpu/i386/cycles.h> | |||
| @@ -23,6 +23,6 @@ | |||
| #include <config/cpu/generic/cycles.h> | |||
| #endif /* processor selection */ | |||
| #endif /* processor selection */ | |||
| #endif /* _jack_sysdep_cycles_h_ */ | |||
| #endif /* _jack_sysdep_cycles_h_ */ | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| Copyright (C) 2001 Paul Davis | |||
| 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 | |||
| @@ -15,7 +15,7 @@ | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| */ | |||
| #ifndef __jack_alsa_driver_h__ | |||
| #define __jack_alsa_driver_h__ | |||
| @@ -38,180 +38,183 @@ | |||
| #include "driver.h" | |||
| #include "memops.h" | |||
| typedef void (*ReadCopyFunction) (jack_default_audio_sample_t *dst, char *src, | |||
| unsigned long src_bytes, | |||
| unsigned long src_skip_bytes); | |||
| typedef void (*WriteCopyFunction) (char *dst, jack_default_audio_sample_t *src, | |||
| unsigned long src_bytes, | |||
| unsigned long dst_skip_bytes, | |||
| dither_state_t *state); | |||
| typedef void (*ReadCopyFunction)(jack_default_audio_sample_t *dst, char *src, | |||
| unsigned long src_bytes, | |||
| unsigned long src_skip_bytes); | |||
| typedef void (*WriteCopyFunction)(char *dst, jack_default_audio_sample_t *src, | |||
| unsigned long src_bytes, | |||
| unsigned long dst_skip_bytes, | |||
| dither_state_t *state); | |||
| typedef struct _alsa_driver { | |||
| JACK_DRIVER_NT_DECL | |||
| int poll_timeout; | |||
| jack_time_t poll_last; | |||
| jack_time_t poll_next; | |||
| char **playback_addr; | |||
| char **capture_addr; | |||
| const snd_pcm_channel_area_t *capture_areas; | |||
| const snd_pcm_channel_area_t *playback_areas; | |||
| struct pollfd *pfd; | |||
| unsigned int playback_nfds; | |||
| unsigned int capture_nfds; | |||
| unsigned long interleave_unit; | |||
| unsigned long *capture_interleave_skip; | |||
| unsigned long *playback_interleave_skip; | |||
| channel_t max_nchannels; | |||
| channel_t user_nchannels; | |||
| channel_t playback_nchannels; | |||
| channel_t capture_nchannels; | |||
| unsigned long playback_sample_bytes; | |||
| unsigned long capture_sample_bytes; | |||
| jack_nframes_t frame_rate; | |||
| jack_nframes_t frames_per_cycle; | |||
| jack_nframes_t capture_frame_latency; | |||
| jack_nframes_t playback_frame_latency; | |||
| unsigned long *silent; | |||
| char *alsa_name_playback; | |||
| char *alsa_name_capture; | |||
| char *alsa_driver; | |||
| bitset_t channels_not_done; | |||
| bitset_t channels_done; | |||
| snd_pcm_format_t playback_sample_format; | |||
| snd_pcm_format_t capture_sample_format; | |||
| float max_sample_val; | |||
| unsigned long user_nperiods; | |||
| unsigned int playback_nperiods; | |||
| unsigned int capture_nperiods; | |||
| unsigned long last_mask; | |||
| snd_ctl_t *ctl_handle; | |||
| snd_pcm_t *playback_handle; | |||
| snd_pcm_t *capture_handle; | |||
| snd_pcm_hw_params_t *playback_hw_params; | |||
| snd_pcm_sw_params_t *playback_sw_params; | |||
| snd_pcm_hw_params_t *capture_hw_params; | |||
| snd_pcm_sw_params_t *capture_sw_params; | |||
| jack_hardware_t *hw; | |||
| ClockSyncStatus *clock_sync_data; | |||
| jack_client_t *client; | |||
| JSList *capture_ports; | |||
| JSList *playback_ports; | |||
| JSList *monitor_ports; | |||
| unsigned long input_monitor_mask; | |||
| char soft_mode; | |||
| char hw_monitoring; | |||
| char hw_metering; | |||
| char all_monitor_in; | |||
| char capture_and_playback_not_synced; | |||
| char playback_interleaved; | |||
| char capture_interleaved; | |||
| char with_monitor_ports; | |||
| char has_clock_sync_reporting; | |||
| char has_hw_monitoring; | |||
| char has_hw_metering; | |||
| char quirk_bswap; | |||
| ReadCopyFunction read_via_copy; | |||
| WriteCopyFunction write_via_copy; | |||
| int dither; | |||
| dither_state_t *dither_state; | |||
| SampleClockMode clock_mode; | |||
| JSList *clock_sync_listeners; | |||
| pthread_mutex_t clock_sync_lock; | |||
| unsigned long next_clock_sync_listener_id; | |||
| int running; | |||
| int run; | |||
| int poll_late; | |||
| int xrun_count; | |||
| int process_count; | |||
| int xrun_recovery; | |||
| int previously_successfully_configured; | |||
| JACK_DRIVER_NT_DECL | |||
| int poll_timeout; | |||
| jack_time_t poll_last; | |||
| jack_time_t poll_next; | |||
| char **playback_addr; | |||
| char **capture_addr; | |||
| const snd_pcm_channel_area_t *capture_areas; | |||
| const snd_pcm_channel_area_t *playback_areas; | |||
| struct pollfd *pfd; | |||
| unsigned int playback_nfds; | |||
| unsigned int capture_nfds; | |||
| unsigned long interleave_unit; | |||
| unsigned long *capture_interleave_skip; | |||
| unsigned long *playback_interleave_skip; | |||
| channel_t max_nchannels; | |||
| channel_t user_nchannels; | |||
| channel_t playback_nchannels; | |||
| channel_t capture_nchannels; | |||
| unsigned long playback_sample_bytes; | |||
| unsigned long capture_sample_bytes; | |||
| jack_nframes_t frame_rate; | |||
| jack_nframes_t frames_per_cycle; | |||
| jack_nframes_t capture_frame_latency; | |||
| jack_nframes_t playback_frame_latency; | |||
| unsigned long *silent; | |||
| char *alsa_name_playback; | |||
| char *alsa_name_capture; | |||
| char *alsa_driver; | |||
| bitset_t channels_not_done; | |||
| bitset_t channels_done; | |||
| snd_pcm_format_t playback_sample_format; | |||
| snd_pcm_format_t capture_sample_format; | |||
| float max_sample_val; | |||
| unsigned long user_nperiods; | |||
| unsigned int playback_nperiods; | |||
| unsigned int capture_nperiods; | |||
| unsigned long last_mask; | |||
| snd_ctl_t *ctl_handle; | |||
| snd_pcm_t *playback_handle; | |||
| snd_pcm_t *capture_handle; | |||
| snd_pcm_hw_params_t *playback_hw_params; | |||
| snd_pcm_sw_params_t *playback_sw_params; | |||
| snd_pcm_hw_params_t *capture_hw_params; | |||
| snd_pcm_sw_params_t *capture_sw_params; | |||
| jack_hardware_t *hw; | |||
| ClockSyncStatus *clock_sync_data; | |||
| jack_client_t *client; | |||
| JSList *capture_ports; | |||
| JSList *playback_ports; | |||
| JSList *monitor_ports; | |||
| unsigned long input_monitor_mask; | |||
| char soft_mode; | |||
| char hw_monitoring; | |||
| char hw_metering; | |||
| char all_monitor_in; | |||
| char capture_and_playback_not_synced; | |||
| char playback_interleaved; | |||
| char capture_interleaved; | |||
| char with_monitor_ports; | |||
| char has_clock_sync_reporting; | |||
| char has_hw_monitoring; | |||
| char has_hw_metering; | |||
| char quirk_bswap; | |||
| ReadCopyFunction read_via_copy; | |||
| WriteCopyFunction write_via_copy; | |||
| int dither; | |||
| dither_state_t *dither_state; | |||
| SampleClockMode clock_mode; | |||
| JSList *clock_sync_listeners; | |||
| pthread_mutex_t clock_sync_lock; | |||
| unsigned long next_clock_sync_listener_id; | |||
| int running; | |||
| int run; | |||
| int poll_late; | |||
| int xrun_count; | |||
| int process_count; | |||
| int xrun_recovery; | |||
| int previously_successfully_configured; | |||
| } alsa_driver_t; | |||
| static inline void | |||
| alsa_driver_mark_channel_done (alsa_driver_t *driver, channel_t chn) { | |||
| static inline void | |||
| alsa_driver_mark_channel_done (alsa_driver_t *driver, channel_t chn) | |||
| { | |||
| bitset_remove (driver->channels_not_done, chn); | |||
| driver->silent[chn] = 0; | |||
| } | |||
| static inline void | |||
| static inline void | |||
| alsa_driver_silence_on_channel (alsa_driver_t *driver, channel_t chn, | |||
| jack_nframes_t nframes) { | |||
| jack_nframes_t nframes) | |||
| { | |||
| if (driver->playback_interleaved) { | |||
| memset_interleave | |||
| memset_interleave | |||
| (driver->playback_addr[chn], | |||
| 0, nframes * driver->playback_sample_bytes, | |||
| driver->interleave_unit, | |||
| driver->playback_interleave_skip[chn]); | |||
| 0, nframes * driver->playback_sample_bytes, | |||
| driver->interleave_unit, | |||
| driver->playback_interleave_skip[chn]); | |||
| } else { | |||
| memset (driver->playback_addr[chn], 0, | |||
| nframes * driver->playback_sample_bytes); | |||
| } | |||
| alsa_driver_mark_channel_done (driver,chn); | |||
| alsa_driver_mark_channel_done (driver, chn); | |||
| } | |||
| static inline void | |||
| static inline void | |||
| alsa_driver_silence_on_channel_no_mark (alsa_driver_t *driver, channel_t chn, | |||
| jack_nframes_t nframes) { | |||
| jack_nframes_t nframes) | |||
| { | |||
| if (driver->playback_interleaved) { | |||
| memset_interleave | |||
| memset_interleave | |||
| (driver->playback_addr[chn], | |||
| 0, nframes * driver->playback_sample_bytes, | |||
| driver->interleave_unit, | |||
| driver->playback_interleave_skip[chn]); | |||
| 0, nframes * driver->playback_sample_bytes, | |||
| driver->interleave_unit, | |||
| driver->playback_interleave_skip[chn]); | |||
| } else { | |||
| memset (driver->playback_addr[chn], 0, | |||
| nframes * driver->playback_sample_bytes); | |||
| } | |||
| } | |||
| static inline void | |||
| static inline void | |||
| alsa_driver_read_from_channel (alsa_driver_t *driver, | |||
| channel_t channel, | |||
| jack_default_audio_sample_t *buf, | |||
| jack_nframes_t nsamples) | |||
| { | |||
| driver->read_via_copy (buf, | |||
| driver->read_via_copy (buf, | |||
| driver->capture_addr[channel], | |||
| nsamples, | |||
| nsamples, | |||
| driver->capture_interleave_skip[channel]); | |||
| } | |||
| static inline void | |||
| static inline void | |||
| alsa_driver_write_to_channel (alsa_driver_t *driver, | |||
| channel_t channel, | |||
| jack_default_audio_sample_t *buf, | |||
| channel_t channel, | |||
| jack_default_audio_sample_t *buf, | |||
| jack_nframes_t nsamples) | |||
| { | |||
| driver->write_via_copy (driver->playback_addr[channel], | |||
| buf, | |||
| nsamples, | |||
| buf, | |||
| nsamples, | |||
| driver->playback_interleave_skip[channel], | |||
| driver->dither_state+channel); | |||
| driver->dither_state + channel); | |||
| alsa_driver_mark_channel_done (driver, channel); | |||
| } | |||
| void alsa_driver_silence_untouched_channels (alsa_driver_t *driver, | |||
| jack_nframes_t nframes); | |||
| void alsa_driver_set_clock_sync_status (alsa_driver_t *driver, channel_t chn, | |||
| ClockSyncStatus status); | |||
| int alsa_driver_listen_for_clock_sync_status (alsa_driver_t *, | |||
| ClockSyncListenerFunction, | |||
| void *arg); | |||
| int alsa_driver_stop_listen_for_clock_sync_status (alsa_driver_t *, | |||
| unsigned int); | |||
| void alsa_driver_clock_sync_notify (alsa_driver_t *, channel_t chn, | |||
| ClockSyncStatus); | |||
| void alsa_driver_silence_untouched_channels(alsa_driver_t *driver, | |||
| jack_nframes_t nframes); | |||
| void alsa_driver_set_clock_sync_status(alsa_driver_t *driver, channel_t chn, | |||
| ClockSyncStatus status); | |||
| int alsa_driver_listen_for_clock_sync_status (alsa_driver_t *, | |||
| ClockSyncListenerFunction, | |||
| void *arg); | |||
| int alsa_driver_stop_listen_for_clock_sync_status(alsa_driver_t *, | |||
| unsigned int); | |||
| void alsa_driver_clock_sync_notify (alsa_driver_t *, channel_t chn, | |||
| ClockSyncStatus); | |||
| #endif /* __jack_alsa_driver_h__ */ | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| 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 | |||
| @@ -15,12 +15,12 @@ | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| */ | |||
| #ifndef __jack_generic_h__ | |||
| #define __jack_generic_h__ | |||
| jack_hardware_t * | |||
| jack_alsa_generic_hw_new (alsa_driver_t *driver); | |||
| jack_alsa_generic_hw_new(alsa_driver_t *driver); | |||
| #endif /* __jack_generic_h__*/ | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| Copyright (C) 2001 Paul Davis | |||
| 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 | |||
| @@ -15,7 +15,7 @@ | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| */ | |||
| #include "hardware.h" | |||
| #include "alsa_driver.h" | |||
| @@ -25,7 +25,7 @@ static int generic_set_input_monitor_mask (jack_hardware_t *hw, unsigned long ma | |||
| return -1; | |||
| } | |||
| static int generic_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode) | |||
| static int generic_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode) | |||
| { | |||
| return -1; | |||
| } | |||
| @@ -42,11 +42,11 @@ jack_alsa_generic_hw_new (alsa_driver_t *driver) | |||
| { | |||
| jack_hardware_t *hw; | |||
| hw = (jack_hardware_t *) malloc (sizeof (jack_hardware_t)); | |||
| hw = (jack_hardware_t*)malloc (sizeof(jack_hardware_t)); | |||
| hw->capabilities = 0; | |||
| hw->input_monitor_mask = 0; | |||
| hw->set_input_monitor_mask = generic_set_input_monitor_mask; | |||
| hw->change_sample_clock = generic_change_sample_clock; | |||
| hw->release = generic_release; | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| Copyright (C) 2001 Paul Davis | |||
| 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 | |||
| @@ -15,7 +15,7 @@ | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| */ | |||
| #include "hardware.h" | |||
| #include "alsa_driver.h" | |||
| @@ -26,7 +26,7 @@ | |||
| * warning: `hammerfall_monitor_controls' defined but not used */ | |||
| #define HAMMERFALL_MONITOR_CONTROLS 0 | |||
| static void | |||
| static void | |||
| set_control_id (snd_ctl_elem_id_t *ctl, const char *name) | |||
| { | |||
| snd_ctl_elem_id_set_name (ctl, name); | |||
| @@ -57,9 +57,8 @@ hammerfall_broadcast_channel_status_change (hammerfall_t *h, int lock, int sync, | |||
| status |= NoSync; | |||
| } | |||
| for (chn = lowchn; chn < highchn; chn++) { | |||
| for (chn = lowchn; chn < highchn; chn++) | |||
| alsa_driver_set_clock_sync_status (h->driver, chn, status); | |||
| } | |||
| } | |||
| static void | |||
| @@ -74,12 +73,12 @@ hammerfall_check_sync_state (hammerfall_t *h, int val, int adat_id) | |||
| XXX - maybe need to make sure that the rate matches our | |||
| idea of the current rate ? | |||
| */ | |||
| */ | |||
| if (!h->said_that_spdif_is_fine) { | |||
| ClockSyncStatus status; | |||
| status = Lock|Sync; | |||
| status = Lock | Sync; | |||
| /* XXX broken! fix for hammerfall light ! */ | |||
| @@ -91,10 +90,10 @@ hammerfall_check_sync_state (hammerfall_t *h, int val, int adat_id) | |||
| lock = (val & 0x1) ? TRUE : FALSE; | |||
| sync = (val & 0x2) ? TRUE : FALSE; | |||
| if (h->lock_status[adat_id] != lock || | |||
| h->sync_status[adat_id] != sync) { | |||
| hammerfall_broadcast_channel_status_change (h, lock, sync, adat_id*8, (adat_id*8)+8); | |||
| hammerfall_broadcast_channel_status_change (h, lock, sync, adat_id * 8, (adat_id * 8) + 8); | |||
| } | |||
| h->lock_status[adat_id] = lock; | |||
| @@ -108,7 +107,7 @@ hammerfall_check_sync (hammerfall_t *h, snd_ctl_elem_value_t *ctl) | |||
| const char *name; | |||
| int val; | |||
| snd_ctl_elem_id_t *ctl_id; | |||
| jack_info ("check sync"); | |||
| snd_ctl_elem_id_alloca (&ctl_id); | |||
| @@ -131,38 +130,37 @@ hammerfall_check_sync (hammerfall_t *h, snd_ctl_elem_value_t *ctl) | |||
| } | |||
| #endif /* HAMMERFALL_MONITOR_CONTROLS */ | |||
| static int | |||
| static int | |||
| hammerfall_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask) | |||
| { | |||
| hammerfall_t *h = (hammerfall_t *) hw->private; | |||
| hammerfall_t *h = (hammerfall_t*)hw->private; | |||
| snd_ctl_elem_value_t *ctl; | |||
| snd_ctl_elem_id_t *ctl_id; | |||
| int err; | |||
| int i; | |||
| snd_ctl_elem_value_alloca (&ctl); | |||
| snd_ctl_elem_id_alloca (&ctl_id); | |||
| set_control_id (ctl_id, "Channels Thru"); | |||
| snd_ctl_elem_value_set_id (ctl, ctl_id); | |||
| for (i = 0; i < 26; i++) { | |||
| snd_ctl_elem_value_set_integer (ctl, i, (mask & (1<<i)) ? 1 : 0); | |||
| } | |||
| for (i = 0; i < 26; i++) | |||
| snd_ctl_elem_value_set_integer (ctl, i, (mask & (1 << i)) ? 1 : 0); | |||
| if ((err = snd_ctl_elem_write (h->driver->ctl_handle, ctl)) != 0) { | |||
| jack_error ("ALSA/Hammerfall: cannot set input monitoring (%s)", snd_strerror (err)); | |||
| return -1; | |||
| } | |||
| hw->input_monitor_mask = mask; | |||
| return 0; | |||
| } | |||
| static int | |||
| hammerfall_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode) | |||
| static int | |||
| hammerfall_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode) | |||
| { | |||
| hammerfall_t *h = (hammerfall_t *) hw->private; | |||
| hammerfall_t *h = (hammerfall_t*)hw->private; | |||
| snd_ctl_elem_value_t *ctl; | |||
| snd_ctl_elem_id_t *ctl_id; | |||
| int err; | |||
| @@ -195,7 +193,7 @@ static void | |||
| hammerfall_release (jack_hardware_t *hw) | |||
| { | |||
| hammerfall_t *h = (hammerfall_t *) hw->private; | |||
| hammerfall_t *h = (hammerfall_t*)hw->private; | |||
| void *status; | |||
| if (h == 0) { | |||
| @@ -212,8 +210,8 @@ hammerfall_release (jack_hardware_t *hw) | |||
| static void * | |||
| hammerfall_monitor_controls (void *arg) | |||
| { | |||
| jack_hardware_t *hw = (jack_hardware_t *) arg; | |||
| hammerfall_t *h = (hammerfall_t *) hw->private; | |||
| jack_hardware_t *hw = (jack_hardware_t*)arg; | |||
| hammerfall_t *h = (hammerfall_t*)hw->private; | |||
| snd_ctl_elem_id_t *switch_id[3]; | |||
| snd_ctl_elem_value_t *sw[3]; | |||
| @@ -250,7 +248,7 @@ hammerfall_monitor_controls (void *arg) | |||
| jack_error ("cannot read control switch 0 ..."); | |||
| } | |||
| hammerfall_check_sync (h, sw[2]); | |||
| if (nanosleep (&h->monitor_interval, 0)) { | |||
| break; | |||
| } | |||
| @@ -267,9 +265,9 @@ jack_alsa_hammerfall_hw_new (alsa_driver_t *driver) | |||
| jack_hardware_t *hw; | |||
| hammerfall_t *h; | |||
| hw = (jack_hardware_t *) malloc (sizeof (jack_hardware_t)); | |||
| hw = (jack_hardware_t*)malloc (sizeof(jack_hardware_t)); | |||
| hw->capabilities = Cap_HardwareMonitoring|Cap_AutoSync|Cap_WordClock|Cap_ClockMaster|Cap_ClockLockReporting; | |||
| hw->capabilities = Cap_HardwareMonitoring | Cap_AutoSync | Cap_WordClock | Cap_ClockMaster | Cap_ClockLockReporting; | |||
| hw->input_monitor_mask = 0; | |||
| hw->private = 0; | |||
| @@ -277,7 +275,7 @@ jack_alsa_hammerfall_hw_new (alsa_driver_t *driver) | |||
| hw->change_sample_clock = hammerfall_change_sample_clock; | |||
| hw->release = hammerfall_release; | |||
| h = (hammerfall_t *) malloc (sizeof (hammerfall_t)); | |||
| h = (hammerfall_t*)malloc (sizeof(hammerfall_t)); | |||
| h->lock_status[0] = FALSE; | |||
| h->sync_status[0] = FALSE; | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| 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 | |||
| @@ -15,7 +15,7 @@ | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| */ | |||
| #ifndef __jack_hammerfall_h__ | |||
| #define __jack_hammerfall_h__ | |||
| @@ -23,14 +23,14 @@ | |||
| #include <sys/time.h> | |||
| typedef struct { | |||
| int lock_status[3]; | |||
| int sync_status[3]; | |||
| int said_that_spdif_is_fine; | |||
| pthread_t monitor_thread; | |||
| alsa_driver_t *driver; | |||
| struct timespec monitor_interval; | |||
| int lock_status[3]; | |||
| int sync_status[3]; | |||
| int said_that_spdif_is_fine; | |||
| pthread_t monitor_thread; | |||
| alsa_driver_t *driver; | |||
| struct timespec monitor_interval; | |||
| } hammerfall_t; | |||
| jack_hardware_t *jack_alsa_hammerfall_hw_new (alsa_driver_t *driver); | |||
| jack_hardware_t *jack_alsa_hammerfall_hw_new(alsa_driver_t *driver); | |||
| #endif /* __jack_hammerfall_h__*/ | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| Copyright (C) 2001 Paul Davis | |||
| Copyright (C) 2001 Paul Davis | |||
| Copyright (C) 2002 Dave LaRose | |||
| This program is free software; you can redistribute it and/or modify | |||
| @@ -16,7 +16,7 @@ | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| */ | |||
| #include "hardware.h" | |||
| #include "alsa_driver.h" | |||
| @@ -29,45 +29,48 @@ static const int HDSP_UNITY_GAIN = 32768; | |||
| static const int HDSP_MAX_GAIN = 65535; | |||
| /* | |||
| * Use these two arrays to choose the value of the input_channel | |||
| * argument to hsdp_set_mixer_gain(). hdsp_physical_input_index[n] | |||
| * selects the nth optical/analog input. audio_stream_index[n] | |||
| * Use these two arrays to choose the value of the input_channel | |||
| * argument to hsdp_set_mixer_gain(). hdsp_physical_input_index[n] | |||
| * selects the nth optical/analog input. audio_stream_index[n] | |||
| * selects the nth channel being received from the host via pci/pccard. | |||
| */ | |||
| static const int hdsp_num_input_channels = 52; | |||
| static const int hdsp_physical_input_index[] = { | |||
| 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, | |||
| 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}; | |||
| 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, | |||
| 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,24, 25 | |||
| }; | |||
| static const int hdsp_audio_stream_index[] = { | |||
| 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, | |||
| 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51}; | |||
| 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, | |||
| 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,50, 51 | |||
| }; | |||
| /* | |||
| * Use this array to choose the value of the output_channel | |||
| * Use this array to choose the value of the output_channel | |||
| * argument to hsdp_set_mixer_gain(). hdsp_physical_output_index[26] | |||
| * and hdsp_physical_output_index[27] refer to the two "line out" | |||
| * channels (1/4" phone jack on the front of digiface/multiface). | |||
| */ | |||
| static const int hdsp_num_output_channels = 28; | |||
| static const int hdsp_physical_output_index[] = { | |||
| 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, | |||
| 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27}; | |||
| 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, | |||
| 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,24, 25, 26, 27 | |||
| }; | |||
| /* Function for checking argument values */ | |||
| static int clamp_int(int value, int lower_bound, int upper_bound) | |||
| static int clamp_int (int value, int lower_bound, int upper_bound) | |||
| { | |||
| if(value < lower_bound) { | |||
| return lower_bound; | |||
| } | |||
| if(value > upper_bound) { | |||
| return upper_bound; | |||
| } | |||
| return value; | |||
| if (value < lower_bound) { | |||
| return lower_bound; | |||
| } | |||
| if (value > upper_bound) { | |||
| return upper_bound; | |||
| } | |||
| return value; | |||
| } | |||
| /* Note(XXX): Maybe should share this code with hammerfall.c? */ | |||
| static void | |||
| static void | |||
| set_control_id (snd_ctl_elem_id_t *ctl, const char *name) | |||
| { | |||
| snd_ctl_elem_id_set_name (ctl, name); | |||
| @@ -86,18 +89,18 @@ set_control_id (snd_ctl_elem_id_t *ctl, const char *name) | |||
| /* gain is an int from 0 to 65535, with 0 being -inf gain, and */ | |||
| /* 65535 being about +2dB. */ | |||
| static int hdsp_set_mixer_gain(jack_hardware_t *hw, int input_channel, | |||
| int output_channel, int gain) | |||
| static int hdsp_set_mixer_gain (jack_hardware_t *hw, int input_channel, | |||
| int output_channel, int gain) | |||
| { | |||
| hdsp_t *h = (hdsp_t *) hw->private; | |||
| hdsp_t *h = (hdsp_t*)hw->private; | |||
| snd_ctl_elem_value_t *ctl; | |||
| snd_ctl_elem_id_t *ctl_id; | |||
| int err; | |||
| /* Check args */ | |||
| input_channel = clamp_int(input_channel, 0, hdsp_num_input_channels); | |||
| output_channel = clamp_int(output_channel, 0, hdsp_num_output_channels); | |||
| gain = clamp_int(gain, HDSP_MINUS_INFINITY_GAIN, HDSP_MAX_GAIN); | |||
| input_channel = clamp_int (input_channel, 0, hdsp_num_input_channels); | |||
| output_channel = clamp_int (output_channel, 0, hdsp_num_output_channels); | |||
| gain = clamp_int (gain, HDSP_MINUS_INFINITY_GAIN, HDSP_MAX_GAIN); | |||
| /* Allocate control element and select "Mixer" control */ | |||
| snd_ctl_elem_value_alloca (&ctl); | |||
| @@ -106,15 +109,15 @@ static int hdsp_set_mixer_gain(jack_hardware_t *hw, int input_channel, | |||
| snd_ctl_elem_value_set_id (ctl, ctl_id); | |||
| /* Apparently non-standard and unstable interface for the */ | |||
| /* mixer control. */ | |||
| /* mixer control. */ | |||
| snd_ctl_elem_value_set_integer (ctl, 0, input_channel); | |||
| snd_ctl_elem_value_set_integer (ctl, 1, output_channel); | |||
| snd_ctl_elem_value_set_integer (ctl, 2, gain); | |||
| /* Commit the mixer value and check for errors */ | |||
| if ((err = snd_ctl_elem_write (h->driver->ctl_handle, ctl)) != 0) { | |||
| jack_error ("ALSA/HDSP: cannot set mixer gain (%s)", snd_strerror (err)); | |||
| return -1; | |||
| jack_error ("ALSA/HDSP: cannot set mixer gain (%s)", snd_strerror (err)); | |||
| return -1; | |||
| } | |||
| /* Note (XXX): Perhaps we should maintain a cache of the current */ | |||
| @@ -122,7 +125,7 @@ static int hdsp_set_mixer_gain(jack_hardware_t *hw, int input_channel, | |||
| /* hdsp hardware. We'll leave this out until a little later. */ | |||
| return 0; | |||
| } | |||
| static int hdsp_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask) | |||
| { | |||
| int i; | |||
| @@ -130,40 +133,40 @@ static int hdsp_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask) | |||
| /* For each input channel */ | |||
| for (i = 0; i < 26; i++) { | |||
| /* Monitoring requested for this channel? */ | |||
| if(mask & (1<<i)) { | |||
| if (mask & (1 << i)) { | |||
| /* Yes. Connect physical input to output */ | |||
| if(hdsp_set_mixer_gain (hw, hdsp_physical_input_index[i], | |||
| hdsp_physical_output_index[i], | |||
| HDSP_UNITY_GAIN) != 0) { | |||
| return -1; | |||
| if (hdsp_set_mixer_gain (hw, hdsp_physical_input_index[i], | |||
| hdsp_physical_output_index[i], | |||
| HDSP_UNITY_GAIN) != 0) { | |||
| return -1; | |||
| } | |||
| #ifdef CANNOT_HEAR_SOFTWARE_STREAM_WHEN_MONITORING | |||
| /* ...and disconnect the corresponding software */ | |||
| /* channel */ | |||
| if(hdsp_set_mixer_gain (hw, hdsp_audio_stream_index[i], | |||
| hdsp_physical_output_index[i], | |||
| HDSP_MINUS_INFINITY_GAIN) != 0) { | |||
| return -1; | |||
| if (hdsp_set_mixer_gain (hw, hdsp_audio_stream_index[i], | |||
| hdsp_physical_output_index[i], | |||
| HDSP_MINUS_INFINITY_GAIN) != 0) { | |||
| return -1; | |||
| } | |||
| #endif | |||
| } else { | |||
| /* No. Disconnect physical input from output */ | |||
| if(hdsp_set_mixer_gain (hw, hdsp_physical_input_index[i], | |||
| hdsp_physical_output_index[i], | |||
| HDSP_MINUS_INFINITY_GAIN) != 0) { | |||
| return -1; | |||
| if (hdsp_set_mixer_gain (hw, hdsp_physical_input_index[i], | |||
| hdsp_physical_output_index[i], | |||
| HDSP_MINUS_INFINITY_GAIN) != 0) { | |||
| return -1; | |||
| } | |||
| #ifdef CANNOT_HEAR_SOFTWARE_STREAM_WHEN_MONITORING | |||
| /* ...and connect the corresponding software */ | |||
| /* channel */ | |||
| if(hdsp_set_mixer_gain (hw, hdsp_audio_stream_index[i], | |||
| hdsp_physical_output_index[i], | |||
| HDSP_UNITY_GAIN) != 0) { | |||
| return -1; | |||
| if (hdsp_set_mixer_gain (hw, hdsp_audio_stream_index[i], | |||
| hdsp_physical_output_index[i], | |||
| HDSP_UNITY_GAIN) != 0) { | |||
| return -1; | |||
| } | |||
| #endif | |||
| } | |||
| @@ -174,11 +177,11 @@ static int hdsp_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask) | |||
| } | |||
| static int hdsp_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode) | |||
| static int hdsp_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode) | |||
| { | |||
| // Empty for now, until Dave understands more about clock sync so | |||
| // he can test. | |||
| return -1; | |||
| // Empty for now, until Dave understands more about clock sync so | |||
| // he can test. | |||
| return -1; | |||
| } | |||
| static double hdsp_get_hardware_peak (jack_port_t *port, jack_nframes_t frame) | |||
| @@ -194,10 +197,10 @@ static double hdsp_get_hardware_power (jack_port_t *port, jack_nframes_t frame) | |||
| static void | |||
| hdsp_release (jack_hardware_t *hw) | |||
| { | |||
| hdsp_t *h = (hdsp_t *) hw->private; | |||
| hdsp_t *h = (hdsp_t*)hw->private; | |||
| if (h != 0) { | |||
| free (h); | |||
| free (h); | |||
| } | |||
| } | |||
| @@ -209,7 +212,7 @@ jack_alsa_hdsp_hw_new (alsa_driver_t *driver) | |||
| jack_hardware_t *hw; | |||
| hdsp_t *h; | |||
| hw = (jack_hardware_t *) malloc (sizeof (jack_hardware_t)); | |||
| hw = (jack_hardware_t*)malloc (sizeof(jack_hardware_t)); | |||
| /* Not using clock lock-sync-whatever in home hardware setup */ | |||
| /* yet. Will write this code when can test it. */ | |||
| @@ -223,8 +226,8 @@ jack_alsa_hdsp_hw_new (alsa_driver_t *driver) | |||
| hw->release = hdsp_release; | |||
| hw->get_hardware_peak = hdsp_get_hardware_peak; | |||
| hw->get_hardware_power = hdsp_get_hardware_power; | |||
| h = (hdsp_t *) malloc (sizeof (hdsp_t)); | |||
| h = (hdsp_t*)malloc (sizeof(hdsp_t)); | |||
| h->driver = driver; | |||
| hw->private = h; | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| 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 | |||
| @@ -15,7 +15,7 @@ | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| */ | |||
| #ifndef __jack_hdsp_h__ | |||
| #define __jack_hdsp_h__ | |||
| @@ -23,10 +23,10 @@ | |||
| #include <sys/time.h> | |||
| typedef struct { | |||
| alsa_driver_t *driver; | |||
| alsa_driver_t *driver; | |||
| } hdsp_t; | |||
| jack_hardware_t * | |||
| jack_alsa_hdsp_hw_new (alsa_driver_t *driver); | |||
| jack_alsa_hdsp_hw_new(alsa_driver_t *driver); | |||
| #endif /* __jack_hdsp_h__*/ | |||
| @@ -1,7 +1,7 @@ | |||
| /* | |||
| Copyright (C) 2002 Anthony Van Groningen | |||
| Parts based on source code taken from the | |||
| Parts based on source code taken from the | |||
| "Env24 chipset (ICE1712) control utility" that is | |||
| Copyright (C) 2000 by Jaroslav Kysela <perex@suse.cz> | |||
| @@ -19,7 +19,7 @@ | |||
| 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. | |||
| */ | |||
| */ | |||
| #include "hardware.h" | |||
| #include "alsa_driver.h" | |||
| @@ -27,13 +27,13 @@ | |||
| #include "internal.h" | |||
| static int | |||
| ice1712_hw_monitor_toggle(jack_hardware_t *hw, int idx, int onoff) | |||
| ice1712_hw_monitor_toggle (jack_hardware_t *hw, int idx, int onoff) | |||
| { | |||
| ice1712_t *h = (ice1712_t *) hw->private; | |||
| ice1712_t *h = (ice1712_t*)hw->private; | |||
| snd_ctl_elem_value_t *val; | |||
| int err; | |||
| snd_ctl_elem_value_alloca (&val); | |||
| snd_ctl_elem_value_set_interface (val, SND_CTL_ELEM_IFACE_MIXER); | |||
| if (idx >= 8) { | |||
| @@ -50,33 +50,33 @@ ice1712_hw_monitor_toggle(jack_hardware_t *hw, int idx, int onoff) | |||
| } | |||
| if ((err = snd_ctl_elem_write (h->driver->ctl_handle, val)) != 0) { | |||
| jack_error ("ALSA/ICE1712: (%d) cannot set input monitoring (%s)", | |||
| idx,snd_strerror (err)); | |||
| idx, snd_strerror (err)); | |||
| return -1; | |||
| } | |||
| return 0; | |||
| } | |||
| static int | |||
| static int | |||
| ice1712_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask) | |||
| { | |||
| int idx; | |||
| ice1712_t *h = (ice1712_t *) hw->private; | |||
| ice1712_t *h = (ice1712_t*)hw->private; | |||
| for (idx = 0; idx < 10; idx++) { | |||
| if (h->active_channels & (1<<idx)) { | |||
| ice1712_hw_monitor_toggle (hw, idx, mask & (1<<idx) ? 1 : 0); | |||
| if (h->active_channels & (1 << idx)) { | |||
| ice1712_hw_monitor_toggle (hw, idx, mask & (1 << idx) ? 1 : 0); | |||
| } | |||
| } | |||
| hw->input_monitor_mask = mask; | |||
| return 0; | |||
| } | |||
| static int | |||
| ice1712_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode) | |||
| static int | |||
| ice1712_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode) | |||
| { | |||
| return -1; | |||
| } | |||
| @@ -84,15 +84,17 @@ ice1712_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode) | |||
| static void | |||
| ice1712_release (jack_hardware_t *hw) | |||
| { | |||
| ice1712_t *h = (ice1712_t *) hw->private; | |||
| if (h == 0) | |||
| return; | |||
| ice1712_t *h = (ice1712_t*)hw->private; | |||
| if (h->eeprom) | |||
| free(h->eeprom); | |||
| if (h == 0) { | |||
| return; | |||
| } | |||
| if (h->eeprom) { | |||
| free (h->eeprom); | |||
| } | |||
| free(h); | |||
| free (h); | |||
| } | |||
| @@ -102,10 +104,10 @@ jack_alsa_ice1712_hw_new (alsa_driver_t *driver) | |||
| { | |||
| jack_hardware_t *hw; | |||
| ice1712_t *h; | |||
| snd_ctl_elem_value_t *val; | |||
| snd_ctl_elem_value_t *val; | |||
| int err; | |||
| hw = (jack_hardware_t *) malloc (sizeof (jack_hardware_t)); | |||
| hw = (jack_hardware_t*)malloc (sizeof(jack_hardware_t)); | |||
| hw->capabilities = Cap_HardwareMonitoring; | |||
| hw->input_monitor_mask = 0; | |||
| @@ -115,42 +117,42 @@ jack_alsa_ice1712_hw_new (alsa_driver_t *driver) | |||
| hw->change_sample_clock = ice1712_change_sample_clock; | |||
| hw->release = ice1712_release; | |||
| h = (ice1712_t *) malloc (sizeof (ice1712_t)); | |||
| h = (ice1712_t*)malloc (sizeof(ice1712_t)); | |||
| h->driver = driver; | |||
| /* Get the EEPROM (adopted from envy24control) */ | |||
| h->eeprom = (ice1712_eeprom_t *) malloc (sizeof (ice1712_eeprom_t)); | |||
| h->eeprom = (ice1712_eeprom_t*)malloc (sizeof(ice1712_eeprom_t)); | |||
| snd_ctl_elem_value_alloca (&val); | |||
| snd_ctl_elem_value_set_interface (val, SND_CTL_ELEM_IFACE_CARD); | |||
| snd_ctl_elem_value_set_name (val, "ICE1712 EEPROM"); | |||
| if ((err = snd_ctl_elem_read (driver->ctl_handle, val)) < 0) { | |||
| jack_error( "ALSA/ICE1712: Unable to read EEPROM contents (%s)\n", snd_strerror (err)); | |||
| /* Recover? */ | |||
| } | |||
| memcpy(h->eeprom, snd_ctl_elem_value_get_bytes(val), 32); | |||
| /* determine number of pro ADC's. We're asumming that there is at least one stereo pair. | |||
| snd_ctl_elem_value_set_name (val, "ICE1712 EEPROM"); | |||
| if ((err = snd_ctl_elem_read (driver->ctl_handle, val)) < 0) { | |||
| jack_error ( "ALSA/ICE1712: Unable to read EEPROM contents (%s)\n", snd_strerror (err)); | |||
| /* Recover? */ | |||
| } | |||
| memcpy (h->eeprom, snd_ctl_elem_value_get_bytes (val), 32); | |||
| /* determine number of pro ADC's. We're asumming that there is at least one stereo pair. | |||
| Should check this first, but how? */ | |||
| switch((h->eeprom->codec & 0xCU) >> 2) { | |||
| switch ((h->eeprom->codec & 0xCU) >> 2) { | |||
| case 0: | |||
| h->active_channels = 0x3U; | |||
| break; | |||
| h->active_channels = 0x3U; | |||
| break; | |||
| case 1: | |||
| h->active_channels = 0xfU; | |||
| break; | |||
| h->active_channels = 0xfU; | |||
| break; | |||
| case 2: | |||
| h->active_channels = 0x3fU; | |||
| break; | |||
| h->active_channels = 0x3fU; | |||
| break; | |||
| case 3: | |||
| h->active_channels = 0xffU; | |||
| break; | |||
| h->active_channels = 0xffU; | |||
| break; | |||
| } | |||
| /* check for SPDIF In's */ | |||
| if (h->eeprom->spdif & 0x1U) { | |||
| h->active_channels |= 0x300U; | |||
| h->active_channels |= 0x300U; | |||
| } | |||
| hw->private = h; | |||
| return hw; | |||
| @@ -1,11 +1,11 @@ | |||
| /* | |||
| Copyright (C) 2002 Anthony Van Groningen | |||
| Parts based on source code taken from the | |||
| Parts based on source code taken from the | |||
| "Env24 chipset (ICE1712) control utility" that is | |||
| Copyright (C) 2000 by Jaroslav Kysela <perex@suse.cz> | |||
| 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 | |||
| @@ -20,7 +20,7 @@ | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| */ | |||
| #ifndef __jack_ice1712_h__ | |||
| #define __jack_ice1712_h__ | |||
| @@ -36,31 +36,31 @@ | |||
| #define MULTITRACK_PEAK_NAME "Multi Track Peak" | |||
| typedef struct { | |||
| unsigned int subvendor; /* PCI[2c-2f] */ | |||
| unsigned char size; /* size of EEPROM image in bytes */ | |||
| unsigned char version; /* must be 1 */ | |||
| unsigned char codec; /* codec configuration PCI[60] */ | |||
| unsigned char aclink; /* ACLink configuration PCI[61] */ | |||
| unsigned char i2sID; /* PCI[62] */ | |||
| unsigned char spdif; /* S/PDIF configuration PCI[63] */ | |||
| unsigned char gpiomask; /* GPIO initial mask, 0 = write, 1 = don't */ | |||
| unsigned char gpiostate; /* GPIO initial state */ | |||
| unsigned char gpiodir; /* GPIO direction state */ | |||
| unsigned short ac97main; | |||
| unsigned short ac97pcm; | |||
| unsigned short ac97rec; | |||
| unsigned char ac97recsrc; | |||
| unsigned char dacID[4]; /* I2S IDs for DACs */ | |||
| unsigned char adcID[4]; /* I2S IDs for ADCs */ | |||
| unsigned char extra[4]; | |||
| unsigned int subvendor; /* PCI[2c-2f] */ | |||
| unsigned char size; /* size of EEPROM image in bytes */ | |||
| unsigned char version; /* must be 1 */ | |||
| unsigned char codec; /* codec configuration PCI[60] */ | |||
| unsigned char aclink; /* ACLink configuration PCI[61] */ | |||
| unsigned char i2sID; /* PCI[62] */ | |||
| unsigned char spdif; /* S/PDIF configuration PCI[63] */ | |||
| unsigned char gpiomask; /* GPIO initial mask, 0 = write, 1 = don't */ | |||
| unsigned char gpiostate; /* GPIO initial state */ | |||
| unsigned char gpiodir; /* GPIO direction state */ | |||
| unsigned short ac97main; | |||
| unsigned short ac97pcm; | |||
| unsigned short ac97rec; | |||
| unsigned char ac97recsrc; | |||
| unsigned char dacID[4]; /* I2S IDs for DACs */ | |||
| unsigned char adcID[4]; /* I2S IDs for ADCs */ | |||
| unsigned char extra[4]; | |||
| } ice1712_eeprom_t; | |||
| typedef struct { | |||
| alsa_driver_t *driver; | |||
| ice1712_eeprom_t *eeprom; | |||
| unsigned long active_channels; | |||
| alsa_driver_t *driver; | |||
| ice1712_eeprom_t *eeprom; | |||
| unsigned long active_channels; | |||
| } ice1712_t; | |||
| jack_hardware_t *jack_alsa_ice1712_hw_new (alsa_driver_t *driver); | |||
| jack_hardware_t *jack_alsa_ice1712_hw_new(alsa_driver_t *driver); | |||
| #endif /* __jack_ice1712_h__*/ | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| Copyright (C) 2000 Paul Davis | |||
| Copyright (C) 2000 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 | |||
| @@ -15,7 +15,7 @@ | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| */ | |||
| #define _ISOC9X_SOURCE 1 | |||
| #define _ISOC99_SOURCE 1 | |||
| @@ -39,7 +39,7 @@ | |||
| the MAX_<N>BIT values are floating point. when multiplied by | |||
| a full-scale normalized floating point sample value (-1.0..+1.0) | |||
| they should give the maxium value representable with an integer | |||
| sample type of N bits. Note that this is asymmetric. Sample ranges | |||
| sample type of N bits. Note that this is asymmetric. Sample ranges | |||
| for signed integer, 2's complement values are -(2^(N-1) to +(2^(N-1)-1) | |||
| Complications | |||
| @@ -59,20 +59,20 @@ | |||
| use the right factor). | |||
| So, for now (October 2008) we use 2^(N-1)-1 as the scaling factor. | |||
| */ | |||
| */ | |||
| #define SAMPLE_24BIT_SCALING 8388607.0f | |||
| #define SAMPLE_16BIT_SCALING 32767.0f | |||
| /* these are just values to use if the floating point value was out of range | |||
| advice from Fons Adriaensen: make the limits symmetrical | |||
| */ | |||
| #define SAMPLE_24BIT_MAX 8388607 | |||
| #define SAMPLE_24BIT_MIN -8388607 | |||
| #define SAMPLE_24BIT_MAX_F 8388607.0f | |||
| #define SAMPLE_24BIT_MIN_F -8388607.0f | |||
| #define SAMPLE_24BIT_MAX 8388607 | |||
| #define SAMPLE_24BIT_MIN -8388607 | |||
| #define SAMPLE_24BIT_MAX_F 8388607.0f | |||
| #define SAMPLE_24BIT_MIN_F -8388607.0f | |||
| #define SAMPLE_16BIT_MAX 32767 | |||
| #define SAMPLE_16BIT_MIN -32767 | |||
| @@ -80,91 +80,93 @@ | |||
| #define SAMPLE_16BIT_MIN_F -32767.0f | |||
| /* these mark the outer edges of the range considered "within" range | |||
| for a floating point sample value. values outside (and on the boundaries) | |||
| of this range will be clipped before conversion; values within this | |||
| for a floating point sample value. values outside (and on the boundaries) | |||
| of this range will be clipped before conversion; values within this | |||
| range will be scaled to appropriate values for the target sample | |||
| type. | |||
| */ | |||
| */ | |||
| #define NORMALIZED_FLOAT_MIN -1.0f | |||
| #define NORMALIZED_FLOAT_MAX 1.0f | |||
| /* define this in case we end up on a platform that is missing | |||
| the real lrintf functions | |||
| */ | |||
| */ | |||
| #define f_round(f) lrintf(f) | |||
| #define f_round(f) lrintf (f) | |||
| #define float_16(s, d)\ | |||
| if ((s) <= NORMALIZED_FLOAT_MIN) {\ | |||
| (d) = SAMPLE_16BIT_MIN;\ | |||
| } else if ((s) >= NORMALIZED_FLOAT_MAX) {\ | |||
| (d) = SAMPLE_16BIT_MAX;\ | |||
| } else {\ | |||
| (d) = f_round ((s) * SAMPLE_16BIT_SCALING);\ | |||
| #define float_16(s, d) \ | |||
| if ((s) <= NORMALIZED_FLOAT_MIN) { \ | |||
| (d) = SAMPLE_16BIT_MIN; \ | |||
| } else if ((s) >= NORMALIZED_FLOAT_MAX) { \ | |||
| (d) = SAMPLE_16BIT_MAX; \ | |||
| } else { \ | |||
| (d) = f_round ((s) * SAMPLE_16BIT_SCALING); \ | |||
| } | |||
| /* call this when "s" has already been scaled (e.g. when dithering) | |||
| */ | |||
| #define float_16_scaled(s, d)\ | |||
| if ((s) <= SAMPLE_16BIT_MIN_F) {\ | |||
| (d) = SAMPLE_16BIT_MIN_F;\ | |||
| #define float_16_scaled(s, d) \ | |||
| if ((s) <= SAMPLE_16BIT_MIN_F) { \ | |||
| (d) = SAMPLE_16BIT_MIN_F; \ | |||
| } else if ((s) >= SAMPLE_16BIT_MAX_F) { \ | |||
| (d) = SAMPLE_16BIT_MAX;\ | |||
| } else {\ | |||
| (d) = f_round ((s));\ | |||
| (d) = SAMPLE_16BIT_MAX; \ | |||
| } else { \ | |||
| (d) = f_round ((s)); \ | |||
| } | |||
| #define float_24u32(s, d) \ | |||
| if ((s) <= NORMALIZED_FLOAT_MIN) {\ | |||
| (d) = SAMPLE_24BIT_MIN << 8;\ | |||
| } else if ((s) >= NORMALIZED_FLOAT_MAX) {\ | |||
| (d) = SAMPLE_24BIT_MAX << 8;\ | |||
| } else {\ | |||
| (d) = f_round ((s) * SAMPLE_24BIT_SCALING) << 8;\ | |||
| if ((s) <= NORMALIZED_FLOAT_MIN) { \ | |||
| (d) = SAMPLE_24BIT_MIN << 8; \ | |||
| } else if ((s) >= NORMALIZED_FLOAT_MAX) { \ | |||
| (d) = SAMPLE_24BIT_MAX << 8; \ | |||
| } else { \ | |||
| (d) = f_round ((s) * SAMPLE_24BIT_SCALING) << 8; \ | |||
| } | |||
| /* call this when "s" has already been scaled (e.g. when dithering) | |||
| */ | |||
| #define float_24u32_scaled(s, d)\ | |||
| if ((s) <= SAMPLE_24BIT_MIN_F) {\ | |||
| (d) = SAMPLE_24BIT_MIN << 8;\ | |||
| #define float_24u32_scaled(s, d) \ | |||
| if ((s) <= SAMPLE_24BIT_MIN_F) { \ | |||
| (d) = SAMPLE_24BIT_MIN << 8; \ | |||
| } else if ((s) >= SAMPLE_24BIT_MAX_F) { \ | |||
| (d) = SAMPLE_24BIT_MAX << 8; \ | |||
| } else {\ | |||
| } else { \ | |||
| (d) = f_round ((s)) << 8; \ | |||
| } | |||
| #define float_24(s, d) \ | |||
| if ((s) <= NORMALIZED_FLOAT_MIN) {\ | |||
| (d) = SAMPLE_24BIT_MIN;\ | |||
| } else if ((s) >= NORMALIZED_FLOAT_MAX) {\ | |||
| (d) = SAMPLE_24BIT_MAX;\ | |||
| } else {\ | |||
| (d) = f_round ((s) * SAMPLE_24BIT_SCALING);\ | |||
| if ((s) <= NORMALIZED_FLOAT_MIN) { \ | |||
| (d) = SAMPLE_24BIT_MIN; \ | |||
| } else if ((s) >= NORMALIZED_FLOAT_MAX) { \ | |||
| (d) = SAMPLE_24BIT_MAX; \ | |||
| } else { \ | |||
| (d) = f_round ((s) * SAMPLE_24BIT_SCALING); \ | |||
| } | |||
| /* call this when "s" has already been scaled (e.g. when dithering) | |||
| */ | |||
| #define float_24_scaled(s, d)\ | |||
| if ((s) <= SAMPLE_24BIT_MIN_F) {\ | |||
| (d) = SAMPLE_24BIT_MIN;\ | |||
| #define float_24_scaled(s, d) \ | |||
| if ((s) <= SAMPLE_24BIT_MIN_F) { \ | |||
| (d) = SAMPLE_24BIT_MIN; \ | |||
| } else if ((s) >= SAMPLE_24BIT_MAX_F) { \ | |||
| (d) = SAMPLE_24BIT_MAX; \ | |||
| } else {\ | |||
| } else { \ | |||
| (d) = f_round ((s)); \ | |||
| } | |||
| /* Linear Congruential noise generator. From the music-dsp list | |||
| * less random than rand(), but good enough and 10x faster | |||
| * less random than rand(), but good enough and 10x faster | |||
| */ | |||
| static inline unsigned int fast_rand() { | |||
| static inline unsigned int fast_rand () | |||
| { | |||
| static unsigned int seed = 22222; | |||
| seed = (seed * 96314165) + 907633515; | |||
| return seed; | |||
| @@ -173,17 +175,19 @@ static inline unsigned int fast_rand() { | |||
| /* functions for native float sample data */ | |||
| void sample_move_floatLE_sSs (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) { | |||
| void sample_move_floatLE_sSs (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) | |||
| { | |||
| while (nsamples--) { | |||
| *dst = *((float *) src); | |||
| *dst = *((float*)src); | |||
| dst++; | |||
| src += src_skip; | |||
| } | |||
| } | |||
| void sample_move_dS_floatLE (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) { | |||
| void sample_move_dS_floatLE (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) | |||
| { | |||
| while (nsamples--) { | |||
| *((float *) dst) = *src; | |||
| *((float*)dst) = *src; | |||
| dst += dst_skip; | |||
| src++; | |||
| } | |||
| @@ -197,7 +201,7 @@ void sample_move_dS_floatLE (char *dst, jack_default_audio_sample_t *src, unsign | |||
| the "s<TYPE>" component defines the source type for the operation | |||
| TYPE can be one of: | |||
| S - sample is a jack_default_audio_sample_t, currently (October 2008) a 32 bit floating point value | |||
| Ss - like S but reverse endian from the host CPU | |||
| 32u24 - sample is an signed 32 bit integer value, but data is in upper 24 bits only | |||
| @@ -210,7 +214,7 @@ void sample_move_dS_floatLE (char *dst, jack_default_audio_sample_t *src, unsign | |||
| For obvious reasons, the reverse endian versions only show as source types. | |||
| This covers all known sample formats at 16 bits or larger. | |||
| */ | |||
| */ | |||
| /* functions for native integer sample data */ | |||
| @@ -224,29 +228,29 @@ void sample_move_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsign | |||
| #if __BYTE_ORDER == __LITTLE_ENDIAN | |||
| dst[0]=(char)(z>>24); | |||
| dst[1]=(char)(z>>16); | |||
| dst[2]=(char)(z>>8); | |||
| dst[3]=(char)(z); | |||
| dst[0] = (char)(z >> 24); | |||
| dst[1] = (char)(z >> 16); | |||
| dst[2] = (char)(z >> 8); | |||
| dst[3] = (char)(z); | |||
| #elif __BYTE_ORDER == __BIG_ENDIAN | |||
| dst[0]=(char)(z); | |||
| dst[1]=(char)(z>>8); | |||
| dst[2]=(char)(z>>16); | |||
| dst[3]=(char)(z>>24); | |||
| dst[0] = (char)(z); | |||
| dst[1] = (char)(z >> 8); | |||
| dst[2] = (char)(z >> 16); | |||
| dst[3] = (char)(z >> 24); | |||
| #endif | |||
| dst += dst_skip; | |||
| src++; | |||
| } | |||
| } | |||
| } | |||
| void sample_move_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) | |||
| { | |||
| while (nsamples--) { | |||
| float_24u32 (*src, *((int32_t*) dst)); | |||
| float_24u32 (*src, *((int32_t*)dst)); | |||
| dst += dst_skip; | |||
| src++; | |||
| } | |||
| } | |||
| } | |||
| void sample_move_dS_s32u24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) | |||
| { | |||
| @@ -275,18 +279,18 @@ void sample_move_dS_s32u24s (jack_default_audio_sample_t *dst, char *src, unsign | |||
| dst++; | |||
| src += src_skip; | |||
| } | |||
| } | |||
| } | |||
| void sample_move_dS_s32u24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) | |||
| { | |||
| /* ALERT: signed sign-extension portability !!! */ | |||
| while (nsamples--) { | |||
| *dst = (*((int *) src) >> 8) / SAMPLE_24BIT_SCALING; | |||
| *dst = (*((int*)src) >> 8) / SAMPLE_24BIT_SCALING; | |||
| dst++; | |||
| src += src_skip; | |||
| } | |||
| } | |||
| } | |||
| void sample_move_d24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) | |||
| { | |||
| @@ -295,34 +299,34 @@ void sample_move_d24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned | |||
| while (nsamples--) { | |||
| float_24 (*src, z); | |||
| #if __BYTE_ORDER == __LITTLE_ENDIAN | |||
| dst[0]=(char)(z>>16); | |||
| dst[1]=(char)(z>>8); | |||
| dst[2]=(char)(z); | |||
| dst[0] = (char)(z >> 16); | |||
| dst[1] = (char)(z >> 8); | |||
| dst[2] = (char)(z); | |||
| #elif __BYTE_ORDER == __BIG_ENDIAN | |||
| dst[0]=(char)(z); | |||
| dst[1]=(char)(z>>8); | |||
| dst[2]=(char)(z>>16); | |||
| dst[0] = (char)(z); | |||
| dst[1] = (char)(z >> 8); | |||
| dst[2] = (char)(z >> 16); | |||
| #endif | |||
| dst += dst_skip; | |||
| src++; | |||
| } | |||
| } | |||
| } | |||
| void sample_move_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) | |||
| { | |||
| int32_t z; | |||
| int32_t z; | |||
| while (nsamples--) { | |||
| float_24 (*src, z); | |||
| #if __BYTE_ORDER == __LITTLE_ENDIAN | |||
| memcpy (dst, &z, 3); | |||
| #elif __BYTE_ORDER == __BIG_ENDIAN | |||
| memcpy (dst, (char *)&z + 1, 3); | |||
| memcpy (dst, (char*)&z + 1, 3); | |||
| #endif | |||
| dst += dst_skip; | |||
| src++; | |||
| } | |||
| } | |||
| } | |||
| void sample_move_dS_s24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) | |||
| { | |||
| @@ -355,7 +359,7 @@ void sample_move_dS_s24s (jack_default_audio_sample_t *dst, char *src, unsigned | |||
| dst++; | |||
| src += src_skip; | |||
| } | |||
| } | |||
| } | |||
| void sample_move_dS_s24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) | |||
| { | |||
| @@ -364,19 +368,19 @@ void sample_move_dS_s24 (jack_default_audio_sample_t *dst, char *src, unsigned l | |||
| while (nsamples--) { | |||
| int x; | |||
| #if __BYTE_ORDER == __LITTLE_ENDIAN | |||
| memcpy((char*)&x + 1, src, 3); | |||
| memcpy ((char*)&x + 1, src, 3); | |||
| #elif __BYTE_ORDER == __BIG_ENDIAN | |||
| memcpy(&x, src, 3); | |||
| memcpy (&x, src, 3); | |||
| #endif | |||
| x >>= 8; | |||
| *dst = x / SAMPLE_24BIT_SCALING; | |||
| dst++; | |||
| src += src_skip; | |||
| } | |||
| } | |||
| } | |||
| void sample_move_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) | |||
| void sample_move_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) | |||
| { | |||
| int16_t tmp; | |||
| @@ -388,108 +392,108 @@ void sample_move_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned | |||
| } else if (*src >= NORMALIZED_FLOAT_MAX) { | |||
| tmp = SAMPLE_16BIT_MAX; | |||
| } else { | |||
| tmp = (int16_t) f_round (*src * SAMPLE_16BIT_SCALING); | |||
| tmp = (int16_t)f_round (*src * SAMPLE_16BIT_SCALING); | |||
| } | |||
| #if __BYTE_ORDER == __LITTLE_ENDIAN | |||
| dst[0]=(char)(tmp>>8); | |||
| dst[1]=(char)(tmp); | |||
| dst[0] = (char)(tmp >> 8); | |||
| dst[1] = (char)(tmp); | |||
| #elif __BYTE_ORDER == __BIG_ENDIAN | |||
| dst[0]=(char)(tmp); | |||
| dst[1]=(char)(tmp>>8); | |||
| dst[0] = (char)(tmp); | |||
| dst[1] = (char)(tmp >> 8); | |||
| #endif | |||
| dst += dst_skip; | |||
| src++; | |||
| } | |||
| } | |||
| void sample_move_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) | |||
| void sample_move_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) | |||
| { | |||
| while (nsamples--) { | |||
| float_16 (*src, *((int16_t*) dst)); | |||
| float_16 (*src, *((int16_t*)dst)); | |||
| dst += dst_skip; | |||
| src++; | |||
| } | |||
| } | |||
| void sample_move_dither_rect_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) | |||
| void sample_move_dither_rect_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) | |||
| { | |||
| jack_default_audio_sample_t val; | |||
| int16_t tmp; | |||
| int16_t tmp; | |||
| while (nsamples--) { | |||
| val = (*src * SAMPLE_16BIT_SCALING) + fast_rand() / (float) UINT_MAX - 0.5f; | |||
| val = (*src * SAMPLE_16BIT_SCALING) + fast_rand () / (float)UINT_MAX - 0.5f; | |||
| float_16_scaled (val, tmp); | |||
| #if __BYTE_ORDER == __LITTLE_ENDIAN | |||
| dst[0]=(char)(tmp>>8); | |||
| dst[1]=(char)(tmp); | |||
| dst[0] = (char)(tmp >> 8); | |||
| dst[1] = (char)(tmp); | |||
| #elif __BYTE_ORDER == __BIG_ENDIAN | |||
| dst[0]=(char)(tmp); | |||
| dst[1]=(char)(tmp>>8); | |||
| dst[0] = (char)(tmp); | |||
| dst[1] = (char)(tmp >> 8); | |||
| #endif | |||
| dst += dst_skip; | |||
| src++; | |||
| } | |||
| } | |||
| void sample_move_dither_rect_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) | |||
| void sample_move_dither_rect_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) | |||
| { | |||
| jack_default_audio_sample_t val; | |||
| while (nsamples--) { | |||
| val = (*src * SAMPLE_16BIT_SCALING) + fast_rand() / (float)UINT_MAX - 0.5f; | |||
| float_16_scaled (val, *((int16_t*) dst)); | |||
| val = (*src * SAMPLE_16BIT_SCALING) + fast_rand () / (float)UINT_MAX - 0.5f; | |||
| float_16_scaled (val, *((int16_t*)dst)); | |||
| dst += dst_skip; | |||
| src++; | |||
| } | |||
| } | |||
| void sample_move_dither_tri_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) | |||
| void sample_move_dither_tri_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) | |||
| { | |||
| jack_default_audio_sample_t val; | |||
| int16_t tmp; | |||
| int16_t tmp; | |||
| while (nsamples--) { | |||
| val = (*src * SAMPLE_16BIT_SCALING) + ((float)fast_rand() + (float)fast_rand()) / (float)UINT_MAX - 1.0f; | |||
| val = (*src * SAMPLE_16BIT_SCALING) + ((float)fast_rand () + (float)fast_rand ()) / (float)UINT_MAX - 1.0f; | |||
| float_16_scaled (val, tmp); | |||
| #if __BYTE_ORDER == __LITTLE_ENDIAN | |||
| dst[0]=(char)(tmp>>8); | |||
| dst[1]=(char)(tmp); | |||
| dst[0] = (char)(tmp >> 8); | |||
| dst[1] = (char)(tmp); | |||
| #elif __BYTE_ORDER == __BIG_ENDIAN | |||
| dst[0]=(char)(tmp); | |||
| dst[1]=(char)(tmp>>8); | |||
| dst[0] = (char)(tmp); | |||
| dst[1] = (char)(tmp >> 8); | |||
| #endif | |||
| dst += dst_skip; | |||
| src++; | |||
| } | |||
| } | |||
| void sample_move_dither_tri_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) | |||
| void sample_move_dither_tri_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) | |||
| { | |||
| jack_default_audio_sample_t val; | |||
| while (nsamples--) { | |||
| val = (*src * SAMPLE_16BIT_SCALING) + ((float)fast_rand() + (float)fast_rand()) / (float)UINT_MAX - 1.0f; | |||
| float_16_scaled (val, *((int16_t*) dst)); | |||
| val = (*src * SAMPLE_16BIT_SCALING) + ((float)fast_rand () + (float)fast_rand ()) / (float)UINT_MAX - 1.0f; | |||
| float_16_scaled (val, *((int16_t*)dst)); | |||
| dst += dst_skip; | |||
| src++; | |||
| } | |||
| } | |||
| void sample_move_dither_shaped_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) | |||
| void sample_move_dither_shaped_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) | |||
| { | |||
| jack_default_audio_sample_t x; | |||
| jack_default_audio_sample_t xe; /* the innput sample - filtered error */ | |||
| jack_default_audio_sample_t xp; /* x' */ | |||
| float r; | |||
| float rm1 = state->rm1; | |||
| jack_default_audio_sample_t x; | |||
| jack_default_audio_sample_t xe; /* the innput sample - filtered error */ | |||
| jack_default_audio_sample_t xp; /* x' */ | |||
| float r; | |||
| float rm1 = state->rm1; | |||
| unsigned int idx = state->idx; | |||
| int16_t tmp; | |||
| int16_t tmp; | |||
| while (nsamples--) { | |||
| x = *src * SAMPLE_16BIT_SCALING; | |||
| r = ((float)fast_rand() + (float)fast_rand()) / (float)UINT_MAX - 1.0f; | |||
| r = ((float)fast_rand () + (float)fast_rand ()) / (float)UINT_MAX - 1.0f; | |||
| /* Filter the error with Lipshitz's minimally audible FIR: | |||
| [2.033 -2.165 1.959 -1.590 0.6149] */ | |||
| xe = x | |||
| @@ -508,11 +512,11 @@ void sample_move_dither_shaped_d16_sSs (char *dst, jack_default_audio_sample_t | |||
| state->e[idx] = xp - xe; | |||
| #if __BYTE_ORDER == __LITTLE_ENDIAN | |||
| dst[0]=(char)(tmp>>8); | |||
| dst[1]=(char)(tmp); | |||
| dst[0] = (char)(tmp >> 8); | |||
| dst[1] = (char)(tmp); | |||
| #elif __BYTE_ORDER == __BIG_ENDIAN | |||
| dst[0]=(char)(tmp); | |||
| dst[1]=(char)(tmp>>8); | |||
| dst[0] = (char)(tmp); | |||
| dst[1] = (char)(tmp >> 8); | |||
| #endif | |||
| dst += dst_skip; | |||
| src++; | |||
| @@ -521,18 +525,18 @@ void sample_move_dither_shaped_d16_sSs (char *dst, jack_default_audio_sample_t | |||
| state->idx = idx; | |||
| } | |||
| void sample_move_dither_shaped_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) | |||
| void sample_move_dither_shaped_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) | |||
| { | |||
| jack_default_audio_sample_t x; | |||
| jack_default_audio_sample_t xe; /* the innput sample - filtered error */ | |||
| jack_default_audio_sample_t xp; /* x' */ | |||
| float r; | |||
| float rm1 = state->rm1; | |||
| jack_default_audio_sample_t x; | |||
| jack_default_audio_sample_t xe; /* the innput sample - filtered error */ | |||
| jack_default_audio_sample_t xp; /* x' */ | |||
| float r; | |||
| float rm1 = state->rm1; | |||
| unsigned int idx = state->idx; | |||
| while (nsamples--) { | |||
| x = *src * SAMPLE_16BIT_SCALING; | |||
| r = ((float)fast_rand() + (float)fast_rand()) / (float)UINT_MAX - 1.0f; | |||
| r = ((float)fast_rand () + (float)fast_rand ()) / (float)UINT_MAX - 1.0f; | |||
| /* Filter the error with Lipshitz's minimally audible FIR: | |||
| [2.033 -2.165 1.959 -1.590 0.6149] */ | |||
| xe = x | |||
| @@ -544,11 +548,11 @@ void sample_move_dither_shaped_d16_sS (char *dst, jack_default_audio_sample_t * | |||
| xp = xe + r - rm1; | |||
| rm1 = r; | |||
| float_16_scaled (xp, *((int16_t*) dst)); | |||
| float_16_scaled (xp, *((int16_t*)dst)); | |||
| /* Intrinsic z^-1 delay */ | |||
| idx = (idx + 1) & DITHER_BUF_MASK; | |||
| state->e[idx] = *((int16_t*) dst) - xe; | |||
| state->e[idx] = *((int16_t*)dst) - xe; | |||
| dst += dst_skip; | |||
| src++; | |||
| @@ -557,7 +561,7 @@ void sample_move_dither_shaped_d16_sS (char *dst, jack_default_audio_sample_t * | |||
| state->idx = idx; | |||
| } | |||
| void sample_move_dS_s16s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) | |||
| void sample_move_dS_s16s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) | |||
| { | |||
| short z; | |||
| @@ -576,22 +580,22 @@ void sample_move_dS_s16s (jack_default_audio_sample_t *dst, char *src, unsigned | |||
| dst++; | |||
| src += src_skip; | |||
| } | |||
| } | |||
| } | |||
| void sample_move_dS_s16 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) | |||
| void sample_move_dS_s16 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) | |||
| { | |||
| /* ALERT: signed sign-extension portability !!! */ | |||
| while (nsamples--) { | |||
| *dst = (*((short *) src)) / SAMPLE_16BIT_SCALING; | |||
| *dst = (*((short*)src)) / SAMPLE_16BIT_SCALING; | |||
| dst++; | |||
| src += src_skip; | |||
| } | |||
| } | |||
| } | |||
| void memset_interleave (char *dst, char val, unsigned long bytes, | |||
| unsigned long unit_bytes, | |||
| unsigned long skip_bytes) | |||
| void memset_interleave (char *dst, char val, unsigned long bytes, | |||
| unsigned long unit_bytes, | |||
| unsigned long skip_bytes) | |||
| { | |||
| switch (unit_bytes) { | |||
| case 1: | |||
| @@ -602,21 +606,21 @@ void memset_interleave (char *dst, char val, unsigned long bytes, | |||
| break; | |||
| case 2: | |||
| while (bytes) { | |||
| *((short *) dst) = (short) val; | |||
| *((short*)dst) = (short)val; | |||
| dst += skip_bytes; | |||
| bytes -= 2; | |||
| } | |||
| break; | |||
| case 4: | |||
| case 4: | |||
| while (bytes) { | |||
| *((int *) dst) = (int) val; | |||
| *((int*)dst) = (int)val; | |||
| dst += skip_bytes; | |||
| bytes -= 4; | |||
| } | |||
| break; | |||
| default: | |||
| while (bytes) { | |||
| memset(dst, val, unit_bytes); | |||
| memset (dst, val, unit_bytes); | |||
| dst += skip_bytes; | |||
| bytes -= unit_bytes; | |||
| } | |||
| @@ -629,46 +633,46 @@ void memset_interleave (char *dst, char val, unsigned long bytes, | |||
| is the same for both channels. This is completely fine | |||
| unless the input and output were on different audio interfaces that | |||
| were interleaved differently. We don't try to handle that. | |||
| */ | |||
| */ | |||
| void | |||
| void | |||
| memcpy_fake (char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar) | |||
| { | |||
| memcpy (dst, src, src_bytes); | |||
| } | |||
| void | |||
| void | |||
| memcpy_interleave_d16_s16 (char *dst, char *src, unsigned long src_bytes, | |||
| unsigned long dst_skip_bytes, unsigned long src_skip_bytes) | |||
| { | |||
| while (src_bytes) { | |||
| *((short *) dst) = *((short *) src); | |||
| *((short*)dst) = *((short*)src); | |||
| dst += dst_skip_bytes; | |||
| src += src_skip_bytes; | |||
| src_bytes -= 2; | |||
| } | |||
| } | |||
| void | |||
| void | |||
| memcpy_interleave_d24_s24 (char *dst, char *src, unsigned long src_bytes, | |||
| unsigned long dst_skip_bytes, unsigned long src_skip_bytes) | |||
| { | |||
| while (src_bytes) { | |||
| memcpy(dst, src, 3); | |||
| memcpy (dst, src, 3); | |||
| dst += dst_skip_bytes; | |||
| src += src_skip_bytes; | |||
| src_bytes -= 3; | |||
| } | |||
| } | |||
| void | |||
| void | |||
| memcpy_interleave_d32_s32 (char *dst, char *src, unsigned long src_bytes, | |||
| unsigned long dst_skip_bytes, unsigned long src_skip_bytes) | |||
| { | |||
| while (src_bytes) { | |||
| *((int *) dst) = *((int *) src); | |||
| *((int*)dst) = *((int*)src); | |||
| dst += dst_skip_bytes; | |||
| src += src_skip_bytes; | |||
| src_bytes -= 4; | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| Copyright (C) 2001 Paul Davis | |||
| Copyright (C) 2001 Paul Davis | |||
| Copyright (C) 2005 Karsten Wiese, Rui Nuno Capela | |||
| This program is free software; you can redistribute it and/or modify | |||
| @@ -16,7 +16,7 @@ | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| */ | |||
| #include "hardware.h" | |||
| #include "alsa_driver.h" | |||
| @@ -36,14 +36,14 @@ | |||
| int dbg_offset; | |||
| char dbg_buffer[8096]; | |||
| #endif | |||
| static | |||
| static | |||
| int usx2y_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask) | |||
| { | |||
| return -1; | |||
| } | |||
| static | |||
| int usx2y_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode) | |||
| int usx2y_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode) | |||
| { | |||
| return -1; | |||
| } | |||
| @@ -51,78 +51,85 @@ int usx2y_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode) | |||
| static void | |||
| usx2y_release (jack_hardware_t *hw) | |||
| { | |||
| usx2y_t *h = (usx2y_t *) hw->private; | |||
| usx2y_t *h = (usx2y_t*)hw->private; | |||
| if (h == 0) | |||
| if (h == 0) { | |||
| return; | |||
| if (h->hwdep_handle) | |||
| snd_hwdep_close(h->hwdep_handle); | |||
| } | |||
| if (h->hwdep_handle) { | |||
| snd_hwdep_close (h->hwdep_handle); | |||
| } | |||
| free(h); | |||
| free (h); | |||
| } | |||
| static int | |||
| usx2y_driver_get_channel_addresses_playback (alsa_driver_t *driver, | |||
| snd_pcm_uframes_t *playback_avail) | |||
| snd_pcm_uframes_t *playback_avail) | |||
| { | |||
| channel_t chn; | |||
| int iso; | |||
| snd_pcm_uframes_t playback_iso_avail; | |||
| char *playback; | |||
| usx2y_t *h = (usx2y_t *) driver->hw->private; | |||
| usx2y_t *h = (usx2y_t*)driver->hw->private; | |||
| if (0 > h->playback_iso_start) { | |||
| int bytes = driver->playback_sample_bytes * 2 * driver->frames_per_cycle * | |||
| driver->user_nperiods; | |||
| driver->user_nperiods; | |||
| iso = h->hwdep_pcm_shm->playback_iso_start; | |||
| if (0 > iso) | |||
| if (0 > iso) { | |||
| return 0; /* FIXME: return -1; */ | |||
| if (++iso >= ARRAY_SIZE(h->hwdep_pcm_shm->captured_iso)) | |||
| } | |||
| if (++iso >= ARRAY_SIZE (h->hwdep_pcm_shm->captured_iso)) { | |||
| iso = 0; | |||
| while((bytes -= h->hwdep_pcm_shm->captured_iso[iso].length) > 0) | |||
| if (++iso >= ARRAY_SIZE(h->hwdep_pcm_shm->captured_iso)) | |||
| } | |||
| while ((bytes -= h->hwdep_pcm_shm->captured_iso[iso].length) > 0) | |||
| if (++iso >= ARRAY_SIZE (h->hwdep_pcm_shm->captured_iso)) { | |||
| iso = 0; | |||
| } | |||
| h->playback_iso_bytes_done = h->hwdep_pcm_shm->captured_iso[iso].length + bytes; | |||
| #ifdef DBGHWDEP | |||
| dbg_offset = sprintf(dbg_buffer, "first iso = %i %i@%p:%i\n", | |||
| iso, h->hwdep_pcm_shm->captured_iso[iso].length, | |||
| h->hwdep_pcm_shm->playback, | |||
| h->hwdep_pcm_shm->captured_iso[iso].offset); | |||
| dbg_offset = sprintf (dbg_buffer, "first iso = %i %i@%p:%i\n", | |||
| iso, h->hwdep_pcm_shm->captured_iso[iso].length, | |||
| h->hwdep_pcm_shm->playback, | |||
| h->hwdep_pcm_shm->captured_iso[iso].offset); | |||
| #endif | |||
| } else { | |||
| iso = h->playback_iso_start; | |||
| } | |||
| #ifdef DBGHWDEP | |||
| dbg_offset += sprintf(dbg_buffer + dbg_offset, "iso = %i(%i;%i); ", iso, | |||
| h->hwdep_pcm_shm->captured_iso[iso].offset, | |||
| h->hwdep_pcm_shm->captured_iso[iso].frame); | |||
| dbg_offset += sprintf (dbg_buffer + dbg_offset, "iso = %i(%i;%i); ", iso, | |||
| h->hwdep_pcm_shm->captured_iso[iso].offset, | |||
| h->hwdep_pcm_shm->captured_iso[iso].frame); | |||
| #endif | |||
| playback = h->hwdep_pcm_shm->playback + | |||
| h->hwdep_pcm_shm->captured_iso[iso].offset + | |||
| h->playback_iso_bytes_done; | |||
| h->hwdep_pcm_shm->captured_iso[iso].offset + | |||
| h->playback_iso_bytes_done; | |||
| playback_iso_avail = (h->hwdep_pcm_shm->captured_iso[iso].length - | |||
| h->playback_iso_bytes_done) / | |||
| (driver->playback_sample_bytes * 2); | |||
| h->playback_iso_bytes_done) / | |||
| (driver->playback_sample_bytes * 2); | |||
| if (*playback_avail >= playback_iso_avail) { | |||
| *playback_avail = playback_iso_avail; | |||
| if (++iso >= ARRAY_SIZE(h->hwdep_pcm_shm->captured_iso)) | |||
| if (++iso >= ARRAY_SIZE (h->hwdep_pcm_shm->captured_iso)) { | |||
| iso = 0; | |||
| } | |||
| h->playback_iso_bytes_done = 0; | |||
| } else | |||
| } else { | |||
| h->playback_iso_bytes_done = | |||
| *playback_avail * (driver->playback_sample_bytes * 2); | |||
| } | |||
| h->playback_iso_start = iso; | |||
| for (chn = 0; chn < driver->playback_nchannels; chn++) { | |||
| const snd_pcm_channel_area_t *a = &driver->playback_areas[chn]; | |||
| driver->playback_addr[chn] = playback + a->first / 8; | |||
| } | |||
| #ifdef DBGHWDEP | |||
| if (dbg_offset < (sizeof(dbg_buffer) - 256)) | |||
| dbg_offset += sprintf(dbg_buffer + dbg_offset, "avail %li@%p\n", *playback_avail, driver->playback_addr[0]); | |||
| else { | |||
| printf(dbg_buffer); | |||
| if (dbg_offset < (sizeof(dbg_buffer) - 256)) { | |||
| dbg_offset += sprintf (dbg_buffer + dbg_offset, "avail %li@%p\n", *playback_avail, driver->playback_addr[0]); | |||
| } else { | |||
| printf (dbg_buffer); | |||
| return -1; | |||
| } | |||
| #endif | |||
| @@ -132,48 +139,51 @@ usx2y_driver_get_channel_addresses_playback (alsa_driver_t *driver, | |||
| static int | |||
| usx2y_driver_get_channel_addresses_capture (alsa_driver_t *driver, | |||
| snd_pcm_uframes_t *capture_avail) | |||
| snd_pcm_uframes_t *capture_avail) | |||
| { | |||
| channel_t chn; | |||
| int iso; | |||
| snd_pcm_uframes_t capture_iso_avail; | |||
| int capture_offset; | |||
| usx2y_t *h = (usx2y_t *) driver->hw->private; | |||
| usx2y_t *h = (usx2y_t*)driver->hw->private; | |||
| if (0 > h->capture_iso_start) { | |||
| iso = h->hwdep_pcm_shm->capture_iso_start; | |||
| if (0 > iso) | |||
| if (0 > iso) { | |||
| return 0; /* FIXME: return -1; */ | |||
| } | |||
| h->capture_iso_bytes_done = 0; | |||
| #ifdef DBGHWDEP | |||
| dbg_offset = sprintf(dbg_buffer, "cfirst iso = %i %i@%p:%i\n", | |||
| iso, h->hwdep_pcm_shm->captured_iso[iso].length, | |||
| h->hwdep_pcm_shm->capture0x8, | |||
| h->hwdep_pcm_shm->captured_iso[iso].offset); | |||
| dbg_offset = sprintf (dbg_buffer, "cfirst iso = %i %i@%p:%i\n", | |||
| iso, h->hwdep_pcm_shm->captured_iso[iso].length, | |||
| h->hwdep_pcm_shm->capture0x8, | |||
| h->hwdep_pcm_shm->captured_iso[iso].offset); | |||
| #endif | |||
| } else { | |||
| iso = h->capture_iso_start; | |||
| } | |||
| #ifdef DBGHWDEP | |||
| dbg_offset += sprintf(dbg_buffer + dbg_offset, "ciso = %i(%i;%i); ", iso, | |||
| h->hwdep_pcm_shm->captured_iso[iso].offset, | |||
| h->hwdep_pcm_shm->captured_iso[iso].frame); | |||
| dbg_offset += sprintf (dbg_buffer + dbg_offset, "ciso = %i(%i;%i); ", iso, | |||
| h->hwdep_pcm_shm->captured_iso[iso].offset, | |||
| h->hwdep_pcm_shm->captured_iso[iso].frame); | |||
| #endif | |||
| capture_offset = | |||
| h->hwdep_pcm_shm->captured_iso[iso].offset + | |||
| h->capture_iso_bytes_done; | |||
| h->capture_iso_bytes_done; | |||
| capture_iso_avail = (h->hwdep_pcm_shm->captured_iso[iso].length - | |||
| h->capture_iso_bytes_done) / | |||
| (driver->capture_sample_bytes * 2); | |||
| h->capture_iso_bytes_done) / | |||
| (driver->capture_sample_bytes * 2); | |||
| if (*capture_avail >= capture_iso_avail) { | |||
| *capture_avail = capture_iso_avail; | |||
| if (++iso >= ARRAY_SIZE(h->hwdep_pcm_shm->captured_iso)) | |||
| if (++iso >= ARRAY_SIZE (h->hwdep_pcm_shm->captured_iso)) { | |||
| iso = 0; | |||
| } | |||
| h->capture_iso_bytes_done = 0; | |||
| } else | |||
| } else { | |||
| h->capture_iso_bytes_done = | |||
| *capture_avail * (driver->capture_sample_bytes * 2); | |||
| } | |||
| h->capture_iso_start = iso; | |||
| for (chn = 0; chn < driver->capture_nchannels; chn++) { | |||
| driver->capture_addr[chn] = | |||
| @@ -182,21 +192,22 @@ usx2y_driver_get_channel_addresses_capture (alsa_driver_t *driver, | |||
| ((chn & 1) ? driver->capture_sample_bytes : 0); | |||
| } | |||
| #ifdef DBGHWDEP | |||
| { | |||
| int f = 0; | |||
| unsigned *u = driver->capture_addr[0]; | |||
| static unsigned last; | |||
| dbg_offset += sprintf(dbg_buffer + dbg_offset, "\nvon %6u bis %6u\n", last, u[0]); | |||
| while (f < *capture_avail && dbg_offset < (sizeof(dbg_buffer) - 256)) { | |||
| if (u[f] != last + 1) | |||
| dbg_offset += sprintf(dbg_buffer + dbg_offset, "\nooops %6u %6u\n", last, u[f]); | |||
| last = u[f++]; | |||
| } | |||
| } | |||
| if (dbg_offset < (sizeof(dbg_buffer) - 256)) | |||
| dbg_offset += sprintf(dbg_buffer + dbg_offset, "avail %li@%p\n", *capture_avail, driver->capture_addr[0]); | |||
| else { | |||
| printf(dbg_buffer); | |||
| { | |||
| int f = 0; | |||
| unsigned *u = driver->capture_addr[0]; | |||
| static unsigned last; | |||
| dbg_offset += sprintf (dbg_buffer + dbg_offset, "\nvon %6u bis %6u\n", last, u[0]); | |||
| while (f < *capture_avail && dbg_offset < (sizeof(dbg_buffer) - 256)) { | |||
| if (u[f] != last + 1) { | |||
| dbg_offset += sprintf (dbg_buffer + dbg_offset, "\nooops %6u %6u\n", last, u[f]); | |||
| } | |||
| last = u[f++]; | |||
| } | |||
| } | |||
| if (dbg_offset < (sizeof(dbg_buffer) - 256)) { | |||
| dbg_offset += sprintf (dbg_buffer + dbg_offset, "avail %li@%p\n", *capture_avail, driver->capture_addr[0]); | |||
| } else { | |||
| printf (dbg_buffer); | |||
| return -1; | |||
| } | |||
| #endif | |||
| @@ -210,7 +221,7 @@ usx2y_driver_start (alsa_driver_t *driver) | |||
| int err, i; | |||
| snd_pcm_uframes_t poffset, pavail; | |||
| usx2y_t *h = (usx2y_t *) driver->hw->private; | |||
| usx2y_t *h = (usx2y_t*)driver->hw->private; | |||
| for (i = 0; i < driver->capture_nchannels; i++) | |||
| // US428 channels 3+4 are on a seperate 2 channel stream. | |||
| @@ -225,40 +236,40 @@ usx2y_driver_start (alsa_driver_t *driver) | |||
| driver->poll_next = 0; | |||
| if ((err = snd_pcm_prepare (driver->playback_handle)) < 0) { | |||
| jack_error ("ALSA/USX2Y: prepare error for playback: %s", snd_strerror(err)); | |||
| jack_error ("ALSA/USX2Y: prepare error for playback: %s", snd_strerror (err)); | |||
| return -1; | |||
| } | |||
| if (driver->playback_handle) { | |||
| /* int i, j; */ | |||
| /* char buffer[2000]; */ | |||
| /* int i, j; */ | |||
| /* char buffer[2000]; */ | |||
| h->playback_iso_start = | |||
| h->capture_iso_start = -1; | |||
| snd_hwdep_poll_descriptors(h->hwdep_handle, &h->pfds, 1); | |||
| snd_hwdep_poll_descriptors (h->hwdep_handle, &h->pfds, 1); | |||
| h->hwdep_pcm_shm = (snd_usX2Y_hwdep_pcm_shm_t*) | |||
| mmap(NULL, sizeof(snd_usX2Y_hwdep_pcm_shm_t), | |||
| PROT_READ, | |||
| MAP_SHARED, h->pfds.fd, | |||
| 0); | |||
| mmap (NULL, sizeof(snd_usX2Y_hwdep_pcm_shm_t), | |||
| PROT_READ, | |||
| MAP_SHARED, h->pfds.fd, | |||
| 0); | |||
| if (MAP_FAILED == h->hwdep_pcm_shm) { | |||
| perror("ALSA/USX2Y: mmap"); | |||
| perror ("ALSA/USX2Y: mmap"); | |||
| return -1; | |||
| } | |||
| if (mprotect(h->hwdep_pcm_shm->playback, | |||
| sizeof(h->hwdep_pcm_shm->playback), | |||
| PROT_READ|PROT_WRITE)) { | |||
| perror("ALSA/USX2Y: mprotect"); | |||
| if (mprotect (h->hwdep_pcm_shm->playback, | |||
| sizeof(h->hwdep_pcm_shm->playback), | |||
| PROT_READ | PROT_WRITE)) { | |||
| perror ("ALSA/USX2Y: mprotect"); | |||
| return -1; | |||
| } | |||
| memset(h->hwdep_pcm_shm->playback, 0, sizeof(h->hwdep_pcm_shm->playback)); | |||
| /* for (i = 0, j = 0; i < 2000;) { */ | |||
| /* j += sprintf(buffer + j, "%04hX ", */ | |||
| /* *(unsigned short*)(h->hwdep_pcm_shm->capture + i)); */ | |||
| /* if (((i += 2) % 32) == 0) { */ | |||
| /* jack_error(buffer); */ | |||
| /* j = 0; */ | |||
| /* } */ | |||
| /* } */ | |||
| memset (h->hwdep_pcm_shm->playback, 0, sizeof(h->hwdep_pcm_shm->playback)); | |||
| /* for (i = 0, j = 0; i < 2000;) { */ | |||
| /* j += sprintf(buffer + j, "%04hX ", */ | |||
| /* *(unsigned short*)(h->hwdep_pcm_shm->capture + i)); */ | |||
| /* if (((i += 2) % 32) == 0) { */ | |||
| /* jack_error(buffer); */ | |||
| /* j = 0; */ | |||
| /* } */ | |||
| /* } */ | |||
| } | |||
| if (driver->hw_monitoring) { | |||
| @@ -269,7 +280,7 @@ usx2y_driver_start (alsa_driver_t *driver) | |||
| if (driver->playback_handle) { | |||
| /* fill playback buffer with zeroes, and mark | |||
| all fragments as having data. | |||
| */ | |||
| */ | |||
| pavail = snd_pcm_avail_update (driver->playback_handle); | |||
| @@ -278,10 +289,10 @@ usx2y_driver_start (alsa_driver_t *driver) | |||
| return -1; | |||
| } | |||
| if (snd_pcm_mmap_begin( | |||
| driver->playback_handle, | |||
| &driver->playback_areas, | |||
| &poffset, &pavail) < 0) { | |||
| if (snd_pcm_mmap_begin ( | |||
| driver->playback_handle, | |||
| &driver->playback_areas, | |||
| &poffset, &pavail) < 0) { | |||
| return -1; | |||
| } | |||
| @@ -292,22 +303,22 @@ usx2y_driver_start (alsa_driver_t *driver) | |||
| alsa-lib may have a better function for doing this | |||
| here, where the goal is to silence the entire | |||
| buffer. | |||
| */ | |||
| */ | |||
| { | |||
| /* snd_pcm_uframes_t frag, nframes = driver->buffer_frames; */ | |||
| /* while (nframes) { */ | |||
| /* frag = nframes; */ | |||
| /* if (usx2y_driver_get_channel_addresses_playback(driver, &frag) < 0) */ | |||
| /* return -1; */ | |||
| /* for (chn = 0; chn < driver->playback_nchannels; chn++) */ | |||
| /* alsa_driver_silence_on_channel (driver, chn, frag); */ | |||
| /* nframes -= frag; */ | |||
| /* } */ | |||
| /* snd_pcm_uframes_t frag, nframes = driver->buffer_frames; */ | |||
| /* while (nframes) { */ | |||
| /* frag = nframes; */ | |||
| /* if (usx2y_driver_get_channel_addresses_playback(driver, &frag) < 0) */ | |||
| /* return -1; */ | |||
| /* for (chn = 0; chn < driver->playback_nchannels; chn++) */ | |||
| /* alsa_driver_silence_on_channel (driver, chn, frag); */ | |||
| /* nframes -= frag; */ | |||
| /* } */ | |||
| } | |||
| snd_pcm_mmap_commit (driver->playback_handle, poffset, | |||
| driver->user_nperiods * driver->frames_per_cycle); | |||
| driver->user_nperiods * driver->frames_per_cycle); | |||
| if ((err = snd_pcm_start (driver->playback_handle)) < 0) { | |||
| jack_error ("ALSA/USX2Y: could not start playback (%s)", | |||
| @@ -326,16 +337,16 @@ usx2y_driver_start (alsa_driver_t *driver) | |||
| } | |||
| } | |||
| driver->playback_nfds = snd_pcm_poll_descriptors_count (driver->playback_handle); | |||
| driver->playback_nfds = snd_pcm_poll_descriptors_count (driver->playback_handle); | |||
| driver->capture_nfds = snd_pcm_poll_descriptors_count (driver->capture_handle); | |||
| if (driver->pfd) { | |||
| free (driver->pfd); | |||
| } | |||
| driver->pfd = (struct pollfd *) | |||
| malloc (sizeof (struct pollfd) * | |||
| (driver->playback_nfds + driver->capture_nfds + 2)); | |||
| driver->pfd = (struct pollfd*) | |||
| malloc (sizeof(struct pollfd) * | |||
| (driver->playback_nfds + driver->capture_nfds + 2)); | |||
| return 0; | |||
| } | |||
| @@ -347,28 +358,28 @@ usx2y_driver_stop (alsa_driver_t *driver) | |||
| JSList* node; | |||
| int chn; | |||
| usx2y_t *h = (usx2y_t *) driver->hw->private; | |||
| usx2y_t *h = (usx2y_t*)driver->hw->private; | |||
| /* silence all capture port buffers, because we might | |||
| be entering offline mode. | |||
| */ | |||
| */ | |||
| for (chn = 0, node = driver->capture_ports; node; | |||
| node = jack_slist_next (node), chn++) { | |||
| node = jack_slist_next (node), chn++) { | |||
| jack_port_t* port; | |||
| char* buf; | |||
| jack_nframes_t nframes = driver->engine->control->buffer_size; | |||
| port = (jack_port_t *) node->data; | |||
| port = (jack_port_t*)node->data; | |||
| buf = jack_port_get_buffer (port, nframes); | |||
| memset (buf, 0, sizeof (jack_default_audio_sample_t) * nframes); | |||
| memset (buf, 0, sizeof(jack_default_audio_sample_t) * nframes); | |||
| } | |||
| if (driver->playback_handle) { | |||
| if ((err = snd_pcm_drop (driver->playback_handle)) < 0) { | |||
| jack_error ("ALSA/USX2Y: channel flush for playback " | |||
| "failed (%s)", snd_strerror (err)); | |||
| "failed (%s)", snd_strerror (err)); | |||
| return -1; | |||
| } | |||
| } | |||
| @@ -377,7 +388,7 @@ usx2y_driver_stop (alsa_driver_t *driver) | |||
| driver->hw->set_input_monitor_mask (driver->hw, 0); | |||
| } | |||
| munmap(h->hwdep_pcm_shm, sizeof(snd_usX2Y_hwdep_pcm_shm_t)); | |||
| munmap (h->hwdep_pcm_shm, sizeof(snd_usX2Y_hwdep_pcm_shm_t)); | |||
| return 0; | |||
| } | |||
| @@ -390,8 +401,8 @@ usx2y_driver_null_cycle (alsa_driver_t* driver, jack_nframes_t nframes) | |||
| snd_pcm_uframes_t contiguous, contiguous_; | |||
| int chn; | |||
| VERBOSE(driver->engine, | |||
| "usx2y_driver_null_cycle (%p, %i)", driver, nframes); | |||
| VERBOSE (driver->engine, | |||
| "usx2y_driver_null_cycle (%p, %i)", driver, nframes); | |||
| if (driver->capture_handle) { | |||
| nf = nframes; | |||
| @@ -399,25 +410,26 @@ usx2y_driver_null_cycle (alsa_driver_t* driver, jack_nframes_t nframes) | |||
| while (nf) { | |||
| contiguous = (nf > driver->frames_per_cycle) ? | |||
| driver->frames_per_cycle : nf; | |||
| driver->frames_per_cycle : nf; | |||
| if (snd_pcm_mmap_begin ( | |||
| driver->capture_handle, | |||
| &driver->capture_areas, | |||
| (snd_pcm_uframes_t *) &offset, | |||
| (snd_pcm_uframes_t *) &contiguous)) { | |||
| driver->capture_handle, | |||
| &driver->capture_areas, | |||
| (snd_pcm_uframes_t*)&offset, | |||
| (snd_pcm_uframes_t*)&contiguous)) { | |||
| return -1; | |||
| } | |||
| contiguous_ = contiguous; | |||
| while (contiguous_) { | |||
| snd_pcm_uframes_t frag = contiguous_; | |||
| if (usx2y_driver_get_channel_addresses_capture(driver, &frag) < 0) | |||
| if (usx2y_driver_get_channel_addresses_capture (driver, &frag) < 0) { | |||
| return -1; | |||
| } | |||
| contiguous_ -= frag; | |||
| } | |||
| if (snd_pcm_mmap_commit (driver->capture_handle, | |||
| offset, contiguous) < 0) { | |||
| offset, contiguous) < 0) { | |||
| return -1; | |||
| } | |||
| @@ -430,13 +442,13 @@ usx2y_driver_null_cycle (alsa_driver_t* driver, jack_nframes_t nframes) | |||
| offset = 0; | |||
| while (nf) { | |||
| contiguous = (nf > driver->frames_per_cycle) ? | |||
| driver->frames_per_cycle : nf; | |||
| driver->frames_per_cycle : nf; | |||
| if (snd_pcm_mmap_begin ( | |||
| driver->playback_handle, | |||
| &driver->playback_areas, | |||
| (snd_pcm_uframes_t *) &offset, | |||
| (snd_pcm_uframes_t *) &contiguous)) { | |||
| (snd_pcm_uframes_t*)&offset, | |||
| (snd_pcm_uframes_t*)&contiguous)) { | |||
| return -1; | |||
| } | |||
| @@ -444,8 +456,9 @@ usx2y_driver_null_cycle (alsa_driver_t* driver, jack_nframes_t nframes) | |||
| snd_pcm_uframes_t frag, nframes = contiguous; | |||
| while (nframes) { | |||
| frag = nframes; | |||
| if (usx2y_driver_get_channel_addresses_playback(driver, &frag) < 0) | |||
| if (usx2y_driver_get_channel_addresses_playback (driver, &frag) < 0) { | |||
| return -1; | |||
| } | |||
| for (chn = 0; chn < driver->playback_nchannels; chn++) | |||
| alsa_driver_silence_on_channel (driver, chn, frag); | |||
| nframes -= frag; | |||
| @@ -453,7 +466,7 @@ usx2y_driver_null_cycle (alsa_driver_t* driver, jack_nframes_t nframes) | |||
| } | |||
| if (snd_pcm_mmap_commit (driver->playback_handle, | |||
| offset, contiguous) < 0) { | |||
| offset, contiguous) < 0) { | |||
| return -1; | |||
| } | |||
| @@ -493,7 +506,7 @@ usx2y_driver_read (alsa_driver_t *driver, jack_nframes_t nframes) | |||
| for (chn = 0, node = driver->capture_ports; | |||
| node; node = jack_slist_next (node), chn++) { | |||
| port = (jack_port_t *) node->data; | |||
| port = (jack_port_t*)node->data; | |||
| if (!jack_port_connected (port)) { | |||
| continue; | |||
| } | |||
| @@ -509,7 +522,7 @@ usx2y_driver_read (alsa_driver_t *driver, jack_nframes_t nframes) | |||
| } | |||
| for (chn = 0, node = driver->capture_ports; | |||
| node; node = jack_slist_next (node), chn++) { | |||
| port = (jack_port_t *) node->data; | |||
| port = (jack_port_t*)node->data; | |||
| if (!jack_port_connected (port)) { | |||
| /* no-copy optimization */ | |||
| continue; | |||
| @@ -517,10 +530,10 @@ usx2y_driver_read (alsa_driver_t *driver, jack_nframes_t nframes) | |||
| alsa_driver_read_from_channel (driver, chn, | |||
| buf[chn] + nread, | |||
| contiguous); | |||
| /* sample_move_dS_s24(buf[chn] + nread, */ | |||
| /* driver->capture_addr[chn], */ | |||
| /* contiguous, */ | |||
| /* driver->capture_interleave_skip); */ | |||
| /* sample_move_dS_s24(buf[chn] + nread, */ | |||
| /* driver->capture_addr[chn], */ | |||
| /* contiguous, */ | |||
| /* driver->capture_interleave_skip); */ | |||
| } | |||
| nread += contiguous; | |||
| nframes -= contiguous; | |||
| @@ -562,24 +575,24 @@ usx2y_driver_write (alsa_driver_t* driver, jack_nframes_t nframes) | |||
| driver->input_monitor_mask = 0; | |||
| for (chn = 0, node = driver->capture_ports; node; | |||
| node = jack_slist_next (node), chn++) { | |||
| if (((jack_port_t *) node->data)->shared->monitor_requests) { | |||
| driver->input_monitor_mask |= (1<<chn); | |||
| node = jack_slist_next (node), chn++) { | |||
| if (((jack_port_t*)node->data)->shared->monitor_requests) { | |||
| driver->input_monitor_mask |= (1 << chn); | |||
| } | |||
| } | |||
| if (driver->hw_monitoring) { | |||
| if ((driver->hw->input_monitor_mask | |||
| != driver->input_monitor_mask) | |||
| && !driver->all_monitor_in) { | |||
| != driver->input_monitor_mask) | |||
| && !driver->all_monitor_in) { | |||
| driver->hw->set_input_monitor_mask ( | |||
| driver->hw, driver->input_monitor_mask); | |||
| } | |||
| } | |||
| if (snd_pcm_mmap_begin(driver->playback_handle, | |||
| &driver->playback_areas, | |||
| &offset, &nframes_) < 0) { | |||
| if (snd_pcm_mmap_begin (driver->playback_handle, | |||
| &driver->playback_areas, | |||
| &offset, &nframes_) < 0) { | |||
| jack_error ("ALSA/USX2Y: %s: mmap areas info error", | |||
| driver->alsa_name_capture); | |||
| return -1; | |||
| @@ -587,7 +600,7 @@ usx2y_driver_write (alsa_driver_t* driver, jack_nframes_t nframes) | |||
| for (chn = 0, node = driver->playback_ports; | |||
| node; node = jack_slist_next (node), chn++) { | |||
| port = (jack_port_t *) node->data; | |||
| port = (jack_port_t*)node->data; | |||
| buf[chn] = jack_port_get_buffer (port, nframes_); | |||
| } | |||
| @@ -600,7 +613,7 @@ usx2y_driver_write (alsa_driver_t* driver, jack_nframes_t nframes) | |||
| } | |||
| for (chn = 0, node = driver->playback_ports; | |||
| node; node = jack_slist_next (node), chn++) { | |||
| port = (jack_port_t *) node->data; | |||
| port = (jack_port_t*)node->data; | |||
| alsa_driver_write_to_channel (driver, chn, | |||
| buf[chn] + nwritten, | |||
| contiguous); | |||
| @@ -613,8 +626,9 @@ usx2y_driver_write (alsa_driver_t* driver, jack_nframes_t nframes) | |||
| offset, nframes_)) < 0) { | |||
| jack_error ("ALSA/USX2Y: could not complete playback of %" | |||
| PRIu32 " frames: error = %d", nframes_, err); | |||
| if (err != EPIPE && err != ESTRPIPE) | |||
| if (err != EPIPE && err != ESTRPIPE) { | |||
| return -1; | |||
| } | |||
| } | |||
| return 0; | |||
| @@ -623,12 +637,12 @@ usx2y_driver_write (alsa_driver_t* driver, jack_nframes_t nframes) | |||
| static void | |||
| usx2y_driver_setup (alsa_driver_t *driver) | |||
| { | |||
| driver->nt_start = (JackDriverNTStartFunction) usx2y_driver_start; | |||
| driver->nt_stop = (JackDriverNTStopFunction) usx2y_driver_stop; | |||
| driver->read = (JackDriverReadFunction) usx2y_driver_read; | |||
| driver->write = (JackDriverReadFunction) usx2y_driver_write; | |||
| driver->nt_start = (JackDriverNTStartFunction)usx2y_driver_start; | |||
| driver->nt_stop = (JackDriverNTStopFunction)usx2y_driver_stop; | |||
| driver->read = (JackDriverReadFunction)usx2y_driver_read; | |||
| driver->write = (JackDriverReadFunction)usx2y_driver_write; | |||
| driver->null_cycle = | |||
| (JackDriverNullCycleFunction) usx2y_driver_null_cycle; | |||
| (JackDriverNullCycleFunction)usx2y_driver_null_cycle; | |||
| } | |||
| @@ -638,13 +652,13 @@ jack_alsa_usx2y_hw_new (alsa_driver_t *driver) | |||
| jack_hardware_t *hw; | |||
| usx2y_t *h; | |||
| int hwdep_cardno; | |||
| int hwdep_devno; | |||
| int hwdep_cardno; | |||
| int hwdep_devno; | |||
| char *hwdep_colon; | |||
| char hwdep_name[9]; | |||
| char hwdep_name[9]; | |||
| snd_hwdep_t *hwdep_handle; | |||
| hw = (jack_hardware_t *) malloc (sizeof (jack_hardware_t)); | |||
| hw = (jack_hardware_t*)malloc (sizeof(jack_hardware_t)); | |||
| hw->capabilities = 0; | |||
| hw->input_monitor_mask = 0; | |||
| @@ -661,22 +675,23 @@ jack_alsa_usx2y_hw_new (alsa_driver_t *driver) | |||
| */ | |||
| hwdep_handle = NULL; | |||
| hwdep_cardno = hwdep_devno = 0; | |||
| if ((hwdep_colon = strrchr(driver->alsa_name_playback, ':')) != NULL) | |||
| sscanf(hwdep_colon, ":%d,%d", &hwdep_cardno, &hwdep_devno); | |||
| if ((hwdep_colon = strrchr (driver->alsa_name_playback, ':')) != NULL) { | |||
| sscanf (hwdep_colon, ":%d,%d", &hwdep_cardno, &hwdep_devno); | |||
| } | |||
| if (hwdep_devno == 2) { | |||
| snprintf(hwdep_name, sizeof(hwdep_name), "hw:%d,1", hwdep_cardno); | |||
| snprintf (hwdep_name, sizeof(hwdep_name), "hw:%d,1", hwdep_cardno); | |||
| if (snd_hwdep_open (&hwdep_handle, hwdep_name, O_RDWR) < 0) { | |||
| jack_error ("ALSA/USX2Y: Cannot open hwdep device \"%s\"", hwdep_name); | |||
| } else { | |||
| /* Allocate specific USX2Y hwdep pcm struct. */ | |||
| h = (usx2y_t *) malloc (sizeof (usx2y_t)); | |||
| h = (usx2y_t*)malloc (sizeof(usx2y_t)); | |||
| h->driver = driver; | |||
| h->hwdep_handle = hwdep_handle; | |||
| hw->private = h; | |||
| /* Set our own operational function pointers. */ | |||
| usx2y_driver_setup(driver); | |||
| jack_info("ALSA/USX2Y: EXPERIMENTAL hwdep pcm device %s" | |||
| " (aka \"rawusb\")", driver->alsa_name_playback); | |||
| usx2y_driver_setup (driver); | |||
| jack_info ("ALSA/USX2Y: EXPERIMENTAL hwdep pcm device %s" | |||
| " (aka \"rawusb\")", driver->alsa_name_playback); | |||
| } | |||
| } | |||
| @@ -1,7 +1,7 @@ | |||
| /* | |||
| Copyright (C) 2001 Paul Davis | |||
| Copyright (C) 2004 Karsten Wiese, Rui Nuno Capela | |||
| 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 | |||
| @@ -16,14 +16,14 @@ | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| */ | |||
| #ifndef __jack_usx2y_h__ | |||
| #define __jack_usx2y_h__ | |||
| #define USX2Y_MAXPACK 50 | |||
| #define USX2Y_MAXBUFFERMS 100 | |||
| #define USX2Y_MAXSTRIDE 3 | |||
| #define USX2Y_MAXPACK 50 | |||
| #define USX2Y_MAXBUFFERMS 100 | |||
| #define USX2Y_MAXSTRIDE 3 | |||
| #define USX2Y_SSS (((USX2Y_MAXPACK * USX2Y_MAXBUFFERMS * USX2Y_MAXSTRIDE + 4096) / 4096) * 4096) | |||
| @@ -34,9 +34,9 @@ struct snd_usX2Y_hwdep_pcm_shm { | |||
| volatile int playback_iso_head; | |||
| int playback_iso_start; | |||
| struct { | |||
| int frame, | |||
| offset, | |||
| length; | |||
| int frame, | |||
| offset, | |||
| length; | |||
| } captured_iso[128]; | |||
| volatile int captured_iso_head; | |||
| volatile unsigned captured_iso_frames; | |||
| @@ -56,6 +56,6 @@ typedef struct { | |||
| } usx2y_t; | |||
| jack_hardware_t * | |||
| jack_alsa_usx2y_hw_new (alsa_driver_t *driver); | |||
| jack_alsa_usx2y_hw_new(alsa_driver_t *driver); | |||
| #endif /* __jack_usx2y_h__*/ | |||
| @@ -39,100 +39,95 @@ | |||
| #define PORT_HASH_SIZE (1 << PORT_HASH_BITS) | |||
| /* Beside enum use, these are indeces for (struct a2j).stream array */ | |||
| #define A2J_PORT_CAPTURE 0 // ALSA playback port -> JACK capture port | |||
| #define A2J_PORT_PLAYBACK 1 // JACK playback port -> ALSA capture port | |||
| #define A2J_PORT_CAPTURE 0 // ALSA playback port -> JACK capture port | |||
| #define A2J_PORT_PLAYBACK 1 // JACK playback port -> ALSA capture port | |||
| typedef struct a2j_port * a2j_port_hash_t[PORT_HASH_SIZE]; | |||
| struct alsa_midi_driver; | |||
| struct a2j_port | |||
| { | |||
| struct a2j_port * next; /* hash - jack */ | |||
| struct list_head siblings; /* list - main loop */ | |||
| struct alsa_midi_driver * driver_ptr; | |||
| bool is_dead; | |||
| char name[64]; | |||
| snd_seq_addr_t remote; | |||
| jack_port_t * jack_port; | |||
| jack_ringbuffer_t * inbound_events; // alsa_midi_event_t + data | |||
| int64_t last_out_time; | |||
| void * jack_buf; | |||
| struct a2j_port { | |||
| struct a2j_port * next; /* hash - jack */ | |||
| struct list_head siblings; /* list - main loop */ | |||
| struct alsa_midi_driver * driver_ptr; | |||
| bool is_dead; | |||
| char name[64]; | |||
| snd_seq_addr_t remote; | |||
| jack_port_t * jack_port; | |||
| jack_ringbuffer_t * inbound_events; // alsa_midi_event_t + data | |||
| int64_t last_out_time; | |||
| void * jack_buf; | |||
| }; | |||
| struct a2j_stream | |||
| { | |||
| snd_midi_event_t *codec; | |||
| jack_ringbuffer_t *new_ports; | |||
| a2j_port_hash_t port_hash; | |||
| struct list_head list; | |||
| struct a2j_stream { | |||
| snd_midi_event_t *codec; | |||
| jack_ringbuffer_t *new_ports; | |||
| a2j_port_hash_t port_hash; | |||
| struct list_head list; | |||
| }; | |||
| typedef struct alsa_midi_driver | |||
| { | |||
| JACK_DRIVER_DECL; | |||
| jack_client_t * jack_client; | |||
| snd_seq_t *seq; | |||
| pthread_t alsa_input_thread; | |||
| pthread_t alsa_output_thread; | |||
| int client_id; | |||
| int port_id; | |||
| int queue; | |||
| bool freewheeling; | |||
| bool running; | |||
| bool finishing; | |||
| jack_ringbuffer_t* port_del; // struct a2j_port* | |||
| jack_ringbuffer_t* outbound_events; // struct a2j_delivery_event | |||
| jack_nframes_t cycle_start; | |||
| sem_t output_semaphore; | |||
| struct a2j_stream stream[2]; | |||
| typedef struct alsa_midi_driver { | |||
| JACK_DRIVER_DECL; | |||
| jack_client_t * jack_client; | |||
| snd_seq_t *seq; | |||
| pthread_t alsa_input_thread; | |||
| pthread_t alsa_output_thread; | |||
| int client_id; | |||
| int port_id; | |||
| int queue; | |||
| bool freewheeling; | |||
| bool running; | |||
| bool finishing; | |||
| jack_ringbuffer_t* port_del; // struct a2j_port* | |||
| jack_ringbuffer_t* outbound_events; // struct a2j_delivery_event | |||
| jack_nframes_t cycle_start; | |||
| sem_t output_semaphore; | |||
| struct a2j_stream stream[2]; | |||
| } alsa_midi_driver_t; | |||
| #define NSEC_PER_SEC ((int64_t)1000*1000*1000) | |||
| #define NSEC_PER_SEC ((int64_t)1000 * 1000 * 1000) | |||
| struct a2j_alsa_midi_event | |||
| { | |||
| int64_t time; | |||
| int size; | |||
| struct a2j_alsa_midi_event { | |||
| int64_t time; | |||
| int size; | |||
| }; | |||
| #define MAX_JACKMIDI_EV_SIZE 64 | |||
| struct a2j_delivery_event | |||
| { | |||
| struct list_head siblings; | |||
| /* a jack MIDI event, plus the port its destined for: everything | |||
| the ALSA output thread needs to deliver the event. time is | |||
| part of the jack_event. | |||
| */ | |||
| jack_midi_event_t jack_event; | |||
| jack_nframes_t time; /* realtime, not offset time */ | |||
| struct a2j_port* port; | |||
| char midistring[MAX_JACKMIDI_EV_SIZE]; | |||
| struct a2j_delivery_event { | |||
| struct list_head siblings; | |||
| /* a jack MIDI event, plus the port its destined for: everything | |||
| the ALSA output thread needs to deliver the event. time is | |||
| part of the jack_event. | |||
| */ | |||
| jack_midi_event_t jack_event; | |||
| jack_nframes_t time; /* realtime, not offset time */ | |||
| struct a2j_port* port; | |||
| char midistring[MAX_JACKMIDI_EV_SIZE]; | |||
| }; | |||
| void a2j_error (const char* fmt, ...); | |||
| void a2j_error(const char* fmt, ...); | |||
| #define A2J_DEBUG | |||
| /*#undef A2J_DEBUG*/ | |||
| #ifdef A2J_DEBUG | |||
| extern bool a2j_do_debug; | |||
| extern void _a2j_debug (const char* fmt, ...); | |||
| #define a2j_debug(fmt, ...) if (a2j_do_debug) { _a2j_debug ((fmt), ##__VA_ARGS__); } | |||
| extern void _a2j_debug(const char* fmt, ...); | |||
| #define a2j_debug(fmt, ...) if (a2j_do_debug) { _a2j_debug ((fmt), ## __VA_ARGS__); } | |||
| #else | |||
| #define a2j_debug(fmt,...) | |||
| #define a2j_debug(fmt, ...) | |||
| #endif | |||
| #endif /* __jack_alsa_midi_h__ */ | |||
| @@ -3,45 +3,45 @@ | |||
| #include <string.h> | |||
| static int | |||
| alsa_midi_driver_attach( alsa_midi_driver_t *driver, jack_engine_t *engine ) | |||
| alsa_midi_driver_attach ( alsa_midi_driver_t *driver, jack_engine_t *engine ) | |||
| { | |||
| return driver->midi->attach(driver->midi); | |||
| return driver->midi->attach (driver->midi); | |||
| } | |||
| static int | |||
| alsa_midi_driver_detach( alsa_midi_driver_t *driver, jack_engine_t *engine ) | |||
| alsa_midi_driver_detach ( alsa_midi_driver_t *driver, jack_engine_t *engine ) | |||
| { | |||
| return driver->midi->detach(driver->midi); | |||
| return driver->midi->detach (driver->midi); | |||
| } | |||
| static int | |||
| alsa_midi_driver_read( alsa_midi_driver_t *driver, jack_nframes_t nframes ) | |||
| alsa_midi_driver_read ( alsa_midi_driver_t *driver, jack_nframes_t nframes ) | |||
| { | |||
| driver->midi->read(driver->midi, nframes); | |||
| driver->midi->read (driver->midi, nframes); | |||
| return 0; | |||
| } | |||
| static int | |||
| alsa_midi_driver_write( alsa_midi_driver_t *driver, jack_nframes_t nframes ) | |||
| alsa_midi_driver_write ( alsa_midi_driver_t *driver, jack_nframes_t nframes ) | |||
| { | |||
| driver->midi->write(driver->midi, nframes); | |||
| driver->midi->write (driver->midi, nframes); | |||
| return 0; | |||
| } | |||
| static int | |||
| alsa_midi_driver_start( alsa_midi_driver_t *driver ) | |||
| alsa_midi_driver_start ( alsa_midi_driver_t *driver ) | |||
| { | |||
| return driver->midi->start(driver->midi); | |||
| return driver->midi->start (driver->midi); | |||
| } | |||
| static int | |||
| alsa_midi_driver_stop( alsa_midi_driver_t *driver ) | |||
| alsa_midi_driver_stop ( alsa_midi_driver_t *driver ) | |||
| { | |||
| return driver->midi->stop(driver->midi); | |||
| return driver->midi->stop (driver->midi); | |||
| } | |||
| static void | |||
| alsa_midi_driver_delete( alsa_midi_driver_t *driver ) | |||
| alsa_midi_driver_delete ( alsa_midi_driver_t *driver ) | |||
| { | |||
| } | |||
| @@ -1,22 +1,22 @@ | |||
| /* -*- Mode: C ; c-basic-offset: 2 -*- */ | |||
| /***************************************************************************** | |||
| * | |||
| * list_sort() adapted from linux kernel. | |||
| * | |||
| * 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; version 2 of the License | |||
| * | |||
| * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |||
| * | |||
| *****************************************************************************/ | |||
| * | |||
| * list_sort() adapted from linux kernel. | |||
| * | |||
| * 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; version 2 of the License | |||
| * | |||
| * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |||
| * | |||
| *****************************************************************************/ | |||
| #include <assert.h> | |||
| @@ -24,124 +24,131 @@ | |||
| /* list sort from Mark J Roberts (mjr@znex.org) */ | |||
| void | |||
| __list_sort( | |||
| struct list_head *head, | |||
| int member_offset, | |||
| int (*cmp)(void * a, void * b)) | |||
| __list_sort ( | |||
| struct list_head *head, | |||
| int member_offset, | |||
| int (*cmp)(void * a, void * b)) | |||
| { | |||
| struct list_head *p, *q, *e, *list, *tail, *oldhead; | |||
| int insize, nmerges, psize, qsize, i; | |||
| list = head->next; | |||
| list_del(head); | |||
| insize = 1; | |||
| for (;;) { | |||
| p = oldhead = list; | |||
| list = tail = NULL; | |||
| nmerges = 0; | |||
| while (p) { | |||
| nmerges++; | |||
| q = p; | |||
| psize = 0; | |||
| for (i = 0; i < insize; i++) { | |||
| psize++; | |||
| q = q->next == oldhead ? NULL : q->next; | |||
| if (!q) | |||
| break; | |||
| } | |||
| qsize = insize; | |||
| while (psize > 0 || (qsize > 0 && q)) { | |||
| if (!psize) { | |||
| e = q; | |||
| q = q->next; | |||
| qsize--; | |||
| if (q == oldhead) | |||
| q = NULL; | |||
| } else if (!qsize || !q) { | |||
| e = p; | |||
| p = p->next; | |||
| psize--; | |||
| if (p == oldhead) | |||
| p = NULL; | |||
| } else if (cmp((void *)p - member_offset, (void *)q - member_offset) <= 0) { | |||
| e = p; | |||
| p = p->next; | |||
| psize--; | |||
| if (p == oldhead) | |||
| p = NULL; | |||
| } else { | |||
| e = q; | |||
| q = q->next; | |||
| qsize--; | |||
| if (q == oldhead) | |||
| q = NULL; | |||
| } | |||
| if (tail) | |||
| tail->next = e; | |||
| else | |||
| list = e; | |||
| e->prev = tail; | |||
| tail = e; | |||
| } | |||
| p = q; | |||
| } | |||
| tail->next = list; | |||
| list->prev = tail; | |||
| if (nmerges <= 1) | |||
| break; | |||
| insize *= 2; | |||
| } | |||
| head->next = list; | |||
| head->prev = list->prev; | |||
| list->prev->next = head; | |||
| list->prev = head; | |||
| struct list_head *p, *q, *e, *list, *tail, *oldhead; | |||
| int insize, nmerges, psize, qsize, i; | |||
| list = head->next; | |||
| list_del (head); | |||
| insize = 1; | |||
| for (;; ) { | |||
| p = oldhead = list; | |||
| list = tail = NULL; | |||
| nmerges = 0; | |||
| while (p) { | |||
| nmerges++; | |||
| q = p; | |||
| psize = 0; | |||
| for (i = 0; i < insize; i++) { | |||
| psize++; | |||
| q = q->next == oldhead ? NULL : q->next; | |||
| if (!q) { | |||
| break; | |||
| } | |||
| } | |||
| qsize = insize; | |||
| while (psize > 0 || (qsize > 0 && q)) { | |||
| if (!psize) { | |||
| e = q; | |||
| q = q->next; | |||
| qsize--; | |||
| if (q == oldhead) { | |||
| q = NULL; | |||
| } | |||
| } else if (!qsize || !q) { | |||
| e = p; | |||
| p = p->next; | |||
| psize--; | |||
| if (p == oldhead) { | |||
| p = NULL; | |||
| } | |||
| } else if (cmp ((void*)p - member_offset, (void*)q - member_offset) <= 0) { | |||
| e = p; | |||
| p = p->next; | |||
| psize--; | |||
| if (p == oldhead) { | |||
| p = NULL; | |||
| } | |||
| } else { | |||
| e = q; | |||
| q = q->next; | |||
| qsize--; | |||
| if (q == oldhead) { | |||
| q = NULL; | |||
| } | |||
| } | |||
| if (tail) { | |||
| tail->next = e; | |||
| } else { | |||
| list = e; | |||
| } | |||
| e->prev = tail; | |||
| tail = e; | |||
| } | |||
| p = q; | |||
| } | |||
| tail->next = list; | |||
| list->prev = tail; | |||
| if (nmerges <= 1) { | |||
| break; | |||
| } | |||
| insize *= 2; | |||
| } | |||
| head->next = list; | |||
| head->prev = list->prev; | |||
| list->prev->next = head; | |||
| list->prev = head; | |||
| } | |||
| struct test_list_el { | |||
| int value; | |||
| struct list_head test_list_node; | |||
| int value; | |||
| struct list_head test_list_node; | |||
| }; | |||
| int test_list_sort_comparator(struct test_list_el * e1, struct test_list_el * e2) | |||
| int test_list_sort_comparator (struct test_list_el * e1, struct test_list_el * e2) | |||
| { | |||
| return e1->value - e2->value; | |||
| return e1->value - e2->value; | |||
| } | |||
| void test_list_sort(void) | |||
| void test_list_sort (void) | |||
| { | |||
| struct list_head test_list; | |||
| struct test_list_el *el, *next; | |||
| struct test_list_el te1 = {.value = 1}; | |||
| struct test_list_el te2 = {.value = 2}; | |||
| struct test_list_el te3 = {.value = 3}; | |||
| struct test_list_el te4 = {.value = 4}; | |||
| struct test_list_el te5 = {.value = 5}; | |||
| struct test_list_el te6 = {.value = 6}; | |||
| struct test_list_el te7 = {.value = 7}; | |||
| const int expected[] = {1, 2, 3, 4, 5, 6, 7}; | |||
| int i; | |||
| INIT_LIST_HEAD(&test_list); | |||
| list_add_tail(&te2.test_list_node, &test_list); | |||
| list_add_tail(&te6.test_list_node, &test_list); | |||
| list_add_tail(&te4.test_list_node, &test_list); | |||
| list_add_tail(&te5.test_list_node, &test_list); | |||
| list_add_tail(&te7.test_list_node, &test_list); | |||
| list_add_tail(&te1.test_list_node, &test_list); | |||
| list_add_tail(&te3.test_list_node, &test_list); | |||
| list_sort(&test_list, struct test_list_el, test_list_node, test_list_sort_comparator); | |||
| i = 0; | |||
| list_for_each_entry_safe(el, next, &test_list, test_list_node) { | |||
| assert(el->value == expected[i]); | |||
| i++; | |||
| } | |||
| struct list_head test_list; | |||
| struct test_list_el *el, *next; | |||
| struct test_list_el te1 = { .value = 1 }; | |||
| struct test_list_el te2 = { .value = 2 }; | |||
| struct test_list_el te3 = { .value = 3 }; | |||
| struct test_list_el te4 = { .value = 4 }; | |||
| struct test_list_el te5 = { .value = 5 }; | |||
| struct test_list_el te6 = { .value = 6 }; | |||
| struct test_list_el te7 = { .value = 7 }; | |||
| const int expected[] = { 1, 2, 3, 4, 5, 6, 7 }; | |||
| int i; | |||
| INIT_LIST_HEAD (&test_list); | |||
| list_add_tail (&te2.test_list_node, &test_list); | |||
| list_add_tail (&te6.test_list_node, &test_list); | |||
| list_add_tail (&te4.test_list_node, &test_list); | |||
| list_add_tail (&te5.test_list_node, &test_list); | |||
| list_add_tail (&te7.test_list_node, &test_list); | |||
| list_add_tail (&te1.test_list_node, &test_list); | |||
| list_add_tail (&te3.test_list_node, &test_list); | |||
| list_sort (&test_list, struct test_list_el, test_list_node, test_list_sort_comparator); | |||
| i = 0; | |||
| list_for_each_entry_safe (el, next, &test_list, test_list_node) { | |||
| assert (el->value == expected[i]); | |||
| i++; | |||
| } | |||
| } | |||
| @@ -27,20 +27,21 @@ typedef struct { | |||
| } midi_pack_t; | |||
| static inline | |||
| void midi_pack_reset(midi_pack_t *p) | |||
| void midi_pack_reset (midi_pack_t *p) | |||
| { | |||
| p->running_status = 0; | |||
| } | |||
| static | |||
| void midi_pack_event(midi_pack_t *p, jack_midi_event_t *e) | |||
| void midi_pack_event (midi_pack_t *p, jack_midi_event_t *e) | |||
| { | |||
| if (e->buffer[0] >= 0x80 && e->buffer[0] < 0xF0) { // Voice Message | |||
| if (e->buffer[0] == p->running_status) { | |||
| e->buffer++; | |||
| e->size--; | |||
| } else | |||
| } else { | |||
| p->running_status = e->buffer[0]; | |||
| } | |||
| } else if (e->buffer[0] < 0xF8) { // not System Realtime | |||
| p->running_status = 0; | |||
| } | |||
| @@ -32,7 +32,7 @@ typedef struct { | |||
| } midi_unpack_t; | |||
| static inline | |||
| void midi_unpack_init(midi_unpack_t *u) | |||
| void midi_unpack_init (midi_unpack_t *u) | |||
| { | |||
| u->pos = 0; | |||
| u->size = sizeof(u->data); | |||
| @@ -40,102 +40,93 @@ void midi_unpack_init(midi_unpack_t *u) | |||
| } | |||
| static inline | |||
| void midi_unpack_reset(midi_unpack_t *u) | |||
| void midi_unpack_reset (midi_unpack_t *u) | |||
| { | |||
| u->pos = 0; | |||
| u->need = u->size; | |||
| } | |||
| static const unsigned char midi_voice_len[] = { | |||
| 3, /*0x80 Note Off*/ | |||
| 3, /*0x90 Note On*/ | |||
| 3, /*0xA0 Aftertouch*/ | |||
| 3, /*0xB0 Control Change*/ | |||
| 2, /*0xC0 Program Change*/ | |||
| 2, /*0xD0 Channel Pressure*/ | |||
| 3, /*0xE0 Pitch Wheel*/ | |||
| 1 /*0xF0 System*/ | |||
| 3, /*0x80 Note Off*/ | |||
| 3, /*0x90 Note On*/ | |||
| 3, /*0xA0 Aftertouch*/ | |||
| 3, /*0xB0 Control Change*/ | |||
| 2, /*0xC0 Program Change*/ | |||
| 2, /*0xD0 Channel Pressure*/ | |||
| 3, /*0xE0 Pitch Wheel*/ | |||
| 1 /*0xF0 System*/ | |||
| }; | |||
| static const unsigned char midi_system_len[] = { | |||
| 0, /*0xF0 System Exclusive Start*/ | |||
| 2, /*0xF1 MTC Quarter Frame*/ | |||
| 3, /*0xF2 Song Postion*/ | |||
| 2, /*0xF3 Song Select*/ | |||
| 0, /*0xF4 undefined*/ | |||
| 0, /*0xF5 undefined*/ | |||
| 1, /*0xF6 Tune Request*/ | |||
| 1 /*0xF7 System Exlusive End*/ | |||
| 0, /*0xF0 System Exclusive Start*/ | |||
| 2, /*0xF1 MTC Quarter Frame*/ | |||
| 3, /*0xF2 Song Postion*/ | |||
| 2, /*0xF3 Song Select*/ | |||
| 0, /*0xF4 undefined*/ | |||
| 0, /*0xF5 undefined*/ | |||
| 1, /*0xF6 Tune Request*/ | |||
| 1 /*0xF7 System Exlusive End*/ | |||
| }; | |||
| static | |||
| int midi_unpack_buf(midi_unpack_t *buf, const unsigned char *data, int len, void *jack_port_buf, jack_nframes_t time) | |||
| int midi_unpack_buf (midi_unpack_t *buf, const unsigned char *data, int len, void *jack_port_buf, jack_nframes_t time) | |||
| { | |||
| int i; | |||
| for (i=0; i<len; ++i) | |||
| { | |||
| for (i = 0; i < len; ++i) { | |||
| const unsigned char byte = data[i]; | |||
| if (byte >= 0xF8) // system realtime | |||
| { | |||
| jack_midi_event_write(jack_port_buf, time, &data[i], 1); | |||
| if (byte >= 0xF8) { // system realtime | |||
| jack_midi_event_write (jack_port_buf, time, &data[i], 1); | |||
| //jack_error("midi_unpack: written system relatime event\n"); | |||
| //midi_input_write(in, &data[i], 1); | |||
| } | |||
| else if (byte < 0x80) // data | |||
| { | |||
| } else if (byte < 0x80) { // data | |||
| assert (buf->pos < buf->size); | |||
| buf->data[buf->pos++] = byte; | |||
| } | |||
| else if (byte < 0xF0) // voice | |||
| { | |||
| } else if (byte < 0xF0) { // voice | |||
| assert (byte >= 0x80 && byte < 0xF0); | |||
| //buf->need = ((byte|0x0F) == 0xCF || (byte|0x0F)==0xDF) ? 2 : 3; | |||
| buf->need = midi_voice_len[(byte-0x80)>>4]; | |||
| buf->need = midi_voice_len[(byte - 0x80) >> 4]; | |||
| buf->data[0] = byte; | |||
| buf->pos = 1; | |||
| } | |||
| else if (byte == 0xF7) // sysex end | |||
| { | |||
| } else if (byte == 0xF7) { // sysex end | |||
| assert (buf->pos < buf->size); | |||
| buf->data[buf->pos++] = byte; | |||
| buf->need = buf->pos; | |||
| } | |||
| else | |||
| { | |||
| } else { | |||
| assert (byte >= 0xF0 && byte < 0xF8); | |||
| buf->pos = 1; | |||
| buf->data[0] = byte; | |||
| buf->need = midi_system_len[byte - 0xF0]; | |||
| if (!buf->need) | |||
| if (!buf->need) { | |||
| buf->need = buf->size; | |||
| } | |||
| } | |||
| if (buf->pos == buf->need) | |||
| { | |||
| if (buf->pos == buf->need) { | |||
| // TODO: deal with big sysex'es (they are silently dropped for now) | |||
| if (buf->data[0] >= 0x80 || (buf->data[0]==0xF0 && buf->data[buf->pos-1] == 0xF7)) { | |||
| if (buf->data[0] >= 0x80 || (buf->data[0] == 0xF0 && buf->data[buf->pos - 1] == 0xF7)) { | |||
| /* convert Note On with velocity 0 to Note Off */ | |||
| if ((buf->data[0] & 0xF0) == 0x90 && buf->data[2] == 0) { | |||
| // we use temp array here to keep running status in sync | |||
| jack_midi_data_t temp[3] = { 0x80, 0, 0x40 }; | |||
| temp[0] |= buf->data[0] & 0x0F; | |||
| temp[1] = buf->data[1]; | |||
| jack_midi_event_write(jack_port_buf, time, temp, 3); | |||
| } else | |||
| jack_midi_event_write(jack_port_buf, time, &buf->data[0], buf->pos); | |||
| jack_midi_event_write (jack_port_buf, time, temp, 3); | |||
| } else { | |||
| jack_midi_event_write (jack_port_buf, time, &buf->data[0], buf->pos); | |||
| } | |||
| //jack_error("midi_unpack: written %d-byte event\n", buf->pos); | |||
| //midi_input_write(in, &buf->data[0], buf->pos); | |||
| } | |||
| /* keep running status */ | |||
| if (buf->data[0] >= 0x80 && buf->data[0] < 0xF0) | |||
| if (buf->data[0] >= 0x80 && buf->data[0] < 0xF0) { | |||
| buf->pos = 1; | |||
| else | |||
| { | |||
| } else { | |||
| buf->pos = 0; | |||
| buf->need = buf->size; | |||
| } | |||
| } | |||
| } | |||
| assert (i==len); | |||
| assert (i == len); | |||
| return i; | |||
| } | |||
| @@ -32,8 +32,8 @@ | |||
| #include "port.h" | |||
| /* This should be part of JACK API */ | |||
| #define JACK_IS_VALID_PORT_NAME_CHAR(c) \ | |||
| (isalnum(c) || \ | |||
| #define JACK_IS_VALID_PORT_NAME_CHAR(c) \ | |||
| (isalnum (c) || \ | |||
| (c) == '/' || \ | |||
| (c) == '_' || \ | |||
| (c) == '(' || \ | |||
| @@ -63,7 +63,7 @@ a2j_alsa_connect_from (alsa_midi_driver_t * driver, int client, int port) | |||
| snd_seq_port_subscribe_set_time_real (sub, 1); | |||
| if ((err = snd_seq_subscribe_port (driver->seq, sub))) { | |||
| a2j_error ("can't subscribe to %d:%d - %s", client, port, snd_strerror(err)); | |||
| a2j_error ("can't subscribe to %d:%d - %s", client, port, snd_strerror (err)); | |||
| } | |||
| return err; | |||
| @@ -72,12 +72,12 @@ a2j_alsa_connect_from (alsa_midi_driver_t * driver, int client, int port) | |||
| void | |||
| a2j_port_setdead (a2j_port_hash_t hash, snd_seq_addr_t addr) | |||
| { | |||
| struct a2j_port *port = a2j_port_get(hash, addr); | |||
| struct a2j_port *port = a2j_port_get (hash, addr); | |||
| if (port) { | |||
| port->is_dead = true; // see jack_process_internal | |||
| } else { | |||
| a2j_debug("port_setdead: not found (%d:%d)", addr.client, addr.port); | |||
| a2j_debug ("port_setdead: not found (%d:%d)", addr.client, addr.port); | |||
| } | |||
| } | |||
| @@ -108,22 +108,22 @@ a2j_port_fill_name (struct a2j_port * port_ptr, int dir, snd_seq_client_info_t * | |||
| snprintf (port_ptr->name, | |||
| sizeof(port_ptr->name), | |||
| "%s [%d] %s %s", | |||
| snd_seq_client_info_get_name(client_info_ptr), | |||
| snd_seq_client_info_get_client(client_info_ptr), | |||
| snd_seq_port_info_get_name(port_info_ptr), | |||
| (dir == A2J_PORT_CAPTURE ? "in" : "out")); | |||
| snd_seq_client_info_get_name (client_info_ptr), | |||
| snd_seq_client_info_get_client (client_info_ptr), | |||
| snd_seq_port_info_get_name (port_info_ptr), | |||
| (dir == A2J_PORT_CAPTURE ? "in" : "out")); | |||
| } else { | |||
| snprintf (port_ptr->name, | |||
| sizeof(port_ptr->name), | |||
| "%s %s %s", | |||
| snd_seq_client_info_get_name(client_info_ptr), | |||
| snd_seq_port_info_get_name(port_info_ptr), | |||
| (dir == A2J_PORT_CAPTURE ? "in" : "out")); | |||
| snd_seq_client_info_get_name (client_info_ptr), | |||
| snd_seq_port_info_get_name (port_info_ptr), | |||
| (dir == A2J_PORT_CAPTURE ? "in" : "out")); | |||
| } | |||
| // replace all offending characters with ' ' | |||
| for (c = port_ptr->name; *c; ++c) { | |||
| if (!JACK_IS_VALID_PORT_NAME_CHAR(*c)) { | |||
| if (!JACK_IS_VALID_PORT_NAME_CHAR (*c)) { | |||
| *c = ' '; | |||
| } | |||
| } | |||
| @@ -142,7 +142,7 @@ a2j_port_create (alsa_midi_driver_t * driver, int dir, snd_seq_addr_t addr, cons | |||
| stream_ptr = &driver->stream[dir]; | |||
| if ((err = snd_seq_client_info_malloc (&client_info_ptr)) != 0) { | |||
| a2j_error("Failed to allocate client info"); | |||
| a2j_error ("Failed to allocate client info"); | |||
| goto fail; | |||
| } | |||
| @@ -150,12 +150,12 @@ a2j_port_create (alsa_midi_driver_t * driver, int dir, snd_seq_addr_t addr, cons | |||
| err = snd_seq_get_any_client_info (driver->seq, client, client_info_ptr); | |||
| if (err != 0) { | |||
| a2j_error("Failed to get client info"); | |||
| a2j_error ("Failed to get client info"); | |||
| goto fail_free_client_info; | |||
| } | |||
| a2j_debug ("client name: '%s'", snd_seq_client_info_get_name(client_info_ptr)); | |||
| a2j_debug ("port name: '%s'", snd_seq_port_info_get_name(info)); | |||
| a2j_debug ("client name: '%s'", snd_seq_client_info_get_name (client_info_ptr)); | |||
| a2j_debug ("port name: '%s'", snd_seq_port_info_get_name (info)); | |||
| port = calloc (1, sizeof(struct a2j_port)); | |||
| if (!port) { | |||
| @@ -170,7 +170,7 @@ a2j_port_create (alsa_midi_driver_t * driver, int dir, snd_seq_addr_t addr, cons | |||
| /* Add port to list early, before registering to JACK, so map functionality is guaranteed to work during port registration */ | |||
| list_add_tail (&port->siblings, &stream_ptr->list); | |||
| if (dir == A2J_PORT_CAPTURE) { | |||
| jack_caps = JackPortIsOutput; | |||
| } else { | |||
| @@ -178,13 +178,13 @@ a2j_port_create (alsa_midi_driver_t * driver, int dir, snd_seq_addr_t addr, cons | |||
| } | |||
| /* mark anything that looks like a hardware port as physical&terminal */ | |||
| if (snd_seq_port_info_get_type (info) & (SND_SEQ_PORT_TYPE_HARDWARE|SND_SEQ_PORT_TYPE_PORT|SND_SEQ_PORT_TYPE_SPECIFIC)) { | |||
| jack_caps |= JackPortIsPhysical|JackPortIsTerminal; | |||
| if (snd_seq_port_info_get_type (info) & (SND_SEQ_PORT_TYPE_HARDWARE | SND_SEQ_PORT_TYPE_PORT | SND_SEQ_PORT_TYPE_SPECIFIC)) { | |||
| jack_caps |= JackPortIsPhysical | JackPortIsTerminal; | |||
| } | |||
| port->jack_port = jack_port_register (driver->jack_client, port->name, JACK_DEFAULT_MIDI_TYPE, jack_caps, 0); | |||
| if (port->jack_port == JACK_INVALID_PORT) { | |||
| a2j_error("jack_port_register() failed for '%s'", port->name); | |||
| a2j_error ("jack_port_register() failed for '%s'", port->name); | |||
| goto fail_free_port; | |||
| } | |||
| @@ -195,23 +195,23 @@ a2j_port_create (alsa_midi_driver_t * driver, int dir, snd_seq_addr_t addr, cons | |||
| } | |||
| if (err) { | |||
| a2j_debug("port skipped: %s", port->name); | |||
| a2j_debug ("port skipped: %s", port->name); | |||
| goto fail_free_port; | |||
| } | |||
| port->inbound_events = jack_ringbuffer_create(MAX_EVENT_SIZE*16); | |||
| port->inbound_events = jack_ringbuffer_create (MAX_EVENT_SIZE * 16); | |||
| a2j_debug("port created: %s", port->name); | |||
| a2j_debug ("port created: %s", port->name); | |||
| return port; | |||
| fail_free_port: | |||
| fail_free_port: | |||
| list_del (&port->siblings); | |||
| a2j_port_free (port); | |||
| fail_free_client_info: | |||
| fail_free_client_info: | |||
| snd_seq_client_info_free (client_info_ptr); | |||
| fail: | |||
| fail: | |||
| return NULL; | |||
| } | |||
| @@ -22,8 +22,8 @@ | |||
| #ifndef PORT_H__757ADD0F_5E53_41F7_8B7F_8119C5E8A9F1__INCLUDED | |||
| #define PORT_H__757ADD0F_5E53_41F7_8B7F_8119C5E8A9F1__INCLUDED | |||
| struct a2j_port* a2j_port_create (alsa_midi_driver_t* driver, int dir, snd_seq_addr_t addr, const snd_seq_port_info_t * info); | |||
| void a2j_port_setdead (a2j_port_hash_t hash, snd_seq_addr_t addr); | |||
| void a2j_port_free (struct a2j_port * port); | |||
| struct a2j_port* a2j_port_create(alsa_midi_driver_t* driver, int dir, snd_seq_addr_t addr, const snd_seq_port_info_t * info); | |||
| void a2j_port_setdead(a2j_port_hash_t hash, snd_seq_addr_t addr); | |||
| void a2j_port_free(struct a2j_port * port); | |||
| #endif /* #ifndef PORT_H__757ADD0F_5E53_41F7_8B7F_8119C5E8A9F1__INCLUDED */ | |||
| @@ -31,33 +31,36 @@ | |||
| static inline | |||
| int | |||
| a2j_port_hash( | |||
| snd_seq_addr_t addr) | |||
| a2j_port_hash ( | |||
| snd_seq_addr_t addr) | |||
| { | |||
| return (addr.client + addr.port) % PORT_HASH_SIZE; | |||
| return (addr.client + addr.port) % PORT_HASH_SIZE; | |||
| } | |||
| struct a2j_port * | |||
| a2j_port_get( | |||
| a2j_port_hash_t hash, | |||
| snd_seq_addr_t addr) | |||
| a2j_port_get ( | |||
| a2j_port_hash_t hash, | |||
| snd_seq_addr_t addr) | |||
| { | |||
| struct a2j_port **pport = &hash[a2j_port_hash(addr)]; | |||
| while (*pport) { | |||
| struct a2j_port *port = *pport; | |||
| if (port->remote.client == addr.client && port->remote.port == addr.port) | |||
| return port; | |||
| pport = &port->next; | |||
| } | |||
| return NULL; | |||
| struct a2j_port **pport = &hash[a2j_port_hash (addr)]; | |||
| while (*pport) { | |||
| struct a2j_port *port = *pport; | |||
| if (port->remote.client == addr.client && port->remote.port == addr.port) { | |||
| return port; | |||
| } | |||
| pport = &port->next; | |||
| } | |||
| return NULL; | |||
| } | |||
| void | |||
| a2j_port_insert( | |||
| a2j_port_hash_t hash, | |||
| struct a2j_port * port) | |||
| a2j_port_insert ( | |||
| a2j_port_hash_t hash, | |||
| struct a2j_port * port) | |||
| { | |||
| struct a2j_port **pport = &hash[a2j_port_hash(port->remote)]; | |||
| port->next = *pport; | |||
| *pport = port; | |||
| struct a2j_port **pport = &hash[a2j_port_hash (port->remote)]; | |||
| port->next = *pport; | |||
| *pport = port; | |||
| } | |||
| @@ -24,12 +24,12 @@ | |||
| void | |||
| a2j_port_insert( | |||
| a2j_port_hash_t hash, | |||
| struct a2j_port * port); | |||
| a2j_port_hash_t hash, | |||
| struct a2j_port * port); | |||
| struct a2j_port * | |||
| a2j_port_get( | |||
| a2j_port_hash_t hash, | |||
| snd_seq_addr_t addr); | |||
| a2j_port_hash_t hash, | |||
| snd_seq_addr_t addr); | |||
| #endif /* #ifndef PORT_HASH_H__A44CBCD6_E075_49CB_8F73_DF9772511D55__INCLUDED */ | |||
| @@ -32,18 +32,16 @@ | |||
| #include "port_thread.h" | |||
| struct a2j_port * | |||
| a2j_find_port_by_addr( | |||
| a2j_find_port_by_addr ( | |||
| struct a2j_stream * stream_ptr, | |||
| snd_seq_addr_t addr) | |||
| { | |||
| struct list_head * node_ptr; | |||
| struct a2j_port * port_ptr; | |||
| list_for_each(node_ptr, &stream_ptr->list) | |||
| { | |||
| port_ptr = list_entry(node_ptr, struct a2j_port, siblings); | |||
| if (port_ptr->remote.client == addr.client && port_ptr->remote.port == addr.port) | |||
| { | |||
| list_for_each (node_ptr, &stream_ptr->list){ | |||
| port_ptr = list_entry (node_ptr, struct a2j_port, siblings); | |||
| if (port_ptr->remote.client == addr.client && port_ptr->remote.port == addr.port) { | |||
| return port_ptr; | |||
| } | |||
| } | |||
| @@ -52,18 +50,16 @@ a2j_find_port_by_addr( | |||
| } | |||
| struct a2j_port * | |||
| a2j_find_port_by_jack_port_name( | |||
| a2j_find_port_by_jack_port_name ( | |||
| struct a2j_stream * stream_ptr, | |||
| const char * jack_port) | |||
| { | |||
| struct list_head * node_ptr; | |||
| struct a2j_port * port_ptr; | |||
| list_for_each(node_ptr, &stream_ptr->list) | |||
| { | |||
| port_ptr = list_entry(node_ptr, struct a2j_port, siblings); | |||
| if (strcmp(port_ptr->name, jack_port) == 0) | |||
| { | |||
| list_for_each (node_ptr, &stream_ptr->list){ | |||
| port_ptr = list_entry (node_ptr, struct a2j_port, siblings); | |||
| if (strcmp (port_ptr->name, jack_port) == 0) { | |||
| return port_ptr; | |||
| } | |||
| } | |||
| @@ -83,10 +79,10 @@ a2j_update_port_type (alsa_midi_driver_t * driver, int dir, snd_seq_addr_t addr, | |||
| int alsa_mask; | |||
| struct a2j_port * port_ptr; | |||
| a2j_debug("update_port_type(%d:%d)", addr.client, addr.port); | |||
| a2j_debug ("update_port_type(%d:%d)", addr.client, addr.port); | |||
| stream_ptr = &driver->stream[dir]; | |||
| port_ptr = a2j_find_port_by_addr(stream_ptr, addr); | |||
| port_ptr = a2j_find_port_by_addr (stream_ptr, addr); | |||
| if (dir == A2J_PORT_CAPTURE) { | |||
| alsa_mask = SND_SEQ_PORT_CAP_SUBS_READ; | |||
| @@ -95,18 +91,18 @@ a2j_update_port_type (alsa_midi_driver_t * driver, int dir, snd_seq_addr_t addr, | |||
| } | |||
| if (port_ptr != NULL && (caps & alsa_mask) != alsa_mask) { | |||
| a2j_debug("setdead: %s", port_ptr->name); | |||
| a2j_debug ("setdead: %s", port_ptr->name); | |||
| port_ptr->is_dead = true; | |||
| } | |||
| if (port_ptr == NULL && (caps & alsa_mask) == alsa_mask) { | |||
| if(jack_ringbuffer_write_space(stream_ptr->new_ports) >= sizeof(port_ptr)) { | |||
| port_ptr = a2j_port_create (driver, dir, addr, info); | |||
| if (jack_ringbuffer_write_space (stream_ptr->new_ports) >= sizeof(port_ptr)) { | |||
| port_ptr = a2j_port_create (driver, dir, addr, info); | |||
| if (port_ptr != NULL) { | |||
| jack_ringbuffer_write(stream_ptr->new_ports, (char *)&port_ptr, sizeof(port_ptr)); | |||
| jack_ringbuffer_write (stream_ptr->new_ports, (char*)&port_ptr, sizeof(port_ptr)); | |||
| } | |||
| } else { | |||
| a2j_error( "dropping new port event... increase MAX_PORTS" ); | |||
| a2j_error ( "dropping new port event... increase MAX_PORTS" ); | |||
| } | |||
| } | |||
| } | |||
| @@ -114,85 +110,85 @@ a2j_update_port_type (alsa_midi_driver_t * driver, int dir, snd_seq_addr_t addr, | |||
| void | |||
| a2j_update_port (alsa_midi_driver_t * driver, snd_seq_addr_t addr, const snd_seq_port_info_t * info) | |||
| { | |||
| unsigned int port_caps = snd_seq_port_info_get_capability(info); | |||
| unsigned int port_type = snd_seq_port_info_get_type(info); | |||
| unsigned int port_caps = snd_seq_port_info_get_capability (info); | |||
| unsigned int port_type = snd_seq_port_info_get_type (info); | |||
| a2j_debug("port %u:%u", addr.client, addr.port); | |||
| a2j_debug("port type: 0x%08X", port_type); | |||
| a2j_debug("port caps: 0x%08X", port_caps); | |||
| a2j_debug ("port %u:%u", addr.client, addr.port); | |||
| a2j_debug ("port type: 0x%08X", port_type); | |||
| a2j_debug ("port caps: 0x%08X", port_caps); | |||
| if (port_type & SND_SEQ_PORT_TYPE_SPECIFIC) { | |||
| a2j_debug("SPECIFIC"); | |||
| a2j_debug ("SPECIFIC"); | |||
| } | |||
| if (port_type & SND_SEQ_PORT_TYPE_MIDI_GENERIC) { | |||
| a2j_debug("MIDI_GENERIC"); | |||
| a2j_debug ("MIDI_GENERIC"); | |||
| } | |||
| if (port_type & SND_SEQ_PORT_TYPE_MIDI_GM) { | |||
| a2j_debug("MIDI_GM"); | |||
| a2j_debug ("MIDI_GM"); | |||
| } | |||
| if (port_type & SND_SEQ_PORT_TYPE_MIDI_GS) { | |||
| a2j_debug("MIDI_GS"); | |||
| a2j_debug ("MIDI_GS"); | |||
| } | |||
| if (port_type & SND_SEQ_PORT_TYPE_MIDI_XG) { | |||
| a2j_debug("MIDI_XG"); | |||
| a2j_debug ("MIDI_XG"); | |||
| } | |||
| if (port_type & SND_SEQ_PORT_TYPE_MIDI_MT32) { | |||
| a2j_debug("MIDI_MT32"); | |||
| a2j_debug ("MIDI_MT32"); | |||
| } | |||
| if (port_type & SND_SEQ_PORT_TYPE_MIDI_GM2) { | |||
| a2j_debug("MIDI_GM2"); | |||
| a2j_debug ("MIDI_GM2"); | |||
| } | |||
| if (port_type & SND_SEQ_PORT_TYPE_SYNTH) { | |||
| a2j_debug("SYNTH"); | |||
| a2j_debug ("SYNTH"); | |||
| } | |||
| if (port_type & SND_SEQ_PORT_TYPE_DIRECT_SAMPLE) { | |||
| a2j_debug("DIRECT_SAMPLE"); | |||
| a2j_debug ("DIRECT_SAMPLE"); | |||
| } | |||
| if (port_type & SND_SEQ_PORT_TYPE_SAMPLE) { | |||
| a2j_debug("SAMPLE"); | |||
| a2j_debug ("SAMPLE"); | |||
| } | |||
| if (port_type & SND_SEQ_PORT_TYPE_HARDWARE) { | |||
| a2j_debug("HARDWARE"); | |||
| a2j_debug ("HARDWARE"); | |||
| } | |||
| if (port_type & SND_SEQ_PORT_TYPE_SOFTWARE) { | |||
| a2j_debug("SOFTWARE"); | |||
| a2j_debug ("SOFTWARE"); | |||
| } | |||
| if (port_type & SND_SEQ_PORT_TYPE_SYNTHESIZER) { | |||
| a2j_debug("SYNTHESIZER"); | |||
| a2j_debug ("SYNTHESIZER"); | |||
| } | |||
| if (port_type & SND_SEQ_PORT_TYPE_PORT) { | |||
| a2j_debug("PORT"); | |||
| a2j_debug ("PORT"); | |||
| } | |||
| if (port_type & SND_SEQ_PORT_TYPE_APPLICATION) { | |||
| a2j_debug("APPLICATION"); | |||
| a2j_debug ("APPLICATION"); | |||
| } | |||
| if (port_type == 0) { | |||
| a2j_debug("Ignoring port of type 0"); | |||
| a2j_debug ("Ignoring port of type 0"); | |||
| return; | |||
| } | |||
| if (port_caps & SND_SEQ_PORT_CAP_NO_EXPORT) { | |||
| a2j_debug("Ignoring no-export port"); | |||
| a2j_debug ("Ignoring no-export port"); | |||
| return; | |||
| } | |||
| a2j_update_port_type (driver, A2J_PORT_CAPTURE, addr, port_caps, info); | |||
| a2j_update_port_type (driver, A2J_PORT_PLAYBACK, addr, port_caps, info); | |||
| a2j_update_port_type (driver, A2J_PORT_CAPTURE, addr, port_caps, info); | |||
| a2j_update_port_type (driver, A2J_PORT_PLAYBACK, addr, port_caps, info); | |||
| } | |||
| void | |||
| @@ -202,47 +198,47 @@ a2j_free_ports (alsa_midi_driver_t * driver) | |||
| int sz; | |||
| while ((sz = jack_ringbuffer_read (driver->port_del, (char*)&port, sizeof(port)))) { | |||
| assert (sz == sizeof(port)); | |||
| a2j_debug("port deleted: %s", port->name); | |||
| list_del (&port->siblings); | |||
| a2j_port_free(port); | |||
| assert (sz == sizeof(port)); | |||
| a2j_debug ("port deleted: %s", port->name); | |||
| list_del (&port->siblings); | |||
| a2j_port_free (port); | |||
| } | |||
| } | |||
| void | |||
| a2j_update_ports (alsa_midi_driver_t * driver, snd_seq_addr_t addr) | |||
| { | |||
| snd_seq_port_info_t * info; | |||
| int err; | |||
| assert (addr.client != driver->client_id); | |||
| snd_seq_port_info_alloca(&info); | |||
| if ((err = snd_seq_get_any_port_info(driver->seq, addr.client, addr.port, info)) >= 0) { | |||
| a2j_debug("updating: %d:%d", addr.client, addr.port); | |||
| a2j_update_port(driver, addr, info); | |||
| } else { | |||
| a2j_debug("setting dead: %d:%d", addr.client, addr.port); | |||
| a2j_port_setdead(driver->stream[A2J_PORT_CAPTURE].port_hash, addr); | |||
| a2j_port_setdead(driver->stream[A2J_PORT_PLAYBACK].port_hash, addr); | |||
| } | |||
| snd_seq_port_info_t * info; | |||
| int err; | |||
| assert (addr.client != driver->client_id); | |||
| snd_seq_port_info_alloca (&info); | |||
| if ((err = snd_seq_get_any_port_info (driver->seq, addr.client, addr.port, info)) >= 0) { | |||
| a2j_debug ("updating: %d:%d", addr.client, addr.port); | |||
| a2j_update_port (driver, addr, info); | |||
| } else { | |||
| a2j_debug ("setting dead: %d:%d", addr.client, addr.port); | |||
| a2j_port_setdead (driver->stream[A2J_PORT_CAPTURE].port_hash, addr); | |||
| a2j_port_setdead (driver->stream[A2J_PORT_PLAYBACK].port_hash, addr); | |||
| } | |||
| } | |||
| void | |||
| a2j_new_ports (alsa_midi_driver_t * driver, snd_seq_addr_t addr) | |||
| { | |||
| snd_seq_port_info_t * port_info; | |||
| snd_seq_port_info_t * port_info; | |||
| assert (addr.client != driver->client_id); | |||
| snd_seq_port_info_alloca(&port_info); | |||
| snd_seq_port_info_alloca (&port_info); | |||
| a2j_debug("adding new port: %d:%d", addr.client, addr.port); | |||
| snd_seq_port_info_set_client(port_info, addr.client); | |||
| snd_seq_port_info_set_port(port_info, -1); | |||
| while (snd_seq_query_next_port(driver->seq, port_info) >= 0) { | |||
| addr.port = snd_seq_port_info_get_port(port_info); | |||
| a2j_update_port(driver, addr, port_info); | |||
| } | |||
| a2j_debug ("adding new port: %d:%d", addr.client, addr.port); | |||
| snd_seq_port_info_set_client (port_info, addr.client); | |||
| snd_seq_port_info_set_port (port_info, -1); | |||
| while (snd_seq_query_next_port (driver->seq, port_info) >= 0) { | |||
| addr.port = snd_seq_port_info_get_port (port_info); | |||
| a2j_update_port (driver, addr, port_info); | |||
| } | |||
| } | |||
| @@ -22,11 +22,11 @@ | |||
| #ifndef PORT_THREAD_H__1C6B5065_5556_4AC6_AA9F_44C32A9648C6__INCLUDED | |||
| #define PORT_THREAD_H__1C6B5065_5556_4AC6_AA9F_44C32A9648C6__INCLUDED | |||
| void a2j_update_port (alsa_midi_driver_t* driver, snd_seq_addr_t addr, const snd_seq_port_info_t* info); | |||
| void a2j_update_ports (alsa_midi_driver_t* driver, snd_seq_addr_t addr); | |||
| void a2j_new_ports (alsa_midi_driver_t* driver, snd_seq_addr_t addr); | |||
| void a2j_free_ports (alsa_midi_driver_t* driver); | |||
| struct a2j_port * a2j_find_port_by_addr (struct a2j_stream * stream_ptr, snd_seq_addr_t addr); | |||
| struct a2j_port * a2j_find_port_by_jack_port_name (struct a2j_stream * stream_ptr, const char * jack_port); | |||
| void a2j_update_port(alsa_midi_driver_t* driver, snd_seq_addr_t addr, const snd_seq_port_info_t* info); | |||
| void a2j_update_ports(alsa_midi_driver_t* driver, snd_seq_addr_t addr); | |||
| void a2j_new_ports(alsa_midi_driver_t* driver, snd_seq_addr_t addr); | |||
| void a2j_free_ports(alsa_midi_driver_t* driver); | |||
| struct a2j_port * a2j_find_port_by_addr(struct a2j_stream * stream_ptr, snd_seq_addr_t addr); | |||
| struct a2j_port * a2j_find_port_by_jack_port_name(struct a2j_stream * stream_ptr, const char * jack_port); | |||
| #endif /* #ifndef PORT_THREAD_H__1C6B5065_5556_4AC6_AA9F_44C32A9648C6__INCLUDED */ | |||
| @@ -38,10 +38,10 @@ alsa_midi_t* alsa_seqmidi_new(jack_client_t *jack, const char* alsa_name); | |||
| typedef struct _alsa_midi_driver { | |||
| JACK_DRIVER_DECL; | |||
| JACK_DRIVER_DECL; | |||
| alsa_midi_t *midi; | |||
| jack_client_t *client; | |||
| alsa_midi_t *midi; | |||
| jack_client_t *client; | |||
| } alsa_midi_driver_t; | |||
| @@ -3,48 +3,49 @@ | |||
| #include <string.h> | |||
| static int | |||
| alsa_midi_driver_attach( alsa_midi_driver_t *driver, jack_engine_t *engine ) | |||
| alsa_midi_driver_attach ( alsa_midi_driver_t *driver, jack_engine_t *engine ) | |||
| { | |||
| return driver->midi->attach(driver->midi); | |||
| return driver->midi->attach (driver->midi); | |||
| } | |||
| static int | |||
| alsa_midi_driver_detach( alsa_midi_driver_t *driver, jack_engine_t *engine ) | |||
| alsa_midi_driver_detach ( alsa_midi_driver_t *driver, jack_engine_t *engine ) | |||
| { | |||
| return driver->midi->detach(driver->midi); | |||
| return driver->midi->detach (driver->midi); | |||
| } | |||
| static int | |||
| alsa_midi_driver_read( alsa_midi_driver_t *driver, jack_nframes_t nframes ) | |||
| alsa_midi_driver_read ( alsa_midi_driver_t *driver, jack_nframes_t nframes ) | |||
| { | |||
| driver->midi->read(driver->midi, nframes); | |||
| driver->midi->read (driver->midi, nframes); | |||
| return 0; | |||
| } | |||
| static int | |||
| alsa_midi_driver_write( alsa_midi_driver_t *driver, jack_nframes_t nframes ) | |||
| alsa_midi_driver_write ( alsa_midi_driver_t *driver, jack_nframes_t nframes ) | |||
| { | |||
| driver->midi->write(driver->midi, nframes); | |||
| driver->midi->write (driver->midi, nframes); | |||
| return 0; | |||
| } | |||
| static int | |||
| alsa_midi_driver_start( alsa_midi_driver_t *driver ) | |||
| alsa_midi_driver_start ( alsa_midi_driver_t *driver ) | |||
| { | |||
| return driver->midi->start(driver->midi); | |||
| return driver->midi->start (driver->midi); | |||
| } | |||
| static int | |||
| alsa_midi_driver_stop( alsa_midi_driver_t *driver ) | |||
| alsa_midi_driver_stop ( alsa_midi_driver_t *driver ) | |||
| { | |||
| return driver->midi->stop(driver->midi); | |||
| return driver->midi->stop (driver->midi); | |||
| } | |||
| static void | |||
| alsa_midi_driver_delete( alsa_midi_driver_t *driver ) | |||
| alsa_midi_driver_delete ( alsa_midi_driver_t *driver ) | |||
| { | |||
| if (driver->midi) | |||
| if (driver->midi) { | |||
| (driver->midi->destroy)(driver->midi); | |||
| } | |||
| free (driver); | |||
| } | |||
| @@ -54,24 +55,24 @@ alsa_midi_driver_new (jack_client_t *client, const char *name) | |||
| { | |||
| alsa_midi_driver_t *driver; | |||
| jack_info ("creating alsa_midi driver ..."); | |||
| jack_info ("creating alsa_midi driver ..."); | |||
| driver = (alsa_midi_driver_t *) calloc (1, sizeof (alsa_midi_driver_t)); | |||
| driver = (alsa_midi_driver_t*)calloc (1, sizeof(alsa_midi_driver_t)); | |||
| jack_driver_init ((jack_driver_t *) driver); | |||
| jack_driver_init ((jack_driver_t*)driver); | |||
| driver->attach = (JackDriverAttachFunction) alsa_midi_driver_attach; | |||
| driver->detach = (JackDriverDetachFunction) alsa_midi_driver_detach; | |||
| driver->read = (JackDriverReadFunction) alsa_midi_driver_read; | |||
| driver->write = (JackDriverWriteFunction) alsa_midi_driver_write; | |||
| driver->start = (JackDriverStartFunction) alsa_midi_driver_start; | |||
| driver->stop = (JackDriverStartFunction) alsa_midi_driver_stop; | |||
| driver->attach = (JackDriverAttachFunction)alsa_midi_driver_attach; | |||
| driver->detach = (JackDriverDetachFunction)alsa_midi_driver_detach; | |||
| driver->read = (JackDriverReadFunction)alsa_midi_driver_read; | |||
| driver->write = (JackDriverWriteFunction)alsa_midi_driver_write; | |||
| driver->start = (JackDriverStartFunction)alsa_midi_driver_start; | |||
| driver->stop = (JackDriverStartFunction)alsa_midi_driver_stop; | |||
| driver->midi = alsa_seqmidi_new(client, NULL); | |||
| driver->midi = alsa_seqmidi_new (client, NULL); | |||
| driver->client = client; | |||
| return (jack_driver_t *) driver; | |||
| return (jack_driver_t*)driver; | |||
| } | |||
| /* DRIVER "PLUGIN" INTERFACE */ | |||
| @@ -83,14 +84,15 @@ driver_get_descriptor () | |||
| { | |||
| jack_driver_desc_t * desc; | |||
| jack_driver_param_desc_t * params; | |||
| //unsigned int i; | |||
| desc = calloc (1, sizeof (jack_driver_desc_t)); | |||
| desc = calloc (1, sizeof(jack_driver_desc_t)); | |||
| strcpy (desc->name,"alsa_midi"); | |||
| strcpy (desc->name, "alsa_midi"); | |||
| desc->nparams = 0; | |||
| params = calloc (desc->nparams, sizeof (jack_driver_param_desc_t)); | |||
| params = calloc (desc->nparams, sizeof(jack_driver_param_desc_t)); | |||
| desc->params = params; | |||
| @@ -104,19 +106,19 @@ driver_initialize (jack_client_t *client, const JSList * params) | |||
| const jack_driver_param_t * param; | |||
| for (node = params; node; node = jack_slist_next (node)) { | |||
| param = (const jack_driver_param_t *) node->data; | |||
| param = (const jack_driver_param_t*)node->data; | |||
| switch (param->character) { | |||
| default: | |||
| break; | |||
| default: | |||
| break; | |||
| } | |||
| } | |||
| return alsa_midi_driver_new (client, NULL); | |||
| } | |||
| void | |||
| driver_finish (jack_driver_t *driver) | |||
| { | |||
| alsa_midi_driver_delete ((alsa_midi_driver_t *) driver); | |||
| alsa_midi_driver_delete ((alsa_midi_driver_t*)driver); | |||
| } | |||
| @@ -27,20 +27,21 @@ typedef struct { | |||
| } midi_pack_t; | |||
| static inline | |||
| void midi_pack_reset(midi_pack_t *p) | |||
| void midi_pack_reset (midi_pack_t *p) | |||
| { | |||
| p->running_status = 0; | |||
| } | |||
| static | |||
| void midi_pack_event(midi_pack_t *p, jack_midi_event_t *e) | |||
| void midi_pack_event (midi_pack_t *p, jack_midi_event_t *e) | |||
| { | |||
| if (e->buffer[0] >= 0x80 && e->buffer[0] < 0xF0) { // Voice Message | |||
| if (e->buffer[0] == p->running_status) { | |||
| e->buffer++; | |||
| e->size--; | |||
| } else | |||
| } else { | |||
| p->running_status = e->buffer[0]; | |||
| } | |||
| } else if (e->buffer[0] < 0xF8) { // not System Realtime | |||
| p->running_status = 0; | |||
| } | |||
| @@ -32,7 +32,7 @@ typedef struct { | |||
| } midi_unpack_t; | |||
| static inline | |||
| void midi_unpack_init(midi_unpack_t *u) | |||
| void midi_unpack_init (midi_unpack_t *u) | |||
| { | |||
| u->pos = 0; | |||
| u->size = sizeof(u->data); | |||
| @@ -40,102 +40,93 @@ void midi_unpack_init(midi_unpack_t *u) | |||
| } | |||
| static inline | |||
| void midi_unpack_reset(midi_unpack_t *u) | |||
| void midi_unpack_reset (midi_unpack_t *u) | |||
| { | |||
| u->pos = 0; | |||
| u->need = u->size; | |||
| } | |||
| static const unsigned char midi_voice_len[] = { | |||
| 3, /*0x80 Note Off*/ | |||
| 3, /*0x90 Note On*/ | |||
| 3, /*0xA0 Aftertouch*/ | |||
| 3, /*0xB0 Control Change*/ | |||
| 2, /*0xC0 Program Change*/ | |||
| 2, /*0xD0 Channel Pressure*/ | |||
| 3, /*0xE0 Pitch Wheel*/ | |||
| 1 /*0xF0 System*/ | |||
| 3, /*0x80 Note Off*/ | |||
| 3, /*0x90 Note On*/ | |||
| 3, /*0xA0 Aftertouch*/ | |||
| 3, /*0xB0 Control Change*/ | |||
| 2, /*0xC0 Program Change*/ | |||
| 2, /*0xD0 Channel Pressure*/ | |||
| 3, /*0xE0 Pitch Wheel*/ | |||
| 1 /*0xF0 System*/ | |||
| }; | |||
| static const unsigned char midi_system_len[] = { | |||
| 0, /*0xF0 System Exclusive Start*/ | |||
| 2, /*0xF1 MTC Quarter Frame*/ | |||
| 3, /*0xF2 Song Postion*/ | |||
| 2, /*0xF3 Song Select*/ | |||
| 0, /*0xF4 undefined*/ | |||
| 0, /*0xF5 undefined*/ | |||
| 1, /*0xF6 Tune Request*/ | |||
| 1 /*0xF7 System Exlusive End*/ | |||
| 0, /*0xF0 System Exclusive Start*/ | |||
| 2, /*0xF1 MTC Quarter Frame*/ | |||
| 3, /*0xF2 Song Postion*/ | |||
| 2, /*0xF3 Song Select*/ | |||
| 0, /*0xF4 undefined*/ | |||
| 0, /*0xF5 undefined*/ | |||
| 1, /*0xF6 Tune Request*/ | |||
| 1 /*0xF7 System Exlusive End*/ | |||
| }; | |||
| static | |||
| int midi_unpack_buf(midi_unpack_t *buf, const unsigned char *data, int len, void *jack_port_buf, jack_nframes_t time) | |||
| int midi_unpack_buf (midi_unpack_t *buf, const unsigned char *data, int len, void *jack_port_buf, jack_nframes_t time) | |||
| { | |||
| int i; | |||
| for (i=0; i<len; ++i) | |||
| { | |||
| for (i = 0; i < len; ++i) { | |||
| const unsigned char byte = data[i]; | |||
| if (byte >= 0xF8) // system realtime | |||
| { | |||
| jack_midi_event_write(jack_port_buf, time, &data[i], 1); | |||
| if (byte >= 0xF8) { // system realtime | |||
| jack_midi_event_write (jack_port_buf, time, &data[i], 1); | |||
| //jack_error("midi_unpack: written system relatime event\n"); | |||
| //midi_input_write(in, &data[i], 1); | |||
| } | |||
| else if (byte < 0x80) // data | |||
| { | |||
| } else if (byte < 0x80) { // data | |||
| assert (buf->pos < buf->size); | |||
| buf->data[buf->pos++] = byte; | |||
| } | |||
| else if (byte < 0xF0) // voice | |||
| { | |||
| } else if (byte < 0xF0) { // voice | |||
| assert (byte >= 0x80 && byte < 0xF0); | |||
| //buf->need = ((byte|0x0F) == 0xCF || (byte|0x0F)==0xDF) ? 2 : 3; | |||
| buf->need = midi_voice_len[(byte-0x80)>>4]; | |||
| buf->need = midi_voice_len[(byte - 0x80) >> 4]; | |||
| buf->data[0] = byte; | |||
| buf->pos = 1; | |||
| } | |||
| else if (byte == 0xF7) // sysex end | |||
| { | |||
| } else if (byte == 0xF7) { // sysex end | |||
| assert (buf->pos < buf->size); | |||
| buf->data[buf->pos++] = byte; | |||
| buf->need = buf->pos; | |||
| } | |||
| else | |||
| { | |||
| } else { | |||
| assert (byte >= 0xF0 && byte < 0xF8); | |||
| buf->pos = 1; | |||
| buf->data[0] = byte; | |||
| buf->need = midi_system_len[byte - 0xF0]; | |||
| if (!buf->need) | |||
| if (!buf->need) { | |||
| buf->need = buf->size; | |||
| } | |||
| } | |||
| if (buf->pos == buf->need) | |||
| { | |||
| if (buf->pos == buf->need) { | |||
| // TODO: deal with big sysex'es (they are silently dropped for now) | |||
| if (buf->data[0] >= 0x80 || (buf->data[0]==0xF0 && buf->data[buf->pos-1] == 0xF7)) { | |||
| if (buf->data[0] >= 0x80 || (buf->data[0] == 0xF0 && buf->data[buf->pos - 1] == 0xF7)) { | |||
| /* convert Note On with velocity 0 to Note Off */ | |||
| if ((buf->data[0] & 0xF0) == 0x90 && buf->data[2] == 0) { | |||
| // we use temp array here to keep running status in sync | |||
| jack_midi_data_t temp[3] = { 0x80, 0, 0x40 }; | |||
| temp[0] |= buf->data[0] & 0x0F; | |||
| temp[1] = buf->data[1]; | |||
| jack_midi_event_write(jack_port_buf, time, temp, 3); | |||
| } else | |||
| jack_midi_event_write(jack_port_buf, time, &buf->data[0], buf->pos); | |||
| jack_midi_event_write (jack_port_buf, time, temp, 3); | |||
| } else { | |||
| jack_midi_event_write (jack_port_buf, time, &buf->data[0], buf->pos); | |||
| } | |||
| //jack_error("midi_unpack: written %d-byte event\n", buf->pos); | |||
| //midi_input_write(in, &buf->data[0], buf->pos); | |||
| } | |||
| /* keep running status */ | |||
| if (buf->data[0] >= 0x80 && buf->data[0] < 0xF0) | |||
| if (buf->data[0] >= 0x80 && buf->data[0] < 0xF0) { | |||
| buf->pos = 1; | |||
| else | |||
| { | |||
| } else { | |||
| buf->pos = 0; | |||
| buf->need = buf->size; | |||
| } | |||
| } | |||
| } | |||
| assert (i==len); | |||
| assert (i == len); | |||
| return i; | |||
| } | |||
| @@ -18,12 +18,12 @@ | |||
| Grame Research Laboratory, 9, rue du Garet 69001 Lyon - France | |||
| grame@rd.grame.fr | |||
| Johnny Petrantoni, johnny@lato-b.com - Italy, Rome. | |||
| 30-01-04, Johnny Petrantoni: first code of the coreaudio driver. | |||
| */ | |||
| Johnny Petrantoni, johnny@lato-b.com - Italy, Rome. | |||
| 30-01-04, Johnny Petrantoni: first code of the coreaudio driver. | |||
| */ | |||
| #ifndef __jack_coreaudio_driver_h__ | |||
| #define __jack_coreaudio_driver_h__ | |||
| @@ -41,32 +41,32 @@ | |||
| typedef struct { | |||
| JACK_DRIVER_DECL struct _jack_engine *engine; | |||
| JACK_DRIVER_DECL struct _jack_engine *engine; | |||
| jack_nframes_t frame_rate; | |||
| jack_nframes_t frames_per_cycle; | |||
| unsigned long user_nperiods; | |||
| int capturing; | |||
| int playing; | |||
| jack_nframes_t frame_rate; | |||
| jack_nframes_t frames_per_cycle; | |||
| unsigned long user_nperiods; | |||
| int capturing; | |||
| int playing; | |||
| channel_t playback_nchannels; | |||
| channel_t capture_nchannels; | |||
| channel_t playback_nchannels; | |||
| channel_t capture_nchannels; | |||
| jack_client_t *client; | |||
| JSList *capture_ports; | |||
| JSList *playback_ports; | |||
| jack_client_t *client; | |||
| JSList *capture_ports; | |||
| JSList *playback_ports; | |||
| char capture_driver_name[256]; | |||
| char playback_driver_name[256]; | |||
| AudioUnit au_hal; | |||
| AudioBufferList* input_list; | |||
| AudioDeviceID device_id; | |||
| int state; | |||
| jack_nframes_t capture_frame_latency; | |||
| jack_nframes_t playback_frame_latency; | |||
| int xrun_detected; | |||
| int null_cycle_occured; | |||
| @@ -74,10 +74,10 @@ typedef struct { | |||
| #define kVersion 01 | |||
| typedef UInt8 CAAudioHardwareDeviceSectionID; | |||
| #define kAudioDeviceSectionInput ((CAAudioHardwareDeviceSectionID)0x01) | |||
| #define kAudioDeviceSectionOutput ((CAAudioHardwareDeviceSectionID)0x00) | |||
| #define kAudioDeviceSectionGlobal ((CAAudioHardwareDeviceSectionID)0x00) | |||
| #define kAudioDeviceSectionWildcard ((CAAudioHardwareDeviceSectionID)0xFF) | |||
| typedef UInt8 CAAudioHardwareDeviceSectionID; | |||
| #define kAudioDeviceSectionInput ((CAAudioHardwareDeviceSectionID)0x01) | |||
| #define kAudioDeviceSectionOutput ((CAAudioHardwareDeviceSectionID)0x00) | |||
| #define kAudioDeviceSectionGlobal ((CAAudioHardwareDeviceSectionID)0x00) | |||
| #define kAudioDeviceSectionWildcard ((CAAudioHardwareDeviceSectionID)0xFF) | |||
| #endif /* __jack_coreaudio_driver_h__ */ | |||
| @@ -17,7 +17,7 @@ | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| */ | |||
| #include <math.h> | |||
| #include <stdio.h> | |||
| @@ -41,69 +41,71 @@ | |||
| #define PRETEND_BUFFER_SIZE 4096 | |||
| void | |||
| FakeVideoSync( dummy_driver_t *driver ) | |||
| FakeVideoSync ( dummy_driver_t *driver ) | |||
| { | |||
| #define VIDEO_SYNC_PERIOD (48000 / 30) | |||
| static int vidCounter = VIDEO_SYNC_PERIOD; | |||
| int period = driver->period_size; | |||
| jack_position_t *position = &driver->engine->control->current_time; | |||
| if ( period >= VIDEO_SYNC_PERIOD ) { | |||
| jack_error("JACK driver period size too large for simple video sync emulation. Halting."); | |||
| exit(0); | |||
| } | |||
| //enable video sync, whether it occurs in this period or not | |||
| position->audio_frames_per_video_frame = VIDEO_SYNC_PERIOD; | |||
| position->valid = (jack_position_bits_t) (position->valid | JackAudioVideoRatio); | |||
| //no video pulse found in this period, just decrement the counter | |||
| if ( vidCounter > period ) { | |||
| vidCounter -= period; | |||
| } | |||
| //video pulse occurs in this period | |||
| if ( vidCounter <= period ) { | |||
| int remainder = period - vidCounter; | |||
| vidCounter = VIDEO_SYNC_PERIOD - remainder; | |||
| position->video_offset = vidCounter; | |||
| position->valid = (jack_position_bits_t) (position->valid | JackVideoFrameOffset); | |||
| } | |||
| #define VIDEO_SYNC_PERIOD (48000 / 30) | |||
| static int vidCounter = VIDEO_SYNC_PERIOD; | |||
| int period = driver->period_size; | |||
| jack_position_t *position = &driver->engine->control->current_time; | |||
| if ( period >= VIDEO_SYNC_PERIOD ) { | |||
| jack_error ("JACK driver period size too large for simple video sync emulation. Halting."); | |||
| exit (0); | |||
| } | |||
| //enable video sync, whether it occurs in this period or not | |||
| position->audio_frames_per_video_frame = VIDEO_SYNC_PERIOD; | |||
| position->valid = (jack_position_bits_t)(position->valid | JackAudioVideoRatio); | |||
| //no video pulse found in this period, just decrement the counter | |||
| if ( vidCounter > period ) { | |||
| vidCounter -= period; | |||
| } | |||
| //video pulse occurs in this period | |||
| if ( vidCounter <= period ) { | |||
| int remainder = period - vidCounter; | |||
| vidCounter = VIDEO_SYNC_PERIOD - remainder; | |||
| position->video_offset = vidCounter; | |||
| position->valid = (jack_position_bits_t)(position->valid | JackVideoFrameOffset); | |||
| } | |||
| } | |||
| #ifdef HAVE_CLOCK_GETTIME | |||
| static inline unsigned long long ts_to_nsec(struct timespec ts) | |||
| static inline unsigned long long ts_to_nsec (struct timespec ts) | |||
| { | |||
| return ts.tv_sec * 1000000000LL + ts.tv_nsec; | |||
| return ts.tv_sec * 1000000000LL + ts.tv_nsec; | |||
| } | |||
| static inline struct timespec nsec_to_ts(unsigned long long nsecs) | |||
| static inline struct timespec nsec_to_ts (unsigned long long nsecs) | |||
| { | |||
| struct timespec ts; | |||
| ts.tv_sec = nsecs / (1000000000LL); | |||
| ts.tv_nsec = nsecs % (1000000000LL); | |||
| return ts; | |||
| struct timespec ts; | |||
| ts.tv_sec = nsecs / (1000000000LL); | |||
| ts.tv_nsec = nsecs % (1000000000LL); | |||
| return ts; | |||
| } | |||
| static inline struct timespec add_ts(struct timespec ts, unsigned int usecs) | |||
| static inline struct timespec add_ts (struct timespec ts, unsigned int usecs) | |||
| { | |||
| unsigned long long nsecs = ts_to_nsec(ts); | |||
| nsecs += usecs * 1000LL; | |||
| return nsec_to_ts(nsecs); | |||
| unsigned long long nsecs = ts_to_nsec (ts); | |||
| nsecs += usecs * 1000LL; | |||
| return nsec_to_ts (nsecs); | |||
| } | |||
| static inline int cmp_lt_ts(struct timespec ts1, struct timespec ts2) | |||
| static inline int cmp_lt_ts (struct timespec ts1, struct timespec ts2) | |||
| { | |||
| if(ts1.tv_sec < ts2.tv_sec) { | |||
| return 1; | |||
| } else if (ts1.tv_sec == ts2.tv_sec && ts1.tv_nsec < ts2.tv_nsec) { | |||
| return 1; | |||
| } else return 0; | |||
| if (ts1.tv_sec < ts2.tv_sec) { | |||
| return 1; | |||
| } else if (ts1.tv_sec == ts2.tv_sec && ts1.tv_nsec < ts2.tv_nsec) { | |||
| return 1; | |||
| } else { return 0; } | |||
| } | |||
| static jack_nframes_t | |||
| static jack_nframes_t | |||
| dummy_driver_wait (dummy_driver_t *driver, int extra_fd, int *status, | |||
| float *delayed_usecs) | |||
| { | |||
| @@ -112,38 +114,38 @@ dummy_driver_wait (dummy_driver_t *driver, int extra_fd, int *status, | |||
| *status = 0; | |||
| /* this driver doesn't work so well if we report a delay */ | |||
| *delayed_usecs = 0; /* lie about it */ | |||
| *delayed_usecs = 0; /* lie about it */ | |||
| clock_gettime (CLOCK_REALTIME, &now); | |||
| clock_gettime(CLOCK_REALTIME, &now); | |||
| if (cmp_lt_ts(driver->next_wakeup, now)) { | |||
| if (cmp_lt_ts (driver->next_wakeup, now)) { | |||
| if (driver->next_wakeup.tv_sec == 0) { | |||
| /* first time through */ | |||
| clock_gettime(CLOCK_REALTIME, &driver->next_wakeup); | |||
| } else if ((ts_to_nsec(now) - ts_to_nsec(driver->next_wakeup))/1000LL | |||
| > (PRETEND_BUFFER_SIZE * 1000000LL | |||
| / driver->sample_rate)) { | |||
| clock_gettime (CLOCK_REALTIME, &driver->next_wakeup); | |||
| } else if ((ts_to_nsec (now) - ts_to_nsec (driver->next_wakeup)) / 1000LL | |||
| > (PRETEND_BUFFER_SIZE * 1000000LL | |||
| / driver->sample_rate)) { | |||
| /* xrun */ | |||
| jack_error("**** dummy: xrun of %ju usec", | |||
| (uintmax_t)(ts_to_nsec(now) - ts_to_nsec(driver->next_wakeup))/1000LL); | |||
| jack_error ("**** dummy: xrun of %ju usec", | |||
| (uintmax_t)(ts_to_nsec (now) - ts_to_nsec (driver->next_wakeup)) / 1000LL); | |||
| nframes = 0; | |||
| driver->next_wakeup.tv_sec = 0; | |||
| } else { | |||
| /* late, but handled by our "buffer"; try to | |||
| * get back on track */ | |||
| } | |||
| driver->next_wakeup = add_ts(driver->next_wakeup, driver->wait_time); | |||
| driver->next_wakeup = add_ts (driver->next_wakeup, driver->wait_time); | |||
| } else { | |||
| if(clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &driver->next_wakeup, NULL)) { | |||
| jack_error("error while sleeping"); | |||
| if (clock_nanosleep (CLOCK_REALTIME, TIMER_ABSTIME, &driver->next_wakeup, NULL)) { | |||
| jack_error ("error while sleeping"); | |||
| *status = -1; | |||
| } else { | |||
| clock_gettime(CLOCK_REALTIME, &now); | |||
| clock_gettime (CLOCK_REALTIME, &now); | |||
| // guaranteed to sleep long enough for this to be correct | |||
| *delayed_usecs = (ts_to_nsec(now) - ts_to_nsec(driver->next_wakeup)); | |||
| *delayed_usecs = (ts_to_nsec (now) - ts_to_nsec (driver->next_wakeup)); | |||
| *delayed_usecs /= 1000.0; | |||
| } | |||
| driver->next_wakeup = add_ts(driver->next_wakeup, driver->wait_time); | |||
| driver->next_wakeup = add_ts (driver->next_wakeup, driver->wait_time); | |||
| } | |||
| driver->last_wait_ust = driver->engine->get_microseconds (); | |||
| @@ -153,30 +155,30 @@ dummy_driver_wait (dummy_driver_t *driver, int extra_fd, int *status, | |||
| return nframes; | |||
| } | |||
| static int dummy_driver_nt_start (dummy_driver_t *drv) | |||
| static int dummy_driver_nt_start (dummy_driver_t *drv) | |||
| { | |||
| drv->next_wakeup.tv_sec = 0; | |||
| return 0; | |||
| return 0; | |||
| } | |||
| #else | |||
| static jack_nframes_t | |||
| static jack_nframes_t | |||
| dummy_driver_wait (dummy_driver_t *driver, int extra_fd, int *status, | |||
| float *delayed_usecs) | |||
| { | |||
| jack_time_t now = driver->engine->get_microseconds(); | |||
| jack_time_t now = driver->engine->get_microseconds (); | |||
| if (driver->next_time < now) { | |||
| if (driver->next_time == 0) { | |||
| /* first time through */ | |||
| driver->next_time = now + driver->wait_time; | |||
| } else if (now - driver->next_time | |||
| > (PRETEND_BUFFER_SIZE * 1000000LL | |||
| / driver->sample_rate)) { | |||
| } else if (now - driver->next_time | |||
| > (PRETEND_BUFFER_SIZE * 1000000LL | |||
| / driver->sample_rate)) { | |||
| /* xrun */ | |||
| jack_error("**** dummy: xrun of %ju usec", | |||
| (uintmax_t)now - driver->next_time); | |||
| jack_error ("**** dummy: xrun of %ju usec", | |||
| (uintmax_t)now - driver->next_time); | |||
| driver->next_time = now + driver->wait_time; | |||
| } else { | |||
| /* late, but handled by our "buffer"; try to | |||
| @@ -185,9 +187,9 @@ dummy_driver_wait (dummy_driver_t *driver, int extra_fd, int *status, | |||
| } | |||
| } else { | |||
| jack_time_t wait = driver->next_time - now; | |||
| struct timespec ts = { .tv_sec = wait / 1000000, | |||
| struct timespec ts = { .tv_sec = wait / 1000000, | |||
| .tv_nsec = (wait % 1000000) * 1000 }; | |||
| nanosleep(&ts,NULL); | |||
| nanosleep (&ts, NULL); | |||
| driver->next_time += driver->wait_time; | |||
| } | |||
| @@ -196,15 +198,15 @@ dummy_driver_wait (dummy_driver_t *driver, int extra_fd, int *status, | |||
| driver->last_wait_ust); | |||
| /* this driver doesn't work so well if we report a delay */ | |||
| *delayed_usecs = 0; /* lie about it */ | |||
| *delayed_usecs = 0; /* lie about it */ | |||
| *status = 0; | |||
| return driver->period_size; | |||
| } | |||
| static int dummy_driver_nt_start (dummy_driver_t *drv) | |||
| static int dummy_driver_nt_start (dummy_driver_t *drv) | |||
| { | |||
| drv->next_time = 0; | |||
| return 0; | |||
| return 0; | |||
| } | |||
| #endif | |||
| @@ -216,23 +218,26 @@ dummy_driver_run_cycle (dummy_driver_t *driver) | |||
| float delayed_usecs; | |||
| jack_nframes_t nframes = dummy_driver_wait (driver, -1, &wait_status, | |||
| &delayed_usecs); | |||
| &delayed_usecs); | |||
| if (nframes == 0) { | |||
| /* we detected an xrun and restarted: notify | |||
| * clients about the delay. */ | |||
| engine->delay (engine, delayed_usecs); | |||
| return 0; | |||
| } | |||
| } | |||
| // FakeVideoSync (driver); | |||
| if (wait_status == 0) | |||
| if (wait_status == 0) { | |||
| return engine->run_cycle (engine, nframes, delayed_usecs); | |||
| } | |||
| if (wait_status < 0) | |||
| if (wait_status < 0) { | |||
| return -1; | |||
| else | |||
| } else { | |||
| return 0; | |||
| } | |||
| } | |||
| static int | |||
| @@ -244,10 +249,10 @@ dummy_driver_null_cycle (dummy_driver_t* driver, jack_nframes_t nframes) | |||
| static int | |||
| dummy_driver_bufsize (dummy_driver_t* driver, jack_nframes_t nframes) | |||
| { | |||
| driver->period_size = nframes; | |||
| driver->period_size = nframes; | |||
| driver->period_usecs = driver->wait_time = | |||
| (jack_time_t) floor ((((float) nframes) / driver->sample_rate) | |||
| * 1000000.0f); | |||
| (jack_time_t)floor ((((float)nframes) / driver->sample_rate) | |||
| * 1000000.0f); | |||
| /* tell the engine to change its buffer size */ | |||
| if (driver->engine->set_buffer_size (driver->engine, nframes)) { | |||
| @@ -279,17 +284,15 @@ dummy_driver_attach (dummy_driver_t *driver) | |||
| } | |||
| driver->engine->set_sample_rate (driver->engine, driver->sample_rate); | |||
| port_flags = JackPortIsOutput|JackPortIsPhysical|JackPortIsTerminal; | |||
| port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; | |||
| for (chn = 0; chn < driver->capture_channels; chn++) | |||
| { | |||
| snprintf (buf, sizeof(buf) - 1, "capture_%u", chn+1); | |||
| for (chn = 0; chn < driver->capture_channels; chn++) { | |||
| snprintf (buf, sizeof(buf) - 1, "capture_%u", chn + 1); | |||
| port = jack_port_register (driver->client, buf, | |||
| JACK_DEFAULT_AUDIO_TYPE, | |||
| port_flags, 0); | |||
| if (!port) | |||
| { | |||
| if (!port) { | |||
| jack_error ("DUMMY: cannot register port for %s", buf); | |||
| break; | |||
| } | |||
| @@ -297,19 +300,17 @@ dummy_driver_attach (dummy_driver_t *driver) | |||
| driver->capture_ports = | |||
| jack_slist_append (driver->capture_ports, port); | |||
| } | |||
| port_flags = JackPortIsInput|JackPortIsPhysical|JackPortIsTerminal; | |||
| for (chn = 0; chn < driver->playback_channels; chn++) | |||
| { | |||
| snprintf (buf, sizeof(buf) - 1, "playback_%u", chn+1); | |||
| port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; | |||
| for (chn = 0; chn < driver->playback_channels; chn++) { | |||
| snprintf (buf, sizeof(buf) - 1, "playback_%u", chn + 1); | |||
| port = jack_port_register (driver->client, buf, | |||
| JACK_DEFAULT_AUDIO_TYPE, | |||
| port_flags, 0); | |||
| if (!port) | |||
| { | |||
| if (!port) { | |||
| jack_error ("DUMMY: cannot register port for %s", buf); | |||
| break; | |||
| } | |||
| @@ -328,20 +329,21 @@ dummy_driver_detach (dummy_driver_t *driver) | |||
| { | |||
| JSList * node; | |||
| if (driver->engine == 0) | |||
| if (driver->engine == 0) { | |||
| return 0; | |||
| } | |||
| for (node = driver->capture_ports; node; node = jack_slist_next (node)) | |||
| jack_port_unregister (driver->client, | |||
| ((jack_port_t *) node->data)); | |||
| ((jack_port_t*)node->data)); | |||
| jack_slist_free (driver->capture_ports); | |||
| driver->capture_ports = NULL; | |||
| for (node = driver->playback_ports; node; node = jack_slist_next (node)) | |||
| jack_port_unregister (driver->client, | |||
| ((jack_port_t *) node->data)); | |||
| ((jack_port_t*)node->data)); | |||
| jack_slist_free (driver->playback_ports); | |||
| driver->playback_ports = NULL; | |||
| @@ -353,7 +355,7 @@ dummy_driver_detach (dummy_driver_t *driver) | |||
| static void | |||
| dummy_driver_delete (dummy_driver_t *driver) | |||
| { | |||
| jack_driver_nt_finish ((jack_driver_nt_t *) driver); | |||
| jack_driver_nt_finish ((jack_driver_nt_t*)driver); | |||
| free (driver); | |||
| } | |||
| @@ -369,24 +371,24 @@ dummy_driver_new (jack_client_t * client, | |||
| dummy_driver_t * driver; | |||
| jack_info ("creating dummy driver ... %s|%" PRIu32 "|%" PRIu32 | |||
| "|%lu|%u|%u", name, sample_rate, period_size, wait_time, | |||
| capture_ports, playback_ports); | |||
| "|%lu|%u|%u", name, sample_rate, period_size, wait_time, | |||
| capture_ports, playback_ports); | |||
| driver = (dummy_driver_t *) calloc (1, sizeof (dummy_driver_t)); | |||
| driver = (dummy_driver_t*)calloc (1, sizeof(dummy_driver_t)); | |||
| jack_driver_nt_init ((jack_driver_nt_t *) driver); | |||
| jack_driver_nt_init ((jack_driver_nt_t*)driver); | |||
| driver->write = (JackDriverReadFunction) dummy_driver_write; | |||
| driver->null_cycle = (JackDriverNullCycleFunction) dummy_driver_null_cycle; | |||
| driver->nt_attach = (JackDriverNTAttachFunction) dummy_driver_attach; | |||
| driver->nt_start = (JackDriverNTStartFunction) dummy_driver_nt_start; | |||
| driver->nt_detach = (JackDriverNTDetachFunction) dummy_driver_detach; | |||
| driver->nt_bufsize = (JackDriverNTBufSizeFunction) dummy_driver_bufsize; | |||
| driver->nt_run_cycle = (JackDriverNTRunCycleFunction) dummy_driver_run_cycle; | |||
| driver->write = (JackDriverReadFunction)dummy_driver_write; | |||
| driver->null_cycle = (JackDriverNullCycleFunction)dummy_driver_null_cycle; | |||
| driver->nt_attach = (JackDriverNTAttachFunction)dummy_driver_attach; | |||
| driver->nt_start = (JackDriverNTStartFunction)dummy_driver_nt_start; | |||
| driver->nt_detach = (JackDriverNTDetachFunction)dummy_driver_detach; | |||
| driver->nt_bufsize = (JackDriverNTBufSizeFunction)dummy_driver_bufsize; | |||
| driver->nt_run_cycle = (JackDriverNTRunCycleFunction)dummy_driver_run_cycle; | |||
| driver->period_usecs = | |||
| (jack_time_t) floor ((((float) period_size) / sample_rate) | |||
| * 1000000.0f); | |||
| (jack_time_t)floor ((((float)period_size) / sample_rate) | |||
| * 1000000.0f); | |||
| driver->sample_rate = sample_rate; | |||
| driver->period_size = period_size; | |||
| driver->wait_time = wait_time; | |||
| @@ -401,7 +403,7 @@ dummy_driver_new (jack_client_t * client, | |||
| driver->client = client; | |||
| driver->engine = NULL; | |||
| return (jack_driver_t *) driver; | |||
| return (jack_driver_t*)driver; | |||
| } | |||
| @@ -414,11 +416,11 @@ driver_get_descriptor () | |||
| jack_driver_param_desc_t * params; | |||
| unsigned int i; | |||
| desc = calloc (1, sizeof (jack_driver_desc_t)); | |||
| desc = calloc (1, sizeof(jack_driver_desc_t)); | |||
| strcpy (desc->name, "dummy"); | |||
| desc->nparams = 5; | |||
| params = calloc (desc->nparams, sizeof (jack_driver_param_desc_t)); | |||
| params = calloc (desc->nparams, sizeof(jack_driver_param_desc_t)); | |||
| i = 0; | |||
| strcpy (params[i].name, "capture"); | |||
| @@ -481,36 +483,37 @@ driver_initialize (jack_client_t *client, const JSList * params) | |||
| const jack_driver_param_t * param; | |||
| for (node = params; node; node = jack_slist_next (node)) { | |||
| param = (const jack_driver_param_t *) node->data; | |||
| param = (const jack_driver_param_t*)node->data; | |||
| switch (param->character) { | |||
| case 'C': | |||
| capture_ports = param->value.ui; | |||
| break; | |||
| capture_ports = param->value.ui; | |||
| break; | |||
| case 'P': | |||
| playback_ports = param->value.ui; | |||
| break; | |||
| playback_ports = param->value.ui; | |||
| break; | |||
| case 'r': | |||
| sample_rate = param->value.ui; | |||
| break; | |||
| sample_rate = param->value.ui; | |||
| break; | |||
| case 'p': | |||
| period_size = param->value.ui; | |||
| break; | |||
| period_size = param->value.ui; | |||
| break; | |||
| case 'w': | |||
| wait_time = param->value.ui; | |||
| wait_time_set = 1; | |||
| break; | |||
| wait_time = param->value.ui; | |||
| wait_time_set = 1; | |||
| break; | |||
| } | |||
| } | |||
| if (!wait_time_set) | |||
| wait_time = (((float)period_size) / ((float)sample_rate)) * 1000000.0; | |||
| if (!wait_time_set) { | |||
| wait_time = (((float)period_size) / ((float)sample_rate)) * 1000000.0; | |||
| } | |||
| return dummy_driver_new (client, "dummy_pcm", capture_ports, | |||
| playback_ports, sample_rate, period_size, | |||
| @@ -520,6 +523,6 @@ driver_initialize (jack_client_t *client, const JSList * params) | |||
| void | |||
| driver_finish (jack_driver_t *driver) | |||
| { | |||
| dummy_driver_delete ((dummy_driver_t *) driver); | |||
| dummy_driver_delete ((dummy_driver_t*)driver); | |||
| } | |||
| @@ -14,7 +14,7 @@ | |||
| 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. | |||
| */ | |||
| */ | |||
| #ifndef __JACK_DUMMY_DRIVER_H__ | |||
| @@ -36,27 +36,26 @@ | |||
| typedef struct _dummy_driver dummy_driver_t; | |||
| struct _dummy_driver | |||
| { | |||
| JACK_DRIVER_NT_DECL; | |||
| struct _dummy_driver { | |||
| JACK_DRIVER_NT_DECL; | |||
| jack_nframes_t sample_rate; | |||
| jack_nframes_t period_size; | |||
| unsigned long wait_time; | |||
| jack_nframes_t sample_rate; | |||
| jack_nframes_t period_size; | |||
| unsigned long wait_time; | |||
| #ifdef HAVE_CLOCK_GETTIME | |||
| struct timespec next_wakeup; | |||
| struct timespec next_wakeup; | |||
| #else | |||
| jack_time_t next_time; | |||
| jack_time_t next_time; | |||
| #endif | |||
| unsigned int capture_channels; | |||
| unsigned int playback_channels; | |||
| unsigned int capture_channels; | |||
| unsigned int playback_channels; | |||
| JSList *capture_ports; | |||
| JSList *playback_ports; | |||
| JSList *capture_ports; | |||
| JSList *playback_ports; | |||
| jack_client_t *client; | |||
| jack_client_t *client; | |||
| }; | |||
| #endif /* __JACK_DUMMY_DRIVER_H__ */ | |||
| @@ -23,11 +23,11 @@ | |||
| * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| /* | |||
| /* | |||
| * Main Jack driver entry routines | |||
| * | |||
| */ | |||
| */ | |||
| #ifndef __JACK_FFADO_DRIVER_H__ | |||
| #define __JACK_FFADO_DRIVER_H__ | |||
| @@ -59,53 +59,53 @@ | |||
| #include "../alsa_midi/midi_unpack.h" | |||
| // debug print control flags | |||
| #define DEBUG_LEVEL_BUFFERS (1<<0) | |||
| #define DEBUG_LEVEL_HANDLERS (1<<1) | |||
| #define DEBUG_LEVEL_XRUN_RECOVERY (1<<2) | |||
| #define DEBUG_LEVEL_WAIT (1<<3) | |||
| #define DEBUG_LEVEL_BUFFERS (1 << 0) | |||
| #define DEBUG_LEVEL_HANDLERS (1 << 1) | |||
| #define DEBUG_LEVEL_XRUN_RECOVERY (1 << 2) | |||
| #define DEBUG_LEVEL_WAIT (1 << 3) | |||
| #define DEBUG_LEVEL_RUN_CYCLE (1<<8) | |||
| #define DEBUG_LEVEL_RUN_CYCLE (1 << 8) | |||
| #define DEBUG_LEVEL_PACKETCOUNTER (1<<16) | |||
| #define DEBUG_LEVEL_STARTUP (1<<17) | |||
| #define DEBUG_LEVEL_THREADS (1<<18) | |||
| #define DEBUG_LEVEL_PACKETCOUNTER (1 << 16) | |||
| #define DEBUG_LEVEL_STARTUP (1 << 17) | |||
| #define DEBUG_LEVEL_THREADS (1 << 18) | |||
| //#define DEBUG_ENABLED | |||
| #ifdef DEBUG_ENABLED | |||
| // default debug level | |||
| // default debug level | |||
| #define DEBUG_LEVEL ( DEBUG_LEVEL_RUN_CYCLE | \ | |||
| (DEBUG_LEVEL_XRUN_RECOVERY)| DEBUG_LEVEL_STARTUP | DEBUG_LEVEL_WAIT | DEBUG_LEVEL_PACKETCOUNTER) | |||
| (DEBUG_LEVEL_XRUN_RECOVERY) | DEBUG_LEVEL_STARTUP | DEBUG_LEVEL_WAIT | DEBUG_LEVEL_PACKETCOUNTER) | |||
| #warning Building debug build! | |||
| #define printMessage(format, args...) jack_error( "firewire MSG: %s:%d (%s): " format, __FILE__, __LINE__, __FUNCTION__, ##args ) | |||
| #define printError(format, args...) jack_error( "firewire ERR: %s:%d (%s): " format, __FILE__, __LINE__, __FUNCTION__, ##args ) | |||
| #define printEnter() jack_error( "FWDRV ENTERS: %s (%s)\n", __FUNCTION__, __FILE__) | |||
| #define printExit() jack_error( "FWDRV EXITS: %s (%s)\n", __FUNCTION__, __FILE__) | |||
| #define printEnter() | |||
| #define printExit() | |||
| #define debugError(format, args...) jack_error( "firewire ERR: %s:%d (%s): " format, __FILE__, __LINE__, __FUNCTION__, ##args ) | |||
| #define debugPrint(Level, format, args...) if(DEBUG_LEVEL & (Level)) jack_error("DEBUG %s:%d (%s) :" format, __FILE__, __LINE__, __FUNCTION__, ##args ); | |||
| #define debugPrintShort(Level, format, args...) if(DEBUG_LEVEL & (Level)) jack_error( format,##args ); | |||
| #define debugPrintWithTimeStamp(Level, format, args...) if(DEBUG_LEVEL & (Level)) jack_error( "%16lu: "format, debugGetCurrentUTime(),##args ); | |||
| #define SEGFAULT int *test=NULL; *test=1; | |||
| #define printMessage(format, args ...) jack_error ( "firewire MSG: %s:%d (%s): " format, __FILE__, __LINE__, __FUNCTION__, ## args ) | |||
| #define printError(format, args ...) jack_error ( "firewire ERR: %s:%d (%s): " format, __FILE__, __LINE__, __FUNCTION__, ## args ) | |||
| #define printEnter() jack_error ( "FWDRV ENTERS: %s (%s)\n", __FUNCTION__, __FILE__) | |||
| #define printExit() jack_error ( "FWDRV EXITS: %s (%s)\n", __FUNCTION__, __FILE__) | |||
| #define printEnter() | |||
| #define printExit() | |||
| #define debugError(format, args ...) jack_error ( "firewire ERR: %s:%d (%s): " format, __FILE__, __LINE__, __FUNCTION__, ## args ) | |||
| #define debugPrint(Level, format, args ...) if (DEBUG_LEVEL & (Level)) { jack_error ("DEBUG %s:%d (%s) :" format, __FILE__, __LINE__, __FUNCTION__, ## args ); } | |||
| #define debugPrintShort(Level, format, args ...) if (DEBUG_LEVEL & (Level)) { jack_error ( format, ## args ); } | |||
| #define debugPrintWithTimeStamp(Level, format, args ...) if (DEBUG_LEVEL & (Level)) { jack_error ( "%16lu: "format, debugGetCurrentUTime (), ## args ); } | |||
| #define SEGFAULT int *test = NULL; *test = 1; | |||
| #else | |||
| #define DEBUG_LEVEL | |||
| #define printMessage(format, args...) if(g_verbose) \ | |||
| jack_error("firewire MSG: " format, ##args ) | |||
| #define printError(format, args...) jack_error("firewire ERR: " format, ##args ) | |||
| #define printEnter() | |||
| #define printExit() | |||
| #define debugError(format, args...) | |||
| #define debugPrint(Level, format, args...) | |||
| #define debugPrintShort(Level, format, args...) | |||
| #define debugPrintWithTimeStamp(Level, format, args...) | |||
| #define printMessage(format, args ...) if (g_verbose) \ | |||
| jack_error ("firewire MSG: " format, ## args ) | |||
| #define printError(format, args ...) jack_error ("firewire ERR: " format, ## args ) | |||
| #define printEnter() | |||
| #define printExit() | |||
| #define debugError(format, args ...) | |||
| #define debugPrint(Level, format, args ...) | |||
| #define debugPrintShort(Level, format, args ...) | |||
| #define debugPrintWithTimeStamp(Level, format, args ...) | |||
| #endif | |||
| typedef struct _ffado_driver ffado_driver_t; | |||
| @@ -116,39 +116,37 @@ typedef struct _ffado_driver ffado_driver_t; | |||
| typedef struct _ffado_jack_settings ffado_jack_settings_t; | |||
| struct _ffado_jack_settings { | |||
| int verbose_level; | |||
| int period_size_set; | |||
| jack_nframes_t period_size; | |||
| int sample_rate_set; | |||
| int sample_rate; | |||
| int buffer_size_set; | |||
| jack_nframes_t buffer_size; | |||
| int playback_ports; | |||
| int capture_ports; | |||
| jack_nframes_t capture_frame_latency; | |||
| jack_nframes_t playback_frame_latency; | |||
| int slave_mode; | |||
| int snoop_mode; | |||
| char *device_info; | |||
| int verbose_level; | |||
| int period_size_set; | |||
| jack_nframes_t period_size; | |||
| int sample_rate_set; | |||
| int sample_rate; | |||
| int buffer_size_set; | |||
| jack_nframes_t buffer_size; | |||
| int playback_ports; | |||
| int capture_ports; | |||
| jack_nframes_t capture_frame_latency; | |||
| jack_nframes_t playback_frame_latency; | |||
| int slave_mode; | |||
| int snoop_mode; | |||
| char *device_info; | |||
| }; | |||
| typedef struct _ffado_capture_channel | |||
| { | |||
| typedef struct _ffado_capture_channel { | |||
| ffado_streaming_stream_type stream_type; | |||
| midi_unpack_t midi_unpack; | |||
| uint32_t *midi_buffer; | |||
| } ffado_capture_channel_t; | |||
| #define MIDI_OVERFLOW_BUFFER_SIZE 4 | |||
| typedef struct _ffado_playback_channel | |||
| { | |||
| typedef struct _ffado_playback_channel { | |||
| ffado_streaming_stream_type stream_type; | |||
| midi_pack_t midi_pack; | |||
| uint32_t *midi_buffer; | |||
| @@ -161,50 +159,49 @@ typedef struct _ffado_playback_channel | |||
| /* | |||
| * JACK driver structure | |||
| */ | |||
| struct _ffado_driver | |||
| { | |||
| struct _ffado_driver { | |||
| JACK_DRIVER_NT_DECL; | |||
| jack_nframes_t sample_rate; | |||
| jack_nframes_t period_size; | |||
| unsigned long wait_time; | |||
| jack_time_t wait_last; | |||
| jack_time_t wait_next; | |||
| jack_nframes_t sample_rate; | |||
| jack_nframes_t period_size; | |||
| unsigned long wait_time; | |||
| jack_time_t wait_last; | |||
| jack_time_t wait_next; | |||
| int wait_late; | |||
| jack_client_t *client; | |||
| int xrun_detected; | |||
| int xrun_count; | |||
| int xrun_detected; | |||
| int xrun_count; | |||
| int process_count; | |||
| /* settings from the command line */ | |||
| ffado_jack_settings_t settings; | |||
| /* the firewire virtual device */ | |||
| ffado_device_t *dev; | |||
| ffado_sample_t *nullbuffer; | |||
| ffado_sample_t *scratchbuffer; | |||
| JSList *capture_ports; | |||
| JSList *playback_ports; | |||
| JSList *monitor_ports; | |||
| channel_t playback_nchannels; | |||
| channel_t capture_nchannels; | |||
| JSList *capture_ports; | |||
| JSList *playback_ports; | |||
| JSList *monitor_ports; | |||
| channel_t playback_nchannels; | |||
| channel_t capture_nchannels; | |||
| ffado_playback_channel_t *playback_channels; | |||
| ffado_capture_channel_t *capture_channels; | |||
| jack_nframes_t playback_frame_latency; | |||
| jack_nframes_t capture_frame_latency; | |||
| jack_nframes_t playback_frame_latency; | |||
| jack_nframes_t capture_frame_latency; | |||
| ffado_device_info_t device_info; | |||
| ffado_options_t device_options; | |||
| }; | |||
| }; | |||
| @@ -23,11 +23,11 @@ | |||
| * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| /* | |||
| /* | |||
| * Main Jack driver entry routines | |||
| * | |||
| */ | |||
| */ | |||
| #ifndef __JACK_FREEBOB_DRIVER_H__ | |||
| #define __JACK_FREEBOB_DRIVER_H__ | |||
| @@ -66,59 +66,59 @@ | |||
| #include "engine.h" | |||
| // debug print control flags | |||
| #define DEBUG_LEVEL_BUFFERS (1<<0) | |||
| #define DEBUG_LEVEL_HANDLERS (1<<1) | |||
| #define DEBUG_LEVEL_XRUN_RECOVERY (1<<2) | |||
| #define DEBUG_LEVEL_WAIT (1<<3) | |||
| #define DEBUG_LEVEL_BUFFERS (1 << 0) | |||
| #define DEBUG_LEVEL_HANDLERS (1 << 1) | |||
| #define DEBUG_LEVEL_XRUN_RECOVERY (1 << 2) | |||
| #define DEBUG_LEVEL_WAIT (1 << 3) | |||
| #define DEBUG_LEVEL_RUN_CYCLE (1<<8) | |||
| #define DEBUG_LEVEL_RUN_CYCLE (1 << 8) | |||
| #define DEBUG_LEVEL_PACKETCOUNTER (1<<16) | |||
| #define DEBUG_LEVEL_STARTUP (1<<17) | |||
| #define DEBUG_LEVEL_THREADS (1<<18) | |||
| #define DEBUG_LEVEL_PACKETCOUNTER (1 << 16) | |||
| #define DEBUG_LEVEL_STARTUP (1 << 17) | |||
| #define DEBUG_LEVEL_THREADS (1 << 18) | |||
| #ifdef DEBUG_ENABLED | |||
| // default debug level | |||
| // default debug level | |||
| #define DEBUG_LEVEL ( DEBUG_LEVEL_RUN_CYCLE | \ | |||
| (DEBUG_LEVEL_XRUN_RECOVERY)| DEBUG_LEVEL_STARTUP | DEBUG_LEVEL_WAIT | DEBUG_LEVEL_PACKETCOUNTER) | |||
| (DEBUG_LEVEL_XRUN_RECOVERY) | DEBUG_LEVEL_STARTUP | DEBUG_LEVEL_WAIT | DEBUG_LEVEL_PACKETCOUNTER) | |||
| #warning Building debug build! | |||
| #define printMessage(format, args...) jack_error( "FreeBoB MSG: %s:%d (%s): " format, __FILE__, __LINE__, __FUNCTION__, ##args ) | |||
| #define printError(format, args...) jack_error( "FreeBoB ERR: %s:%d (%s): " format, __FILE__, __LINE__, __FUNCTION__, ##args ) | |||
| //#define printEnter() jack_error( "FBDRV ENTERS: %s (%s)\n", __FUNCTION__, __FILE__) | |||
| //#define printExit() jack_error( "FBDRV EXITS: %s (%s)\n", __FUNCTION__, __FILE__) | |||
| #define printEnter() | |||
| #define printExit() | |||
| #define debugError(format, args...) jack_error( "FREEBOB ERR: %s:%d (%s): " format, __FILE__, __LINE__, __FUNCTION__, ##args ) | |||
| #define debugPrint(Level, format, args...) if(DEBUG_LEVEL & (Level)) jack_error("DEBUG %s:%d (%s) :" format, __FILE__, __LINE__, __FUNCTION__, ##args ); | |||
| #define debugPrintShort(Level, format, args...) if(DEBUG_LEVEL & (Level)) jack_error( format,##args ); | |||
| #define debugPrintWithTimeStamp(Level, format, args...) if(DEBUG_LEVEL & (Level)) jack_error( "%16lu: "format, debugGetCurrentUTime(),##args ); | |||
| #define SEGFAULT int *test=NULL; *test=1; | |||
| #define printMessage(format, args ...) jack_error ( "FreeBoB MSG: %s:%d (%s): " format, __FILE__, __LINE__, __FUNCTION__, ## args ) | |||
| #define printError(format, args ...) jack_error ( "FreeBoB ERR: %s:%d (%s): " format, __FILE__, __LINE__, __FUNCTION__, ## args ) | |||
| //#define printEnter() jack_error( "FBDRV ENTERS: %s (%s)\n", __FUNCTION__, __FILE__) | |||
| //#define printExit() jack_error( "FBDRV EXITS: %s (%s)\n", __FUNCTION__, __FILE__) | |||
| #define printEnter() | |||
| #define printExit() | |||
| #define debugError(format, args ...) jack_error ( "FREEBOB ERR: %s:%d (%s): " format, __FILE__, __LINE__, __FUNCTION__, ## args ) | |||
| #define debugPrint(Level, format, args ...) if (DEBUG_LEVEL & (Level)) { jack_error ("DEBUG %s:%d (%s) :" format, __FILE__, __LINE__, __FUNCTION__, ## args ); } | |||
| #define debugPrintShort(Level, format, args ...) if (DEBUG_LEVEL & (Level)) { jack_error ( format, ## args ); } | |||
| #define debugPrintWithTimeStamp(Level, format, args ...) if (DEBUG_LEVEL & (Level)) { jack_error ( "%16lu: "format, debugGetCurrentUTime (), ## args ); } | |||
| #define SEGFAULT int *test = NULL; *test = 1; | |||
| #else | |||
| #define DEBUG_LEVEL | |||
| #define printMessage(format, args...) if(g_verbose) \ | |||
| jack_error("FreeBoB MSG: " format, ##args ) | |||
| #define printError(format, args...) jack_error("FreeBoB ERR: " format, ##args ) | |||
| #define printEnter() | |||
| #define printExit() | |||
| #define debugError(format, args...) | |||
| #define debugPrint(Level, format, args...) | |||
| #define debugPrintShort(Level, format, args...) | |||
| #define debugPrintWithTimeStamp(Level, format, args...) | |||
| #define printMessage(format, args ...) if (g_verbose) \ | |||
| jack_error ("FreeBoB MSG: " format, ## args ) | |||
| #define printError(format, args ...) jack_error ("FreeBoB ERR: " format, ## args ) | |||
| #define printEnter() | |||
| #define printExit() | |||
| #define debugError(format, args ...) | |||
| #define debugPrint(Level, format, args ...) | |||
| #define debugPrintShort(Level, format, args ...) | |||
| #define debugPrintWithTimeStamp(Level, format, args ...) | |||
| #endif | |||
| // thread priority setup | |||
| #define FREEBOB_RT_PRIORITY_PACKETIZER_RELATIVE 5 | |||
| #define FREEBOB_RT_PRIORITY_PACKETIZER_RELATIVE 5 | |||
| // MIDI | |||
| // MIDI | |||
| #ifdef FREEBOB_DRIVER_WITH_ALSA_MIDI | |||
| @@ -130,9 +130,9 @@ | |||
| #define MIDI_THREAD_SLEEP_TIME_USECS 100 | |||
| // midi priority should be higher than the audio priority in order to | |||
| // make sure events are not only delivered on period boundarys | |||
| // but I think it should be smaller than the packetizer thread in order not | |||
| // but I think it should be smaller than the packetizer thread in order not | |||
| // to lose any packets | |||
| #define FREEBOB_RT_PRIORITY_MIDI_RELATIVE 4 | |||
| #define FREEBOB_RT_PRIORITY_MIDI_RELATIVE 4 | |||
| #endif // FREEBOB_DRIVER_WITH_ALSA_MIDI | |||
| @@ -145,7 +145,7 @@ | |||
| typedef struct freebob_midi_input_port_t { | |||
| // jack | |||
| midi_unpack_t unpack; | |||
| // midi | |||
| int overruns; | |||
| } freebob_midi_input_port_t; | |||
| @@ -168,22 +168,22 @@ typedef struct _freebob_jack_settings freebob_jack_settings_t; | |||
| struct _freebob_jack_settings { | |||
| int period_size_set; | |||
| jack_nframes_t period_size; | |||
| int sample_rate_set; | |||
| int sample_rate; | |||
| int buffer_size_set; | |||
| jack_nframes_t buffer_size; | |||
| int port_set; | |||
| int port; | |||
| int node_id_set; | |||
| int node_id; | |||
| int playback_ports; | |||
| int capture_ports; | |||
| jack_nframes_t capture_frame_latency; | |||
| jack_nframes_t playback_frame_latency; | |||
| @@ -205,7 +205,7 @@ typedef struct _freebob_driver_midi_handle { | |||
| freebob_driver_t *driver; | |||
| snd_seq_t *seq_handle; | |||
| pthread_t queue_thread; | |||
| pthread_t dequeue_thread; | |||
| int queue_thread_realtime; | |||
| @@ -227,41 +227,40 @@ typedef struct _freebob_driver_midi_handle { | |||
| /* | |||
| * JACK driver structure | |||
| */ | |||
| struct _freebob_driver | |||
| { | |||
| struct _freebob_driver { | |||
| JACK_DRIVER_NT_DECL | |||
| jack_nframes_t sample_rate; | |||
| jack_nframes_t period_size; | |||
| unsigned long wait_time; | |||
| jack_time_t wait_last; | |||
| jack_time_t wait_next; | |||
| jack_nframes_t sample_rate; | |||
| jack_nframes_t period_size; | |||
| unsigned long wait_time; | |||
| jack_time_t wait_last; | |||
| jack_time_t wait_next; | |||
| int wait_late; | |||
| jack_client_t *client; | |||
| int xrun_detected; | |||
| int xrun_count; | |||
| int xrun_detected; | |||
| int xrun_count; | |||
| int process_count; | |||
| /* settings from the command line */ | |||
| freebob_jack_settings_t settings; | |||
| /* the freebob virtual device */ | |||
| freebob_device_t *dev; | |||
| JSList *capture_ports; | |||
| JSList *playback_ports; | |||
| JSList *monitor_ports; | |||
| channel_t playback_nchannels; | |||
| channel_t capture_nchannels; | |||
| channel_t playback_nchannels; | |||
| channel_t capture_nchannels; | |||
| jack_nframes_t playback_frame_latency; | |||
| jack_nframes_t capture_frame_latency; | |||
| jack_nframes_t playback_frame_latency; | |||
| jack_nframes_t capture_frame_latency; | |||
| freebob_device_info_t device_info; | |||
| freebob_options_t device_options; | |||
| @@ -276,7 +275,7 @@ struct _freebob_driver | |||
| #endif | |||
| }; | |||
| }; | |||
| @@ -15,7 +15,7 @@ | |||
| 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. | |||
| */ | |||
| */ | |||
| #ifndef __JACK_NET_DRIVER_H__ | |||
| @@ -35,11 +35,10 @@ | |||
| typedef struct _net_driver net_driver_t; | |||
| struct _net_driver | |||
| { | |||
| JACK_DRIVER_NT_DECL; | |||
| struct _net_driver { | |||
| JACK_DRIVER_NT_DECL; | |||
| netjack_driver_state_t netj; | |||
| netjack_driver_state_t netj; | |||
| }; | |||
| #endif /* __JACK_NET_DRIVER_H__ */ | |||
| @@ -16,7 +16,7 @@ | |||
| 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. | |||
| */ | |||
| */ | |||
| #ifndef __NETJACK_H__ | |||
| #define __NETJACK_H__ | |||
| @@ -45,105 +45,105 @@ struct _packet_cache; | |||
| typedef struct _netjack_driver_state netjack_driver_state_t; | |||
| struct _netjack_driver_state { | |||
| jack_nframes_t net_period_up; | |||
| jack_nframes_t net_period_down; | |||
| jack_nframes_t net_period_up; | |||
| jack_nframes_t net_period_down; | |||
| jack_nframes_t sample_rate; | |||
| jack_nframes_t bitdepth; | |||
| jack_nframes_t period_size; | |||
| jack_time_t period_usecs; | |||
| int dont_htonl_floats; | |||
| int always_deadline; | |||
| jack_nframes_t sample_rate; | |||
| jack_nframes_t bitdepth; | |||
| jack_nframes_t period_size; | |||
| jack_time_t period_usecs; | |||
| int dont_htonl_floats; | |||
| int always_deadline; | |||
| jack_nframes_t codec_latency; | |||
| jack_nframes_t codec_latency; | |||
| unsigned int listen_port; | |||
| unsigned int listen_port; | |||
| unsigned int capture_channels; | |||
| unsigned int playback_channels; | |||
| unsigned int capture_channels_audio; | |||
| unsigned int playback_channels_audio; | |||
| unsigned int capture_channels_midi; | |||
| unsigned int playback_channels_midi; | |||
| unsigned int capture_channels; | |||
| unsigned int playback_channels; | |||
| unsigned int capture_channels_audio; | |||
| unsigned int playback_channels_audio; | |||
| unsigned int capture_channels_midi; | |||
| unsigned int playback_channels_midi; | |||
| JSList *capture_ports; | |||
| JSList *playback_ports; | |||
| JSList *playback_srcs; | |||
| JSList *capture_srcs; | |||
| JSList *capture_ports; | |||
| JSList *playback_ports; | |||
| JSList *playback_srcs; | |||
| JSList *capture_srcs; | |||
| jack_client_t *client; | |||
| jack_client_t *client; | |||
| #ifdef WIN32 | |||
| SOCKET sockfd; | |||
| SOCKET outsockfd; | |||
| SOCKET sockfd; | |||
| SOCKET outsockfd; | |||
| #else | |||
| int sockfd; | |||
| int outsockfd; | |||
| int sockfd; | |||
| int outsockfd; | |||
| #endif | |||
| struct sockaddr_in syncsource_address; | |||
| int reply_port; | |||
| int srcaddress_valid; | |||
| int sync_state; | |||
| unsigned int handle_transport_sync; | |||
| unsigned int *rx_buf; | |||
| unsigned int rx_bufsize; | |||
| //unsigned int tx_bufsize; | |||
| unsigned int mtu; | |||
| unsigned int latency; | |||
| unsigned int redundancy; | |||
| jack_nframes_t expected_framecnt; | |||
| int expected_framecnt_valid; | |||
| unsigned int num_lost_packets; | |||
| jack_time_t next_deadline; | |||
| jack_time_t deadline_offset; | |||
| int next_deadline_valid; | |||
| int packet_data_valid; | |||
| int resync_threshold; | |||
| int running_free; | |||
| int deadline_goodness; | |||
| jack_time_t time_to_deadline; | |||
| unsigned int use_autoconfig; | |||
| unsigned int resample_factor; | |||
| unsigned int resample_factor_up; | |||
| int jitter_val; | |||
| struct _packet_cache * packcache; | |||
| struct sockaddr_in syncsource_address; | |||
| int reply_port; | |||
| int srcaddress_valid; | |||
| int sync_state; | |||
| unsigned int handle_transport_sync; | |||
| unsigned int *rx_buf; | |||
| unsigned int rx_bufsize; | |||
| //unsigned int tx_bufsize; | |||
| unsigned int mtu; | |||
| unsigned int latency; | |||
| unsigned int redundancy; | |||
| jack_nframes_t expected_framecnt; | |||
| int expected_framecnt_valid; | |||
| unsigned int num_lost_packets; | |||
| jack_time_t next_deadline; | |||
| jack_time_t deadline_offset; | |||
| int next_deadline_valid; | |||
| int packet_data_valid; | |||
| int resync_threshold; | |||
| int running_free; | |||
| int deadline_goodness; | |||
| jack_time_t time_to_deadline; | |||
| unsigned int use_autoconfig; | |||
| unsigned int resample_factor; | |||
| unsigned int resample_factor_up; | |||
| int jitter_val; | |||
| struct _packet_cache * packcache; | |||
| #if HAVE_CELT | |||
| CELTMode *celt_mode; | |||
| CELTMode *celt_mode; | |||
| #endif | |||
| }; | |||
| int netjack_wait( netjack_driver_state_t *netj, jack_time_t (*get_microseconds)(void) ); | |||
| int netjack_wait ( netjack_driver_state_t * netj, jack_time_t (*get_microseconds)(void) ); | |||
| void netjack_send_silence( netjack_driver_state_t *netj, int syncstate ); | |||
| void netjack_read( netjack_driver_state_t *netj, jack_nframes_t nframes ) ; | |||
| void netjack_read( netjack_driver_state_t *netj, jack_nframes_t nframes ); | |||
| void netjack_write( netjack_driver_state_t *netj, jack_nframes_t nframes, int syncstate ); | |||
| void netjack_attach( netjack_driver_state_t *netj ); | |||
| void netjack_detach( netjack_driver_state_t *netj ); | |||
| netjack_driver_state_t *netjack_init (netjack_driver_state_t *netj, | |||
| jack_client_t * client, | |||
| const char *name, | |||
| unsigned int capture_ports, | |||
| unsigned int playback_ports, | |||
| unsigned int capture_ports_midi, | |||
| unsigned int playback_ports_midi, | |||
| jack_nframes_t sample_rate, | |||
| jack_nframes_t period_size, | |||
| unsigned int listen_port, | |||
| unsigned int transport_sync, | |||
| unsigned int resample_factor, | |||
| unsigned int resample_factor_up, | |||
| unsigned int bitdepth, | |||
| unsigned int use_autoconfig, | |||
| unsigned int latency, | |||
| unsigned int redundancy, | |||
| int dont_htonl_floats, | |||
| int always_deadline, | |||
| int jitter_val ); | |||
| netjack_driver_state_t *netjack_init(netjack_driver_state_t *netj, | |||
| jack_client_t * client, | |||
| const char *name, | |||
| unsigned int capture_ports, | |||
| unsigned int playback_ports, | |||
| unsigned int capture_ports_midi, | |||
| unsigned int playback_ports_midi, | |||
| jack_nframes_t sample_rate, | |||
| jack_nframes_t period_size, | |||
| unsigned int listen_port, | |||
| unsigned int transport_sync, | |||
| unsigned int resample_factor, | |||
| unsigned int resample_factor_up, | |||
| unsigned int bitdepth, | |||
| unsigned int use_autoconfig, | |||
| unsigned int latency, | |||
| unsigned int redundancy, | |||
| int dont_htonl_floats, | |||
| int always_deadline, | |||
| int jitter_val ); | |||
| void netjack_release( netjack_driver_state_t *netj ); | |||
| int netjack_startup( netjack_driver_state_t *netj ); | |||
| @@ -28,8 +28,8 @@ | |||
| #define __JACK_NET_PACKET_H__ | |||
| #ifdef __cplusplus | |||
| extern "C" | |||
| { | |||
| extern "C" | |||
| { | |||
| #endif | |||
| #include <jack/jack.h> | |||
| @@ -46,81 +46,77 @@ | |||
| typedef struct _jacknet_packet_header jacknet_packet_header; | |||
| struct _jacknet_packet_header | |||
| { | |||
| // General AutoConf Data | |||
| jack_nframes_t capture_channels_audio; | |||
| jack_nframes_t playback_channels_audio; | |||
| jack_nframes_t capture_channels_midi; | |||
| jack_nframes_t playback_channels_midi; | |||
| jack_nframes_t period_size; | |||
| jack_nframes_t sample_rate; | |||
| // Transport Sync | |||
| jack_nframes_t sync_state; | |||
| jack_nframes_t transport_frame; | |||
| jack_nframes_t transport_state; | |||
| // Packet loss Detection, and latency reduction | |||
| jack_nframes_t framecnt; | |||
| jack_nframes_t latency; | |||
| jack_nframes_t reply_port; | |||
| jack_nframes_t mtu; | |||
| jack_nframes_t fragment_nr; | |||
| struct _jacknet_packet_header { | |||
| // General AutoConf Data | |||
| jack_nframes_t capture_channels_audio; | |||
| jack_nframes_t playback_channels_audio; | |||
| jack_nframes_t capture_channels_midi; | |||
| jack_nframes_t playback_channels_midi; | |||
| jack_nframes_t period_size; | |||
| jack_nframes_t sample_rate; | |||
| // Transport Sync | |||
| jack_nframes_t sync_state; | |||
| jack_nframes_t transport_frame; | |||
| jack_nframes_t transport_state; | |||
| // Packet loss Detection, and latency reduction | |||
| jack_nframes_t framecnt; | |||
| jack_nframes_t latency; | |||
| jack_nframes_t reply_port; | |||
| jack_nframes_t mtu; | |||
| jack_nframes_t fragment_nr; | |||
| }; | |||
| typedef union _int_float int_float_t; | |||
| union _int_float | |||
| { | |||
| uint32_t i; | |||
| float f; | |||
| union _int_float { | |||
| uint32_t i; | |||
| float f; | |||
| }; | |||
| // fragment reorder cache. | |||
| typedef struct _cache_packet cache_packet; | |||
| struct _cache_packet | |||
| { | |||
| int valid; | |||
| int num_fragments; | |||
| int packet_size; | |||
| int mtu; | |||
| jack_time_t recv_timestamp; | |||
| jack_nframes_t framecnt; | |||
| char * fragment_array; | |||
| char * packet_buf; | |||
| struct _cache_packet { | |||
| int valid; | |||
| int num_fragments; | |||
| int packet_size; | |||
| int mtu; | |||
| jack_time_t recv_timestamp; | |||
| jack_nframes_t framecnt; | |||
| char * fragment_array; | |||
| char * packet_buf; | |||
| }; | |||
| typedef struct _packet_cache packet_cache; | |||
| struct _packet_cache | |||
| { | |||
| int size; | |||
| cache_packet *packets; | |||
| int mtu; | |||
| struct sockaddr_in master_address; | |||
| int master_address_valid; | |||
| jack_nframes_t last_framecnt_retreived; | |||
| int last_framecnt_retreived_valid; | |||
| struct _packet_cache { | |||
| int size; | |||
| cache_packet *packets; | |||
| int mtu; | |||
| struct sockaddr_in master_address; | |||
| int master_address_valid; | |||
| jack_nframes_t last_framecnt_retreived; | |||
| int last_framecnt_retreived_valid; | |||
| }; | |||
| // fragment cache function prototypes | |||
| // XXX: Some of these are private. | |||
| packet_cache *packet_cache_new(int num_packets, int pkt_size, int mtu); | |||
| void packet_cache_free(packet_cache *pkt_cache); | |||
| void packet_cache_free(packet_cache *pkt_cache); | |||
| cache_packet *packet_cache_get_packet(packet_cache *pkt_cache, jack_nframes_t framecnt); | |||
| cache_packet *packet_cache_get_oldest_packet(packet_cache *pkt_cache); | |||
| cache_packet *packet_cache_get_free_packet(packet_cache *pkt_cache); | |||
| void cache_packet_reset(cache_packet *pack); | |||
| void cache_packet_set_framecnt(cache_packet *pack, jack_nframes_t framecnt); | |||
| void cache_packet_add_fragment(cache_packet *pack, char *packet_buf, int rcv_len); | |||
| int cache_packet_is_complete(cache_packet *pack); | |||
| void cache_packet_reset(cache_packet *pack); | |||
| void cache_packet_set_framecnt(cache_packet *pack, jack_nframes_t framecnt); | |||
| void cache_packet_add_fragment(cache_packet *pack, char *packet_buf, int rcv_len); | |||
| int cache_packet_is_complete(cache_packet *pack); | |||
| void packet_cache_drain_socket( packet_cache *pcache, int sockfd, jack_time_t (*get_microseconds)(void) ); | |||
| void packet_cache_drain_socket ( packet_cache * pcache, int sockfd, jack_time_t (*get_microseconds)(void) ); | |||
| void packet_cache_reset_master_address( packet_cache *pcache ); | |||
| float packet_cache_get_fill( packet_cache *pcache, jack_nframes_t expected_framecnt ); | |||
| int packet_cache_retreive_packet_pointer( packet_cache *pcache, jack_nframes_t framecnt, char **packet_buf, int pkt_size, jack_time_t *timestamp ); | |||
| @@ -149,10 +145,10 @@ void render_jack_ports_to_payload(int bitdepth, JSList *playback_ports, JSList * | |||
| // This one waits forever. an is not using ppoll | |||
| int netjack_poll(int sockfd, int timeout); | |||
| void decode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf); | |||
| void encode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf); | |||
| void decode_midi_buffer(uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf); | |||
| void encode_midi_buffer(uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf); | |||
| #ifdef __cplusplus | |||
| } | |||
| } | |||
| #endif | |||
| #endif | |||
| @@ -1,24 +1,24 @@ | |||
| /* | |||
| OSS driver for Jack | |||
| Copyright (C) 2003-2007 Jussi Laako <jussi@sonarnerd.net> | |||
| OSS driver for Jack | |||
| Copyright (C) 2003-2007 Jussi Laako <jussi@sonarnerd.net> | |||
| 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 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. | |||
| 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., 59 Temple Place, Suite 330, Boston, | |||
| MA 02111-1307 USA | |||
| 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., 59 Temple Place, Suite 330, Boston, | |||
| MA 02111-1307 USA | |||
| */ | |||
| */ | |||
| #ifndef __JACK_OSS_DRIVER_H__ | |||
| @@ -35,19 +35,18 @@ | |||
| #include "driver.h" | |||
| #define OSS_DRIVER_DEF_DEV "/dev/dsp" | |||
| #define OSS_DRIVER_DEF_FS 48000 | |||
| #define OSS_DRIVER_DEF_BLKSIZE 1024 | |||
| #define OSS_DRIVER_DEF_NPERIODS 2 | |||
| #define OSS_DRIVER_DEF_BITS 16 | |||
| #define OSS_DRIVER_DEF_INS 2 | |||
| #define OSS_DRIVER_DEF_OUTS 2 | |||
| #define OSS_DRIVER_DEF_DEV "/dev/dsp" | |||
| #define OSS_DRIVER_DEF_FS 48000 | |||
| #define OSS_DRIVER_DEF_BLKSIZE 1024 | |||
| #define OSS_DRIVER_DEF_NPERIODS 2 | |||
| #define OSS_DRIVER_DEF_BITS 16 | |||
| #define OSS_DRIVER_DEF_INS 2 | |||
| #define OSS_DRIVER_DEF_OUTS 2 | |||
| typedef jack_default_audio_sample_t jack_sample_t; | |||
| typedef struct _oss_driver | |||
| { | |||
| typedef struct _oss_driver { | |||
| JACK_DRIVER_DECL | |||
| jack_nframes_t sample_rate; | |||
| @@ -89,9 +88,9 @@ typedef struct _oss_driver | |||
| pthread_t thread_out; | |||
| pthread_mutex_t mutex_in; | |||
| pthread_mutex_t mutex_out; | |||
| # ifdef USE_BARRIER | |||
| # ifdef USE_BARRIER | |||
| pthread_barrier_t barrier; | |||
| # endif | |||
| # endif | |||
| sem_t sem_start; | |||
| } oss_driver_t; | |||
| @@ -14,10 +14,10 @@ | |||
| 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. | |||
| Grame Research Laboratory, 9, rue du Garet 69001 Lyon - France | |||
| grame@rd.grame.fr | |||
| */ | |||
| */ | |||
| #ifndef __jack_portaudio_driver_h__ | |||
| #define __jack_portaudio_driver_h__ | |||
| @@ -35,27 +35,27 @@ | |||
| typedef struct { | |||
| JACK_DRIVER_DECL | |||
| JACK_DRIVER_DECL | |||
| struct _jack_engine *engine; | |||
| struct _jack_engine *engine; | |||
| jack_nframes_t frame_rate; | |||
| jack_nframes_t frames_per_cycle; | |||
| unsigned long user_nperiods; | |||
| int capturing; | |||
| int playing; | |||
| jack_nframes_t frame_rate; | |||
| jack_nframes_t frames_per_cycle; | |||
| unsigned long user_nperiods; | |||
| int capturing; | |||
| int playing; | |||
| channel_t playback_nchannels; | |||
| channel_t capture_nchannels; | |||
| channel_t playback_nchannels; | |||
| channel_t capture_nchannels; | |||
| jack_client_t *client; | |||
| JSList *capture_ports; | |||
| JSList *playback_ports; | |||
| jack_client_t *client; | |||
| JSList *capture_ports; | |||
| JSList *playback_ports; | |||
| float *inPortAudio; | |||
| float *outPortAudio; | |||
| char driver_name[256]; | |||
| PortAudioStream* stream; | |||
| float *inPortAudio; | |||
| float *outPortAudio; | |||
| char driver_name[256]; | |||
| PortAudioStream* stream; | |||
| } portaudio_driver_t; | |||
| @@ -1,28 +1,28 @@ | |||
| /* | |||
| Sun Audio API driver for Jack | |||
| Copyright (C) 2008 Jacob Meuser <jakemsr@sdf.lonestar.org> | |||
| Based heavily on oss_driver.h which came with the following | |||
| copyright notice. | |||
| Sun Audio API driver for Jack | |||
| Copyright (C) 2008 Jacob Meuser <jakemsr@sdf.lonestar.org> | |||
| Based heavily on oss_driver.h which came with the following | |||
| copyright notice. | |||
| Copyright (C) 2003-2007 Jussi Laako <jussi@sonarnerd.net> | |||
| Copyright (C) 2003-2007 Jussi Laako <jussi@sonarnerd.net> | |||
| 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 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. | |||
| 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., 59 Temple Place, Suite 330, Boston, | |||
| MA 02111-1307 USA | |||
| 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., 59 Temple Place, Suite 330, Boston, | |||
| MA 02111-1307 USA | |||
| */ | |||
| */ | |||
| #ifndef __JACK_SUN_DRIVER_H__ | |||
| @@ -38,19 +38,18 @@ | |||
| #include "driver.h" | |||
| #define SUN_DRIVER_DEF_DEV "/dev/audio" | |||
| #define SUN_DRIVER_DEF_FS 48000 | |||
| #define SUN_DRIVER_DEF_BLKSIZE 1024 | |||
| #define SUN_DRIVER_DEF_NPERIODS 2 | |||
| #define SUN_DRIVER_DEF_BITS 16 | |||
| #define SUN_DRIVER_DEF_INS 2 | |||
| #define SUN_DRIVER_DEF_OUTS 2 | |||
| #define SUN_DRIVER_DEF_DEV "/dev/audio" | |||
| #define SUN_DRIVER_DEF_FS 48000 | |||
| #define SUN_DRIVER_DEF_BLKSIZE 1024 | |||
| #define SUN_DRIVER_DEF_NPERIODS 2 | |||
| #define SUN_DRIVER_DEF_BITS 16 | |||
| #define SUN_DRIVER_DEF_INS 2 | |||
| #define SUN_DRIVER_DEF_OUTS 2 | |||
| typedef jack_default_audio_sample_t jack_sample_t; | |||
| typedef struct _sun_driver | |||
| { | |||
| typedef struct _sun_driver { | |||
| JACK_DRIVER_NT_DECL | |||
| jack_nframes_t sample_rate; | |||
| @@ -1 +1 @@ | |||
| Subproject commit 7fa089095c81e81dacd2554ae3184acc7f2d58ed | |||
| Subproject commit e74323c535876abca9a2293bd2ca426a3b91ff8b | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| Copyright (C) 2004 Jack O'Quin | |||
| 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 | |||
| @@ -15,7 +15,7 @@ | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| */ | |||
| #ifndef __jack_atomicity_h__ | |||
| #define __jack_atomicity_h__ | |||
| @@ -19,12 +19,12 @@ | |||
| * 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. | |||
| @@ -33,8 +33,8 @@ | |||
| #ifndef __bitset_h__ | |||
| #define __bitset_h__ | |||
| #include <inttypes.h> /* POSIX standard fixed-size types */ | |||
| #include <assert.h> /* `#define NDEBUG' to disable */ | |||
| #include <inttypes.h> /* POSIX standard fixed-size types */ | |||
| #include <assert.h> /* `#define NDEBUG' to disable */ | |||
| /* On some 64-bit machines, this implementation may be slightly | |||
| * inefficient, depending on how compilers allocate space for | |||
| @@ -45,67 +45,67 @@ | |||
| typedef uint32_t _bitset_word_t; | |||
| typedef _bitset_word_t *bitset_t; | |||
| #define WORD_SIZE(cardinality) (1+((cardinality)+31)/32) | |||
| #define BYTE_SIZE(cardinality) (WORD_SIZE(cardinality)*sizeof(_bitset_word_t)) | |||
| #define WORD_INDEX(element) (1+(element)/32) | |||
| #define BIT_INDEX(element) ((element)&037) | |||
| #define WORD_SIZE(cardinality) (1 + ((cardinality) + 31) / 32) | |||
| #define BYTE_SIZE(cardinality) (WORD_SIZE (cardinality) * sizeof(_bitset_word_t)) | |||
| #define WORD_INDEX(element) (1 + (element) / 32) | |||
| #define BIT_INDEX(element) ((element) & 037) | |||
| static inline void | |||
| bitset_add(bitset_t set, unsigned int element) | |||
| bitset_add (bitset_t set, unsigned int element) | |||
| { | |||
| assert(element < set[0]); | |||
| set[WORD_INDEX(element)] |= (1 << BIT_INDEX(element)); | |||
| assert (element < set[0]); | |||
| set[WORD_INDEX (element)] |= (1 << BIT_INDEX (element)); | |||
| } | |||
| static inline void | |||
| bitset_copy(bitset_t to_set, bitset_t from_set) | |||
| bitset_copy (bitset_t to_set, bitset_t from_set) | |||
| { | |||
| assert(to_set[0] == from_set[0]); | |||
| memcpy(to_set, from_set, BYTE_SIZE(to_set[0])); | |||
| assert (to_set[0] == from_set[0]); | |||
| memcpy (to_set, from_set, BYTE_SIZE (to_set[0])); | |||
| } | |||
| static inline void | |||
| bitset_create(bitset_t *set, unsigned int cardinality) | |||
| bitset_create (bitset_t *set, unsigned int cardinality) | |||
| { | |||
| *set = (bitset_t) calloc(WORD_SIZE(cardinality), | |||
| *set = (bitset_t)calloc (WORD_SIZE (cardinality), | |||
| sizeof(_bitset_word_t)); | |||
| assert(*set); | |||
| assert (*set); | |||
| *set[0] = cardinality; | |||
| } | |||
| static inline void | |||
| bitset_destroy(bitset_t *set) | |||
| bitset_destroy (bitset_t *set) | |||
| { | |||
| if (*set) { | |||
| free(*set); | |||
| *set = (bitset_t) 0; | |||
| free (*set); | |||
| *set = (bitset_t)0; | |||
| } | |||
| } | |||
| static inline int | |||
| bitset_empty(bitset_t set) | |||
| bitset_empty (bitset_t set) | |||
| { | |||
| int i; | |||
| _bitset_word_t result = 0; | |||
| int nwords = WORD_SIZE(set[0]); | |||
| for (i = 1; i < nwords; i++) { | |||
| int nwords = WORD_SIZE (set[0]); | |||
| for (i = 1; i < nwords; i++) | |||
| result |= set[i]; | |||
| } | |||
| return (result == 0); | |||
| return result == 0; | |||
| } | |||
| static inline int | |||
| bitset_contains(bitset_t set, unsigned int element) | |||
| bitset_contains (bitset_t set, unsigned int element) | |||
| { | |||
| assert(element < set[0]); | |||
| return (0 != (set[WORD_INDEX(element)] & (1<<BIT_INDEX(element)))); | |||
| assert (element < set[0]); | |||
| return 0 != (set[WORD_INDEX (element)] & (1 << BIT_INDEX (element))); | |||
| } | |||
| static inline void | |||
| bitset_remove(bitset_t set, unsigned int element) | |||
| bitset_remove (bitset_t set, unsigned int element) | |||
| { | |||
| assert(element < set[0]); | |||
| set[WORD_INDEX(element)] &= ~(1<<BIT_INDEX(element)); | |||
| assert (element < set[0]); | |||
| set[WORD_INDEX (element)] &= ~(1 << BIT_INDEX (element)); | |||
| } | |||
| #endif /* __bitset_h__ */ | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| Copyright (C) 2001 Paul Davis | |||
| 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 | |||
| @@ -15,7 +15,7 @@ | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| */ | |||
| #ifndef __jack_driver_h__ | |||
| #define __jack_driver_h__ | |||
| @@ -26,53 +26,53 @@ | |||
| #include "port.h" | |||
| #include "driver_interface.h" | |||
| typedef float gain_t; | |||
| typedef float gain_t; | |||
| typedef unsigned long channel_t; | |||
| typedef enum { | |||
| typedef enum { | |||
| Lock = 0x1, | |||
| NoLock = 0x2, | |||
| Sync = 0x4, | |||
| NoSync = 0x8 | |||
| } ClockSyncStatus; | |||
| typedef void (*ClockSyncListenerFunction)(channel_t,ClockSyncStatus,void*); | |||
| typedef void (*ClockSyncListenerFunction)(channel_t, ClockSyncStatus, void*); | |||
| typedef struct { | |||
| unsigned long id; | |||
| ClockSyncListenerFunction function; | |||
| void *arg; | |||
| 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); | |||
| /* | |||
| 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 | |||
| - 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 () | |||
| driver->engine->run_cycle () | |||
| } | |||
| 5) engine stops driver | |||
| 6) engine detaches from driver | |||
| @@ -80,7 +80,7 @@ typedef int (*JackDriverBufSizeFunction)(struct _jack_driver *, | |||
| Note that stop/start may be called multiple times in the event of an | |||
| error return from the `wait' function. | |||
| */ | |||
| */ | |||
| typedef struct _jack_driver { | |||
| @@ -88,7 +88,7 @@ typedef struct _jack_driver { | |||
| 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. | |||
| @@ -106,7 +106,7 @@ typedef struct _jack_driver { | |||
| 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; | |||
| @@ -133,23 +133,23 @@ typedef struct _jack_driver { | |||
| JackDriverDetachFunction detach; | |||
| The JACK engine will call this when it wants to wait until the | |||
| 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. | |||
| 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. | |||
| 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 | |||
| in this variable. the engine will use this to decide if it | |||
| plans to continue execution. | |||
| JackDriverWaitFunction wait; | |||
| @@ -157,8 +157,8 @@ typedef struct _jack_driver { | |||
| 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. | |||
| return 0 to indicate successful completion, negative otherwise. | |||
| This function will always be called after the wait function (above). | |||
| JackDriverReadFunction read; | |||
| @@ -166,8 +166,8 @@ typedef struct _jack_driver { | |||
| 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. | |||
| return 0 to indicate successful completion, negative otherwise. | |||
| this function will always be called after the read function (above). | |||
| JackDriverWriteFunction write; | |||
| @@ -181,7 +181,7 @@ typedef struct _jack_driver { | |||
| 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). | |||
| @@ -198,7 +198,7 @@ typedef struct _jack_driver { | |||
| 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 | |||
| @@ -206,48 +206,48 @@ typedef struct _jack_driver { | |||
| prior to this, and the start function after this one has returned. | |||
| JackDriverBufSizeFunction bufsize; | |||
| */ | |||
| */ | |||
| /* define the fields here... */ | |||
| /* 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_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; | |||
| typedef jack_driver_desc_t * (*JackDriverDescFunction) (); | |||
| typedef jack_driver_desc_t * (*JackDriverDescFunction)(); | |||
| void jack_driver_init (jack_driver_t *); | |||
| void jack_driver_release (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 *); | |||
| jack_driver_t *jack_driver_load(int argc, char **argv); | |||
| void jack_driver_unload(jack_driver_t *); | |||
| /**************************** | |||
| *** Non-Threaded Drivers *** | |||
| ****************************/ | |||
| *** 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 | |||
| - 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 | |||
| @@ -263,43 +263,43 @@ void jack_driver_unload (jack_driver_t *); | |||
| 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 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; | |||
| 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_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); | |||
| void jack_driver_nt_init(jack_driver_nt_t * driver); | |||
| void jack_driver_nt_finish(jack_driver_nt_t * driver); | |||
| #endif /* __jack_driver_h__ */ | |||
| @@ -1,21 +1,21 @@ | |||
| /* | |||
| Copyright (C) 2003 Bob Ham <rah@bash.sh> | |||
| 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 | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| */ | |||
| */ | |||
| #ifndef __jack_driver_interface_h__ | |||
| #define __jack_driver_interface_h__ | |||
| @@ -33,82 +33,77 @@ extern "C" { | |||
| #define JACK_DRIVER_PARAM_NAME_MAX 15 | |||
| #define JACK_DRIVER_PARAM_STRING_MAX 63 | |||
| #define JACK_CONSTRAINT_FLAG_RANGE ((uint32_t)1) /**< if set, constraint is a range (min-max) */ | |||
| #define JACK_CONSTRAINT_FLAG_STRICT ((uint32_t)2) /**< if set, constraint is strict, i.e. supplying non-matching value will not work */ | |||
| #define JACK_CONSTRAINT_FLAG_FAKE_VALUE ((uint32_t)4) /**< if set, values have no user meaningful meaning */ | |||
| #define JACK_CONSTRAINT_FLAG_RANGE ((uint32_t)1) /**< if set, constraint is a range (min-max) */ | |||
| #define JACK_CONSTRAINT_FLAG_STRICT ((uint32_t)2) /**< if set, constraint is strict, i.e. supplying non-matching value will not work */ | |||
| #define JACK_CONSTRAINT_FLAG_FAKE_VALUE ((uint32_t)4) /**< if set, values have no user meaningful meaning */ | |||
| /** Driver parameter types */ | |||
| typedef enum | |||
| { | |||
| JackDriverParamInt = 1, | |||
| JackDriverParamUInt, | |||
| JackDriverParamChar, | |||
| JackDriverParamString, | |||
| JackDriverParamBool | |||
| typedef enum { | |||
| JackDriverParamInt = 1, | |||
| JackDriverParamUInt, | |||
| JackDriverParamChar, | |||
| JackDriverParamString, | |||
| JackDriverParamBool | |||
| } jack_driver_param_type_t; | |||
| /** Driver parameter value */ | |||
| typedef union | |||
| { | |||
| uint32_t ui; | |||
| int32_t i; | |||
| char c; | |||
| char str[JACK_DRIVER_PARAM_STRING_MAX+1]; | |||
| typedef union { | |||
| uint32_t ui; | |||
| int32_t i; | |||
| char c; | |||
| char str[JACK_DRIVER_PARAM_STRING_MAX + 1]; | |||
| } jack_driver_param_value_t; | |||
| typedef struct { | |||
| jack_driver_param_value_t value; | |||
| char short_desc[64]; /**< A short (~30 chars) description for the user */ | |||
| jack_driver_param_value_t value; | |||
| char short_desc[64]; /**< A short (~30 chars) description for the user */ | |||
| } jack_driver_param_value_enum_t; | |||
| typedef struct { | |||
| uint32_t flags; /**< JACK_CONSTRAINT_FLAG_XXX */ | |||
| union { | |||
| struct { | |||
| jack_driver_param_value_t min; | |||
| jack_driver_param_value_t max; | |||
| } range; /**< valid when JACK_CONSTRAINT_FLAG_RANGE flag is set */ | |||
| struct { | |||
| uint32_t count; | |||
| jack_driver_param_value_enum_t * possible_values_array; | |||
| } enumeration; /**< valid when JACK_CONSTRAINT_FLAG_RANGE flag is not set */ | |||
| } constraint; | |||
| uint32_t flags; /**< JACK_CONSTRAINT_FLAG_XXX */ | |||
| union { | |||
| struct { | |||
| jack_driver_param_value_t min; | |||
| jack_driver_param_value_t max; | |||
| } range; /**< valid when JACK_CONSTRAINT_FLAG_RANGE flag is set */ | |||
| struct { | |||
| uint32_t count; | |||
| jack_driver_param_value_enum_t * possible_values_array; | |||
| } enumeration; /**< valid when JACK_CONSTRAINT_FLAG_RANGE flag is not set */ | |||
| } constraint; | |||
| } jack_driver_param_constraint_desc_t; | |||
| /** A driver parameter descriptor */ | |||
| typedef struct | |||
| { | |||
| char name[JACK_DRIVER_NAME_MAX+1]; /**< The parameter's name */ | |||
| char character; /**< The parameter's character (for getopt, etc) */ | |||
| jack_driver_param_type_t type; /**< The parameter's type */ | |||
| jack_driver_param_value_t value; /**< The parameter's (default) value */ | |||
| jack_driver_param_constraint_desc_t * constraint; /**< Pointer to parameter constraint descriptor. NULL if there is no constraint */ | |||
| char short_desc[64]; /**< A short (~30 chars) description for the user */ | |||
| char long_desc[1024]; /**< A longer description for the user */ | |||
| typedef struct { | |||
| char name[JACK_DRIVER_NAME_MAX + 1]; /**< The parameter's name */ | |||
| char character; /**< The parameter's character (for getopt, etc) */ | |||
| jack_driver_param_type_t type; /**< The parameter's type */ | |||
| jack_driver_param_value_t value; /**< The parameter's (default) value */ | |||
| jack_driver_param_constraint_desc_t * constraint; /**< Pointer to parameter constraint descriptor. NULL if there is no constraint */ | |||
| char short_desc[64]; /**< A short (~30 chars) description for the user */ | |||
| char long_desc[1024]; /**< A longer description for the user */ | |||
| } jack_driver_param_desc_t; | |||
| /** A driver parameter */ | |||
| typedef struct | |||
| { | |||
| char character; | |||
| jack_driver_param_value_t value; | |||
| typedef struct { | |||
| char character; | |||
| jack_driver_param_value_t value; | |||
| } jack_driver_param_t; | |||
| /** A struct for describing a jack driver */ | |||
| typedef struct | |||
| { | |||
| char name[JACK_DRIVER_NAME_MAX+1]; /**< The driver's canonical name */ | |||
| char file[PATH_MAX+1]; /**< The filename of the driver's shared object file */ | |||
| uint32_t nparams; /**< The number of parameters the driver has */ | |||
| jack_driver_param_desc_t * params; /**< An array of parameter descriptors */ | |||
| typedef struct { | |||
| char name[JACK_DRIVER_NAME_MAX + 1]; /**< The driver's canonical name */ | |||
| char file[PATH_MAX + 1]; /**< The filename of the driver's shared object file */ | |||
| uint32_t nparams; /**< The number of parameters the driver has */ | |||
| jack_driver_param_desc_t * params; /**< An array of parameter descriptors */ | |||
| } jack_driver_desc_t; | |||
| @@ -1,22 +1,22 @@ | |||
| /* -*- mode: c; c-file-style: "linux"; -*- */ | |||
| /* | |||
| Copyright (C) 2003 Bob Ham <rah@bash.sh | |||
| 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. | |||
| Copyright (C) 2003 Bob Ham <rah@bash.sh | |||
| 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. | |||
| 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. | |||
| 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. | |||
| 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. | |||
| */ | |||
| #ifndef __jack_driver_parse_h__ | |||
| #define __jack_driver_parse_h__ | |||
| @@ -43,10 +43,11 @@ jack_print_driver_options (jack_driver_desc_t * desc, FILE *file) | |||
| break; | |||
| case JackDriverParamString: | |||
| if (desc->params[i].value.str && | |||
| strcmp (desc->params[i].value.str, "") != 0) | |||
| strcmp (desc->params[i].value.str, "") != 0) { | |||
| sprintf (arg_default, "%s", desc->params[i].value.str); | |||
| else | |||
| } else { | |||
| sprintf (arg_default, "none"); | |||
| } | |||
| break; | |||
| case JackDriverParamBool: | |||
| sprintf (arg_default, "%s", desc->params[i].value.i ? "true" : "false"); | |||
| @@ -66,7 +67,7 @@ jack_print_driver_param_usage (jack_driver_desc_t * desc, unsigned long param, F | |||
| { | |||
| fprintf (file, "Usage information for the '%s' parameter for driver '%s':\n", | |||
| desc->params[param].name, desc->name); | |||
| fprintf (file, "%s\n", desc->params[param].long_desc); | |||
| } | |||
| @@ -108,14 +109,14 @@ jack_parse_driver_params (jack_driver_desc_t * desc, int argc, char **argv, JSLi | |||
| /* set up the stuff for getopt */ | |||
| options = calloc (desc->nparams*3 + 1, sizeof (char)); | |||
| long_options = calloc (desc->nparams + 1, sizeof (struct option)); | |||
| options = calloc (desc->nparams * 3 + 1, sizeof(char)); | |||
| long_options = calloc (desc->nparams + 1, sizeof(struct option)); | |||
| options_ptr = options; | |||
| for (i = 0; i < desc->nparams; i++) { | |||
| sprintf (options_ptr, "%c::", desc->params[i].character); | |||
| options_ptr += 3; | |||
| long_options[i].name = desc->params[i].name; | |||
| long_options[i].flag = NULL; | |||
| long_options[i].val = desc->params[i].character; | |||
| @@ -125,7 +126,7 @@ jack_parse_driver_params (jack_driver_desc_t * desc, int argc, char **argv, JSLi | |||
| /* create the params */ | |||
| optind = 0; | |||
| opterr = 0; | |||
| while ((opt = getopt_long(argc, argv, options, long_options, NULL)) != -1) { | |||
| while ((opt = getopt_long (argc, argv, options, long_options, NULL)) != -1) { | |||
| if (opt == ':' || opt == '?') { | |||
| if (opt == ':') { | |||
| @@ -145,12 +146,12 @@ jack_parse_driver_params (jack_driver_desc_t * desc, int argc, char **argv, JSLi | |||
| } | |||
| } | |||
| driver_param = calloc (1, sizeof (jack_driver_param_t)); | |||
| driver_param = calloc (1, sizeof(jack_driver_param_t)); | |||
| driver_param->character = desc->params[param_index].character; | |||
| if (!optarg && optind < argc && | |||
| strlen(argv[optind]) && | |||
| strlen (argv[optind]) && | |||
| argv[optind][0] != '-') { | |||
| optarg = argv[optind]; | |||
| } | |||
| @@ -186,7 +187,7 @@ jack_parse_driver_params (jack_driver_desc_t * desc, int argc, char **argv, JSLi | |||
| } | |||
| break; | |||
| } | |||
| } else { | |||
| } else { | |||
| if (desc->params[param_index].type == JackDriverParamBool) { | |||
| driver_param->value.i = TRUE; | |||
| } else { | |||
| @@ -200,8 +201,9 @@ jack_parse_driver_params (jack_driver_desc_t * desc, int argc, char **argv, JSLi | |||
| free (options); | |||
| free (long_options); | |||
| if (param_ptr) | |||
| if (param_ptr) { | |||
| *param_ptr = params; | |||
| } | |||
| return 0; | |||
| } | |||
| @@ -1,7 +1,7 @@ | |||
| /* -*- mode: c; c-file-style: "bsd"; -*- */ | |||
| /* | |||
| Copyright (C) 2001-2003 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 | |||
| @@ -16,7 +16,7 @@ | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| */ | |||
| #ifndef __jack_engine_h__ | |||
| #define __jack_engine_h__ | |||
| @@ -30,30 +30,30 @@ struct _jack_client_internal; | |||
| struct _jack_port_internal; | |||
| /* Structures is allocated by the engine in local memory to keep track | |||
| * of port buffers and connections. | |||
| * of port buffers and connections. | |||
| */ | |||
| typedef struct { | |||
| jack_shm_info_t* shm_info; | |||
| jack_shmsize_t offset; | |||
| jack_shm_info_t* shm_info; | |||
| jack_shmsize_t offset; | |||
| } jack_port_buffer_info_t; | |||
| /* The engine keeps an array of these in its local memory. */ | |||
| typedef struct _jack_port_internal { | |||
| struct _jack_port_shared *shared; | |||
| JSList *connections; | |||
| jack_port_buffer_info_t *buffer_info; | |||
| struct _jack_port_shared *shared; | |||
| JSList *connections; | |||
| jack_port_buffer_info_t *buffer_info; | |||
| } jack_port_internal_t; | |||
| /* The engine's internal port type structure. */ | |||
| typedef struct _jack_port_buffer_list { | |||
| pthread_mutex_t lock; /* only lock within server */ | |||
| JSList *freelist; /* list of free buffers */ | |||
| jack_port_buffer_info_t *info; /* jack_buffer_info_t array */ | |||
| pthread_mutex_t lock; /* only lock within server */ | |||
| JSList *freelist; /* list of free buffers */ | |||
| jack_port_buffer_info_t *info; /* jack_buffer_info_t array */ | |||
| } jack_port_buffer_list_t; | |||
| typedef struct _jack_reserved_name { | |||
| jack_uuid_t uuid; | |||
| char name[JACK_CLIENT_NAME_SIZE]; | |||
| jack_uuid_t uuid; | |||
| char name[JACK_CLIENT_NAME_SIZE]; | |||
| } jack_reserved_name_t; | |||
| #define JACKD_WATCHDOG_TIMEOUT 10000 | |||
| @@ -61,167 +61,169 @@ typedef struct _jack_reserved_name { | |||
| /* The main engine structure in local memory. */ | |||
| struct _jack_engine { | |||
| jack_control_t *control; | |||
| JSList *drivers; | |||
| struct _jack_driver *driver; | |||
| jack_driver_desc_t *driver_desc; | |||
| JSList *driver_params; | |||
| JSList *slave_drivers; | |||
| /* these are "callbacks" made by the driver backend */ | |||
| int (*set_buffer_size) (struct _jack_engine *, jack_nframes_t frames); | |||
| int (*set_sample_rate) (struct _jack_engine *, jack_nframes_t frames); | |||
| int (*run_cycle) (struct _jack_engine *, jack_nframes_t nframes, | |||
| float delayed_usecs); | |||
| void (*delay) (struct _jack_engine *, float delayed_usecs); | |||
| void (*transport_cycle_start) (struct _jack_engine *, jack_time_t time); | |||
| void (*driver_exit) (struct _jack_engine *); | |||
| jack_time_t (*get_microseconds)(void); | |||
| /* "private" sections starts here */ | |||
| /* engine serialization -- use precedence for deadlock avoidance */ | |||
| pthread_mutex_t request_lock; /* precedes client_lock */ | |||
| pthread_rwlock_t client_lock; | |||
| pthread_mutex_t port_lock; | |||
| pthread_mutex_t problem_lock; /* must hold write lock on client_lock */ | |||
| int process_errors; | |||
| int period_msecs; | |||
| /* Time to wait for clients in msecs. Used when jackd is run | |||
| * without realtime priority enabled. */ | |||
| int client_timeout_msecs; | |||
| /* info on the shm segment containing this->control */ | |||
| jack_shm_info_t control_shm; | |||
| /* address-space local port buffer and segment info, | |||
| indexed by the port type_id | |||
| */ | |||
| jack_port_buffer_list_t port_buffers[JACK_MAX_PORT_TYPES]; | |||
| jack_shm_info_t port_segment[JACK_MAX_PORT_TYPES]; | |||
| unsigned int port_max; | |||
| pthread_t server_thread; | |||
| int fds[2]; | |||
| int cleanup_fifo[2]; | |||
| size_t pfd_size; | |||
| size_t pfd_max; | |||
| struct pollfd *pfd; | |||
| char fifo_prefix[PATH_MAX+1]; | |||
| int *fifo; | |||
| unsigned long fifo_size; | |||
| /* session handling */ | |||
| int session_reply_fd; | |||
| int session_pending_replies; | |||
| unsigned long external_client_cnt; | |||
| int rtpriority; | |||
| volatile char freewheeling; | |||
| volatile char stop_freewheeling; | |||
| jack_uuid_t fwclient; | |||
| pthread_t freewheel_thread; | |||
| char verbose; | |||
| char do_munlock; | |||
| const char *server_name; | |||
| char temporary; | |||
| int reordered; | |||
| int feedbackcount; | |||
| int removing_clients; | |||
| pid_t wait_pid; | |||
| int nozombies; | |||
| int timeout_count_threshold; | |||
| volatile int problems; | |||
| volatile int timeout_count; | |||
| volatile int new_clients_allowed; | |||
| /* these lists are protected by `client_lock' */ | |||
| JSList *clients; | |||
| JSList *clients_waiting; | |||
| JSList *reserved_client_names; | |||
| jack_port_internal_t *internal_ports; | |||
| jack_client_internal_t *timebase_client; | |||
| jack_port_buffer_info_t *silent_buffer; | |||
| jack_client_internal_t *current_client; | |||
| jack_control_t *control; | |||
| JSList *drivers; | |||
| struct _jack_driver *driver; | |||
| jack_driver_desc_t *driver_desc; | |||
| JSList *driver_params; | |||
| JSList *slave_drivers; | |||
| /* these are "callbacks" made by the driver backend */ | |||
| int (*set_buffer_size)(struct _jack_engine *, jack_nframes_t frames); | |||
| int (*set_sample_rate)(struct _jack_engine *, jack_nframes_t frames); | |||
| int (*run_cycle)(struct _jack_engine *, jack_nframes_t nframes, | |||
| float delayed_usecs); | |||
| void (*delay)(struct _jack_engine *, float delayed_usecs); | |||
| void (*transport_cycle_start)(struct _jack_engine *, jack_time_t time); | |||
| void (*driver_exit)(struct _jack_engine *); | |||
| jack_time_t (*get_microseconds)(void); | |||
| /* "private" sections starts here */ | |||
| /* engine serialization -- use precedence for deadlock avoidance */ | |||
| pthread_mutex_t request_lock; /* precedes client_lock */ | |||
| pthread_rwlock_t client_lock; | |||
| pthread_mutex_t port_lock; | |||
| pthread_mutex_t problem_lock; /* must hold write lock on client_lock */ | |||
| int process_errors; | |||
| int period_msecs; | |||
| /* Time to wait for clients in msecs. Used when jackd is run | |||
| * without realtime priority enabled. */ | |||
| int client_timeout_msecs; | |||
| /* info on the shm segment containing this->control */ | |||
| jack_shm_info_t control_shm; | |||
| /* address-space local port buffer and segment info, | |||
| indexed by the port type_id | |||
| */ | |||
| jack_port_buffer_list_t port_buffers[JACK_MAX_PORT_TYPES]; | |||
| jack_shm_info_t port_segment[JACK_MAX_PORT_TYPES]; | |||
| unsigned int port_max; | |||
| pthread_t server_thread; | |||
| int fds[2]; | |||
| int cleanup_fifo[2]; | |||
| size_t pfd_size; | |||
| size_t pfd_max; | |||
| struct pollfd *pfd; | |||
| char fifo_prefix[PATH_MAX + 1]; | |||
| int *fifo; | |||
| unsigned long fifo_size; | |||
| /* session handling */ | |||
| int session_reply_fd; | |||
| int session_pending_replies; | |||
| unsigned long external_client_cnt; | |||
| int rtpriority; | |||
| volatile char freewheeling; | |||
| volatile char stop_freewheeling; | |||
| jack_uuid_t fwclient; | |||
| pthread_t freewheel_thread; | |||
| char verbose; | |||
| char do_munlock; | |||
| const char *server_name; | |||
| char temporary; | |||
| int reordered; | |||
| int feedbackcount; | |||
| int removing_clients; | |||
| pid_t wait_pid; | |||
| int nozombies; | |||
| int timeout_count_threshold; | |||
| volatile int problems; | |||
| volatile int timeout_count; | |||
| volatile int new_clients_allowed; | |||
| /* these lists are protected by `client_lock' */ | |||
| JSList *clients; | |||
| JSList *clients_waiting; | |||
| JSList *reserved_client_names; | |||
| jack_port_internal_t *internal_ports; | |||
| jack_client_internal_t *timebase_client; | |||
| jack_port_buffer_info_t *silent_buffer; | |||
| jack_client_internal_t *current_client; | |||
| #define JACK_ENGINE_ROLLING_COUNT 32 | |||
| #define JACK_ENGINE_ROLLING_INTERVAL 1024 | |||
| jack_time_t rolling_client_usecs[JACK_ENGINE_ROLLING_COUNT]; | |||
| int rolling_client_usecs_cnt; | |||
| int rolling_client_usecs_index; | |||
| int rolling_interval; | |||
| float max_usecs; | |||
| float spare_usecs; | |||
| jack_time_t rolling_client_usecs[JACK_ENGINE_ROLLING_COUNT]; | |||
| int rolling_client_usecs_cnt; | |||
| int rolling_client_usecs_index; | |||
| int rolling_interval; | |||
| float max_usecs; | |||
| float spare_usecs; | |||
| int first_wakeup; | |||
| int first_wakeup; | |||
| #ifdef JACK_USE_MACH_THREADS | |||
| /* specific resources for server/client real-time thread communication */ | |||
| mach_port_t servertask, bp; | |||
| int portnum; | |||
| /* specific resources for server/client real-time thread communication */ | |||
| mach_port_t servertask, bp; | |||
| int portnum; | |||
| #endif | |||
| /* used for port names munging */ | |||
| int audio_out_cnt; | |||
| int audio_in_cnt; | |||
| int midi_out_cnt; | |||
| int midi_in_cnt; | |||
| /* used for port names munging */ | |||
| int audio_out_cnt; | |||
| int audio_in_cnt; | |||
| int midi_out_cnt; | |||
| int midi_in_cnt; | |||
| }; | |||
| /* public functions */ | |||
| jack_engine_t *jack_engine_new (int real_time, int real_time_priority, | |||
| int do_mlock, int do_unlock, | |||
| const char *server_name, int temporary, | |||
| int verbose, int client_timeout, | |||
| unsigned int port_max, | |||
| pid_t waitpid, jack_nframes_t frame_time_offset, int nozombies, | |||
| int timeout_count_threshold, | |||
| JSList *drivers); | |||
| void jack_engine_delete (jack_engine_t *); | |||
| int jack_run (jack_engine_t *engine); | |||
| int jack_wait (jack_engine_t *engine); | |||
| int jack_engine_load_driver (jack_engine_t *engine, | |||
| jack_driver_desc_t * driver_desc, | |||
| JSList * driver_params); | |||
| int jack_engine_load_slave_driver (jack_engine_t *engine, | |||
| jack_driver_desc_t * driver_desc, | |||
| JSList * driver_params); | |||
| void jack_dump_configuration(jack_engine_t *engine, int take_lock); | |||
| jack_engine_t *jack_engine_new(int real_time, int real_time_priority, | |||
| int do_mlock, int do_unlock, | |||
| const char *server_name, int temporary, | |||
| int verbose, int client_timeout, | |||
| unsigned int port_max, | |||
| pid_t waitpid, jack_nframes_t frame_time_offset, int nozombies, | |||
| int timeout_count_threshold, | |||
| JSList *drivers); | |||
| void jack_engine_delete(jack_engine_t *); | |||
| int jack_run(jack_engine_t *engine); | |||
| int jack_wait(jack_engine_t *engine); | |||
| int jack_engine_load_driver(jack_engine_t *engine, | |||
| jack_driver_desc_t * driver_desc, | |||
| JSList * driver_params); | |||
| int jack_engine_load_slave_driver(jack_engine_t *engine, | |||
| jack_driver_desc_t * driver_desc, | |||
| JSList * driver_params); | |||
| void jack_dump_configuration(jack_engine_t *engine, int take_lock); | |||
| /* private engine functions */ | |||
| void jack_engine_reset_rolling_usecs (jack_engine_t *engine); | |||
| int internal_client_request (void* ptr, jack_request_t *request); | |||
| int jack_get_fifo_fd (jack_engine_t *engine, | |||
| unsigned int which_fifo); | |||
| void jack_engine_reset_rolling_usecs(jack_engine_t *engine); | |||
| int internal_client_request(void* ptr, jack_request_t *request); | |||
| int jack_get_fifo_fd(jack_engine_t *engine, | |||
| unsigned int which_fifo); | |||
| extern jack_timer_type_t clock_source; | |||
| extern jack_client_internal_t * | |||
| jack_client_internal_by_id (jack_engine_t *engine, jack_uuid_t id); | |||
| jack_client_internal_by_id(jack_engine_t *engine, jack_uuid_t id); | |||
| #define jack_rdlock_graph(e) { DEBUG ("acquiring graph read lock"); if (pthread_rwlock_rdlock (&e->client_lock)) abort(); } | |||
| #define jack_lock_graph(e) { DEBUG ("acquiring graph write lock"); if (pthread_rwlock_wrlock (&e->client_lock)) abort(); } | |||
| #define jack_rdlock_graph(e) { DEBUG ("acquiring graph read lock"); if (pthread_rwlock_rdlock (&e->client_lock)) { abort (); } } | |||
| #define jack_lock_graph(e) { DEBUG ("acquiring graph write lock"); if (pthread_rwlock_wrlock (&e->client_lock)) { abort (); } } | |||
| #define jack_try_rdlock_graph(e) pthread_rwlock_tryrdlock (&e->client_lock) | |||
| #define jack_unlock_graph(e) { DEBUG ("release graph lock"); if (pthread_rwlock_unlock (&e->client_lock)) abort(); } | |||
| #define jack_unlock_graph(e) { DEBUG ("release graph lock"); if (pthread_rwlock_unlock (&e->client_lock)) { abort (); } } | |||
| #define jack_trylock_problems(e) pthread_mutex_trylock (&e->problem_lock) | |||
| #define jack_lock_problems(e) { DEBUG ("acquiring problem lock"); if (pthread_mutex_lock (&e->problem_lock)) abort(); } | |||
| #define jack_unlock_problems(e) { DEBUG ("release problem lock"); if (pthread_mutex_unlock (&e->problem_lock)) abort(); } | |||
| #define jack_lock_problems(e) { DEBUG ("acquiring problem lock"); if (pthread_mutex_lock (&e->problem_lock)) { abort (); } } | |||
| #define jack_unlock_problems(e) { DEBUG ("release problem lock"); if (pthread_mutex_unlock (&e->problem_lock)) { abort (); } } | |||
| #if 0 | |||
| static inline void jack_rdlock_graph (jack_engine_t* engine) { | |||
| static inline void jack_rdlock_graph (jack_engine_t* engine) | |||
| { | |||
| DEBUG ("acquiring graph read lock"); | |||
| pthread_rwlock_rdlock (&engine->client_lock); | |||
| } | |||
| static inline void jack_lock_graph (jack_engine_t* engine) { | |||
| static inline void jack_lock_graph (jack_engine_t* engine) | |||
| { | |||
| DEBUG ("acquiring graph lock"); | |||
| pthread_rwlock_wrlock (&engine->client_lock); | |||
| } | |||
| @@ -232,7 +234,7 @@ static inline int jack_try_rdlock_graph (jack_engine_t *engine) | |||
| return pthread_rwlock_tryrdlock (&engine->client_lock); | |||
| } | |||
| static inline void jack_unlock_graph (jack_engine_t* engine) | |||
| static inline void jack_unlock_graph (jack_engine_t* engine) | |||
| { | |||
| DEBUG ("releasing graph lock"); | |||
| pthread_rwlock_unlock (&engine->client_lock); | |||
| @@ -245,24 +247,24 @@ static inline unsigned int jack_power_of_two (unsigned int n) | |||
| } | |||
| /* Internal port handling interfaces for JACK engine. */ | |||
| void jack_port_clear_connections (jack_engine_t *engine, | |||
| jack_port_internal_t *port); | |||
| void jack_port_registration_notify (jack_engine_t *, jack_port_id_t, int); | |||
| void jack_port_release (jack_engine_t *engine, jack_port_internal_t *); | |||
| void jack_sort_graph (jack_engine_t *engine); | |||
| int jack_stop_freewheeling (jack_engine_t* engine, int engine_exiting); | |||
| void jack_port_clear_connections(jack_engine_t *engine, | |||
| jack_port_internal_t *port); | |||
| void jack_port_registration_notify (jack_engine_t *, jack_port_id_t, int); | |||
| void jack_port_release(jack_engine_t *engine, jack_port_internal_t *); | |||
| void jack_sort_graph(jack_engine_t *engine); | |||
| int jack_stop_freewheeling(jack_engine_t* engine, int engine_exiting); | |||
| jack_client_internal_t * | |||
| jack_client_by_name (jack_engine_t *engine, const char *name); | |||
| jack_client_by_name(jack_engine_t *engine, const char *name); | |||
| int jack_deliver_event (jack_engine_t *, jack_client_internal_t *, const jack_event_t *, ...); | |||
| int jack_deliver_event(jack_engine_t *, jack_client_internal_t *, const jack_event_t *, ...); | |||
| void | |||
| jack_engine_signal_problems (jack_engine_t* engine); | |||
| jack_engine_signal_problems(jack_engine_t* engine); | |||
| int | |||
| jack_use_driver (jack_engine_t *engine, struct _jack_driver *driver); | |||
| jack_use_driver(jack_engine_t *engine, struct _jack_driver *driver); | |||
| int | |||
| jack_drivers_start (jack_engine_t *engine); | |||
| jack_drivers_start(jack_engine_t *engine); | |||
| int | |||
| jack_add_slave_driver (jack_engine_t *engine, struct _jack_driver *driver); | |||
| jack_add_slave_driver(jack_engine_t *engine, struct _jack_driver *driver); | |||
| #endif /* __jack_engine_h__ */ | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| 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 | |||
| @@ -15,14 +15,14 @@ | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| */ | |||
| #ifndef __jack_hardware_h__ | |||
| #define __jack_hardware_h__ | |||
| #include <jack/types.h> | |||
| typedef enum { | |||
| typedef enum { | |||
| AutoSync, | |||
| WordClock, | |||
| ClockMaster | |||
| @@ -48,18 +48,18 @@ typedef double (*JackHardwareGetHardwarePower)(jack_port_t *port, jack_nframes_t | |||
| typedef struct _jack_hardware { | |||
| unsigned long capabilities; | |||
| unsigned long input_monitor_mask; | |||
| unsigned long capabilities; | |||
| unsigned long input_monitor_mask; | |||
| JackHardwareChangeSampleClockFunction change_sample_clock; | |||
| JackHardwareSetInputMonitorMaskFunction set_input_monitor_mask; | |||
| JackHardwareReleaseFunction release; | |||
| JackHardwareGetHardwarePeak get_hardware_peak; | |||
| JackHardwareGetHardwarePower get_hardware_power; | |||
| void *private; | |||
| JackHardwareChangeSampleClockFunction change_sample_clock; | |||
| JackHardwareSetInputMonitorMaskFunction set_input_monitor_mask; | |||
| JackHardwareReleaseFunction release; | |||
| JackHardwareGetHardwarePeak get_hardware_peak; | |||
| JackHardwareGetHardwarePower get_hardware_power; | |||
| void *private; | |||
| } jack_hardware_t; | |||
| jack_hardware_t * jack_hardware_new (); | |||
| jack_hardware_t * jack_hardware_new(); | |||
| #endif /* __jack_hardware_h__ */ | |||
| @@ -6,7 +6,7 @@ | |||
| JACK_PROTOCOL_VERSION in configure.in. | |||
| Copyright (C) 2001-2003 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 | |||
| @@ -21,7 +21,7 @@ | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| */ | |||
| #ifndef __jack_internal_h__ | |||
| #define __jack_internal_h__ | |||
| @@ -35,9 +35,9 @@ | |||
| #include <sys/time.h> | |||
| /* Needed by <sysdeps/time.h> */ | |||
| extern void jack_error (const char *fmt, ...); | |||
| extern void jack_error(const char *fmt, ...); | |||
| extern void jack_info (const char *fmt, ...); | |||
| extern void jack_info(const char *fmt, ...); | |||
| #include <jack/jack.h> | |||
| #include <jack/types.h> | |||
| @@ -55,8 +55,8 @@ typedef enum { | |||
| JACK_TIMER_HPET, | |||
| } jack_timer_type_t; | |||
| void jack_init_time (); | |||
| void jack_set_clock_source (jack_timer_type_t); | |||
| void jack_init_time(); | |||
| void jack_set_clock_source (jack_timer_type_t); | |||
| const char* jack_clock_source_name (jack_timer_type_t); | |||
| #include <sysdeps/time.h> | |||
| @@ -73,31 +73,31 @@ const char* jack_clock_source_name (jack_timer_type_t); | |||
| #define PATH_MAX MAXPATHLEN | |||
| #else | |||
| #define PATH_MAX 1024 | |||
| #endif /* MAXPATHLEN */ | |||
| #endif /* !PATH_MAX */ | |||
| #endif /* MAXPATHLEN */ | |||
| #endif /* !PATH_MAX */ | |||
| #ifdef DEBUG_ENABLED | |||
| /* grab thread id instead of PID on linux */ | |||
| #if defined(__gnu_linux__) | |||
| #ifdef gettid /* glibc has a version */ | |||
| #define GETTID() gettid() | |||
| #define GETTID() gettid () | |||
| #else /* use our own version */ | |||
| #include <sys/syscall.h> | |||
| #define GETTID() syscall(__NR_gettid) | |||
| #include <sys/syscall.h> | |||
| #define GETTID() syscall (__NR_gettid) | |||
| #endif | |||
| #else | |||
| #define GETTID() getpid() | |||
| #define GETTID() getpid () | |||
| #endif | |||
| #define DEBUG(format,args...) \ | |||
| MESSAGE("jack:%5d:%" PRIu64 " %s:%s:%d: " format "", GETTID(), jack_get_microseconds(), __FILE__, __FUNCTION__, __LINE__ , ## args) | |||
| #define DEBUG(format, args ...) \ | |||
| MESSAGE ("jack:%5d:%" PRIu64 " %s:%s:%d: " format "", GETTID (), jack_get_microseconds (), __FILE__, __FUNCTION__, __LINE__, ## args) | |||
| #else | |||
| #if JACK_CPP_VARARGS_BROKEN | |||
| #define DEBUG(format...) | |||
| #define DEBUG(format ...) | |||
| #else | |||
| #define DEBUG(format,args...) | |||
| #define DEBUG(format, args ...) | |||
| #endif | |||
| #endif | |||
| @@ -109,129 +109,129 @@ const char* jack_clock_source_name (jack_timer_type_t); | |||
| * sends SIGUSR2 to the client. | |||
| */ | |||
| #ifdef DO_PREEMPTION_CHECKING | |||
| #define CHECK_PREEMPTION(engine, onoff) \ | |||
| #define CHECK_PREEMPTION(engine, onoff) \ | |||
| if ((engine)->real_time) gettimeofday (1, (onoff)) | |||
| #else | |||
| #define CHECK_PREEMPTION(engine, onoff) | |||
| #endif | |||
| #ifndef FALSE | |||
| #define FALSE (0) | |||
| #ifndef FALSE | |||
| #define FALSE (0) | |||
| #endif | |||
| #ifndef TRUE | |||
| #define TRUE (1) | |||
| #ifndef TRUE | |||
| #define TRUE (1) | |||
| #endif | |||
| typedef struct _jack_engine jack_engine_t; | |||
| typedef struct _jack_engine jack_engine_t; | |||
| typedef struct _jack_request jack_request_t; | |||
| typedef void * dlhandle; | |||
| typedef enum { | |||
| TransportCommandNone = 0, | |||
| TransportCommandStart = 1, | |||
| TransportCommandStop = 2, | |||
| TransportCommandNone = 0, | |||
| TransportCommandStart = 1, | |||
| TransportCommandStop = 2, | |||
| } transport_command_t; | |||
| typedef struct { | |||
| volatile uint32_t guard1; | |||
| volatile jack_nframes_t frames; | |||
| volatile jack_time_t current_wakeup; | |||
| volatile jack_time_t next_wakeup; | |||
| volatile float period_usecs; | |||
| volatile int32_t initialized; | |||
| volatile uint32_t guard2; | |||
| volatile uint32_t guard1; | |||
| volatile jack_nframes_t frames; | |||
| volatile jack_time_t current_wakeup; | |||
| volatile jack_time_t next_wakeup; | |||
| volatile float period_usecs; | |||
| volatile int32_t initialized; | |||
| volatile uint32_t guard2; | |||
| /* not accessed by clients */ | |||
| int32_t reset_pending; /* xrun happened, deal with it */ | |||
| float filter_omega; /* set once, never altered */ | |||
| int32_t reset_pending; /* xrun happened, deal with it */ | |||
| float filter_omega; /* set once, never altered */ | |||
| } POST_PACKED_STRUCTURE jack_frame_timer_t; | |||
| /* JACK engine shared memory data structure. */ | |||
| typedef struct { | |||
| jack_transport_state_t transport_state; | |||
| volatile transport_command_t transport_cmd; | |||
| transport_command_t previous_cmd; /* previous transport_cmd */ | |||
| jack_position_t current_time; /* position for current cycle */ | |||
| jack_position_t pending_time; /* position for next cycle */ | |||
| jack_position_t request_time; /* latest requested position */ | |||
| jack_unique_t prev_request; /* previous request unique ID */ | |||
| volatile _Atomic_word seq_number; /* unique ID sequence number */ | |||
| int8_t new_pos; /* new position this cycle */ | |||
| int8_t pending_pos; /* new position request pending */ | |||
| jack_nframes_t pending_frame; /* pending frame number */ | |||
| int32_t sync_clients; /* number of active_slowsync clients */ | |||
| int32_t sync_remain; /* number of them with sync_poll */ | |||
| jack_time_t sync_timeout; | |||
| jack_time_t sync_time_left; | |||
| jack_frame_timer_t frame_timer; | |||
| int32_t internal; | |||
| jack_timer_type_t clock_source; | |||
| pid_t engine_pid; | |||
| jack_nframes_t buffer_size; | |||
| int8_t real_time; | |||
| int8_t do_mlock; | |||
| int8_t do_munlock; | |||
| int32_t client_priority; | |||
| int32_t max_client_priority; | |||
| int32_t has_capabilities; | |||
| float cpu_load; | |||
| float xrun_delayed_usecs; | |||
| float max_delayed_usecs; | |||
| uint32_t port_max; | |||
| int32_t engine_ok; | |||
| jack_port_type_id_t n_port_types; | |||
| jack_port_type_info_t port_types[JACK_MAX_PORT_TYPES]; | |||
| jack_port_shared_t ports[0]; | |||
| jack_transport_state_t transport_state; | |||
| volatile transport_command_t transport_cmd; | |||
| transport_command_t previous_cmd; /* previous transport_cmd */ | |||
| jack_position_t current_time; /* position for current cycle */ | |||
| jack_position_t pending_time; /* position for next cycle */ | |||
| jack_position_t request_time; /* latest requested position */ | |||
| jack_unique_t prev_request; /* previous request unique ID */ | |||
| volatile _Atomic_word seq_number; /* unique ID sequence number */ | |||
| int8_t new_pos; /* new position this cycle */ | |||
| int8_t pending_pos; /* new position request pending */ | |||
| jack_nframes_t pending_frame; /* pending frame number */ | |||
| int32_t sync_clients; /* number of active_slowsync clients */ | |||
| int32_t sync_remain; /* number of them with sync_poll */ | |||
| jack_time_t sync_timeout; | |||
| jack_time_t sync_time_left; | |||
| jack_frame_timer_t frame_timer; | |||
| int32_t internal; | |||
| jack_timer_type_t clock_source; | |||
| pid_t engine_pid; | |||
| jack_nframes_t buffer_size; | |||
| int8_t real_time; | |||
| int8_t do_mlock; | |||
| int8_t do_munlock; | |||
| int32_t client_priority; | |||
| int32_t max_client_priority; | |||
| int32_t has_capabilities; | |||
| float cpu_load; | |||
| float xrun_delayed_usecs; | |||
| float max_delayed_usecs; | |||
| uint32_t port_max; | |||
| int32_t engine_ok; | |||
| jack_port_type_id_t n_port_types; | |||
| jack_port_type_info_t port_types[JACK_MAX_PORT_TYPES]; | |||
| jack_port_shared_t ports[0]; | |||
| } POST_PACKED_STRUCTURE jack_control_t; | |||
| typedef enum { | |||
| BufferSizeChange, | |||
| SampleRateChange, | |||
| AttachPortSegment, | |||
| PortConnected, | |||
| PortDisconnected, | |||
| GraphReordered, | |||
| PortRegistered, | |||
| PortUnregistered, | |||
| XRun, | |||
| StartFreewheel, | |||
| StopFreewheel, | |||
| ClientRegistered, | |||
| ClientUnregistered, | |||
| SaveSession, | |||
| LatencyCallback, | |||
| PropertyChange, | |||
| PortRename | |||
| BufferSizeChange, | |||
| SampleRateChange, | |||
| AttachPortSegment, | |||
| PortConnected, | |||
| PortDisconnected, | |||
| GraphReordered, | |||
| PortRegistered, | |||
| PortUnregistered, | |||
| XRun, | |||
| StartFreewheel, | |||
| StopFreewheel, | |||
| ClientRegistered, | |||
| ClientUnregistered, | |||
| SaveSession, | |||
| LatencyCallback, | |||
| PropertyChange, | |||
| PortRename | |||
| } JackEventType; | |||
| const char* jack_event_type_name (JackEventType); | |||
| typedef struct { | |||
| JackEventType type; | |||
| union { | |||
| uint32_t n; | |||
| char name[JACK_PORT_NAME_SIZE]; | |||
| jack_port_id_t port_id; | |||
| jack_port_id_t self_id; | |||
| jack_uuid_t uuid; | |||
| } x; | |||
| union { | |||
| uint32_t n; | |||
| jack_port_type_id_t ptid; | |||
| jack_port_id_t other_id; | |||
| uint32_t key_size; /* key data will follow the event structure */ | |||
| } y; | |||
| union { | |||
| char other_name[JACK_PORT_NAME_SIZE]; | |||
| jack_property_change_t property_change; | |||
| } z; | |||
| JackEventType type; | |||
| union { | |||
| uint32_t n; | |||
| char name[JACK_PORT_NAME_SIZE]; | |||
| jack_port_id_t port_id; | |||
| jack_port_id_t self_id; | |||
| jack_uuid_t uuid; | |||
| } x; | |||
| union { | |||
| uint32_t n; | |||
| jack_port_type_id_t ptid; | |||
| jack_port_id_t other_id; | |||
| uint32_t key_size; /* key data will follow the event structure */ | |||
| } y; | |||
| union { | |||
| char other_name[JACK_PORT_NAME_SIZE]; | |||
| jack_property_change_t property_change; | |||
| } z; | |||
| } POST_PACKED_STRUCTURE jack_event_t; | |||
| typedef enum { | |||
| @@ -250,112 +250,112 @@ typedef enum { | |||
| /* JACK client shared memory data structure. */ | |||
| typedef volatile struct { | |||
| jack_uuid_t uuid; /* w: engine r: engine and client */ | |||
| volatile jack_client_state_t state; /* w: engine and client r: engine */ | |||
| volatile char name[JACK_CLIENT_NAME_SIZE]; | |||
| volatile char session_command[JACK_PORT_NAME_SIZE]; | |||
| volatile jack_session_flags_t session_flags; | |||
| volatile ClientType type; /* w: engine r: engine and client */ | |||
| volatile int8_t active; /* w: engine r: engine and client */ | |||
| volatile int8_t dead; /* r/w: engine */ | |||
| volatile int8_t timed_out; /* r/w: engine */ | |||
| volatile int8_t is_timebase; /* w: engine, r: engine and client */ | |||
| volatile int8_t timebase_new; /* w: engine and client, r: engine */ | |||
| volatile int8_t is_slowsync; /* w: engine, r: engine and client */ | |||
| volatile int8_t active_slowsync; /* w: engine, r: engine and client */ | |||
| volatile int8_t sync_poll; /* w: engine and client, r: engine */ | |||
| volatile int8_t sync_new; /* w: engine and client, r: engine */ | |||
| volatile pid_t pid; /* w: client r: engine; client pid */ | |||
| volatile pid_t pgrp; /* w: client r: engine; client pgrp */ | |||
| volatile uint64_t signalled_at; | |||
| volatile uint64_t awake_at; | |||
| volatile uint64_t finished_at; | |||
| volatile int32_t last_status; /* w: client, r: engine and client */ | |||
| /* indicators for whether callbacks have been set for this client. | |||
| We do not include ptrs to the callbacks here (or their arguments) | |||
| so that we can avoid 32/64 bit pointer size mismatches between | |||
| the jack server and a client. The pointers are in the client- | |||
| local structure which is part of the libjack compiled for | |||
| either 32 bit or 64 bit clients. | |||
| */ | |||
| volatile uint8_t process_cbset; | |||
| volatile uint8_t thread_init_cbset; | |||
| volatile uint8_t bufsize_cbset; | |||
| volatile uint8_t srate_cbset; | |||
| volatile uint8_t port_register_cbset; | |||
| volatile uint8_t port_connect_cbset; | |||
| volatile uint8_t graph_order_cbset; | |||
| volatile uint8_t xrun_cbset; | |||
| volatile uint8_t sync_cb_cbset; | |||
| volatile uint8_t timebase_cb_cbset; | |||
| volatile uint8_t freewheel_cb_cbset; | |||
| volatile uint8_t client_register_cbset; | |||
| volatile uint8_t thread_cb_cbset; | |||
| volatile uint8_t session_cbset; | |||
| volatile uint8_t latency_cbset; | |||
| volatile uint8_t property_cbset; | |||
| volatile uint8_t port_rename_cbset; | |||
| jack_uuid_t uuid; /* w: engine r: engine and client */ | |||
| volatile jack_client_state_t state; /* w: engine and client r: engine */ | |||
| volatile char name[JACK_CLIENT_NAME_SIZE]; | |||
| volatile char session_command[JACK_PORT_NAME_SIZE]; | |||
| volatile jack_session_flags_t session_flags; | |||
| volatile ClientType type; /* w: engine r: engine and client */ | |||
| volatile int8_t active; /* w: engine r: engine and client */ | |||
| volatile int8_t dead; /* r/w: engine */ | |||
| volatile int8_t timed_out; /* r/w: engine */ | |||
| volatile int8_t is_timebase; /* w: engine, r: engine and client */ | |||
| volatile int8_t timebase_new; /* w: engine and client, r: engine */ | |||
| volatile int8_t is_slowsync; /* w: engine, r: engine and client */ | |||
| volatile int8_t active_slowsync; /* w: engine, r: engine and client */ | |||
| volatile int8_t sync_poll; /* w: engine and client, r: engine */ | |||
| volatile int8_t sync_new; /* w: engine and client, r: engine */ | |||
| volatile pid_t pid; /* w: client r: engine; client pid */ | |||
| volatile pid_t pgrp; /* w: client r: engine; client pgrp */ | |||
| volatile uint64_t signalled_at; | |||
| volatile uint64_t awake_at; | |||
| volatile uint64_t finished_at; | |||
| volatile int32_t last_status; /* w: client, r: engine and client */ | |||
| /* indicators for whether callbacks have been set for this client. | |||
| We do not include ptrs to the callbacks here (or their arguments) | |||
| so that we can avoid 32/64 bit pointer size mismatches between | |||
| the jack server and a client. The pointers are in the client- | |||
| local structure which is part of the libjack compiled for | |||
| either 32 bit or 64 bit clients. | |||
| */ | |||
| volatile uint8_t process_cbset; | |||
| volatile uint8_t thread_init_cbset; | |||
| volatile uint8_t bufsize_cbset; | |||
| volatile uint8_t srate_cbset; | |||
| volatile uint8_t port_register_cbset; | |||
| volatile uint8_t port_connect_cbset; | |||
| volatile uint8_t graph_order_cbset; | |||
| volatile uint8_t xrun_cbset; | |||
| volatile uint8_t sync_cb_cbset; | |||
| volatile uint8_t timebase_cb_cbset; | |||
| volatile uint8_t freewheel_cb_cbset; | |||
| volatile uint8_t client_register_cbset; | |||
| volatile uint8_t thread_cb_cbset; | |||
| volatile uint8_t session_cbset; | |||
| volatile uint8_t latency_cbset; | |||
| volatile uint8_t property_cbset; | |||
| volatile uint8_t port_rename_cbset; | |||
| } POST_PACKED_STRUCTURE jack_client_control_t; | |||
| typedef struct { | |||
| uint32_t protocol_v; /* protocol version, must go first */ | |||
| int32_t load; | |||
| ClientType type; | |||
| jack_options_t options; | |||
| jack_uuid_t uuid; | |||
| char name[JACK_CLIENT_NAME_SIZE]; | |||
| char object_path[PATH_MAX+1]; | |||
| char object_data[1024]; | |||
| uint32_t protocol_v; /* protocol version, must go first */ | |||
| int32_t load; | |||
| ClientType type; | |||
| jack_options_t options; | |||
| jack_uuid_t uuid; | |||
| char name[JACK_CLIENT_NAME_SIZE]; | |||
| char object_path[PATH_MAX + 1]; | |||
| char object_data[1024]; | |||
| } POST_PACKED_STRUCTURE jack_client_connect_request_t; | |||
| typedef struct { | |||
| jack_status_t status; | |||
| jack_status_t status; | |||
| jack_shm_registry_index_t client_shm_index; | |||
| jack_shm_registry_index_t engine_shm_index; | |||
| jack_shm_registry_index_t client_shm_index; | |||
| jack_shm_registry_index_t engine_shm_index; | |||
| char fifo_prefix[PATH_MAX+1]; | |||
| char fifo_prefix[PATH_MAX + 1]; | |||
| int32_t realtime; | |||
| int32_t realtime_priority; | |||
| int32_t realtime; | |||
| int32_t realtime_priority; | |||
| char name[JACK_CLIENT_NAME_SIZE]; /* unique name, if assigned */ | |||
| char name[JACK_CLIENT_NAME_SIZE]; /* unique name, if assigned */ | |||
| /* these are actually pointers, but they must | |||
| be the same size regardless of whether the | |||
| server and/or client are 64 bit or 32 bit. | |||
| force them to be 64 bit. | |||
| */ | |||
| /* these are actually pointers, but they must | |||
| be the same size regardless of whether the | |||
| server and/or client are 64 bit or 32 bit. | |||
| force them to be 64 bit. | |||
| */ | |||
| uint64_t client_control; | |||
| uint64_t engine_control; | |||
| uint64_t client_control; | |||
| uint64_t engine_control; | |||
| #ifdef JACK_USE_MACH_THREADS | |||
| /* specific resources for server/client real-time thread communication */ | |||
| int32_t portnum; | |||
| /* specific resources for server/client real-time thread communication */ | |||
| int32_t portnum; | |||
| #endif | |||
| } POST_PACKED_STRUCTURE jack_client_connect_result_t; | |||
| typedef struct { | |||
| jack_uuid_t client_id; | |||
| jack_uuid_t client_id; | |||
| } POST_PACKED_STRUCTURE jack_client_connect_ack_request_t; | |||
| typedef struct { | |||
| int8_t status; | |||
| int8_t status; | |||
| } POST_PACKED_STRUCTURE jack_client_connect_ack_result_t; | |||
| typedef enum { | |||
| RegisterPort = 1, | |||
| UnRegisterPort = 2, | |||
| ConnectPorts = 3, | |||
| DisconnectPorts = 4, | |||
| DisconnectPorts = 4, | |||
| SetTimeBaseClient = 5, | |||
| ActivateClient = 6, | |||
| DeactivateClient = 7, | |||
| @@ -387,69 +387,69 @@ typedef enum { | |||
| } RequestType; | |||
| struct _jack_request { | |||
| //RequestType type; | |||
| uint32_t type; | |||
| union { | |||
| struct { | |||
| char name[JACK_PORT_NAME_SIZE]; | |||
| char type[JACK_PORT_TYPE_SIZE]; | |||
| uint32_t flags; | |||
| jack_shmsize_t buffer_size; | |||
| jack_port_id_t port_id; | |||
| jack_uuid_t client_id; | |||
| } POST_PACKED_STRUCTURE port_info; | |||
| struct { | |||
| char source_port[JACK_PORT_NAME_SIZE]; | |||
| char destination_port[JACK_PORT_NAME_SIZE]; | |||
| } POST_PACKED_STRUCTURE connect; | |||
| struct { | |||
| char path[JACK_PORT_NAME_SIZE]; | |||
| jack_session_event_type_t type; | |||
| char target[JACK_CLIENT_NAME_SIZE]; | |||
| } POST_PACKED_STRUCTURE session; | |||
| struct { | |||
| int32_t nports; | |||
| const char **ports; /* this is only exposed to internal clients, so there | |||
| is no 64/32 issue. external clients read the ports | |||
| one by one from the server, and allocate their | |||
| own "ports" array in their own address space. | |||
| we are lucky, because this is part of a union | |||
| whose other components are bigger than this one. | |||
| otherwise it would change structure size when | |||
| comparing the 64 and 32 bit versions. | |||
| */ | |||
| } POST_PACKED_STRUCTURE port_connections; | |||
| struct { | |||
| jack_uuid_t client_id; | |||
| int32_t conditional; | |||
| } POST_PACKED_STRUCTURE timebase; | |||
| struct { | |||
| char name[JACK_CLIENT_NAME_SIZE]; | |||
| jack_uuid_t uuid; | |||
| } POST_PACKED_STRUCTURE reservename; | |||
| struct { | |||
| //jack_options_t options; | |||
| uint32_t options; | |||
| jack_uuid_t uuid; | |||
| char name[JACK_CLIENT_NAME_SIZE]; | |||
| char path[PATH_MAX+1]; | |||
| char init[JACK_LOAD_INIT_LIMIT]; | |||
| } POST_PACKED_STRUCTURE intclient; | |||
| struct { | |||
| jack_property_change_t change; | |||
| jack_uuid_t uuid; | |||
| size_t keylen; | |||
| const char* key; /* not delivered inline to server, see oop_client_deliver_request() */ | |||
| } POST_PACKED_STRUCTURE property; | |||
| jack_uuid_t client_id; | |||
| jack_nframes_t nframes; | |||
| jack_time_t timeout; | |||
| pid_t cap_pid; | |||
| char name[JACK_CLIENT_NAME_SIZE]; | |||
| } POST_PACKED_STRUCTURE x; | |||
| int32_t status; | |||
| //RequestType type; | |||
| uint32_t type; | |||
| union { | |||
| struct { | |||
| char name[JACK_PORT_NAME_SIZE]; | |||
| char type[JACK_PORT_TYPE_SIZE]; | |||
| uint32_t flags; | |||
| jack_shmsize_t buffer_size; | |||
| jack_port_id_t port_id; | |||
| jack_uuid_t client_id; | |||
| } POST_PACKED_STRUCTURE port_info; | |||
| struct { | |||
| char source_port[JACK_PORT_NAME_SIZE]; | |||
| char destination_port[JACK_PORT_NAME_SIZE]; | |||
| } POST_PACKED_STRUCTURE connect; | |||
| struct { | |||
| char path[JACK_PORT_NAME_SIZE]; | |||
| jack_session_event_type_t type; | |||
| char target[JACK_CLIENT_NAME_SIZE]; | |||
| } POST_PACKED_STRUCTURE session; | |||
| struct { | |||
| int32_t nports; | |||
| const char **ports; /* this is only exposed to internal clients, so there | |||
| is no 64/32 issue. external clients read the ports | |||
| one by one from the server, and allocate their | |||
| own "ports" array in their own address space. | |||
| we are lucky, because this is part of a union | |||
| whose other components are bigger than this one. | |||
| otherwise it would change structure size when | |||
| comparing the 64 and 32 bit versions. | |||
| */ | |||
| } POST_PACKED_STRUCTURE port_connections; | |||
| struct { | |||
| jack_uuid_t client_id; | |||
| int32_t conditional; | |||
| } POST_PACKED_STRUCTURE timebase; | |||
| struct { | |||
| char name[JACK_CLIENT_NAME_SIZE]; | |||
| jack_uuid_t uuid; | |||
| } POST_PACKED_STRUCTURE reservename; | |||
| struct { | |||
| //jack_options_t options; | |||
| uint32_t options; | |||
| jack_uuid_t uuid; | |||
| char name[JACK_CLIENT_NAME_SIZE]; | |||
| char path[PATH_MAX + 1]; | |||
| char init[JACK_LOAD_INIT_LIMIT]; | |||
| } POST_PACKED_STRUCTURE intclient; | |||
| struct { | |||
| jack_property_change_t change; | |||
| jack_uuid_t uuid; | |||
| size_t keylen; | |||
| const char* key; /* not delivered inline to server, see oop_client_deliver_request() */ | |||
| } POST_PACKED_STRUCTURE property; | |||
| jack_uuid_t client_id; | |||
| jack_nframes_t nframes; | |||
| jack_time_t timeout; | |||
| pid_t cap_pid; | |||
| char name[JACK_CLIENT_NAME_SIZE]; | |||
| } POST_PACKED_STRUCTURE x; | |||
| int32_t status; | |||
| } POST_PACKED_STRUCTURE; | |||
| /* Per-client structure allocated in the server's address space. | |||
| @@ -458,36 +458,36 @@ struct _jack_request { | |||
| typedef struct _jack_client_internal { | |||
| jack_client_control_t *control; | |||
| int request_fd; | |||
| int event_fd; | |||
| int subgraph_start_fd; | |||
| int subgraph_wait_fd; | |||
| JSList *ports; /* protected by engine->client_lock */ | |||
| JSList *truefeeds; /* protected by engine->client_lock */ | |||
| JSList *sortfeeds; /* protected by engine->client_lock */ | |||
| int fedcount; | |||
| int tfedcount; | |||
| jack_shm_info_t control_shm; | |||
| unsigned long execution_order; | |||
| struct _jack_client_internal *next_client; /* not a linked list! */ | |||
| dlhandle handle; | |||
| int (*initialize)(jack_client_t*, const char*); /* int. clients only */ | |||
| void (*finish)(void *); /* internal clients only */ | |||
| int error; | |||
| int session_reply_pending; | |||
| jack_client_control_t *control; | |||
| int request_fd; | |||
| int event_fd; | |||
| int subgraph_start_fd; | |||
| int subgraph_wait_fd; | |||
| JSList *ports; /* protected by engine->client_lock */ | |||
| JSList *truefeeds; /* protected by engine->client_lock */ | |||
| JSList *sortfeeds; /* protected by engine->client_lock */ | |||
| int fedcount; | |||
| int tfedcount; | |||
| jack_shm_info_t control_shm; | |||
| unsigned long execution_order; | |||
| struct _jack_client_internal *next_client; /* not a linked list! */ | |||
| dlhandle handle; | |||
| int (*initialize)(jack_client_t*, const char*); /* int. clients only */ | |||
| void (*finish)(void *); /* internal clients only */ | |||
| int error; | |||
| int session_reply_pending; | |||
| #ifdef JACK_USE_MACH_THREADS | |||
| /* specific resources for server/client real-time thread communication */ | |||
| mach_port_t serverport; | |||
| trivial_message message; | |||
| int running; | |||
| int portnum; | |||
| #endif /* JACK_USE_MACH_THREADS */ | |||
| jack_client_t *private_client; | |||
| /* specific resources for server/client real-time thread communication */ | |||
| mach_port_t serverport; | |||
| trivial_message message; | |||
| int running; | |||
| int portnum; | |||
| #endif /* JACK_USE_MACH_THREADS */ | |||
| jack_client_t *private_client; | |||
| } jack_client_internal_t; | |||
| typedef struct _jack_thread_arg { | |||
| @@ -499,21 +499,21 @@ typedef struct _jack_thread_arg { | |||
| pid_t cap_pid; | |||
| } jack_thread_arg_t; | |||
| extern int jack_client_handle_port_connection (jack_client_t *client, | |||
| jack_event_t *event); | |||
| extern jack_client_t *jack_driver_client_new (jack_engine_t *, | |||
| const char *client_name); | |||
| extern jack_client_t *jack_client_alloc_internal (jack_client_control_t*, | |||
| jack_engine_t*); | |||
| extern int jack_client_handle_port_connection(jack_client_t *client, | |||
| jack_event_t *event); | |||
| extern jack_client_t *jack_driver_client_new(jack_engine_t *, | |||
| const char *client_name); | |||
| extern jack_client_t *jack_client_alloc_internal(jack_client_control_t*, | |||
| jack_engine_t*); | |||
| /* internal clients call this. it's defined in jack/engine.c */ | |||
| void handle_internal_client_request (jack_control_t*, jack_request_t*); | |||
| void handle_internal_client_request(jack_control_t*, jack_request_t*); | |||
| extern char *jack_tmpdir; | |||
| extern char *jack_user_dir (void); | |||
| extern char *jack_user_dir(void); | |||
| extern char *jack_server_dir (const char *server_name, char *server_dir); | |||
| extern char *jack_server_dir(const char *server_name, char *server_dir); | |||
| extern void *jack_zero_filled_buffer; | |||
| @@ -521,46 +521,46 @@ extern jack_port_functions_t jack_builtin_audio_functions; | |||
| extern jack_port_type_info_t jack_builtin_port_types[]; | |||
| extern void jack_client_fix_port_buffers (jack_client_t *client); | |||
| extern void jack_client_fix_port_buffers(jack_client_t *client); | |||
| extern void jack_transport_copy_position (jack_position_t *from, | |||
| jack_position_t *to); | |||
| extern void jack_call_sync_client (jack_client_t *client); | |||
| extern void jack_transport_copy_position(jack_position_t *from, | |||
| jack_position_t *to); | |||
| extern void jack_call_sync_client(jack_client_t *client); | |||
| extern void jack_call_timebase_master (jack_client_t *client); | |||
| extern void jack_call_timebase_master(jack_client_t *client); | |||
| extern char *jack_default_server_name (void); | |||
| extern char *jack_default_server_name(void); | |||
| void silent_jack_error_callback (const char *desc); | |||
| void silent_jack_error_callback(const char *desc); | |||
| /* needed for port management */ | |||
| extern jack_port_t *jack_port_by_id_int (const jack_client_t *client, | |||
| jack_port_id_t id, int* free); | |||
| extern jack_port_t *jack_port_by_id_int(const jack_client_t *client, | |||
| jack_port_id_t id, int* free); | |||
| extern jack_port_t *jack_port_by_name_int (jack_client_t *client, | |||
| const char *port_name); | |||
| extern int jack_port_name_equals (jack_port_shared_t* port, const char* target); | |||
| extern jack_port_t *jack_port_by_name_int(jack_client_t *client, | |||
| const char *port_name); | |||
| extern int jack_port_name_equals(jack_port_shared_t* port, const char* target); | |||
| /** Get the size (in bytes) of the data structure used to store | |||
| * MIDI events internally. | |||
| * MIDI events internally. | |||
| */ | |||
| extern size_t jack_midi_internal_event_size (); | |||
| extern size_t jack_midi_internal_event_size(); | |||
| extern int jack_client_handle_latency_callback (jack_client_t *client, jack_event_t *event, int is_driver); | |||
| extern int jack_client_handle_latency_callback(jack_client_t *client, jack_event_t *event, int is_driver); | |||
| #ifdef __GNUC__ | |||
| # define likely(x) __builtin_expect((x),1) | |||
| # define unlikely(x) __builtin_expect((x),0) | |||
| # define likely(x) __builtin_expect ((x), 1) | |||
| # define unlikely(x) __builtin_expect ((x), 0) | |||
| #else | |||
| # define likely(x) (x) | |||
| # define unlikely(x) (x) | |||
| # define likely(x) (x) | |||
| # define unlikely(x) (x) | |||
| #endif | |||
| #ifdef VALGRIND_CLEAN | |||
| #include <string.h> | |||
| #define VALGRIND_MEMSET(ptr,val,size) memset ((ptr),(val),(size)) | |||
| #define VALGRIND_MEMSET(ptr, val, size) memset ((ptr), (val), (size)) | |||
| #else | |||
| #define VALGRIND_MEMSET(ptr,val,size) | |||
| #define VALGRIND_MEMSET(ptr, val, size) | |||
| #endif | |||
| #endif /* __jack_internal_h__ */ | |||
| @@ -1,21 +1,21 @@ | |||
| /* | |||
| Copyright (C) 2005-2007 Jussi Laako | |||
| 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. | |||
| */ | |||
| */ | |||
| #ifndef __jack_intsimd_h__ | |||
| #define __jack_intsimd_h__ | |||
| @@ -23,34 +23,34 @@ | |||
| #ifdef USE_DYNSIMD | |||
| #if (defined(__i386__) || defined(__x86_64__)) | |||
| #define ARCH_X86 | |||
| #endif /* __i386__ || __x86_64__ */ | |||
| #endif /* USE_DYNSIMD */ | |||
| #endif /* __i386__ || __x86_64__ */ | |||
| #endif /* USE_DYNSIMD */ | |||
| #ifdef ARCH_X86 | |||
| #define ARCH_X86_SSE(x) ((x) & 0xff) | |||
| #define ARCH_X86_HAVE_SSE2(x) (ARCH_X86_SSE(x) >= 2) | |||
| #define ARCH_X86_3DNOW(x) ((x) >> 8) | |||
| #define ARCH_X86_HAVE_3DNOW(x) (ARCH_X86_3DNOW(x)) | |||
| #define ARCH_X86_SSE(x) ((x) & 0xff) | |||
| #define ARCH_X86_HAVE_SSE2(x) (ARCH_X86_SSE (x) >= 2) | |||
| #define ARCH_X86_3DNOW(x) ((x) >> 8) | |||
| #define ARCH_X86_HAVE_3DNOW(x) (ARCH_X86_3DNOW (x)) | |||
| typedef float v2sf __attribute__((vector_size(8))); | |||
| typedef float v4sf __attribute__((vector_size(16))); | |||
| typedef float v2sf __attribute__((vector_size (8))); | |||
| typedef float v4sf __attribute__((vector_size (16))); | |||
| typedef v2sf * pv2sf; | |||
| typedef v4sf * pv4sf; | |||
| extern int cpu_type; | |||
| int have_3dnow (void); | |||
| int have_sse (void); | |||
| void x86_3dnow_copyf (float *, const float *, int); | |||
| void x86_3dnow_add2f (float *, const float *, int); | |||
| void x86_sse_copyf (float *, const float *, int); | |||
| void x86_sse_add2f (float *, const float *, int); | |||
| void x86_sse_f2i (int *, const float *, int, float); | |||
| void x86_sse_i2f (float *, const int *, int, float); | |||
| int have_3dnow(void); | |||
| int have_sse(void); | |||
| void x86_3dnow_copyf(float *, const float *, int); | |||
| void x86_3dnow_add2f(float *, const float *, int); | |||
| void x86_sse_copyf(float *, const float *, int); | |||
| void x86_sse_add2f(float *, const float *, int); | |||
| void x86_sse_f2i(int *, const float *, int, float); | |||
| void x86_sse_i2f(float *, const int *, int, float); | |||
| #endif /* ARCH_X86 */ | |||
| void jack_port_set_funcs (void); | |||
| void jack_port_set_funcs(void); | |||
| #endif /* __jack_intsimd_h__ */ | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| Copyright (C) 1999-2000 Paul Davis | |||
| Copyright (C) 1999-2000 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 | |||
| @@ -15,14 +15,14 @@ | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| */ | |||
| #ifndef __jack_memops_h__ | |||
| #define __jack_memops_h__ | |||
| #include <jack/types.h> | |||
| typedef enum { | |||
| typedef enum { | |||
| None, | |||
| Rectangular, | |||
| Triangular, | |||
| @@ -33,52 +33,52 @@ typedef enum { | |||
| #define DITHER_BUF_MASK 7 | |||
| typedef struct { | |||
| unsigned int depth; | |||
| float rm1; | |||
| unsigned int idx; | |||
| float e[DITHER_BUF_SIZE]; | |||
| unsigned int depth; | |||
| float rm1; | |||
| unsigned int idx; | |||
| float e[DITHER_BUF_SIZE]; | |||
| } dither_state_t; | |||
| /* float functions */ | |||
| void sample_move_floatLE_sSs (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long dst_skip); | |||
| void sample_move_dS_floatLE (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_floatLE_sSs(jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long dst_skip); | |||
| void sample_move_dS_floatLE(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| /* integer functions */ | |||
| void sample_move_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_d24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_rect_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_rect_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_tri_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_tri_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_shaped_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_shaped_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_rect_d24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_rect_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_tri_d24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_tri_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_shaped_d24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_shaped_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_rect_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_rect_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_tri_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_tri_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_shaped_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_shaped_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dS_s32u24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); | |||
| void sample_move_dS_s32u24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); | |||
| void sample_move_dS_s24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); | |||
| void sample_move_dS_s24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); | |||
| void sample_move_dS_s16s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); | |||
| void sample_move_dS_s16 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); | |||
| void sample_merge_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_merge_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_d32u24_sSs(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_d32u24_sS(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_d24_sSs(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_d24_sS(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_d16_sSs(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_d16_sS(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_rect_d32u24_sSs(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_rect_d32u24_sS(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_tri_d32u24_sSs(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_tri_d32u24_sS(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_shaped_d32u24_sSs(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_shaped_d32u24_sS(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_rect_d24_sSs(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_rect_d24_sS(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_tri_d24_sSs(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_tri_d24_sS(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_shaped_d24_sSs(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_shaped_d24_sS(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_rect_d16_sSs(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_rect_d16_sS(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_tri_d16_sSs(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_tri_d16_sS(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_shaped_d16_sSs(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_shaped_d16_sS(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dS_s32u24s(jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); | |||
| void sample_move_dS_s32u24(jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); | |||
| void sample_move_dS_s24s(jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); | |||
| void sample_move_dS_s24(jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); | |||
| void sample_move_dS_s16s(jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); | |||
| void sample_move_dS_s16(jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); | |||
| void sample_merge_d16_sS(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_merge_d32u24_sS(char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| static __inline__ void | |||
| sample_merge (jack_default_audio_sample_t *dst, jack_default_audio_sample_t *src, unsigned long cnt) | |||
| @@ -95,21 +95,21 @@ static __inline__ void | |||
| sample_memcpy (jack_default_audio_sample_t *dst, jack_default_audio_sample_t *src, unsigned long cnt) | |||
| { | |||
| memcpy (dst, src, cnt * sizeof (jack_default_audio_sample_t)); | |||
| memcpy (dst, src, cnt * sizeof(jack_default_audio_sample_t)); | |||
| } | |||
| void memset_interleave (char *dst, char val, unsigned long bytes, unsigned long unit_bytes, unsigned long skip_bytes); | |||
| void memcpy_fake (char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar); | |||
| void memset_interleave(char *dst, char val, unsigned long bytes, unsigned long unit_bytes, unsigned long skip_bytes); | |||
| void memcpy_fake(char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar); | |||
| void memcpy_interleave_d16_s16 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); | |||
| void memcpy_interleave_d24_s24 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); | |||
| void memcpy_interleave_d32_s32 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); | |||
| void memcpy_interleave_d16_s16(char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); | |||
| void memcpy_interleave_d24_s24(char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); | |||
| void memcpy_interleave_d32_s32(char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); | |||
| void merge_memcpy_interleave_d16_s16 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); | |||
| void merge_memcpy_interleave_d24_s24 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); | |||
| void merge_memcpy_interleave_d32_s32 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); | |||
| void merge_memcpy_interleave_d16_s16(char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); | |||
| void merge_memcpy_interleave_d24_s24(char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); | |||
| void merge_memcpy_interleave_d32_s32(char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); | |||
| void merge_memcpy_d16_s16 (char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar); | |||
| void merge_memcpy_d32_s32 (char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar); | |||
| void merge_memcpy_d16_s16(char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar); | |||
| void merge_memcpy_d32_s32(char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar); | |||
| #endif /* __jack_memops_h__ */ | |||
| @@ -8,19 +8,19 @@ | |||
| /* | |||
| * Copyright (C) 2004 Rui Nuno Capela, Steve Harris | |||
| * | |||
| * | |||
| * 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 | |||
| * along with this program; if not, write to the Free Software | |||
| * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| * | |||
| */ | |||
| @@ -28,17 +28,17 @@ | |||
| #ifndef __jack_messagebuffer_h__ | |||
| #define __jack_messagebuffer_h__ | |||
| #define MESSAGE(fmt,args...) jack_messagebuffer_add(fmt , ##args) | |||
| #define VERBOSE(engine,fmt,args...) \ | |||
| #define MESSAGE(fmt, args ...) jack_messagebuffer_add (fmt, ## args) | |||
| #define VERBOSE(engine, fmt, args ...) \ | |||
| if ((engine)->verbose) \ | |||
| jack_messagebuffer_add(fmt , ##args) | |||
| jack_messagebuffer_add (fmt, ## args) | |||
| void jack_messagebuffer_init(); | |||
| void jack_messagebuffer_exit(); | |||
| void jack_message_buffer_thread_init (void (*cb)(void*), void*); | |||
| void jack_message_buffer_thread_init(void (*cb)(void*), void*); | |||
| void jack_messagebuffer_add(const char *fmt, ...); | |||
| void jack_messagebuffer_thread_init (void (*cb)(void*), void* arg); | |||
| void jack_messagebuffer_thread_init(void (*cb)(void*), void* arg); | |||
| #endif /* __jack_messagebuffer_h__ */ | |||
| @@ -1,28 +1,28 @@ | |||
| /* | |||
| Copyright (C) 2001 Paul Davis | |||
| 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 | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| */ | |||
| */ | |||
| #ifndef __jack_pool_h__ | |||
| #define __jack_pool_h__ | |||
| #include <sys/types.h> | |||
| void * jack_pool_alloc (size_t bytes); | |||
| void jack_pool_release (void *); | |||
| void * jack_pool_alloc(size_t bytes); | |||
| void jack_pool_release(void *); | |||
| #endif /* __jack_pool_h__ */ | |||
| @@ -1,21 +1,21 @@ | |||
| /* | |||
| Copyright (C) 2001 Paul Davis | |||
| 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 | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| */ | |||
| */ | |||
| #ifndef __jack_port_h__ | |||
| #define __jack_port_h__ | |||
| @@ -38,7 +38,7 @@ | |||
| * - one other | |||
| * | |||
| * which is probably enough for more than just the foreseeable future. | |||
| */ | |||
| */ | |||
| #define JACK_MAX_PORT_TYPES 4 | |||
| #define JACK_AUDIO_PORT_TYPE 0 | |||
| #define JACK_MIDI_PORT_TYPE 1 | |||
| @@ -47,14 +47,14 @@ | |||
| #define JACK_CLIENT_NAME_SIZE 33 | |||
| /* JACK shared memory segments are limited to MAX_INT32, they can be | |||
| * shared between 32-bit and 64-bit clients. | |||
| * shared between 32-bit and 64-bit clients. | |||
| */ | |||
| #define JACK_SHM_MAX (MAX_INT32) | |||
| typedef int32_t jack_port_type_id_t; | |||
| #define JACK_BACKEND_ALIAS "system" | |||
| /* Port type structure. | |||
| /* Port type structure. | |||
| * | |||
| * (1) One for each port type is part of the engine's jack_control_t | |||
| * shared memory structure. | |||
| @@ -66,71 +66,71 @@ typedef int32_t jack_port_type_id_t; | |||
| */ | |||
| typedef struct _jack_port_type_info { | |||
| jack_port_type_id_t ptype_id; | |||
| const char type_name[JACK_PORT_TYPE_SIZE]; | |||
| jack_port_type_id_t ptype_id; | |||
| const char type_name[JACK_PORT_TYPE_SIZE]; | |||
| /* If == 1, then a buffer to handle nframes worth of data has | |||
| * sizeof(jack_default_audio_sample_t) * nframes bytes. | |||
| * | |||
| * If > 1, the buffer allocated for input mixing will be | |||
| * this value times sizeof(jack_default_audio_sample_t) | |||
| * * nframes bytes in size. For non-audio data types, | |||
| * it may have a different value. | |||
| * | |||
| * If < 0, the value should be ignored, and buffer_size | |||
| * should be used. | |||
| */ | |||
| int32_t buffer_scale_factor; | |||
| /* If == 1, then a buffer to handle nframes worth of data has | |||
| * sizeof(jack_default_audio_sample_t) * nframes bytes. | |||
| * | |||
| * If > 1, the buffer allocated for input mixing will be | |||
| * this value times sizeof(jack_default_audio_sample_t) | |||
| * * nframes bytes in size. For non-audio data types, | |||
| * it may have a different value. | |||
| * | |||
| * If < 0, the value should be ignored, and buffer_size | |||
| * should be used. | |||
| */ | |||
| int32_t buffer_scale_factor; | |||
| /* ignored unless buffer_scale_factor is < 0. see above */ | |||
| jack_shmsize_t buffer_size; | |||
| /* ignored unless buffer_scale_factor is < 0. see above */ | |||
| jack_shmsize_t buffer_size; | |||
| jack_shm_registry_index_t shm_registry_index; | |||
| jack_shm_registry_index_t shm_registry_index; | |||
| jack_shmsize_t zero_buffer_offset; | |||
| jack_shmsize_t zero_buffer_offset; | |||
| } POST_PACKED_STRUCTURE jack_port_type_info_t; | |||
| /* Allocated by the engine in shared memory. */ | |||
| typedef struct _jack_port_shared { | |||
| jack_port_type_id_t ptype_id; /* index into port type array */ | |||
| jack_shmsize_t offset; /* buffer offset in shm segment */ | |||
| jack_port_id_t id; /* index into engine port array */ | |||
| jack_uuid_t uuid; | |||
| uint32_t flags; | |||
| char name[JACK_CLIENT_NAME_SIZE+JACK_PORT_NAME_SIZE]; | |||
| char alias1[JACK_CLIENT_NAME_SIZE+JACK_PORT_NAME_SIZE]; | |||
| char alias2[JACK_CLIENT_NAME_SIZE+JACK_PORT_NAME_SIZE]; | |||
| jack_uuid_t client_id; /* who owns me */ | |||
| volatile jack_nframes_t latency; | |||
| volatile jack_nframes_t total_latency; | |||
| volatile jack_latency_range_t playback_latency; | |||
| volatile jack_latency_range_t capture_latency; | |||
| volatile uint8_t monitor_requests; | |||
| char has_mixdown; /* port has a mixdown function */ | |||
| char in_use; | |||
| char unused; /* legacy locked field */ | |||
| jack_port_type_id_t ptype_id; /* index into port type array */ | |||
| jack_shmsize_t offset; /* buffer offset in shm segment */ | |||
| jack_port_id_t id; /* index into engine port array */ | |||
| jack_uuid_t uuid; | |||
| uint32_t flags; | |||
| char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; | |||
| char alias1[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; | |||
| char alias2[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; | |||
| jack_uuid_t client_id; /* who owns me */ | |||
| volatile jack_nframes_t latency; | |||
| volatile jack_nframes_t total_latency; | |||
| volatile jack_latency_range_t playback_latency; | |||
| volatile jack_latency_range_t capture_latency; | |||
| volatile uint8_t monitor_requests; | |||
| char has_mixdown; /* port has a mixdown function */ | |||
| char in_use; | |||
| char unused; /* legacy locked field */ | |||
| } POST_PACKED_STRUCTURE jack_port_shared_t; | |||
| typedef struct _jack_port_functions { | |||
| /* Function to initialize port buffer. Cannot be NULL. | |||
| * NOTE: This must take a buffer rather than jack_port_t as it is called | |||
| * in jack_engine_place_buffers() before any port creation. | |||
| * A better solution is to make jack_engine_place_buffers to be type-specific, | |||
| * but this works. | |||
| */ | |||
| void (*buffer_init)(void *buffer, size_t size, jack_nframes_t); | |||
| /* Function to initialize port buffer. Cannot be NULL. | |||
| * NOTE: This must take a buffer rather than jack_port_t as it is called | |||
| * in jack_engine_place_buffers() before any port creation. | |||
| * A better solution is to make jack_engine_place_buffers to be type-specific, | |||
| * but this works. | |||
| */ | |||
| void (*buffer_init)(void *buffer, size_t size, jack_nframes_t); | |||
| /* Function to mixdown multiple inputs to a buffer. Can be NULL, | |||
| * indicating that multiple input connections are not legal for | |||
| * this data type. | |||
| */ | |||
| void (*mixdown)(jack_port_t *, jack_nframes_t); | |||
| /* Function to mixdown multiple inputs to a buffer. Can be NULL, | |||
| * indicating that multiple input connections are not legal for | |||
| * this data type. | |||
| */ | |||
| void (*mixdown)(jack_port_t *, jack_nframes_t); | |||
| } jack_port_functions_t; | |||
| @@ -146,14 +146,14 @@ jack_get_port_functions(jack_port_type_id_t ptid); | |||
| /* Allocated by the client in local memory. */ | |||
| struct _jack_port { | |||
| void **client_segment_base; | |||
| void *mix_buffer; | |||
| jack_port_type_info_t *type_info; /* shared memory type info */ | |||
| struct _jack_port_shared *shared; /* corresponding shm struct */ | |||
| struct _jack_port *tied; /* locally tied source port */ | |||
| jack_port_functions_t fptr; | |||
| pthread_mutex_t connection_lock; | |||
| JSList *connections; | |||
| void **client_segment_base; | |||
| void *mix_buffer; | |||
| jack_port_type_info_t *type_info; /* shared memory type info */ | |||
| struct _jack_port_shared *shared; /* corresponding shm struct */ | |||
| struct _jack_port *tied; /* locally tied source port */ | |||
| jack_port_functions_t fptr; | |||
| pthread_mutex_t connection_lock; | |||
| JSList *connections; | |||
| }; | |||
| /* Inline would be cleaner, but it needs to be fast even in | |||
| @@ -161,13 +161,13 @@ struct _jack_port { | |||
| * ports. jack_port_buffer() works for both input and output ports. | |||
| */ | |||
| #define jack_port_buffer(p) \ | |||
| ((void *) ((p)->mix_buffer? (p)->mix_buffer: \ | |||
| *(p)->client_segment_base + (p)->shared->offset)) | |||
| ((void*)((p)->mix_buffer ? (p)->mix_buffer : \ | |||
| *(p)->client_segment_base + (p)->shared->offset)) | |||
| #define jack_output_port_buffer(p) \ | |||
| ((void *) (*(p)->client_segment_base + (p)->shared->offset)) | |||
| ((void*)(*(p)->client_segment_base + (p)->shared->offset)) | |||
| /* not for use by JACK applications */ | |||
| size_t jack_port_type_buffer_size (jack_port_type_info_t* port_type_info, jack_nframes_t nframes); | |||
| size_t jack_port_type_buffer_size(jack_port_type_info_t* port_type_info, jack_nframes_t nframes); | |||
| #endif /* __jack_port_h__ */ | |||
| @@ -16,7 +16,7 @@ | |||
| * | |||
| **/ | |||
| int sanitycheck (int do_realtime_check, | |||
| int do_freqscaling_check); | |||
| int sanitycheck(int do_realtime_check, | |||
| int do_freqscaling_check); | |||
| #endif /* __jack_sanitycheck_h__ */ | |||
| @@ -5,12 +5,12 @@ | |||
| #include <sys/types.h> | |||
| #include <jack/types.h> | |||
| #define MAX_SERVERS 8 /* maximum concurrent servers */ | |||
| #define MAX_SHM_ID 256 /* generally about 16 per server */ | |||
| #define JACK_SERVER_NAME_SIZE 256 /* maximum length of server name */ | |||
| #define JACK_SHM_MAGIC 0x4a41434b /* shm magic number: "JACK" */ | |||
| #define JACK_SHM_NULL_INDEX -1 /* NULL SHM index */ | |||
| #define JACK_SHM_REGISTRY_INDEX -2 /* pseudo SHM index for registry */ | |||
| #define MAX_SERVERS 8 /* maximum concurrent servers */ | |||
| #define MAX_SHM_ID 256 /* generally about 16 per server */ | |||
| #define JACK_SERVER_NAME_SIZE 256 /* maximum length of server name */ | |||
| #define JACK_SHM_MAGIC 0x4a41434b /* shm magic number: "JACK" */ | |||
| #define JACK_SHM_NULL_INDEX -1 /* NULL SHM index */ | |||
| #define JACK_SHM_REGISTRY_INDEX -2 /* pseudo SHM index for registry */ | |||
| /* On Mac OS X, SHM_NAME_MAX is the maximum length of a shared memory | |||
| @@ -21,21 +21,21 @@ | |||
| #ifndef SHM_NAME_MAX | |||
| #define SHM_NAME_MAX NAME_MAX | |||
| #endif | |||
| typedef char shm_name_t[SHM_NAME_MAX]; | |||
| typedef char shm_name_t[SHM_NAME_MAX]; | |||
| typedef shm_name_t jack_shm_id_t; | |||
| #else /* System V SHM */ | |||
| typedef int jack_shm_id_t; | |||
| typedef int jack_shm_id_t; | |||
| #endif /* SHM type */ | |||
| /* shared memory type */ | |||
| typedef enum { | |||
| shm_POSIX = 1, /* POSIX shared memory */ | |||
| shm_SYSV = 2 /* System V shared memory */ | |||
| shm_POSIX = 1, /* POSIX shared memory */ | |||
| shm_SYSV = 2 /* System V shared memory */ | |||
| } jack_shmtype_t; | |||
| typedef int16_t jack_shm_registry_index_t; | |||
| /** | |||
| /** | |||
| * A structure holding information about shared memory allocated by | |||
| * JACK. this persists across invocations of JACK, and can be used by | |||
| * multiple JACK servers. It contains no pointers and is valid across | |||
| @@ -45,31 +45,31 @@ typedef int16_t jack_shm_registry_index_t; | |||
| * server names, followed by an array of segment registry entries. | |||
| */ | |||
| typedef struct _jack_shm_server { | |||
| pid_t pid; /* process ID */ | |||
| char name[JACK_SERVER_NAME_SIZE]; | |||
| pid_t pid; /* process ID */ | |||
| char name[JACK_SERVER_NAME_SIZE]; | |||
| } jack_shm_server_t; | |||
| typedef struct _jack_shm_header { | |||
| uint32_t magic; /* magic number */ | |||
| uint16_t protocol; /* JACK protocol version */ | |||
| jack_shmtype_t type; /* shm type */ | |||
| jack_shmsize_t size; /* total registry segment size */ | |||
| jack_shmsize_t hdr_len; /* size of header */ | |||
| jack_shmsize_t entry_len; /* size of registry entry */ | |||
| jack_shm_server_t server[MAX_SERVERS]; /* current server array */ | |||
| uint32_t magic; /* magic number */ | |||
| uint16_t protocol; /* JACK protocol version */ | |||
| jack_shmtype_t type; /* shm type */ | |||
| jack_shmsize_t size; /* total registry segment size */ | |||
| jack_shmsize_t hdr_len; /* size of header */ | |||
| jack_shmsize_t entry_len; /* size of registry entry */ | |||
| jack_shm_server_t server[MAX_SERVERS]; /* current server array */ | |||
| } jack_shm_header_t; | |||
| typedef struct _jack_shm_registry { | |||
| jack_shm_registry_index_t index; /* offset into the registry */ | |||
| pid_t allocator; /* PID that created shm segment */ | |||
| jack_shmsize_t size; /* for POSIX unattach */ | |||
| jack_shm_id_t id; /* API specific, see above */ | |||
| jack_shm_registry_index_t index; /* offset into the registry */ | |||
| pid_t allocator; /* PID that created shm segment */ | |||
| jack_shmsize_t size; /* for POSIX unattach */ | |||
| jack_shm_id_t id; /* API specific, see above */ | |||
| } jack_shm_registry_t; | |||
| #define JACK_SHM_REGISTRY_SIZE (sizeof (jack_shm_header_t) \ | |||
| + sizeof (jack_shm_registry_t) * MAX_SHM_ID) | |||
| #define JACK_SHM_REGISTRY_SIZE (sizeof(jack_shm_header_t) \ | |||
| + sizeof(jack_shm_registry_t) * MAX_SHM_ID) | |||
| /** | |||
| /** | |||
| * a structure holding information about shared memory | |||
| * allocated by JACK. this version is valid only | |||
| * for a given address space. It contains a pointer | |||
| @@ -77,34 +77,35 @@ typedef struct _jack_shm_registry { | |||
| * attached to the address space. | |||
| */ | |||
| typedef struct _jack_shm_info { | |||
| jack_shm_registry_index_t index; /* offset into the registry */ | |||
| void *attached_at; /* address where attached */ | |||
| jack_shm_registry_index_t index; /* offset into the registry */ | |||
| void *attached_at; /* address where attached */ | |||
| } jack_shm_info_t; | |||
| /* utility functions used only within JACK */ | |||
| extern void jack_shm_copy_from_registry (jack_shm_info_t*, | |||
| extern void jack_shm_copy_from_registry (jack_shm_info_t *, | |||
| jack_shm_registry_index_t); | |||
| extern void jack_shm_copy_to_registry (jack_shm_info_t*, | |||
| jack_shm_registry_index_t*); | |||
| extern void jack_shm_copy_to_registry(jack_shm_info_t*, | |||
| jack_shm_registry_index_t*); | |||
| extern void jack_release_shm_info (jack_shm_registry_index_t); | |||
| static inline char* jack_shm_addr (jack_shm_info_t* si) { | |||
| static inline char* jack_shm_addr (jack_shm_info_t* si) | |||
| { | |||
| return si->attached_at; | |||
| } | |||
| /* here beginneth the API */ | |||
| extern int jack_register_server (const char *server_name, int new_registry); | |||
| extern void jack_unregister_server (const char *server_name); | |||
| extern int jack_register_server(const char *server_name, int new_registry); | |||
| extern void jack_unregister_server(const char *server_name); | |||
| extern int jack_initialize_shm (const char *server_name); | |||
| extern int jack_cleanup_shm (void); | |||
| extern int jack_initialize_shm(const char *server_name); | |||
| extern int jack_cleanup_shm(void); | |||
| extern int jack_shmalloc (jack_shmsize_t size, jack_shm_info_t* result); | |||
| extern void jack_release_shm (jack_shm_info_t*); | |||
| extern void jack_destroy_shm (jack_shm_info_t*); | |||
| extern int jack_attach_shm (jack_shm_info_t*); | |||
| extern int jack_resize_shm (jack_shm_info_t*, jack_shmsize_t size); | |||
| extern int jack_shmalloc(jack_shmsize_t size, jack_shm_info_t* result); | |||
| extern void jack_release_shm(jack_shm_info_t*); | |||
| extern void jack_destroy_shm(jack_shm_info_t*); | |||
| extern int jack_attach_shm(jack_shm_info_t*); | |||
| extern int jack_resize_shm(jack_shm_info_t*, jack_shmsize_t size); | |||
| #endif /* __jack_shm_h__ */ | |||