diff --git a/audio/chuck/Makefile b/audio/chuck/Makefile new file mode 100644 index 0000000..5d3a0f3 --- /dev/null +++ b/audio/chuck/Makefile @@ -0,0 +1,40 @@ +COMMENT = strongly-timed music programming language + +DIST_TUPLE = github ccrma chuck chuck-1.5.5.7 . +PKGNAME = chuck-1.5.5.7 +CATEGORIES = audio +REVISION = 0 + +HOMEPAGE = https://chuck.stanford.edu/ + +# Dual-licensed: MIT or GPLv2+ +PERMIT_PACKAGE = Yes + +WANTLIB += ${COMPILER_LIBCXX} c m pthread sndfile sndio + +COMPILER = base-clang + +LIB_DEPENDS = audio/libsndfile + +BUILD_DEPENDS = devel/bison + +USE_GMAKE = Yes + +WRKDIST = ${WRKDIR}/chuck-chuck-1.5.5.7 +WRKSRC = ${WRKDIST}/src + +MAKE_FILE = makefile +ALL_TARGET = openbsd-sndio +MAKE_FLAGS += CC="${CC}" CXX="${CXX}" YACC=${LOCALBASE}/bin/bison \ + CFLAGS="${CFLAGS} -I${WRKSRC} -I${WRKSRC}/core -I${WRKSRC}/core/lo -I${LOCALBASE}/include -D__OPENBSD_SNDIO__ -fno-strict-aliasing -D__CK_SNDFILE_NATIVE__ -D__DISABLE_HID__" \ + LDFLAGS="${LDFLAGS} -L${LOCALBASE}/lib -lsndio -lstdc++ -lm -lsndfile -lpthread" + +NO_TEST = Yes + +pre-build: + ${INSTALL} -m 644 ${FILESDIR}/makefile.sndio ${WRKSRC}/core/makefile.x/makefile.sndio + +do-install: + ${INSTALL_PROGRAM} ${WRKSRC}/chuck ${PREFIX}/bin/chuck + +.include diff --git a/audio/chuck/distinfo b/audio/chuck/distinfo new file mode 100644 index 0000000..53e7ffc --- /dev/null +++ b/audio/chuck/distinfo @@ -0,0 +1,2 @@ +SHA256 (ccrma-chuck-chuck-1.5.5.7.tar.gz) = BWEe9laQNXvCcpXhcwFlBg0cFGTC1nXY1V+4sYwLbWk= +SIZE (ccrma-chuck-chuck-1.5.5.7.tar.gz) = 22405823 diff --git a/audio/chuck/files/makefile.sndio b/audio/chuck/files/makefile.sndio new file mode 100644 index 0000000..7b234be --- /dev/null +++ b/audio/chuck/files/makefile.sndio @@ -0,0 +1,5 @@ +# compiler flags +CFLAGS+= -D__OPENBSD_SNDIO__ -fno-strict-aliasing -D__CK_SNDFILE_NATIVE__ -D__DISABLE_HID__ -I/usr/local/include + +# linker / library flags +LDFLAGS+= -lsndio -lstdc++ -lm -L/usr/local/lib -lsndfile -lpthread diff --git a/audio/chuck/patches/patch-src_core_chuck_compile_cpp b/audio/chuck/patches/patch-src_core_chuck_compile_cpp new file mode 100644 index 0000000..41954d6 --- /dev/null +++ b/audio/chuck/patches/patch-src_core_chuck_compile_cpp @@ -0,0 +1,13 @@ +Index: src/core/chuck_compile.cpp +--- src/core/chuck_compile.cpp.orig ++++ src/core/chuck_compile.cpp +@@ -1198,6 +1198,9 @@ t_CKBOOL Chuck_Compiler::bind( f_ck_query query_func, + // commit what is in the type checker at this point + env->global()->commit(); + ++ // preserve all operator overloads currently in registry | added 1.5.5.8 (ben) ++ env->op_registry.preserve(); ++ + // pop indent level + EM_poplog(); + diff --git a/audio/chuck/patches/patch-src_core_chuck_cpp b/audio/chuck/patches/patch-src_core_chuck_cpp new file mode 100644 index 0000000..6275d52 --- /dev/null +++ b/audio/chuck/patches/patch-src_core_chuck_cpp @@ -0,0 +1,16 @@ +Index: src/core/chuck.cpp +--- src/core/chuck.cpp.orig ++++ src/core/chuck.cpp +@@ -1531,10 +1531,10 @@ void ChucK::globalCleanup() + // midirw_detach(); + //#endif // __DISABLE_MIDI__ + +- #ifndef __ALTER_HID__ ++ #if !defined(__ALTER_HID__) && !defined(__DISABLE_HID__) + // shutdown HID + HidInManager::cleanup( 100 ); +- #endif // __ALTER_HID__ ++ #endif // __ALTER_HID__ && __DISABLE_HID__ + + #ifndef __DISABLE_SERIAL__ + // shutdown serial diff --git a/audio/chuck/patches/patch-src_core_chuck_def_h b/audio/chuck/patches/patch-src_core_chuck_def_h new file mode 100644 index 0000000..08a7c0a --- /dev/null +++ b/audio/chuck/patches/patch-src_core_chuck_def_h @@ -0,0 +1,28 @@ +Index: src/core/chuck_def.h +--- src/core/chuck_def.h.orig ++++ src/core/chuck_def.h +@@ -49,7 +49,7 @@ + // 1.5.0.0 (ge) | moved to chuck.h for at-a-glance visibility + // 1.5.2.0 (ge) | moved to chuck_def.h for chugins headers streamlining + //----------------------------------------------------------------------------- +-#define CHUCK_VERSION_STRING "1.5.5.7 (chai)" ++#define CHUCK_VERSION_STRING "1.5.5.8-dev (chai)" + //----------------------------------------------------------------------------- + + +@@ -261,13 +261,13 @@ typedef struct { SAMPLE re ; SAMPLE im ; } t_CKCOMPLEX + // platform: linux + // related macros: __LINUX_ALSA__ __LINUX_PULSE__ __LINUX_OSS__ __LINUX_JACK__ __UNIX_JACK__ + //------------------------------------------- +-#if defined(__linux__) || defined(__FreeBSD__) ++#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + //------------------------------------------- + #ifndef __PLATFORM_LINUX__ + #define __PLATFORM_LINUX__ + #endif + //------------------------------------------- +-#endif // defined(__linux__) || defined(__FreeBSD__) ++#endif // defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + //------------------------------------------- + + diff --git a/audio/chuck/patches/patch-src_core_chuck_errmsg_h b/audio/chuck/patches/patch-src_core_chuck_errmsg_h new file mode 100644 index 0000000..a4e31f4 --- /dev/null +++ b/audio/chuck/patches/patch-src_core_chuck_errmsg_h @@ -0,0 +1,11 @@ +Index: src/core/chuck_errmsg.h +--- src/core/chuck_errmsg.h.orig ++++ src/core/chuck_errmsg.h +@@ -37,6 +37,7 @@ + #define __CHUCK_ERRORMSG_H__ + + #include "chuck_def.h" ++#include + #include + + diff --git a/audio/chuck/patches/patch-src_core_chuck_lang_cpp b/audio/chuck/patches/patch-src_core_chuck_lang_cpp new file mode 100644 index 0000000..e411fc5 --- /dev/null +++ b/audio/chuck/patches/patch-src_core_chuck_lang_cpp @@ -0,0 +1,15 @@ +Index: src/core/chuck_lang.cpp +--- src/core/chuck_lang.cpp.orig ++++ src/core/chuck_lang.cpp +@@ -3823,7 +3823,10 @@ static void typeGetTypes( + for( t_CKINT i = 0; i < types.size(); i++ ) + { + // check special +- t_CKBOOL special = (types[i]->base_name.length()>0 && types[i]->base_name[0] == '@'); ++ // 1.5.5.8 (ge) account for "auto" ++ t_CKBOOL special = (types[i]->base_name.length()>0 && ++ (types[i]->base_name[0] == '@' || ++ types[i]->xid == te_auto) ); + // if not requesting special types + if( !isSpecial && (special == TRUE) ) continue; + // check origin diff --git a/audio/chuck/patches/patch-src_core_lo_config_h b/audio/chuck/patches/patch-src_core_lo_config_h new file mode 100644 index 0000000..1379d5c --- /dev/null +++ b/audio/chuck/patches/patch-src_core_lo_config_h @@ -0,0 +1,16 @@ +Index: src/core/lo/config.h +--- src/core/lo/config.h.orig ++++ src/core/lo/config.h +@@ -1,5 +1,5 @@ + +-#if defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__) ++#if defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + // 1.5.0.7 (ge) since this is in the lo/ sub-directory, + // and does not include chuck_def.h, directly check platform macros + // #if defined(__PLATFORM_APPLE__) || defined(__PLATFORM_LINUX__) +@@ -205,4 +205,4 @@ + /* Define to `unsigned int' if does not define. */ + /* #undef size_t */ + +-#endif // defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__) ++#endif // defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) diff --git a/audio/chuck/patches/patch-src_core_makefile b/audio/chuck/patches/patch-src_core_makefile new file mode 100644 index 0000000..6ccedca --- /dev/null +++ b/audio/chuck/patches/patch-src_core_makefile @@ -0,0 +1,25 @@ +Index: src/core/makefile +--- src/core/makefile.orig ++++ src/core/makefile +@@ -4,8 +4,8 @@ current: + @echo " make linux-alsa, make linux-jack, make linux-pulse, linux-all," + @echo " make mac, make mac-ub, make cygwin, make win32, or make vanilla" + +-.PHONY: mac mac-ub osx linux-all linux linux-pulse linux-jack linux-alsa vanilla cygwin osx-rl test +-mac mac-ub osx linux-all linux linux-pulse linux-jack linux-alsa vanilla cygwin osx-rl: chuck-core ++.PHONY: mac mac-ub osx linux-all linux linux-pulse linux-jack linux-alsa openbsd-sndio vanilla cygwin osx-rl test ++mac mac-ub osx linux-all linux linux-pulse linux-jack linux-alsa openbsd-sndio vanilla cygwin osx-rl: chuck-core + + win32: + make -f makefile.win32 +@@ -75,6 +75,10 @@ endif + + ifneq (,$(strip $(filter linux-alsa,$(MAKECMDGOALS)))) + include makefile.x/makefile.alsa ++endif ++ ++ifneq (,$(strip $(filter openbsd-sndio,$(MAKECMDGOALS)))) ++include makefile.x/makefile.sndio + endif + + ifneq (,$(strip $(filter vanilla,$(MAKECMDGOALS)))) diff --git a/audio/chuck/patches/patch-src_core_makefile_x_makefile_jack b/audio/chuck/patches/patch-src_core_makefile_x_makefile_jack new file mode 100644 index 0000000..63546f1 --- /dev/null +++ b/audio/chuck/patches/patch-src_core_makefile_x_makefile_jack @@ -0,0 +1,12 @@ +Index: src/core/makefile.x/makefile.jack +--- src/core/makefile.x/makefile.jack.orig ++++ src/core/makefile.x/makefile.jack +@@ -1,6 +1,6 @@ + # compiler flags +-CFLAGS+= -D__UNIX_JACK__ -fno-strict-aliasing -D__CK_SNDFILE_NATIVE__ ++CFLAGS+= -D__UNIX_JACK__ -fno-strict-aliasing -D__CK_SNDFILE_NATIVE__ -D__DISABLE_HID__ + CFLAGS+= $(shell pkg-config --cflags jack) + + # linker / library flags +-LDFLAGS+= -lasound $(shell pkg-config --libs jack) -lstdc++ -ldl -lm -lsndfile -lpthread ++LDFLAGS+= $(shell pkg-config --libs jack) -lstdc++ -lm -lsndfile -lpthread diff --git a/audio/chuck/patches/patch-src_core_ugen_stk_h b/audio/chuck/patches/patch-src_core_ugen_stk_h new file mode 100644 index 0000000..cc93721 --- /dev/null +++ b/audio/chuck/patches/patch-src_core_ugen_stk_h @@ -0,0 +1,21 @@ +Index: src/core/ugen_stk.h +--- src/core/ugen_stk.h.orig ++++ src/core/ugen_stk.h +@@ -81,6 +81,17 @@ t_CKBOOL stk_detach( Chuck_Carrier * carrier ); + #if !defined(__STK_H) + #define __STK_H + ++// undef OpenBSD/BSD endian macros that clash with Stk member function names ++#ifdef swap16 ++#undef swap16 ++#endif ++#ifdef swap32 ++#undef swap32 ++#endif ++#ifdef swap64 ++#undef swap64 ++#endif ++ + #include + #include + diff --git a/audio/chuck/patches/patch-src_core_ulib_math_cpp b/audio/chuck/patches/patch-src_core_ulib_math_cpp new file mode 100644 index 0000000..2021654 --- /dev/null +++ b/audio/chuck/patches/patch-src_core_ulib_math_cpp @@ -0,0 +1,57 @@ +Index: src/core/ulib_math.cpp +--- src/core/ulib_math.cpp.orig ++++ src/core/ulib_math.cpp +@@ -581,6 +581,13 @@ DLL_QUERY libmath_query( Chuck_DL_Query * QUERY ) + QUERY->add_svar( QUERY, "complex", "j", TRUE, &g_i ); + QUERY->doc_var( QUERY, "The complex number sqrt(-1)." ); + ++ // spherical harmonics | (added) 1.5.5.8 by everett 2026 ++ QUERY->add_sfun( QUERY, sh_impl, "float[]", "sh" ); ++ QUERY->add_arg( QUERY, "int", "order" ); ++ QUERY->add_arg( QUERY, "float", "azimuth" ); ++ QUERY->add_arg( QUERY, "float", "zenith" ); ++ QUERY->doc_func(QUERY, "Returns an array of size (N+1)^2, containing ACN ordered spherical harmonics."); ++ + // add examples + // QUERY->add_ex( QUERY, "map.ck" ); + // QUERY->add_ex( QUERY, "math-help.ck" ); +@@ -1435,5 +1442,38 @@ CK_DLL_SFUN( map2_impl ) + + // std::cerr << v << " " << x1 << " " << y1 << " " << x2 << " " << y2 << std::endl; + // remap +- RETURN->v_float = x2 + (v-x1)/(y1-x1)*(y2-x2); ++ RETURN->v_float = x2 + (v - x1) / (y1 - x1) * (y2 - x2); ++} ++ ++// spherical harmonics implementation | (added) 1.5.5.8 by everett 2026 ++CK_DLL_SFUN( sh_impl ) ++{ ++ t_CKINT order = GET_NEXT_INT(ARGS); ++ t_CKFLOAT direction = GET_NEXT_FLOAT(ARGS); ++ t_CKFLOAT elevation = GET_NEXT_FLOAT(ARGS); ++ t_CKFLOAT * coord = new t_CKFLOAT[(order + 1) * (order + 1) + 1]; ++ if( order <= 5 ) ++ { ++ t_CKUINT size = (order + 1) * (order + 1); ++ // moved memory ownership to ck_SH emc 2/26 (memory was previously allocated by ck_SH() and deleted by sh_impl) ++ ck_SH( coord,order, direction, elevation, 0 ); ++ // Create a float[] array ++ Chuck_DL_Api::Object returnarray = API->object->create( SHRED, API->type->lookup(VM, "float[]"), false ); ++ Chuck_ArrayFloat * coordinatearray = (Chuck_ArrayFloat *)returnarray; ++ for( t_CKINT i = 0; i < size; i++ ) ++ { ++ API->object->array_float_push_back(coordinatearray, coord[i]); ++ } ++ // set return value ++ RETURN->v_object = coordinatearray; ++ } ++ else ++ { ++ // throw exception ++ API->vm->throw_exception("Math.sh() : InvalidSHOrder", "only up to 5th order currently supported", nullptr); ++ RETURN->v_int = 0; ++ } ++ ++ // clean up ++ CK_SAFE_DELETE_ARRAY( coord ); + } diff --git a/audio/chuck/patches/patch-src_core_ulib_math_h b/audio/chuck/patches/patch-src_core_ulib_math_h new file mode 100644 index 0000000..2e5f178 --- /dev/null +++ b/audio/chuck/patches/patch-src_core_ulib_math_h @@ -0,0 +1,13 @@ +Index: src/core/ulib_math.h +--- src/core/ulib_math.h.orig ++++ src/core/ulib_math.h +@@ -119,7 +119,7 @@ CK_DLL_SFUN( euclidean4d_impl ); + CK_DLL_SFUN( map_impl ); + CK_DLL_SFUN( map2_impl ); + +- +- ++// spherical harmonics | (added) 1.5.5.8 by everett 2026 ++CK_DLL_SFUN( sh_impl ); + + #endif diff --git a/audio/chuck/patches/patch-src_core_util_hid_cpp b/audio/chuck/patches/patch-src_core_util_hid_cpp new file mode 100644 index 0000000..ef1d7ff --- /dev/null +++ b/audio/chuck/patches/patch-src_core_util_hid_cpp @@ -0,0 +1,65 @@ +Index: src/core/util_hid.cpp +--- src/core/util_hid.cpp.orig ++++ src/core/util_hid.cpp +@@ -6368,7 +6368,7 @@ int Keyboard_close( int js ) + + + +-#elif defined(__PLATFORM_LINUX__) ++#elif defined(__PLATFORM_LINUX__) && !defined(__OpenBSD__) && !defined(__NetBSD__) + /***************************************************************************** + Linux general HID support + *****************************************************************************/ +@@ -7805,6 +7805,34 @@ const char * Keyboard_name( int k ) + #endif + + ++// OpenBSD/NetBSD: HID not supported; provide no-op stubs ++#if (defined(__OpenBSD__) || defined(__NetBSD__)) && defined(__PLATFORM_LINUX__) ++void Hid_init() {} ++void Hid_quit() {} ++void Joystick_init() {} ++void Joystick_quit() {} ++int Joystick_count() { return 0; } ++int Joystick_open(int) { return -1; } ++int Joystick_close(int) { return -1; } ++const char * Joystick_name(int) { return NULL; } ++void Keyboard_init() {} ++void Keyboard_quit() {} ++int Keyboard_count() { return 0; } ++int Keyboard_open(int) { return -1; } ++int Keyboard_close(int) { return -1; } ++const char * Keyboard_name(int) { return NULL; } ++void Mouse_init() {} ++void Mouse_quit() {} ++int Mouse_count() { return 0; } ++int Mouse_open(int) { return -1; } ++int Mouse_close(int) { return -1; } ++const char * Mouse_name(int) { return NULL; } ++void Hid_poll() {} ++t_CKINT TiltSensor_setPollRate(t_CKINT) { return 0; } ++t_CKINT TiltSensor_getPollRate() { return 0; } ++#endif // OpenBSD/NetBSD stubs ++ ++ + #ifdef __PLATFORM_WINDOWS__ + + // multiple monitors info: +@@ -7904,7 +7932,7 @@ t_CKVEC2 ck_get_mouse_xy_normalize() + + // t_CKFLOAT screenWidth = GetSystemMetrics( SM_CXVIRTUALSCREEN ); + // t_CKFLOAT screenHeight = GetSystemMetrics( SM_CYVIRTUALSCREEN ); +-#elif defined(__PLATFORM_LINUX__) ++#elif defined(__PLATFORM_LINUX__) && !defined(__OpenBSD__) && !defined(__NetBSD__) + + #if defined(__USE_X11__) + // stuff to query +@@ -7973,7 +8001,7 @@ t_CKVEC2 ck_get_mouse_xy_absolute() + retval.x = pt.x; + retval.y = pt.y; + } +-#elif defined(__PLATFORM_LINUX__) ++#elif defined(__PLATFORM_LINUX__) && !defined(__OpenBSD__) && !defined(__NetBSD__) + + #if defined(__USE_X11__) + // stuff to query diff --git a/audio/chuck/patches/patch-src_core_util_math_cpp b/audio/chuck/patches/patch-src_core_util_math_cpp new file mode 100644 index 0000000..7c39fb4 --- /dev/null +++ b/audio/chuck/patches/patch-src_core_util_math_cpp @@ -0,0 +1,148 @@ +Index: src/core/util_math.cpp +--- src/core/util_math.cpp.orig ++++ src/core/util_math.cpp +@@ -368,5 +368,143 @@ t_CKFLOAT ck_vec3_magnitude( const t_CKVEC3 & v ) + //----------------------------------------------------------------------------- + t_CKFLOAT ck_vec4_magnitude( const t_CKVEC4 & v ) + { +- return ::sqrt( v.x*v.x + v.y*v.y + v.z*v.z + v.w*v.w ); ++ return ::sqrt( v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w ); ++} ++ ++ ++ ++ ++//----------------------------------------------------------------------------- ++// name: ck_factorial32() ++// desc: factorial calculator function (for 32 bit) ++// author: everett m. carpenter | 1.5.5.8 ++// modified for 32-bit (ge, nick) ++//----------------------------------------------------------------------------- ++t_CKINT ck_factorial32( t_CKINT n ) ++{ ++ // 12! is the largest factorial that can fit in a 32-bit integer ++ if( n < 0 || n > 12 ) return -1; ++ ++ t_CKINT result = 1; ++ for( t_CKINT i = 1; i <= n; i++ ) ++ { result = i * result; } ++ ++ return result; ++} ++ ++ ++ ++ ++//----------------------------------------------------------------------------- ++// name: ck_associated_legendre() ++// desc: closed form associated legendre polynomials of some order l ++// author: everett m. carpenter | 1.5.5.8 ++//----------------------------------------------------------------------------- ++t_CKFLOAT ck_associated_legendre( const t_CKINT m, const t_CKINT l, const t_CKFLOAT x ) ++{ ++ // check bounds ++ if (l < 0 || l > 5) return 0.0; ++ if (abs(m) > l) return 0.0; ++ ++ float x2 = x * x; // x^2 ++ float x3 = x2 * x; // x^3 ++ float x4 = x2 * x2; // x^4 ++ float cf = 1.0 - x2; // pops up in every associated legendre ++ float sqrtcf = sqrt(cf);; // also pops up everywhere ++ t_CKINT absm = abs(m); // assume m is positive, then apply -m case at end ++ float result = 0.f; ++ float flip = 1.f; ++ ++ if (m < 0) flip = (float)(pow(-1.0, absm) * (ck_factorial32(l - absm) / ck_factorial32(l + absm))); ++ ++ switch (l) // order and absm ++ { ++ case(0): ++ { result = 1.0; break; } ++ case(1): ++ { ++ if (absm == 0) { result = x; } ++ else if (absm == 1) { result = -sqrtcf; } ++ break; ++ } ++ case(2): ++ { ++ if (absm == 0) { result = 0.5 * (3.0 * x2 - 1); } ++ else if (absm == 1) { result = -3.0 * x * sqrtcf; } ++ else if (absm == 2) { result = 3.0 * cf; } ++ break; ++ } ++ case(3): ++ { ++ if (absm == 0) { result = 0.5 * (5.0 * x3 - 3.0 * x); } ++ else if (absm == 1) { result = 1.5 * (1.0 - 5.0 * x2) * sqrtcf; } ++ else if (absm == 2) { result = 15.0 * x * cf; } ++ else if (absm == 3) { result = -15.0 * sqrtcf * cf; } ++ break; ++ } ++ case(4): ++ { ++ if (absm == 0) { result = 0.125 * (35.0 * x4 - 30.0 * x2 + 3.0); } ++ else if (absm == 1) { result = -2.5 * (7.0 * x3 - 3.0 * x) * sqrtcf; } ++ else if (absm == 2) { result = 7.5 * (7.0 * x2 - 1) * cf; } ++ else if (absm == 3) { result = -105.0 * x * sqrtcf * cf; } ++ else if (absm == 4) { result = 105.0 * cf * cf; } ++ break; ++ } ++ case(5): ++ { ++ if (absm == 0) { result = 0.125 * (63.0 * x3 * x2 - 70 * x3 + 15 * x); } ++ else if (absm == 1) { result = -1.875 * sqrtcf * (21.0 * x4 - 14 * x2 + 1); } ++ else if (absm == 2) { result = 52.5 * x * cf * (3.0 * x2 - 1.0); } ++ else if (absm == 3) { result = -52.5 * cf * sqrtcf * (9.0 * x2 - 1.0); } ++ else if (absm == 4) { result = 945.0 * x * cf * cf; } ++ else if (absm == 5) { result = -945.0 * sqrtcf * cf * cf; } ++ break; ++ } ++ } ++ ++ return pow(-1.0, m) * result * flip; ++} ++ ++ ++ ++ ++//----------------------------------------------------------------------------- ++// name: ck_SN3D ++// desc: normalization calculator for spherical harmonics ++// author: everett m. carpenter | 1.5.5.8 ++//----------------------------------------------------------------------------- ++t_CKFLOAT ck_SN3D( const t_CKUINT order, const t_CKINT degree ) // calculate SN3D value ++{ ++ int d = (degree == 0) ? 1 : 0; // kronecker delta ++ float ratio = static_cast(ck_factorial32(order - abs(degree))) / static_cast(ck_factorial32(order + abs(degree))); // ratio of factorials ++ return sqrtf((2.f - d) * ratio); ++} ++ ++ ++ ++ ++//----------------------------------------------------------------------------- ++// name: ck_SH() ++// desc: calculation of spherical harmonics according to some order and normalization ++// author: everett m. carpenter | 1.5.5.8 ++//----------------------------------------------------------------------------- ++void ck_SH( t_CKFLOAT * output, const t_CKUINT order_, const t_CKFLOAT azimuth_, const t_CKFLOAT zenith_, const t_CKBOOL n3d ) ++{ ++ float azimuth_shift = (azimuth_) * 0.01745329252; // degree 2 rad ++ float zenith_shift = (90.f - zenith_) * 0.01745329252; ++ float coszeni = cosf(zenith_shift); ++ t_CKINT size = (order_ + 1) * (order_ + 1); ++ for (int order = 0; order <= (int)order_; order++) ++ { ++ if (order == 0) ++ output[0] = ck_SN3D(order, 0); ++ for (int degree = -order; degree <= order; degree++) ++ { ++ float n = n3d ? sqrtf(2 * order + 1) * ck_SN3D(order, degree) : ck_SN3D(order, degree); // normalization term if n3d bool = TRUE, return N3D else SN3D ++ float p = (ck_associated_legendre((int)abs(degree), (int)order, coszeni)); ++ float r = (degree < 0) ? sinf(abs(degree) * (azimuth_shift)) : cosf(degree * (azimuth_shift)); // degree positive? Re(exp(i*azimuth*degree)) degree negative? Im(exp(i*azimuth*degree)) ++ output[(order * order) + order + degree] = n * p * r; ++ } ++ } + } diff --git a/audio/chuck/patches/patch-src_core_util_math_h b/audio/chuck/patches/patch-src_core_util_math_h new file mode 100644 index 0000000..307eb81 --- /dev/null +++ b/audio/chuck/patches/patch-src_core_util_math_h @@ -0,0 +1,18 @@ +Index: src/core/util_math.h +--- src/core/util_math.h.orig ++++ src/core/util_math.h +@@ -112,8 +112,12 @@ t_CKFLOAT ck_vec2_phase( const t_CKVEC2 & v ); + t_CKFLOAT ck_vec3_magnitude( const t_CKVEC3 & v ); + // magnitude of vec4 + t_CKFLOAT ck_vec4_magnitude( const t_CKVEC4 & v ); +- +- ++// integer factorial (for up to 12! which is the largest factorial that can fit inside a 32-bit integer) ++t_CKINT ck_factorial32( t_CKINT n ); ++// associated legendre for spherical harmonics | (added) 1.5.5.8 by everett 2026 ++t_CKFLOAT ck_associated_legendre( const t_CKINT m, const t_CKINT l, const t_CKFLOAT x ); ++// spherical harmonics | (added) 1.5.5.8 by everett 2026 ++void ck_SH( t_CKFLOAT* output, const t_CKUINT order_, const t_CKFLOAT azimuth_, const t_CKFLOAT zenith_, const t_CKBOOL n3d ); + + #if defined (__cplusplus) || defined(_cplusplus) + } diff --git a/audio/chuck/patches/patch-src_core_util_network_c b/audio/chuck/patches/patch-src_core_util_network_c new file mode 100644 index 0000000..c9607bc --- /dev/null +++ b/audio/chuck/patches/patch-src_core_util_network_c @@ -0,0 +1,21 @@ +Index: src/core/util_network.c +--- src/core/util_network.c.orig ++++ src/core/util_network.c +@@ -173,7 +173,7 @@ t_CKBOOL ck_connect( ck_socket sock, const char * host + t_CKINT ret; + struct hostent * host; + +-#ifdef __PLATFORM_WINDOWS__ ++#if defined( __PLATFORM_WINDOWS__ ) || defined( __ANDROID__ ) + memset( &sock->sock_in, 0, sizeof(struct sockaddr_in) ); + #else + bzero( &sock->sock_in, sizeof(struct sockaddr_in) ); +@@ -218,7 +218,7 @@ t_CKBOOL ck_bind( ck_socket sock, int port ) + { + int ret; + +-#ifdef __PLATFORM_WINDOWS__ ++#if defined( __PLATFORM_WINDOWS__ ) || defined( __ANDROID__ ) + memset( &sock->sock_in, 0, sizeof(struct sockaddr_in) ); + #else + bzero( &sock->sock_in, sizeof(struct sockaddr_in) ); diff --git a/audio/chuck/patches/patch-src_core_util_platforms_cpp b/audio/chuck/patches/patch-src_core_util_platforms_cpp new file mode 100644 index 0000000..122f5b1 --- /dev/null +++ b/audio/chuck/patches/patch-src_core_util_platforms_cpp @@ -0,0 +1,12 @@ +Index: src/core/util_platforms.cpp +--- src/core/util_platforms.cpp.orig ++++ src/core/util_platforms.cpp +@@ -461,7 +461,7 @@ int ck_gettimeofday( long * tv_sec, long * tv_usec, vo + // timeval + timeval tv; + // call on through +- int retval = gettimeofday( &tv, tzp ); ++ int retval = gettimeofday( &tv, (struct timezone *)tzp ); + // check it + if( retval ) return retval; + // set return values diff --git a/audio/chuck/patches/patch-src_core_util_platforms_h b/audio/chuck/patches/patch-src_core_util_platforms_h new file mode 100644 index 0000000..7924338 --- /dev/null +++ b/audio/chuck/patches/patch-src_core_util_platforms_h @@ -0,0 +1,12 @@ +Index: src/core/util_platforms.h +--- src/core/util_platforms.h.orig ++++ src/core/util_platforms.h +@@ -102,7 +102,7 @@ int ck_gettimeofday( long * tv_sec, long * tv_usec, vo + #define CHUCK_PLATFORM_STRING "android" + #elif defined(__PLATFORM_CYGWIN__) + #define CHUCK_PLATFORM_STRING "cygwin" // not sure if needed, as cygwin implies windows +-#elif ++#else + #define CHUCK_PLATFORM_STRING "unknown" + #endif + diff --git a/audio/chuck/patches/patch-src_core_util_string_cpp b/audio/chuck/patches/patch-src_core_util_string_cpp new file mode 100644 index 0000000..cf10fb3 --- /dev/null +++ b/audio/chuck/patches/patch-src_core_util_string_cpp @@ -0,0 +1,42 @@ +Index: src/core/util_string.cpp +--- src/core/util_string.cpp.orig ++++ src/core/util_string.cpp +@@ -570,18 +570,26 @@ t_CKBOOL extract_args( const string & token, + //----------------------------------------------------------------------------- + #if !defined(__PLATFORM_WINDOWS__) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !defined(__CHIP_MODE__) + ++#include ++#if !defined(__OpenBSD__) && !defined(__NetBSD__) + #include ++#endif + //----------------------------------------------------------------------------- + // name: expandTildePath() + // desc: expand ~ path, does not care whether path is valid or not + //----------------------------------------------------------------------------- + std::string expandTildePath( const std::string & path ) + { ++ std::string exp; ++#if defined(__OpenBSD__) || defined(__NetBSD__) ++ // wordexp not available; use glob with GLOB_TILDE for tilde expansion ++ glob_t g; ++ if( glob(path.c_str(), GLOB_TILDE | GLOB_NOCHECK, NULL, &g) == 0 && g.gl_pathc > 0 ) ++ exp = g.gl_pathv[0]; ++ globfree( &g ); ++#else + // wordexp result + wordexp_t we; +- // the result +- std::string exp; +- + // "perform shell-style word expansions" + if( wordexp(path.c_str(), &we, 0 ) == 0 ) // success + { +@@ -594,7 +602,7 @@ std::string expandTildePath( const std::string & path + // free up + wordfree( &we ); + } +- ++#endif + // if still empty for any reason, default to original + if( exp == "" ) exp = path; + diff --git a/audio/chuck/patches/patch-src_core_util_thread_cpp b/audio/chuck/patches/patch-src_core_util_thread_cpp new file mode 100644 index 0000000..9cbd6ec --- /dev/null +++ b/audio/chuck/patches/patch-src_core_util_thread_cpp @@ -0,0 +1,113 @@ +Index: src/core/util_thread.cpp +--- src/core/util_thread.cpp.orig ++++ src/core/util_thread.cpp +@@ -66,7 +66,8 @@ XThread::XThread( ) + //----------------------------------------------------------------------------- + XThread::~XThread( ) + { +-#if defined(__PLATFORM_APPLE__) || defined(__PLATFORM_LINUX__) || defined(__WINDOWS_PTHREAD__) ++ // 1.5.5.8 (ben, ge) added emscripten since it uses POSIX ++#if defined(__PLATFORM_APPLE__) || defined(__PLATFORM_LINUX__) || defined(__WINDOWS_PTHREAD__) || defined(__PLATFORM_EMSCRIPTEN__) + // can't self-terminate (much like the Terminator) + bool is_self_thread = (thread == pthread_self()); + #elif defined(__PLATFORM_WINDOWS__) +@@ -78,7 +79,8 @@ XThread::~XThread( ) + if( thread != 0 && !is_self_thread ) + { + // TODO: find an alternative for Android? +-#if defined(__PLATFORM_APPLE__) || ( defined(__PLATFORM_LINUX__) && !defined(__ANDROID__) ) || defined(__WINDOWS_PTHREAD__) ++ // 1.5.5.8 (ben, ge) added emscripten since it uses POSIX ++#if defined(__PLATFORM_APPLE__) || ( defined(__PLATFORM_LINUX__) && !defined(__ANDROID__) ) || defined(__WINDOWS_PTHREAD__) || defined(__PLATFORM_EMSCRIPTEN__) + // log + EM_log( CK_LOG_FINER, "cancelling thread [0x%x] from [0x%x]...", getID(thread), getID(pthread_self()) ); + pthread_cancel(thread); +@@ -104,7 +106,8 @@ bool XThread::start( THREAD_FUNCTION routine, void * p + { + bool result = false; + +-#if ( defined(__PLATFORM_APPLE__) || defined(__PLATFORM_LINUX__) || defined(__WINDOWS_PTHREAD__) ) ++ // 1.5.5.8 (ben, ge) added emscripten since it uses POSIX ++#if defined(__PLATFORM_APPLE__) || defined(__PLATFORM_LINUX__) || defined(__WINDOWS_PTHREAD__) || defined(__PLATFORM_EMSCRIPTEN__) + if( pthread_create( &thread, NULL, *routine, ptr ) == 0 ) + { + EM_log( CK_LOG_FINER, "starting thread [0x%x] from [0x%x]...", thread, getID(pthread_self()) ); +@@ -134,7 +137,8 @@ bool XThread::wait( long milliseconds, bool cancel ) + bool result = false; + + // TODO: find an alternative for Android? +-#if( defined(__PLATFORM_APPLE__) || ( defined(__PLATFORM_LINUX__) && !defined(__ANDROID__) ) || defined(__WINDOWS_PTHREAD__) ) ++ // 1.5.5.8 (ben, ge) added emscripten since it uses POSIX ++#if defined(__PLATFORM_APPLE__) || ( defined(__PLATFORM_LINUX__) && !defined(__ANDROID__) ) || defined(__WINDOWS_PTHREAD__) || defined(__PLATFORM_EMSCRIPTEN__) + // cancel the thread? + if( cancel ) pthread_cancel( thread ); + // wait for the thread to terminate +@@ -164,7 +168,8 @@ bool XThread::wait( long milliseconds, bool cancel ) + void XThread :: test( ) + { + // TODO: find an alternative for Android? +-#if ( defined(__PLATFORM_APPLE__) || ( defined(__PLATFORM_LINUX__) && !defined(__ANDROID__) ) || defined(__WINDOWS_PTHREAD__) ) ++ // 1.5.5.8 (ben, ge) added emscripten since it uses POSIX ++#if defined(__PLATFORM_APPLE__) || ( defined(__PLATFORM_LINUX__) && !defined(__ANDROID__) ) || defined(__WINDOWS_PTHREAD__) || defined(__PLATFORM_EMSCRIPTEN__) + pthread_testcancel(); + #endif + } +@@ -178,7 +183,8 @@ void XThread :: test( ) + //----------------------------------------------------------------------------- + t_CKUINT XThread::getID( THREAD_HANDLE t ) + { +-#if ( defined(__PLATFORM_APPLE__) || defined(__PLATFORM_LINUX__) || defined(__WINDOWS_PTHREAD__) ) ++ // 1.5.5.8 (ben, ge) added emscripten since it uses POSIX ++#if defined(__PLATFORM_APPLE__) || defined(__PLATFORM_LINUX__) || defined(__WINDOWS_PTHREAD__) || defined(__PLATFORM_EMSCRIPTEN__) + return (t_CKUINT)t; + #elif defined(__PLATFORM_WINDOWS__) + return (t_CKUINT)GetThreadId( (HANDLE)t ); +@@ -194,7 +200,8 @@ t_CKUINT XThread::getID( THREAD_HANDLE t ) + //----------------------------------------------------------------------------- + XMutex::XMutex( ) + { +-#if ( defined(__PLATFORM_APPLE__) || defined(__PLATFORM_LINUX__) || defined(__WINDOWS_PTHREAD__) ) ++ // 1.5.5.8 (ben, ge) added emscripten since it uses POSIX ++#if defined(__PLATFORM_APPLE__) || defined(__PLATFORM_LINUX__) || defined(__WINDOWS_PTHREAD__) || defined(__PLATFORM_EMSCRIPTEN__) + pthread_mutex_init(&mutex, NULL); + #elif defined(__PLATFORM_WINDOWS__) + InitializeCriticalSection(&mutex); +@@ -210,7 +217,8 @@ XMutex::XMutex( ) + //----------------------------------------------------------------------------- + XMutex::~XMutex( ) + { +-#if ( defined(__PLATFORM_APPLE__) || defined(__PLATFORM_LINUX__) || defined(__WINDOWS_PTHREAD__) ) ++ // 1.5.5.8 (ben, ge) added emscripten since it uses POSIX ++#if defined(__PLATFORM_APPLE__) || defined(__PLATFORM_LINUX__) || defined(__WINDOWS_PTHREAD__) || defined(__PLATFORM_EMSCRIPTEN__) + pthread_mutex_destroy( &mutex ); + #elif defined(__PLATFORM_WINDOWS__) + DeleteCriticalSection(&mutex); +@@ -226,7 +234,8 @@ XMutex::~XMutex( ) + //----------------------------------------------------------------------------- + void XMutex::acquire( ) + { +-#if ( defined(__PLATFORM_APPLE__) || defined(__PLATFORM_LINUX__) || defined(__WINDOWS_PTHREAD__) ) ++ // 1.5.5.8 (ben, ge) added emscripten since it uses POSIX ++#if defined(__PLATFORM_APPLE__) || defined(__PLATFORM_LINUX__) || defined(__WINDOWS_PTHREAD__) || defined(__PLATFORM_EMSCRIPTEN__) + pthread_mutex_lock(&mutex); + #elif defined(__PLATFORM_WINDOWS__) + EnterCriticalSection(&mutex); +@@ -242,7 +251,8 @@ void XMutex::acquire( ) + //----------------------------------------------------------------------------- + void XMutex::release( ) + { +-#if ( defined(__PLATFORM_APPLE__) || defined(__PLATFORM_LINUX__) || defined(__WINDOWS_PTHREAD__) ) ++ // 1.5.5.8 (ben, ge) added emscripten since it uses POSIX ++#if defined(__PLATFORM_APPLE__) || defined(__PLATFORM_LINUX__) || defined(__WINDOWS_PTHREAD__) || defined(__PLATFORM_EMSCRIPTEN__) + pthread_mutex_unlock(&mutex); + #elif defined(__PLATFORM_WINDOWS__) + LeaveCriticalSection(&mutex); +@@ -440,7 +450,8 @@ void XWriteThread::flush_data_buffer() + // name: write_cb() + // desc: thread function + //----------------------------------------------------------------------------- +-#if ( defined(__PLATFORM_APPLE__) || defined(__PLATFORM_LINUX__) || defined(__WINDOWS_PTHREAD__) ) ++// 1.5.5.8 (ben, ge) added emscripten since it uses POSIX ++#if defined(__PLATFORM_APPLE__) || defined(__PLATFORM_LINUX__) || defined(__WINDOWS_PTHREAD__) || defined(__PLATFORM_EMSCRIPTEN__) + void * XWriteThread::write_cb(void * _thiss) + #elif defined(__PLATFORM_WINDOWS__) + unsigned XWriteThread::write_cb(void * _thiss) diff --git a/audio/chuck/patches/patch-src_core_util_thread_h b/audio/chuck/patches/patch-src_core_util_thread_h new file mode 100644 index 0000000..bb1cf4a --- /dev/null +++ b/audio/chuck/patches/patch-src_core_util_thread_h @@ -0,0 +1,22 @@ +Index: src/core/util_thread.h +--- src/core/util_thread.h.orig ++++ src/core/util_thread.h +@@ -44,7 +44,8 @@ class FastCircularBuffer; + template class CircularBuffer; + + +-#if ( defined(__PLATFORM_APPLE__) || defined(__PLATFORM_LINUX__) || defined(__WINDOWS_PTHREAD__) ) ++#if defined(__PLATFORM_APPLE__) || defined(__PLATFORM_LINUX__) || defined(__WINDOWS_PTHREAD__) || defined(__PLATFORM_EMSCRIPTEN__) ++ // 1.5.5.8 (ben, ge) added emscripten above since it uses POSIX + #include + #define THREAD_TYPE + typedef pthread_t THREAD_HANDLE; +@@ -188,7 +189,7 @@ class XWriteThread (private) + void flush_data_buffer(); + + // callback +-#if ( defined(__PLATFORM_APPLE__) || defined(__PLATFORM_LINUX__) || defined(__WINDOWS_PTHREAD__) ) ++#if defined(__PLATFORM_APPLE__) || defined(__PLATFORM_LINUX__) || defined(__WINDOWS_PTHREAD__) || defined(__PLATFORM_EMSCRIPTEN__) + static void * write_cb( void * _thiss ); + #elif defined(__PLATFORM_WINDOWS__) + static unsigned THREAD_TYPE write_cb( void * _thiss ); diff --git a/audio/chuck/patches/patch-src_host_RtAudio_RtAudio_cpp b/audio/chuck/patches/patch-src_host_RtAudio_RtAudio_cpp new file mode 100644 index 0000000..1d81d11 --- /dev/null +++ b/audio/chuck/patches/patch-src_host_RtAudio_RtAudio_cpp @@ -0,0 +1,631 @@ +Index: src/host/RtAudio/RtAudio.cpp +--- src/host/RtAudio/RtAudio.cpp.orig ++++ src/host/RtAudio/RtAudio.cpp +@@ -109,6 +109,7 @@ const char* rtaudio_api_names[][2] = { + { "alsa" , "ALSA" }, + { "pulse" , "Pulse" }, + { "oss" , "OpenSoundSystem" }, ++ { "sndio" , "sndio" }, + { "jack" , "Jack" }, + { "core" , "CoreAudio" }, + { "wasapi" , "WASAPI" }, +@@ -135,6 +136,9 @@ extern "C" const RtAudio::Api rtaudio_compiled_apis[] + #if defined(__LINUX_OSS__) + RtAudio::LINUX_OSS, + #endif ++#if defined(__OPENBSD_SNDIO__) ++ RtAudio::OPENBSD_SNDIO, ++#endif + #if defined(__WINDOWS_ASIO__) + RtAudio::WINDOWS_ASIO, + #endif +@@ -216,6 +220,10 @@ void RtAudio :: openRtApi( RtAudio::Api api ) + if ( api == LINUX_OSS ) + rtapi_ = new RtApiOss(); + #endif ++#if defined(__OPENBSD_SNDIO__) ++ if ( api == OPENBSD_SNDIO ) ++ rtapi_ = new RtApiSndio(); ++#endif + #if defined(__WINDOWS_ASIO__) + if ( api == WINDOWS_ASIO ) + rtapi_ = new RtApiAsio(); +@@ -10387,6 +10395,598 @@ static void *ossCallbackHandler( void *ptr ) + //******************** End of __LINUX_OSS__ *********************// + #endif + ++#if defined(__OPENBSD_SNDIO__) ++ ++#include ++#include ++#include ++#include ++ ++static void *sndioCallbackHandler( void *ptr ); ++ ++struct SndioHandle { ++ struct sio_hdl *handle; ++ bool xrun[2]; // [0]=output underflow, [1]=input overflow ++ ++ SndioHandle() : handle(nullptr) { xrun[0] = false; xrun[1] = false; } ++}; ++ ++static void sndioXrunCb( void *arg ) ++{ ++ SndioHandle *h = (SndioHandle *) arg; ++ h->xrun[0] = true; ++ h->xrun[1] = true; ++} ++ ++RtApiSndio :: RtApiSndio() {} ++ ++RtApiSndio :: ~RtApiSndio() ++{ ++ if ( stream_.state != STREAM_CLOSED ) closeStream(); ++} ++ ++unsigned int RtApiSndio :: getDeviceCount( void ) ++{ ++ return 1; ++} ++ ++RtAudio::DeviceInfo RtApiSndio :: getDeviceInfo( unsigned int device ) ++{ ++ RtAudio::DeviceInfo info; ++ info.probed = false; ++ ++ if ( device != 0 ) { ++ errorText_ = "RtApiSndio::getDeviceInfo: invalid device ID!"; ++ error( RTAUDIO_INVALID_DEVICE ); ++ return info; ++ } ++ ++ // Advertise default capabilities; actual negotiation happens in probeDeviceOpen. ++ // We do not require sndiod to be running at probe time. ++ info.name = "sndio default"; ++ info.outputChannels = 2; ++ info.inputChannels = 2; ++ info.duplexChannels = 2; ++ info.isDefaultOutput = true; ++ info.isDefaultInput = true; ++ ++ // sndio accepts most standard sample rates ++ static const unsigned int rates[] = { ++ 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200, 96000, 0 ++ }; ++ for ( int i = 0; rates[i]; i++ ) { ++ info.sampleRates.push_back( rates[i] ); ++ if ( rates[i] == 48000 ) ++ info.preferredSampleRate = 48000; ++ } ++ ++ info.nativeFormats = RTAUDIO_SINT16 | RTAUDIO_SINT32; ++ info.probed = true; ++ return info; ++} ++ ++bool RtApiSndio :: probeDeviceOpen( unsigned int device, StreamMode mode, ++ unsigned int channels, ++ unsigned int firstChannel, ++ unsigned int sampleRate, ++ RtAudioFormat format, ++ unsigned int *bufferSize, ++ RtAudio::StreamOptions *options ) ++{ ++ if ( device != 0 ) { ++ errorText_ = "RtApiSndio::probeDeviceOpen: only device 0 is supported."; ++ return FAILURE; ++ } ++ if ( firstChannel != 0 ) { ++ errorText_ = "RtApiSndio::probeDeviceOpen: channel offset not supported."; ++ return FAILURE; ++ } ++ ++ SndioHandle *handle = (SndioHandle *) stream_.apiHandle; ++ ++ // When adding INPUT to an already-open OUTPUT stream (going duplex), reuse the ++ // existing play-only sndio handle instead of closing and reopening as ++ // SIO_PLAY|SIO_REC. sndiod's default sub-device ("-m play -s default") is ++ // play-only: a duplex open succeeds but the record clock never ticks, so ++ // sio_write stalls after the initial pre-fill. Keeping the play-only handle ++ // lets the poll-with-timeout path in callbackEvent() substitute silence for ++ // input without blocking. True duplex recording requires a sndiod sub-device ++ // configured with "-m play,rec" or "-m rec". ++ if ( mode == INPUT && stream_.mode == OUTPUT && handle && handle->handle ) { ++ // Set up INPUT bookkeeping using the same format/params as OUTPUT. ++ stream_.deviceFormat[INPUT] = stream_.deviceFormat[OUTPUT]; ++ stream_.nUserChannels[INPUT] = channels; ++ stream_.nDeviceChannels[INPUT] = channels; ++ stream_.deviceInterleaved[INPUT] = true; ++ ++ stream_.doConvertBuffer[INPUT] = false; ++ stream_.doByteSwap[INPUT] = false; ++ if ( stream_.userFormat != stream_.deviceFormat[INPUT] ) ++ stream_.doConvertBuffer[INPUT] = true; ++ if ( stream_.nUserChannels[INPUT] < stream_.nDeviceChannels[INPUT] ) ++ stream_.doConvertBuffer[INPUT] = true; ++ if ( stream_.userInterleaved != stream_.deviceInterleaved[INPUT] && ++ stream_.nUserChannels[INPUT] > 1 ) ++ stream_.doConvertBuffer[INPUT] = true; ++ ++ unsigned long bufBytes = stream_.nUserChannels[INPUT] * stream_.bufferSize * ++ formatBytes( stream_.userFormat ); ++ stream_.userBuffer[INPUT] = (char *) calloc( bufBytes, 1 ); ++ if ( !stream_.userBuffer[INPUT] ) { ++ errorText_ = "RtApiSndio::probeDeviceOpen: error allocating input buffer."; ++ return FAILURE; ++ } ++ ++ if ( stream_.doConvertBuffer[INPUT] ) { ++ unsigned long devBytes = stream_.nDeviceChannels[INPUT] * ++ formatBytes( stream_.deviceFormat[INPUT] ) * ++ stream_.bufferSize; ++ if ( !stream_.deviceBuffer || devBytes > ++ stream_.nDeviceChannels[OUTPUT] * formatBytes( stream_.deviceFormat[OUTPUT] ) ++ * stream_.bufferSize ) { ++ if ( stream_.deviceBuffer ) free( stream_.deviceBuffer ); ++ stream_.deviceBuffer = (char *) calloc( devBytes, 1 ); ++ if ( !stream_.deviceBuffer ) { ++ free( stream_.userBuffer[INPUT] ); ++ stream_.userBuffer[INPUT] = nullptr; ++ errorText_ = "RtApiSndio::probeDeviceOpen: error allocating device buffer."; ++ return FAILURE; ++ } ++ } ++ setConvertInfo( INPUT, firstChannel ); ++ } ++ ++ stream_.device[INPUT] = device; ++ stream_.mode = DUPLEX; ++ return SUCCESS; ++ } ++ ++ // Normal path: open a new sndio device handle. ++ unsigned int sioMode = ( mode == OUTPUT ) ? SIO_PLAY : SIO_REC; struct sio_hdl *hdl = sio_open( SIO_DEVANY, sioMode, 0 ); if ( !hdl ) { ++ errorText_ = "RtApiSndio::probeDeviceOpen: error opening sndio device."; ++ goto error; ++ } ++ ++ // Map RtAudio format to sndio encoding ++ stream_.userFormat = format; ++ { ++ unsigned int bits, bps; ++ ++ if ( format == RTAUDIO_SINT8 ) { ++ bits = 8; bps = 1; ++ stream_.deviceFormat[mode] = RTAUDIO_SINT8; ++ } else if ( format == RTAUDIO_SINT16 ) { ++ bits = 16; bps = 2; ++ stream_.deviceFormat[mode] = RTAUDIO_SINT16; ++ } else if ( format == RTAUDIO_SINT24 ) { ++ bits = 24; bps = 4; ++ stream_.deviceFormat[mode] = RTAUDIO_SINT24; ++ } else if ( format == RTAUDIO_SINT32 ) { ++ bits = 32; bps = 4; ++ stream_.deviceFormat[mode] = RTAUDIO_SINT32; ++ } else { ++ // Float formats not natively supported: use SINT16, RtAudio converts ++ bits = 16; bps = 2; ++ stream_.deviceFormat[mode] = RTAUDIO_SINT16; ++ } ++ ++ struct sio_par par; ++ sio_initpar( &par ); ++ par.bits = bits; ++ par.bps = bps; ++ par.sig = 1; ++ par.le = SIO_LE_NATIVE; ++ par.rate = sampleRate; ++ par.round = *bufferSize; ++ par.appbufsz = *bufferSize * 4; ++ par.pchan = ( mode == OUTPUT ) ? channels : 0; ++ par.rchan = ( mode == INPUT ) ? channels : 0; if ( !sio_setpar( hdl, &par ) ) { ++ sio_close( hdl ); ++ errorText_ = "RtApiSndio::probeDeviceOpen: error setting stream parameters."; ++ return FAILURE; ++ } if ( !sio_getpar( hdl, &par ) ) { ++ sio_close( hdl ); ++ errorText_ = "RtApiSndio::probeDeviceOpen: error getting stream parameters."; ++ return FAILURE; ++ } ++ ++ if ( par.rate != sampleRate ) { ++ sio_close( hdl ); ++ errorStream_ << "RtApiSndio::probeDeviceOpen: sample rate " << sampleRate ++ << " not supported (got " << par.rate << ")."; ++ errorText_ = errorStream_.str(); ++ return FAILURE; ++ } ++ ++ *bufferSize = par.round; ++ stream_.bufferSize = *bufferSize; ++ stream_.nBuffers = par.appbufsz / par.round; ++ stream_.sampleRate = sampleRate; ++ } // end format/par scope ++ ++ stream_.nUserChannels[mode] = channels; ++ stream_.nDeviceChannels[mode] = channels; ++ ++ stream_.userInterleaved = true; ++ stream_.deviceInterleaved[mode] = true; ++ if ( options && options->flags & RTAUDIO_NONINTERLEAVED ) ++ stream_.userInterleaved = false; ++ ++ stream_.doConvertBuffer[mode] = false; ++ stream_.doByteSwap[mode] = false; ++ if ( stream_.userFormat != stream_.deviceFormat[mode] ) ++ stream_.doConvertBuffer[mode] = true; ++ if ( stream_.nUserChannels[mode] < stream_.nDeviceChannels[mode] ) ++ stream_.doConvertBuffer[mode] = true; ++ if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] && ++ stream_.nUserChannels[mode] > 1 ) ++ stream_.doConvertBuffer[mode] = true; ++ ++ // Allocate or reuse SndioHandle ++ if ( !handle ) { ++ try { ++ handle = new SndioHandle; ++ } ++ catch ( std::bad_alloc& ) { ++ sio_close( hdl ); ++ errorText_ = "RtApiSndio::probeDeviceOpen: error allocating SndioHandle."; ++ goto error; ++ } ++ stream_.apiHandle = (void *) handle; ++ } ++ handle->handle = hdl; ++ sio_onxrun( hdl, sndioXrunCb, handle ); ++ ++ // Allocate user buffer ++ { ++ unsigned long bufBytes = stream_.nUserChannels[mode] * *bufferSize * ++ formatBytes( stream_.userFormat ); ++ stream_.userBuffer[mode] = (char *) calloc( bufBytes, 1 ); ++ if ( !stream_.userBuffer[mode] ) { ++ errorText_ = "RtApiSndio::probeDeviceOpen: error allocating user buffer."; ++ goto error; ++ } ++ } ++ ++ if ( stream_.doConvertBuffer[mode] ) { ++ bool makeBuffer = true; ++ unsigned long bufBytes = stream_.nDeviceChannels[mode] * ++ formatBytes( stream_.deviceFormat[mode] ); ++ if ( mode == INPUT ) { ++ if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) { ++ unsigned long bytesOut = stream_.nDeviceChannels[0] * ++ formatBytes( stream_.deviceFormat[0] ); ++ if ( bufBytes <= bytesOut ) makeBuffer = false; ++ } ++ } ++ if ( makeBuffer ) { ++ bufBytes *= *bufferSize; ++ if ( stream_.deviceBuffer ) free( stream_.deviceBuffer ); ++ stream_.deviceBuffer = (char *) calloc( bufBytes, 1 ); ++ if ( !stream_.deviceBuffer ) { ++ errorText_ = "RtApiSndio::probeDeviceOpen: error allocating device buffer."; ++ goto error; ++ } ++ } ++ } ++ ++ stream_.device[mode] = device; ++ stream_.state = STREAM_STOPPED; ++ ++ if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, firstChannel ); ++ ++ // Setup mode and callback thread ++ if ( stream_.mode == OUTPUT && mode == INPUT ) { ++ stream_.mode = DUPLEX; ++ } else { ++ stream_.mode = mode; ++ ++ stream_.callbackInfo.object = (void *) this; ++ ++ pthread_attr_t attr; ++ pthread_attr_init( &attr ); ++ pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE ); ++ pthread_attr_setschedpolicy( &attr, SCHED_OTHER ); ++ ++ stream_.callbackInfo.isRunning = true; ++ int result = pthread_create( &stream_.callbackInfo.thread, &attr, ++ sndioCallbackHandler, &stream_.callbackInfo ); ++ pthread_attr_destroy( &attr ); ++ if ( result ) { ++ stream_.callbackInfo.isRunning = false; ++ errorText_ = "RtApiSndio::probeDeviceOpen: error creating callback thread!"; ++ goto error; ++ } ++ } ++ ++ return SUCCESS; ++ ++ error: ++ // If a callback thread is already running (e.g., from a prior OUTPUT pass ++ // that succeeded before this INPUT/DUPLEX pass failed), stop it now so the ++ // thread doesn't access the handle after we free it below. ++ if ( stream_.callbackInfo.isRunning ) { ++ stream_.callbackInfo.isRunning = false; ++ // Thread spins in 5ms nanosleep when state != RUNNING; it will exit promptly. ++ pthread_join( stream_.callbackInfo.thread, nullptr ); ++ } ++ if ( handle ) { ++ if ( handle->handle ) sio_close( handle->handle ); ++ delete handle; ++ stream_.apiHandle = nullptr; ++ } ++ for ( int i = 0; i < 2; i++ ) { ++ if ( stream_.userBuffer[i] ) { ++ free( stream_.userBuffer[i] ); ++ stream_.userBuffer[i] = nullptr; ++ } ++ } ++ if ( stream_.deviceBuffer ) { ++ free( stream_.deviceBuffer ); ++ stream_.deviceBuffer = nullptr; ++ } ++ stream_.state = STREAM_CLOSED; ++ return FAILURE; ++} ++ ++void RtApiSndio :: closeStream() ++{ ++ if ( stream_.state == STREAM_CLOSED ) { ++ errorText_ = "RtApiSndio::closeStream(): no open stream to close!"; ++ error( RTAUDIO_WARNING ); ++ return; ++ } ++ ++ SndioHandle *handle = (SndioHandle *) stream_.apiHandle; ++ stream_.callbackInfo.isRunning = false; ++ ++ MUTEX_LOCK( &stream_.mutex ); ++ stream_.state = STREAM_CLOSED; ++ MUTEX_UNLOCK( &stream_.mutex ); ++ ++ // Join FIRST: thread may be in poll/sio_write (up to 23ms timeout). ++ // Only call sio_stop/sio_close after join; sio is not thread-safe. ++ pthread_join( stream_.callbackInfo.thread, nullptr ); ++ if ( handle ) { ++ if ( handle->handle ) { ++ sio_stop( handle->handle ); ++ sio_close( handle->handle ); ++ } ++ delete handle; ++ stream_.apiHandle = nullptr; ++ } ++ ++ for ( int i = 0; i < 2; i++ ) { ++ if ( stream_.userBuffer[i] ) { ++ free( stream_.userBuffer[i] ); ++ stream_.userBuffer[i] = nullptr; ++ } ++ } ++ if ( stream_.deviceBuffer ) { ++ free( stream_.deviceBuffer ); ++ stream_.deviceBuffer = nullptr; ++ } ++ ++ clearStreamInfo(); ++} ++ ++RtAudioErrorType RtApiSndio :: startStream() ++{ ++ if ( stream_.state != STREAM_STOPPED ) { ++ if ( stream_.state == STREAM_RUNNING ) ++ errorText_ = "RtApiSndio::startStream(): stream already running!"; ++ else ++ errorText_ = "RtApiSndio::startStream(): stream is stopping or closed!"; ++ return error( RTAUDIO_WARNING ); ++ } ++ ++ SndioHandle *handle = (SndioHandle *) stream_.apiHandle; ++ ++ MUTEX_LOCK( &stream_.mutex ); if ( !sio_start( handle->handle ) ) { ++ MUTEX_UNLOCK( &stream_.mutex ); ++ errorText_ = "RtApiSndio::startStream(): error starting sndio stream."; ++ return error( RTAUDIO_SYSTEM_ERROR ); ++ } stream_.state = STREAM_RUNNING; ++ MUTEX_UNLOCK( &stream_.mutex ); ++ return RTAUDIO_NO_ERROR; ++} ++ ++RtAudioErrorType RtApiSndio :: stopStream() ++{ ++ if ( stream_.state != STREAM_RUNNING && stream_.state != STREAM_STOPPING ) { ++ if ( stream_.state == STREAM_STOPPED ) ++ errorText_ = "RtApiSndio::stopStream(): stream already stopped!"; ++ else ++ errorText_ = "RtApiSndio::stopStream(): stream is closed!"; ++ return error( RTAUDIO_WARNING ); ++ } ++ ++ MUTEX_LOCK( &stream_.mutex ); ++ ++ if ( stream_.state == STREAM_STOPPED ) { ++ MUTEX_UNLOCK( &stream_.mutex ); ++ return RTAUDIO_NO_ERROR; ++ } ++ ++ SndioHandle *handle = (SndioHandle *) stream_.apiHandle; ++ ++ // Do NOT call sio_stop() here: stopStream() may be called from any thread, ++ // including while the callback thread holds the sio handle in sio_write(). ++ // sio is not thread-safe; concurrent sio_stop()+sio_write() causes hangs. ++ // Instead, just set state=STOPPED; closeStream() calls sio_stop() after ++ // pthread_join() ensures no concurrent sio I/O. ++ stream_.state = STREAM_STOPPED; ++ MUTEX_UNLOCK( &stream_.mutex ); ++ return RTAUDIO_NO_ERROR; ++} ++ ++RtAudioErrorType RtApiSndio :: abortStream() ++{ ++ if ( stream_.state != STREAM_RUNNING ) { ++ if ( stream_.state == STREAM_STOPPED ) ++ errorText_ = "RtApiSndio::abortStream(): stream already stopped!"; ++ else ++ errorText_ = "RtApiSndio::abortStream(): stream is stopping or closed!"; ++ return error( RTAUDIO_WARNING ); ++ } ++ ++ MUTEX_LOCK( &stream_.mutex ); ++ // Same thread-safety rule as stopStream(): no sio_stop() here. ++ // closeStream() will call sio_stop() after pthread_join(). ++ stream_.state = STREAM_STOPPED; ++ MUTEX_UNLOCK( &stream_.mutex ); ++ return RTAUDIO_NO_ERROR; ++} ++ ++void RtApiSndio :: callbackEvent() ++{ ++ SndioHandle *handle = (SndioHandle *) stream_.apiHandle; ++ ++ if ( stream_.state == STREAM_STOPPED || stream_.state == STREAM_CLOSED ) { ++ // Spin-wait briefly when stopped to avoid busy-looping ++ struct timespec ts = { 0, 5000000 }; // 5 ms ++ nanosleep( &ts, nullptr ); ++ return; ++ } ++ ++ if ( stream_.state != STREAM_RUNNING ) return; ++ ++ // Invoke user callback ++ int doStopStream = 0; ++ RtAudioCallback callback = (RtAudioCallback) stream_.callbackInfo.callback; ++ double streamTime = getStreamTime(); ++ RtAudioStreamStatus status = 0; ++ if ( stream_.mode != INPUT && handle->xrun[0] ) { ++ status |= RTAUDIO_OUTPUT_UNDERFLOW; ++ handle->xrun[0] = false; ++ } ++ if ( stream_.mode != OUTPUT && handle->xrun[1] ) { ++ status |= RTAUDIO_INPUT_OVERFLOW; ++ handle->xrun[1] = false; ++ } ++ ++ { static int _cb_pre=0; if(++_cb_pre<=3) { fprintf(stderr,"[sndio-dbg] invoking user callback #%d\n",_cb_pre); fflush(stderr); } } ++ doStopStream = callback( stream_.userBuffer[0], stream_.userBuffer[1], ++ stream_.bufferSize, streamTime, status, ++ stream_.callbackInfo.userData ); ++ if ( doStopStream == 2 ) { ++ abortStream(); ++ return; ++ } ++ ++ // Perform I/O outside the mutex so closeStream() can set state and call ++ // sio_stop() to unblock a thread waiting in sio_read/sio_write. ++ if ( stream_.state != STREAM_RUNNING ) { ++ RtApi::tickStreamTime(); ++ return; ++ } ++ ++ { ++ char *buffer; ++ int samples; ++ RtAudioFormat format; ++ size_t nbytes, written; ++ ++ if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { ++ if ( stream_.doConvertBuffer[0] ) { ++ buffer = stream_.deviceBuffer; ++ convertBuffer( buffer, stream_.userBuffer[0], stream_.convertInfo[0] ); ++ samples = stream_.bufferSize * stream_.nDeviceChannels[0]; ++ format = stream_.deviceFormat[0]; ++ } else { ++ buffer = stream_.userBuffer[0]; ++ samples = stream_.bufferSize * stream_.nUserChannels[0]; ++ format = stream_.userFormat; ++ } ++ if ( stream_.doByteSwap[0] ) ++ byteSwapBuffer( buffer, samples, format ); ++ ++ nbytes = samples * formatBytes( format ); ++ ++ // Use poll with a timeout so sio_write() cannot block indefinitely. ++ // This is critical for clean shutdown: stopStream() calls sio_stop() ++ // which stops the device clock, so POLLOUT may never fire again after ++ // that point. Two buffer periods is plenty under normal operation. ++ { ++ int timeoutMs = (int)( 2000.0 * stream_.bufferSize / stream_.sampleRate ) + 10; ++ struct pollfd pfd[8]; ++ { static int _cb_n=0; if(++_cb_n<=5||_cb_n%100==0) { fprintf(stderr,"[sndio-dbg] callbackEvent #%d pre-poll\n",_cb_n); fflush(stderr); } } ++ int nfds = sio_pollfd( handle->handle, pfd, POLLOUT ); ++ int ready = ( nfds > 0 ) ? poll( pfd, nfds, timeoutMs ) : 0; ++ written = 0; ++ { static int _pb=0; if(++_pb<=10||_pb%50==0) { int rev = (ready>0)?sio_revents(handle->handle,pfd):0; fprintf(stderr,"[sndio-dbg] poll#%d nfds=%d ready=%d rev=0x%x POLLOUT=%d\n",_pb,nfds,ready,rev,!!(rev&POLLOUT)); fflush(stderr); } } ++ if ( ready > 0 && ( sio_revents( handle->handle, pfd ) & POLLOUT ) ) ++ written = sio_write( handle->handle, buffer, nbytes ); ++ } ++ if ( written != nbytes ) { ++ handle->xrun[0] = true; ++ errorText_ = "RtApiSndio::callbackEvent: audio write error."; ++ error( RTAUDIO_WARNING ); ++ } ++ } ++ ++ if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) { ++ if ( stream_.doConvertBuffer[1] ) { ++ buffer = stream_.deviceBuffer; ++ samples = stream_.bufferSize * stream_.nDeviceChannels[1]; ++ format = stream_.deviceFormat[1]; ++ } else { ++ buffer = stream_.userBuffer[1]; ++ samples = stream_.bufferSize * stream_.nUserChannels[1]; ++ format = stream_.userFormat; ++ } ++ ++ nbytes = samples * formatBytes( format ); ++ ++ // Use poll with a timeout so we don't block forever on play-only devices. ++ // Two buffer periods (in ms) is enough for normal operation. ++ int timeoutMs = (int)( 2000.0 * stream_.bufferSize / stream_.sampleRate ) + 10; ++ struct pollfd pfd[8]; ++ int nfds = sio_pollfd( handle->handle, pfd, POLLIN ); ++ int ready = ( nfds > 0 ) ? poll( pfd, nfds, timeoutMs ) : 0; ++ ++ size_t got = 0; ++ if ( ready > 0 && ( sio_revents( handle->handle, pfd ) & POLLIN ) ) ++ got = sio_read( handle->handle, buffer, nbytes ); ++ ++ if ( got != nbytes ) { ++ if ( got == 0 ) ++ memset( buffer, 0, nbytes ); // play-only device: substitute silence ++ else { ++ handle->xrun[1] = true; ++ errorText_ = "RtApiSndio::callbackEvent: audio read error."; ++ error( RTAUDIO_WARNING ); ++ } ++ } ++ if ( got > 0 ) { ++ if ( stream_.doByteSwap[1] ) ++ byteSwapBuffer( buffer, samples, format ); ++ if ( stream_.doConvertBuffer[1] ) ++ convertBuffer( stream_.userBuffer[1], stream_.deviceBuffer, stream_.convertInfo[1] ); ++ } ++ } ++ } ++ ++ RtApi::tickStreamTime(); ++ if ( doStopStream == 1 ) stopStream(); ++} ++ ++static void *sndioCallbackHandler( void *ptr ) ++{ ++ CallbackInfo *info = (CallbackInfo *) ptr; ++ RtApiSndio *object = (RtApiSndio *) info->object; ++ bool *isRunning = &info->isRunning; ++ ++ while ( *isRunning == true ) { ++ pthread_testcancel(); ++ object->callbackEvent(); ++ } ++ ++ pthread_exit( nullptr ); ++} ++ ++//******************** End of __OPENBSD_SNDIO__ *********************// ++#endif + + // *************************************************** // + // diff --git a/audio/chuck/patches/patch-src_host_RtAudio_RtAudio_cpp.orig b/audio/chuck/patches/patch-src_host_RtAudio_RtAudio_cpp.orig new file mode 100644 index 0000000..11b5188 --- /dev/null +++ b/audio/chuck/patches/patch-src_host_RtAudio_RtAudio_cpp.orig @@ -0,0 +1,627 @@ +Index: src/host/RtAudio/RtAudio.cpp +--- src/host/RtAudio/RtAudio.cpp.orig ++++ src/host/RtAudio/RtAudio.cpp +@@ -109,6 +109,7 @@ const char* rtaudio_api_names[][2] = { + { "alsa" , "ALSA" }, + { "pulse" , "Pulse" }, + { "oss" , "OpenSoundSystem" }, ++ { "sndio" , "sndio" }, + { "jack" , "Jack" }, + { "core" , "CoreAudio" }, + { "wasapi" , "WASAPI" }, +@@ -135,6 +136,9 @@ extern "C" const RtAudio::Api rtaudio_compiled_apis[] + #if defined(__LINUX_OSS__) + RtAudio::LINUX_OSS, + #endif ++#if defined(__OPENBSD_SNDIO__) ++ RtAudio::OPENBSD_SNDIO, ++#endif + #if defined(__WINDOWS_ASIO__) + RtAudio::WINDOWS_ASIO, + #endif +@@ -216,6 +220,10 @@ void RtAudio :: openRtApi( RtAudio::Api api ) + if ( api == LINUX_OSS ) + rtapi_ = new RtApiOss(); + #endif ++#if defined(__OPENBSD_SNDIO__) ++ if ( api == OPENBSD_SNDIO ) ++ rtapi_ = new RtApiSndio(); ++#endif + #if defined(__WINDOWS_ASIO__) + if ( api == WINDOWS_ASIO ) + rtapi_ = new RtApiAsio(); +@@ -10387,6 +10395,594 @@ static void *ossCallbackHandler( void *ptr ) + //******************** End of __LINUX_OSS__ *********************// + #endif + ++#if defined(__OPENBSD_SNDIO__) ++ ++#include ++#include ++#include ++#include ++ ++static void *sndioCallbackHandler( void *ptr ); ++ ++struct SndioHandle { ++ struct sio_hdl *handle; ++ bool xrun[2]; // [0]=output underflow, [1]=input overflow ++ ++ SndioHandle() : handle(nullptr) { xrun[0] = false; xrun[1] = false; } ++}; ++ ++static void sndioXrunCb( void *arg ) ++{ ++ SndioHandle *h = (SndioHandle *) arg; ++ h->xrun[0] = true; ++ h->xrun[1] = true; ++} ++ ++RtApiSndio :: RtApiSndio() {} ++ ++RtApiSndio :: ~RtApiSndio() ++{ ++ if ( stream_.state != STREAM_CLOSED ) closeStream(); ++} ++ ++unsigned int RtApiSndio :: getDeviceCount( void ) ++{ ++ return 1; ++} ++ ++RtAudio::DeviceInfo RtApiSndio :: getDeviceInfo( unsigned int device ) ++{ ++ RtAudio::DeviceInfo info; ++ info.probed = false; ++ ++ if ( device != 0 ) { ++ errorText_ = "RtApiSndio::getDeviceInfo: invalid device ID!"; ++ error( RTAUDIO_INVALID_DEVICE ); ++ return info; ++ } ++ ++ // Advertise default capabilities; actual negotiation happens in probeDeviceOpen. ++ // We do not require sndiod to be running at probe time. ++ info.name = "sndio default"; ++ info.outputChannels = 2; ++ info.inputChannels = 2; ++ info.duplexChannels = 2; ++ info.isDefaultOutput = true; ++ info.isDefaultInput = true; ++ ++ // sndio accepts most standard sample rates ++ static const unsigned int rates[] = { ++ 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200, 96000, 0 ++ }; ++ for ( int i = 0; rates[i]; i++ ) { ++ info.sampleRates.push_back( rates[i] ); ++ if ( rates[i] == 48000 ) ++ info.preferredSampleRate = 48000; ++ } ++ ++ info.nativeFormats = RTAUDIO_SINT16 | RTAUDIO_SINT32; ++ info.probed = true; ++ return info; ++} ++ ++bool RtApiSndio :: probeDeviceOpen( unsigned int device, StreamMode mode, ++ unsigned int channels, ++ unsigned int firstChannel, ++ unsigned int sampleRate, ++ RtAudioFormat format, ++ unsigned int *bufferSize, ++ RtAudio::StreamOptions *options ) ++{ ++ if ( device != 0 ) { ++ errorText_ = "RtApiSndio::probeDeviceOpen: only device 0 is supported."; ++ return FAILURE; ++ } ++ if ( firstChannel != 0 ) { ++ errorText_ = "RtApiSndio::probeDeviceOpen: channel offset not supported."; ++ return FAILURE; ++ } ++ ++ SndioHandle *handle = (SndioHandle *) stream_.apiHandle; ++ ++ // When adding INPUT to an already-open OUTPUT stream (going duplex), reuse the ++ // existing play-only sndio handle instead of closing and reopening as ++ // SIO_PLAY|SIO_REC. sndiod's default sub-device ("-m play -s default") is ++ // play-only: a duplex open succeeds but the record clock never ticks, so ++ // sio_write stalls after the initial pre-fill. Keeping the play-only handle ++ // lets the poll-with-timeout path in callbackEvent() substitute silence for ++ // input without blocking. True duplex recording requires a sndiod sub-device ++ // configured with "-m play,rec" or "-m rec". ++ if ( mode == INPUT && stream_.mode == OUTPUT && handle && handle->handle ) { ++ // Set up INPUT bookkeeping using the same format/params as OUTPUT. ++ stream_.deviceFormat[INPUT] = stream_.deviceFormat[OUTPUT]; ++ stream_.nUserChannels[INPUT] = channels; ++ stream_.nDeviceChannels[INPUT] = channels; ++ stream_.deviceInterleaved[INPUT] = true; ++ ++ stream_.doConvertBuffer[INPUT] = false; ++ stream_.doByteSwap[INPUT] = false; ++ if ( stream_.userFormat != stream_.deviceFormat[INPUT] ) ++ stream_.doConvertBuffer[INPUT] = true; ++ if ( stream_.nUserChannels[INPUT] < stream_.nDeviceChannels[INPUT] ) ++ stream_.doConvertBuffer[INPUT] = true; ++ if ( stream_.userInterleaved != stream_.deviceInterleaved[INPUT] && ++ stream_.nUserChannels[INPUT] > 1 ) ++ stream_.doConvertBuffer[INPUT] = true; ++ ++ unsigned long bufBytes = stream_.nUserChannels[INPUT] * stream_.bufferSize * ++ formatBytes( stream_.userFormat ); ++ stream_.userBuffer[INPUT] = (char *) calloc( bufBytes, 1 ); ++ if ( !stream_.userBuffer[INPUT] ) { ++ errorText_ = "RtApiSndio::probeDeviceOpen: error allocating input buffer."; ++ return FAILURE; ++ } ++ ++ if ( stream_.doConvertBuffer[INPUT] ) { ++ unsigned long devBytes = stream_.nDeviceChannels[INPUT] * ++ formatBytes( stream_.deviceFormat[INPUT] ) * ++ stream_.bufferSize; ++ if ( !stream_.deviceBuffer || devBytes > ++ stream_.nDeviceChannels[OUTPUT] * formatBytes( stream_.deviceFormat[OUTPUT] ) ++ * stream_.bufferSize ) { ++ if ( stream_.deviceBuffer ) free( stream_.deviceBuffer ); ++ stream_.deviceBuffer = (char *) calloc( devBytes, 1 ); ++ if ( !stream_.deviceBuffer ) { ++ free( stream_.userBuffer[INPUT] ); ++ stream_.userBuffer[INPUT] = nullptr; ++ errorText_ = "RtApiSndio::probeDeviceOpen: error allocating device buffer."; ++ return FAILURE; ++ } ++ } ++ setConvertInfo( INPUT, firstChannel ); ++ } ++ ++ stream_.device[INPUT] = device; ++ stream_.mode = DUPLEX; ++ return SUCCESS; ++ } ++ ++ // Normal path: open a new sndio device handle. ++ unsigned int sioMode = ( mode == OUTPUT ) ? SIO_PLAY : SIO_REC; struct sio_hdl *hdl = sio_open( SIO_DEVANY, sioMode, 0 ); if ( !hdl ) { ++ errorText_ = "RtApiSndio::probeDeviceOpen: error opening sndio device."; ++ goto error; ++ } ++ ++ // Map RtAudio format to sndio encoding ++ stream_.userFormat = format; ++ { ++ unsigned int bits, bps; ++ ++ if ( format == RTAUDIO_SINT8 ) { ++ bits = 8; bps = 1; ++ stream_.deviceFormat[mode] = RTAUDIO_SINT8; ++ } else if ( format == RTAUDIO_SINT16 ) { ++ bits = 16; bps = 2; ++ stream_.deviceFormat[mode] = RTAUDIO_SINT16; ++ } else if ( format == RTAUDIO_SINT24 ) { ++ bits = 24; bps = 4; ++ stream_.deviceFormat[mode] = RTAUDIO_SINT24; ++ } else if ( format == RTAUDIO_SINT32 ) { ++ bits = 32; bps = 4; ++ stream_.deviceFormat[mode] = RTAUDIO_SINT32; ++ } else { ++ // Float formats not natively supported: use SINT16, RtAudio converts ++ bits = 16; bps = 2; ++ stream_.deviceFormat[mode] = RTAUDIO_SINT16; ++ } ++ ++ struct sio_par par; ++ sio_initpar( &par ); ++ par.bits = bits; ++ par.bps = bps; ++ par.sig = 1; ++ par.le = SIO_LE_NATIVE; ++ par.rate = sampleRate; ++ par.round = *bufferSize; ++ par.appbufsz = *bufferSize * 4; ++ par.pchan = ( mode == OUTPUT ) ? channels : 0; ++ par.rchan = ( mode == INPUT ) ? channels : 0; if ( !sio_setpar( hdl, &par ) ) { ++ sio_close( hdl ); ++ errorText_ = "RtApiSndio::probeDeviceOpen: error setting stream parameters."; ++ return FAILURE; ++ } if ( !sio_getpar( hdl, &par ) ) { ++ sio_close( hdl ); ++ errorText_ = "RtApiSndio::probeDeviceOpen: error getting stream parameters."; ++ return FAILURE; ++ } ++ ++ if ( par.rate != sampleRate ) { ++ sio_close( hdl ); ++ errorStream_ << "RtApiSndio::probeDeviceOpen: sample rate " << sampleRate ++ << " not supported (got " << par.rate << ")."; ++ errorText_ = errorStream_.str(); ++ return FAILURE; ++ } ++ ++ *bufferSize = par.round; ++ stream_.bufferSize = *bufferSize; ++ stream_.nBuffers = par.appbufsz / par.round; ++ stream_.sampleRate = sampleRate; ++ } // end format/par scope ++ ++ stream_.nUserChannels[mode] = channels; ++ stream_.nDeviceChannels[mode] = channels; ++ ++ stream_.userInterleaved = true; ++ stream_.deviceInterleaved[mode] = true; ++ if ( options && options->flags & RTAUDIO_NONINTERLEAVED ) ++ stream_.userInterleaved = false; ++ ++ stream_.doConvertBuffer[mode] = false; ++ stream_.doByteSwap[mode] = false; ++ if ( stream_.userFormat != stream_.deviceFormat[mode] ) ++ stream_.doConvertBuffer[mode] = true; ++ if ( stream_.nUserChannels[mode] < stream_.nDeviceChannels[mode] ) ++ stream_.doConvertBuffer[mode] = true; ++ if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] && ++ stream_.nUserChannels[mode] > 1 ) ++ stream_.doConvertBuffer[mode] = true; ++ ++ // Allocate or reuse SndioHandle ++ if ( !handle ) { ++ try { ++ handle = new SndioHandle; ++ } ++ catch ( std::bad_alloc& ) { ++ sio_close( hdl ); ++ errorText_ = "RtApiSndio::probeDeviceOpen: error allocating SndioHandle."; ++ goto error; ++ } ++ stream_.apiHandle = (void *) handle; ++ } ++ handle->handle = hdl; ++ sio_onxrun( hdl, sndioXrunCb, handle ); ++ ++ // Allocate user buffer ++ { ++ unsigned long bufBytes = stream_.nUserChannels[mode] * *bufferSize * ++ formatBytes( stream_.userFormat ); ++ stream_.userBuffer[mode] = (char *) calloc( bufBytes, 1 ); ++ if ( !stream_.userBuffer[mode] ) { ++ errorText_ = "RtApiSndio::probeDeviceOpen: error allocating user buffer."; ++ goto error; ++ } ++ } ++ ++ if ( stream_.doConvertBuffer[mode] ) { ++ bool makeBuffer = true; ++ unsigned long bufBytes = stream_.nDeviceChannels[mode] * ++ formatBytes( stream_.deviceFormat[mode] ); ++ if ( mode == INPUT ) { ++ if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) { ++ unsigned long bytesOut = stream_.nDeviceChannels[0] * ++ formatBytes( stream_.deviceFormat[0] ); ++ if ( bufBytes <= bytesOut ) makeBuffer = false; ++ } ++ } ++ if ( makeBuffer ) { ++ bufBytes *= *bufferSize; ++ if ( stream_.deviceBuffer ) free( stream_.deviceBuffer ); ++ stream_.deviceBuffer = (char *) calloc( bufBytes, 1 ); ++ if ( !stream_.deviceBuffer ) { ++ errorText_ = "RtApiSndio::probeDeviceOpen: error allocating device buffer."; ++ goto error; ++ } ++ } ++ } ++ ++ stream_.device[mode] = device; ++ stream_.state = STREAM_STOPPED; ++ ++ if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, firstChannel ); ++ ++ // Setup mode and callback thread ++ if ( stream_.mode == OUTPUT && mode == INPUT ) { ++ stream_.mode = DUPLEX; ++ } else { ++ stream_.mode = mode; ++ ++ stream_.callbackInfo.object = (void *) this; ++ ++ pthread_attr_t attr; ++ pthread_attr_init( &attr ); ++ pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE ); ++ pthread_attr_setschedpolicy( &attr, SCHED_OTHER ); ++ ++ stream_.callbackInfo.isRunning = true; ++ int result = pthread_create( &stream_.callbackInfo.thread, &attr, ++ sndioCallbackHandler, &stream_.callbackInfo ); ++ pthread_attr_destroy( &attr ); ++ if ( result ) { ++ stream_.callbackInfo.isRunning = false; ++ errorText_ = "RtApiSndio::probeDeviceOpen: error creating callback thread!"; ++ goto error; ++ } ++ } ++ ++ return SUCCESS; ++ ++ error: ++ // If a callback thread is already running (e.g., from a prior OUTPUT pass ++ // that succeeded before this INPUT/DUPLEX pass failed), stop it now so the ++ // thread doesn't access the handle after we free it below. ++ if ( stream_.callbackInfo.isRunning ) { ++ stream_.callbackInfo.isRunning = false; ++ // Thread spins in 5ms nanosleep when state != RUNNING; it will exit promptly. ++ pthread_join( stream_.callbackInfo.thread, nullptr ); ++ } ++ if ( handle ) { ++ if ( handle->handle ) sio_close( handle->handle ); ++ delete handle; ++ stream_.apiHandle = nullptr; ++ } ++ for ( int i = 0; i < 2; i++ ) { ++ if ( stream_.userBuffer[i] ) { ++ free( stream_.userBuffer[i] ); ++ stream_.userBuffer[i] = nullptr; ++ } ++ } ++ if ( stream_.deviceBuffer ) { ++ free( stream_.deviceBuffer ); ++ stream_.deviceBuffer = nullptr; ++ } ++ stream_.state = STREAM_CLOSED; ++ return FAILURE; ++} ++ ++void RtApiSndio :: closeStream() ++{ ++ if ( stream_.state == STREAM_CLOSED ) { ++ errorText_ = "RtApiSndio::closeStream(): no open stream to close!"; ++ error( RTAUDIO_WARNING ); ++ return; ++ } ++ ++ SndioHandle *handle = (SndioHandle *) stream_.apiHandle; ++ stream_.callbackInfo.isRunning = false; ++ ++ MUTEX_LOCK( &stream_.mutex ); ++ stream_.state = STREAM_CLOSED; ++ MUTEX_UNLOCK( &stream_.mutex ); ++ ++ // Join FIRST (thread may be in sio_write with poll timeout ~23ms). ++ // Then call sio_stop/sio_close with no concurrent sio I/O. pthread_join( stream_.callbackInfo.thread, nullptr ); ++ if ( handle ) { ++ if ( handle->handle ) { sio_stop( handle->handle ); sio_close( handle->handle ); } ++ delete handle; ++ stream_.apiHandle = nullptr; ++ } ++ ++ for ( int i = 0; i < 2; i++ ) { ++ if ( stream_.userBuffer[i] ) { ++ free( stream_.userBuffer[i] ); ++ stream_.userBuffer[i] = nullptr; ++ } ++ } ++ if ( stream_.deviceBuffer ) { ++ free( stream_.deviceBuffer ); ++ stream_.deviceBuffer = nullptr; ++ } ++ ++ clearStreamInfo(); ++} ++ ++RtAudioErrorType RtApiSndio :: startStream() ++{ ++ if ( stream_.state != STREAM_STOPPED ) { ++ if ( stream_.state == STREAM_RUNNING ) ++ errorText_ = "RtApiSndio::startStream(): stream already running!"; ++ else ++ errorText_ = "RtApiSndio::startStream(): stream is stopping or closed!"; ++ return error( RTAUDIO_WARNING ); ++ } ++ ++ SndioHandle *handle = (SndioHandle *) stream_.apiHandle; ++ ++ MUTEX_LOCK( &stream_.mutex ); if ( !sio_start( handle->handle ) ) { ++ MUTEX_UNLOCK( &stream_.mutex ); ++ errorText_ = "RtApiSndio::startStream(): error starting sndio stream."; ++ return error( RTAUDIO_SYSTEM_ERROR ); ++ } stream_.state = STREAM_RUNNING; ++ MUTEX_UNLOCK( &stream_.mutex ); ++ return RTAUDIO_NO_ERROR; ++} ++ ++RtAudioErrorType RtApiSndio :: stopStream() ++{ ++ if ( stream_.state != STREAM_RUNNING && stream_.state != STREAM_STOPPING ) { ++ if ( stream_.state == STREAM_STOPPED ) ++ errorText_ = "RtApiSndio::stopStream(): stream already stopped!"; ++ else ++ errorText_ = "RtApiSndio::stopStream(): stream is closed!"; ++ return error( RTAUDIO_WARNING ); ++ } ++ ++ MUTEX_LOCK( &stream_.mutex ); ++ ++ if ( stream_.state == STREAM_STOPPED ) { ++ MUTEX_UNLOCK( &stream_.mutex ); ++ return RTAUDIO_NO_ERROR; ++ } ++ ++ SndioHandle *handle = (SndioHandle *) stream_.apiHandle; ++ ++ // Do NOT call sio_stop() here: stopStream() may be called from any thread, ++ // including while the callback thread holds the sio handle in sio_write(). ++ // sio is not thread-safe; concurrent sio_stop()+sio_write() causes hangs. ++ // Instead, just set state=STOPPED; closeStream() calls sio_stop() after ++ // pthread_join() ensures no concurrent sio I/O. ++ stream_.state = STREAM_STOPPED; ++ MUTEX_UNLOCK( &stream_.mutex ); ++ return RTAUDIO_NO_ERROR; ++} ++ ++RtAudioErrorType RtApiSndio :: abortStream() ++{ ++ if ( stream_.state != STREAM_RUNNING ) { ++ if ( stream_.state == STREAM_STOPPED ) ++ errorText_ = "RtApiSndio::abortStream(): stream already stopped!"; ++ else ++ errorText_ = "RtApiSndio::abortStream(): stream is stopping or closed!"; ++ return error( RTAUDIO_WARNING ); ++ } ++ ++ MUTEX_LOCK( &stream_.mutex ); ++ // Same thread-safety rule as stopStream(): no sio_stop() here. ++ // closeStream() will call sio_stop() after pthread_join(). ++ stream_.state = STREAM_STOPPED; ++ MUTEX_UNLOCK( &stream_.mutex ); ++ return RTAUDIO_NO_ERROR; ++} ++ ++void RtApiSndio :: callbackEvent() ++{ ++ SndioHandle *handle = (SndioHandle *) stream_.apiHandle; ++ ++ if ( stream_.state == STREAM_STOPPED || stream_.state == STREAM_CLOSED ) { ++ // Spin-wait briefly when stopped to avoid busy-looping ++ struct timespec ts = { 0, 5000000 }; // 5 ms ++ nanosleep( &ts, nullptr ); ++ return; ++ } ++ ++ if ( stream_.state != STREAM_RUNNING ) return; ++ ++ // Invoke user callback ++ int doStopStream = 0; ++ RtAudioCallback callback = (RtAudioCallback) stream_.callbackInfo.callback; ++ double streamTime = getStreamTime(); ++ RtAudioStreamStatus status = 0; ++ if ( stream_.mode != INPUT && handle->xrun[0] ) { ++ status |= RTAUDIO_OUTPUT_UNDERFLOW; ++ handle->xrun[0] = false; ++ } ++ if ( stream_.mode != OUTPUT && handle->xrun[1] ) { ++ status |= RTAUDIO_INPUT_OVERFLOW; ++ handle->xrun[1] = false; ++ } ++ ++ { static int _cb_pre=0; if(++_cb_pre<=3) { fprintf(stderr,"[sndio-dbg] invoking user callback #%d\n",_cb_pre); fflush(stderr); } } ++ doStopStream = callback( stream_.userBuffer[0], stream_.userBuffer[1], ++ stream_.bufferSize, streamTime, status, ++ stream_.callbackInfo.userData ); ++ if ( doStopStream == 2 ) { ++ abortStream(); ++ return; ++ } ++ ++ // Perform I/O outside the mutex so closeStream() can set state and call ++ // sio_stop() to unblock a thread waiting in sio_read/sio_write. ++ if ( stream_.state != STREAM_RUNNING ) { ++ RtApi::tickStreamTime(); ++ return; ++ } ++ ++ { ++ char *buffer; ++ int samples; ++ RtAudioFormat format; ++ size_t nbytes, written; ++ ++ if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { ++ if ( stream_.doConvertBuffer[0] ) { ++ buffer = stream_.deviceBuffer; ++ convertBuffer( buffer, stream_.userBuffer[0], stream_.convertInfo[0] ); ++ samples = stream_.bufferSize * stream_.nDeviceChannels[0]; ++ format = stream_.deviceFormat[0]; ++ } else { ++ buffer = stream_.userBuffer[0]; ++ samples = stream_.bufferSize * stream_.nUserChannels[0]; ++ format = stream_.userFormat; ++ } ++ if ( stream_.doByteSwap[0] ) ++ byteSwapBuffer( buffer, samples, format ); ++ ++ nbytes = samples * formatBytes( format ); ++ ++ // Use poll with a timeout so sio_write() cannot block indefinitely. ++ // This is critical for clean shutdown: stopStream() calls sio_stop() ++ // which stops the device clock, so POLLOUT may never fire again after ++ // that point. Two buffer periods is plenty under normal operation. ++ { ++ int timeoutMs = (int)( 2000.0 * stream_.bufferSize / stream_.sampleRate ) + 10; ++ struct pollfd pfd[8]; ++ { static int _cb_n=0; if(++_cb_n<=5||_cb_n%100==0) { fprintf(stderr,"[sndio-dbg] callbackEvent #%d pre-poll\n",_cb_n); fflush(stderr); } } ++ int nfds = sio_pollfd( handle->handle, pfd, POLLOUT ); ++ int ready = ( nfds > 0 ) ? poll( pfd, nfds, timeoutMs ) : 0; ++ written = 0; ++ { static int _pb=0; if(++_pb<=10||_pb%50==0) { int rev = (ready>0)?sio_revents(handle->handle,pfd):0; fprintf(stderr,"[sndio-dbg] poll#%d nfds=%d ready=%d rev=0x%x POLLOUT=%d\n",_pb,nfds,ready,rev,!!(rev&POLLOUT)); fflush(stderr); } } ++ if ( ready > 0 && ( sio_revents( handle->handle, pfd ) & POLLOUT ) ) ++ written = sio_write( handle->handle, buffer, nbytes ); ++ } ++ if ( written != nbytes ) { ++ handle->xrun[0] = true; ++ errorText_ = "RtApiSndio::callbackEvent: audio write error."; ++ error( RTAUDIO_WARNING ); ++ } ++ } ++ ++ if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) { ++ if ( stream_.doConvertBuffer[1] ) { ++ buffer = stream_.deviceBuffer; ++ samples = stream_.bufferSize * stream_.nDeviceChannels[1]; ++ format = stream_.deviceFormat[1]; ++ } else { ++ buffer = stream_.userBuffer[1]; ++ samples = stream_.bufferSize * stream_.nUserChannels[1]; ++ format = stream_.userFormat; ++ } ++ ++ nbytes = samples * formatBytes( format ); ++ ++ // Use poll with a timeout so we don't block forever on play-only devices. ++ // Two buffer periods (in ms) is enough for normal operation. ++ int timeoutMs = (int)( 2000.0 * stream_.bufferSize / stream_.sampleRate ) + 10; ++ struct pollfd pfd[8]; ++ int nfds = sio_pollfd( handle->handle, pfd, POLLIN ); ++ int ready = ( nfds > 0 ) ? poll( pfd, nfds, timeoutMs ) : 0; ++ ++ size_t got = 0; ++ if ( ready > 0 && ( sio_revents( handle->handle, pfd ) & POLLIN ) ) ++ got = sio_read( handle->handle, buffer, nbytes ); ++ ++ if ( got != nbytes ) { ++ if ( got == 0 ) ++ memset( buffer, 0, nbytes ); // play-only device: substitute silence ++ else { ++ handle->xrun[1] = true; ++ errorText_ = "RtApiSndio::callbackEvent: audio read error."; ++ error( RTAUDIO_WARNING ); ++ } ++ } ++ if ( got > 0 ) { ++ if ( stream_.doByteSwap[1] ) ++ byteSwapBuffer( buffer, samples, format ); ++ if ( stream_.doConvertBuffer[1] ) ++ convertBuffer( stream_.userBuffer[1], stream_.deviceBuffer, stream_.convertInfo[1] ); ++ } ++ } ++ } ++ ++ RtApi::tickStreamTime(); ++ if ( doStopStream == 1 ) stopStream(); ++} ++ ++static void *sndioCallbackHandler( void *ptr ) ++{ ++ CallbackInfo *info = (CallbackInfo *) ptr; ++ RtApiSndio *object = (RtApiSndio *) info->object; ++ bool *isRunning = &info->isRunning; ++ ++ while ( *isRunning == true ) { ++ pthread_testcancel(); ++ object->callbackEvent(); ++ } ++ ++ pthread_exit( nullptr ); ++} ++ ++//******************** End of __OPENBSD_SNDIO__ *********************// ++#endif + + // *************************************************** // + // diff --git a/audio/chuck/patches/patch-src_host_RtAudio_RtAudio_h b/audio/chuck/patches/patch-src_host_RtAudio_RtAudio_h new file mode 100644 index 0000000..6986fdc --- /dev/null +++ b/audio/chuck/patches/patch-src_host_RtAudio_RtAudio_h @@ -0,0 +1,50 @@ +Index: src/host/RtAudio/RtAudio.h +--- src/host/RtAudio/RtAudio.h.orig ++++ src/host/RtAudio/RtAudio.h +@@ -255,6 +255,7 @@ class RTAUDIO_DLL_PUBLIC RtAudio + LINUX_ALSA, /*!< The Advanced Linux Sound Architecture API. */ + LINUX_PULSE, /*!< The Linux PulseAudio API. */ + LINUX_OSS, /*!< The Linux Open Sound System API. */ ++ OPENBSD_SNDIO, /*!< The OpenBSD sndio API. */ + UNIX_JACK, /*!< The Jack Low-Latency Audio Server API. */ + MACOSX_CORE, /*!< Macintosh OS-X Core Audio API. */ + WINDOWS_WASAPI, /*!< The Microsoft WASAPI API. */ +@@ -1144,6 +1145,38 @@ class RtApiOss: public RtApi (public) + private: + + bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, ++ unsigned int firstChannel, unsigned int sampleRate, ++ RtAudioFormat format, unsigned int *bufferSize, ++ RtAudio::StreamOptions *options ) /* override */; ++}; ++ ++#endif ++ ++#if defined(__OPENBSD_SNDIO__) ++ ++class RtApiSndio: public RtApi ++{ ++public: ++ ++ RtApiSndio(); ++ ~RtApiSndio(); ++ RtAudio::Api getCurrentApi() /* override */ { return RtAudio::OPENBSD_SNDIO; } ++ unsigned int getDeviceCount( void ) /* override */; ++ RtAudio::DeviceInfo getDeviceInfo( unsigned int device ) /* override */; ++ void closeStream( void ) /* override */; ++ RtAudioErrorType startStream( void ) /* override */; ++ RtAudioErrorType stopStream( void ) /* override */; ++ RtAudioErrorType abortStream( void ) /* override */; ++ ++ // This function is intended for internal use only. It must be ++ // public because it is called by the internal callback handler, ++ // which is not a member of RtAudio. External use of this function ++ // will most likely produce highly undesirable results! ++ void callbackEvent( void ); ++ ++ private: ++ ++ bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, + unsigned int firstChannel, unsigned int sampleRate, + RtAudioFormat format, unsigned int *bufferSize, + RtAudio::StreamOptions *options ) /* override */; diff --git a/audio/chuck/patches/patch-src_host_chuck_audio_cpp b/audio/chuck/patches/patch-src_host_chuck_audio_cpp new file mode 100644 index 0000000..13753b5 --- /dev/null +++ b/audio/chuck/patches/patch-src_host_chuck_audio_cpp @@ -0,0 +1,31 @@ +Index: src/host/chuck_audio.cpp +--- src/host/chuck_audio.cpp.orig ++++ src/host/chuck_audio.cpp +@@ -147,6 +147,10 @@ static RtAudio::Api driverNameToApi( const char * driv + if( driverLower == "oss" ) + api = RtAudio::LINUX_OSS; + #endif ++ #if defined(__OPENBSD_SNDIO__) ++ if( driverLower == "sndio" ) ++ api = RtAudio::OPENBSD_SNDIO; ++ #endif + #if defined(__UNIX_JACK__) + if( driverLower == "jack" ) + api = RtAudio::UNIX_JACK; +@@ -184,6 +188,8 @@ static RtAudio::Api driverNameToApi( const char * driv + api = RtAudio::LINUX_OSS; + #elif defined(__PLATFORM_LINUX__) && defined(__UNIX_JACK__) + api = RtAudio::UNIX_JACK; ++ #elif defined(__OPENBSD_SNDIO__) ++ api = RtAudio::OPENBSD_SNDIO; + #elif defined(__MACOSX_CORE__) + api = RtAudio::MACOSX_CORE; + #endif +@@ -206,6 +212,7 @@ static const char * apiToDriverName( RtAudio::Api api + "ALSA", + "Pulse", + "OSS", ++ "sndio", + "Jack", + "CoreAudio", + "WASAPI", diff --git a/audio/chuck/patches/patch-src_host_chuck_main_cpp b/audio/chuck/patches/patch-src_host_chuck_main_cpp new file mode 100644 index 0000000..104aeac --- /dev/null +++ b/audio/chuck/patches/patch-src_host_chuck_main_cpp @@ -0,0 +1,24 @@ +Index: src/host/chuck_main.cpp +--- src/host/chuck_main.cpp.orig ++++ src/host/chuck_main.cpp +@@ -1213,7 +1213,9 @@ t_CKBOOL go( int argc, const char ** argv ) + #endif // __DISABLE_MIDI__ + + // probe HID devices ++ #ifndef __DISABLE_HID__ + HidInManager::probeHidIn(); ++ #endif // __DISABLE_HID__ + + // restore log level + the_chuck->setLogLevel( log_level ); +@@ -1493,8 +1495,10 @@ t_CKBOOL go( int argc, const char ** argv ) + + //------------------------- HID RELATED SETUP ----------------------------- + #ifndef __ALTER_HID__ ++ #ifndef __DISABLE_HID__ + // pre-load hid + if( load_hid ) HidInManager::init(); ++ #endif // __DISABLE_HID__ + #endif // __ALTER_HID__ + + diff --git a/audio/chuck/patches/patch-src_makefile b/audio/chuck/patches/patch-src_makefile new file mode 100644 index 0000000..bf087ba --- /dev/null +++ b/audio/chuck/patches/patch-src_makefile @@ -0,0 +1,42 @@ +Index: src/makefile +--- src/makefile.orig ++++ src/makefile +@@ -16,7 +16,7 @@ CK_HOST_DIR=host + # where to find RtAudio + RTAUDIO_DIR=RtAudio + # chuck version +-CK_VERSION=1.5.5.7 ++CK_VERSION=1.5.5.8-dev + + + ########################## DEFAULT MAKE TARGET ################################ +@@ -24,6 +24,7 @@ CK_VERSION=1.5.5.7 + current: + @echo "[chuck build]: please use one of the following configurations:" + @echo " make linux-alsa, make linux-jack, make linux-pulse, linux-all," ++ @echo " make openbsd-sndio," + @echo " make mac, make mac-ub, make web, make win32" + + +@@ -80,8 +81,8 @@ host-web/webchuck/js/webchuck.js: $(EMSCRIPTENSRCS) $( + # https://github.com/ccrma/chuck#readme + + # make targets +-.PHONY: mac mac-ub osx linux-all linux linux-pulse linux-jack linux-alsa test +-mac mac-ub osx linux-all linux linux-pulse linux-jack linux-alsa: chuck ++.PHONY: mac mac-ub osx linux-all linux linux-pulse linux-jack linux-alsa openbsd-sndio test ++mac mac-ub osx linux-all linux linux-pulse linux-jack linux-alsa openbsd-sndio: chuck + + win32: + @echo "for Windows build, see visual-studio/chuck.sln" +@@ -173,6 +174,10 @@ endif + + ifneq (,$(strip $(filter linux-alsa,$(MAKECMDGOALS)))) + include $(CK_CORE_DIR)/makefile.x/makefile.alsa ++endif ++ ++ifneq (,$(strip $(filter openbsd-sndio,$(MAKECMDGOALS)))) ++include $(CK_CORE_DIR)/makefile.x/makefile.sndio + endif + + # ifneq (,$(strip $(filter cygwin,$(MAKECMDGOALS)))) diff --git a/audio/chuck/peg b/audio/chuck/peg new file mode 100644 index 0000000..e69de29 diff --git a/audio/chuck/pkg/DESCR b/audio/chuck/pkg/DESCR new file mode 100644 index 0000000..3b1e198 --- /dev/null +++ b/audio/chuck/pkg/DESCR @@ -0,0 +1,15 @@ +ChucK is a strongly-timed, concurrent, and on-the-fly music programming +language. It is compiled in real-time, on-the-fly, and allows code to be +added and modified while the program is running, without stopping or +restarting. It is used for synthesis, composition, performance, and +analysis. + +ChucK presents a unique time-based, concurrent programming model that's +precise and expressive (with regards to time), dynamic (with regards to +concurrency), and interactive (with regards to interface). It is open-source +and freely available. + +On OpenBSD, ChucK uses the JACK audio server for output. Start jackd (via +sndio or another backend) before running chuck. + +Website: https://chuck.stanford.edu/ diff --git a/audio/chuck/pkg/PLIST b/audio/chuck/pkg/PLIST new file mode 100644 index 0000000..7f892c6 --- /dev/null +++ b/audio/chuck/pkg/PLIST @@ -0,0 +1 @@ +bin/chuck diff --git a/ruby/ruby-airstream/Makefile b/ruby/ruby-airstream/Makefile index c225802..2859ff6 100644 --- a/ruby/ruby-airstream/Makefile +++ b/ruby/ruby-airstream/Makefile @@ -10,7 +10,7 @@ HOMEPAGE = https://github.com/unused/airstream # Unknown PERMIT_PACKAGE = Yes -MASTER_SITES = https://codevoid.de/9/p/ +SITES = https://codevoid.de/9/p/ DISTFILES = airstream-0.4.10.gem MODULES = lang/ruby diff --git a/security/browserpass-native/Makefile b/security/browserpass-native/Makefile deleted file mode 100644 index 2d522e7..0000000 --- a/security/browserpass-native/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -COMMENT = companion app for the chromium browserpass extension - -MODGO_MODNAME = github.com/browserpass/browserpass-native -MODGO_VERSION = v0.0.0-20231004071550-ed246ee62824 - -APP_ID = com.github.browserpass.native - -DISTNAME = browserpass-native-${MODGO_VERSION} -PKGNAME = browserpass-native-20231004071550 - -CATEGORIES = security - -# ISC License -PERMIT_PACKAGE = yes - -# uses pledge() -MODULES = lang/go - -WANTLIB += c pthread - -SUBST_VARS += APP_ID - -do-install: - sed -i "s|%%replace%%|${TRUEPREFIX}/share/browserpass/browserpass|g" \ - ${WRKSRC}/browser-files/{firefox,chromium}-host.json - ${INSTALL_DATA_DIR} ${PREFIX}/share/browserpass/{hosts,policies}/{chromium,firefox} - ${INSTALL} ${WRKDIR}/go/bin/browserpass-native ${PREFIX}/share/browserpass/browserpass - ${INSTALL_DATA} ${WRKSRC}/LICENSE ${PREFIX}/share/browserpass - ${INSTALL_DATA} ${WRKSRC}/README.md ${PREFIX}/share/browserpass - ${INSTALL_DATA} ${WRKSRC}/browser-files/chromium-host.json \ - ${PREFIX}/share/browserpass/hosts/chromium/${APP_ID}.json - ${INSTALL_DATA} ${WRKSRC}/browser-files/chromium-policy.json \ - ${PREFIX}/share/browserpass/policies/chromium/${APP_ID}.json - ${INSTALL_DATA} ${WRKSRC}/browser-files/firefox-host.json \ - ${PREFIX}/share/browserpass/hosts/firefox/${APP_ID}.json - -.include "modules.inc" - -.include diff --git a/security/browserpass-native/distinfo b/security/browserpass-native/distinfo deleted file mode 100644 index 360d654..0000000 --- a/security/browserpass-native/distinfo +++ /dev/null @@ -1,46 +0,0 @@ -SHA256 (browserpass-native-v0.0.0-20231004071550-ed246ee62824.zip) = XIehrPpfv9bA7OL/CH0H7zw6r7Qvti9Ibs+3RRZBYYw= -SHA256 (go_modules/github.com/davecgh/go-spew/@v/v1.1.0.mod) = vLKTkyUSN7eaF7bBm/KRNPQ+j0OMMZiYj81GGhzfBcw= -SHA256 (go_modules/github.com/davecgh/go-spew/@v/v1.1.1.mod) = vLKTkyUSN7eaF7bBm/KRNPQ+j0OMMZiYj81GGhzfBcw= -SHA256 (go_modules/github.com/davecgh/go-spew/@v/v1.1.1.zip) = a0SoQ5UfNxtwEMdU7MPKvv6BXVztHFuUCfstaX6KiQ0= -SHA256 (go_modules/github.com/mattn/go-zglob/@v/v0.0.4.mod) = wRhbNd/8vntJVXBw49nXi5bGVclJr6k1FLg/z1C4jHM= -SHA256 (go_modules/github.com/mattn/go-zglob/@v/v0.0.4.zip) = KbEH083UUi1qf4kzWI/V0MoMpH5JoW2l1O7APpjP/VA= -SHA256 (go_modules/github.com/pmezard/go-difflib/@v/v1.0.0.mod) = dLLnZushU3eGTVh7rfV+lVIfaS0qeGCzx3WQk/nJvsI= -SHA256 (go_modules/github.com/pmezard/go-difflib/@v/v1.0.0.zip) = 3gTOzBpLjVPkNXBRAmeUvLxU8uaiYM+sUIzmnV1kV6A= -SHA256 (go_modules/github.com/rifflock/lfshook/@v/v0.0.0-20180920164130-b9218ef580f5.mod) = HJWM2VriA97XYkUNLpu1hn7Tt3xSRgEETQCW3njVsWs= -SHA256 (go_modules/github.com/rifflock/lfshook/@v/v0.0.0-20180920164130-b9218ef580f5.zip) = qHzc1tTw0HjGxw0rK0yv0Xr2j70JdaCLdbeIhILohMw= -SHA256 (go_modules/github.com/sirupsen/logrus/@v/v1.9.3.mod) = AeghItVH0SKBUaYj/mysxNepyzGKD2aM4Iu2tn/bKLE= -SHA256 (go_modules/github.com/sirupsen/logrus/@v/v1.9.3.zip) = RQH05rhYv92ZdnH83S9kejF4sptrTRNEyqfAdRcSHdA= -SHA256 (go_modules/github.com/stretchr/objx/@v/v0.1.0.mod) = E1A1TVLSKHpiM27MDVYjLUxHaZr5u6ScZ8K0glTamPE= -SHA256 (go_modules/github.com/stretchr/objx/@v/v0.1.0.zip) = H6ENq0BO1/yO0qAz+HhBh9XfNRPO04Qc455G03hQ6x0= -SHA256 (go_modules/github.com/stretchr/testify/@v/v1.7.0.mod) = //gWjZjmoHFWxFShtuklUJ8xd+lsFVUW1/lrQHnMo78= -SHA256 (go_modules/github.com/stretchr/testify/@v/v1.7.0.zip) = WkbM6+/1EN8+L204Qu550/aNDnsVVM1u6TOQ1otsazQ= -SHA256 (go_modules/golang.org/x/sys/@v/v0.0.0-20220715151400-c0bba94af5f8.mod) = 8DMzMJb+GY8xUd7tk/LeunTlC7/nc5E0BFvDt85KUCQ= -SHA256 (go_modules/golang.org/x/sys/@v/v0.12.0.mod) = 8DMzMJb+GY8xUd7tk/LeunTlC7/nc5E0BFvDt85KUCQ= -SHA256 (go_modules/golang.org/x/sys/@v/v0.12.0.zip) = iSJdnmYDwJD/2TKGt8oSSEn63+QyDDsYpr3MxKwIZyw= -SHA256 (go_modules/gopkg.in/check.v1/@v/v0.0.0-20161208181325-20d25e280405.mod) = XDBuDWM81moRtA4uX7vG2kIRDbfXLqPBUkzrRe5Awz8= -SHA256 (go_modules/gopkg.in/check.v1/@v/v0.0.0-20161208181325-20d25e280405.zip) = ThgX+WTKNOVFuBr9oDJaXonPWN4uQT2CB8Cv3dD9wVw= -SHA256 (go_modules/gopkg.in/yaml.v3/@v/v3.0.0-20200313102051-9f266ea9e77c.mod) = IVeYYKIDBvz0OxvSNNH7oxlJnHdhG3HAX5vzupDauTk= -SHA256 (go_modules/gopkg.in/yaml.v3/@v/v3.0.0-20200313102051-9f266ea9e77c.zip) = rPGcy0/KmDsjSjnvAy+vmrcOdZaAZzuz3/B353/uIP4= -SIZE (browserpass-native-v0.0.0-20231004071550-ed246ee62824.zip) = 36660 -SIZE (go_modules/github.com/davecgh/go-spew/@v/v1.1.0.mod) = 34 -SIZE (go_modules/github.com/davecgh/go-spew/@v/v1.1.1.mod) = 34 -SIZE (go_modules/github.com/davecgh/go-spew/@v/v1.1.1.zip) = 60320 -SIZE (go_modules/github.com/mattn/go-zglob/@v/v0.0.4.mod) = 42 -SIZE (go_modules/github.com/mattn/go-zglob/@v/v0.0.4.zip) = 12914 -SIZE (go_modules/github.com/pmezard/go-difflib/@v/v1.0.0.mod) = 37 -SIZE (go_modules/github.com/pmezard/go-difflib/@v/v1.0.0.zip) = 12433 -SIZE (go_modules/github.com/rifflock/lfshook/@v/v0.0.0-20180920164130-b9218ef580f5.mod) = 35 -SIZE (go_modules/github.com/rifflock/lfshook/@v/v0.0.0-20180920164130-b9218ef580f5.zip) = 4775 -SIZE (go_modules/github.com/sirupsen/logrus/@v/v1.9.3.mod) = 192 -SIZE (go_modules/github.com/sirupsen/logrus/@v/v1.9.3.zip) = 69937 -SIZE (go_modules/github.com/stretchr/objx/@v/v0.1.0.mod) = 32 -SIZE (go_modules/github.com/stretchr/objx/@v/v0.1.0.zip) = 34637 -SIZE (go_modules/github.com/stretchr/testify/@v/v1.7.0.mod) = 216 -SIZE (go_modules/github.com/stretchr/testify/@v/v1.7.0.zip) = 105564 -SIZE (go_modules/golang.org/x/sys/@v/v0.0.0-20220715151400-c0bba94af5f8.mod) = 33 -SIZE (go_modules/golang.org/x/sys/@v/v0.12.0.mod) = 33 -SIZE (go_modules/golang.org/x/sys/@v/v0.12.0.zip) = 1908262 -SIZE (go_modules/gopkg.in/check.v1/@v/v0.0.0-20161208181325-20d25e280405.mod) = 25 -SIZE (go_modules/gopkg.in/check.v1/@v/v0.0.0-20161208181325-20d25e280405.zip) = 39844 -SIZE (go_modules/gopkg.in/yaml.v3/@v/v3.0.0-20200313102051-9f266ea9e77c.mod) = 95 -SIZE (go_modules/gopkg.in/yaml.v3/@v/v3.0.0-20200313102051-9f266ea9e77c.zip) = 101467 diff --git a/security/browserpass-native/modules.inc b/security/browserpass-native/modules.inc deleted file mode 100644 index 79f8423..0000000 --- a/security/browserpass-native/modules.inc +++ /dev/null @@ -1,14 +0,0 @@ -MODGO_MODULES = \ - github.com/davecgh/go-spew v1.1.1 \ - github.com/mattn/go-zglob v0.0.4 \ - github.com/pmezard/go-difflib v1.0.0 \ - github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 \ - github.com/sirupsen/logrus v1.9.3 \ - github.com/stretchr/objx v0.1.0 \ - github.com/stretchr/testify v1.7.0 \ - golang.org/x/sys v0.12.0 \ - gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 \ - gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c -MODGO_MODFILES = \ - github.com/davecgh/go-spew v1.1.0 \ - golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 diff --git a/security/browserpass-native/pkg/DESCR b/security/browserpass-native/pkg/DESCR deleted file mode 100644 index 2abebe4..0000000 --- a/security/browserpass-native/pkg/DESCR +++ /dev/null @@ -1,3 +0,0 @@ -This is a host application for browserpass browser extension providing -it access to your password store. The communication is handled through -Native Messaging API. diff --git a/security/browserpass-native/pkg/PLIST b/security/browserpass-native/pkg/PLIST deleted file mode 100644 index 9d4b793..0000000 --- a/security/browserpass-native/pkg/PLIST +++ /dev/null @@ -1,14 +0,0 @@ -share/browserpass/ -share/browserpass/LICENSE -share/browserpass/README.md -@bin share/browserpass/browserpass -share/browserpass/hosts/ -share/browserpass/hosts/chromium/ -share/browserpass/hosts/chromium/${APP_ID}.json -share/browserpass/hosts/firefox/ -share/browserpass/hosts/firefox/${APP_ID}.json -share/browserpass/policies/ -share/browserpass/policies/chromium/ -share/browserpass/policies/chromium/${APP_ID}.json -share/browserpass/policies/firefox/ -share/doc/pkg-readmes/${PKGSTEM} diff --git a/security/browserpass-native/pkg/README b/security/browserpass-native/pkg/README deleted file mode 100644 index 544e71e..0000000 --- a/security/browserpass-native/pkg/README +++ /dev/null @@ -1,40 +0,0 @@ -+------------------------------------------------------------------------------- -| Running ${PKGSTEM} on OpenBSD -+------------------------------------------------------------------------------- - -Step 1: Install the browser extension from one of the following sources: - -Chrome Web Store: -https://chrome.google.com/webstore/detail/browserpass-ce/naepdomgkenhinolocfifgehidddafch - -Firefox AddOns: -https://addons.mozilla.org/en-US/firefox/addon/browserpass-ce - -Or manually from github: -https://github.com/browserpass/browserpass-extension/releases - -Step 2: Register the native messaging host to allow the extension to talk to - the browserapp companion app: - -For chromium based browsers, adjust the DIR variabable and run: - -DIR=chromium # ungoogled-chromium chromium iridium -mkdir -p ${SYSCONFDIR}/$DIR/native-messaging-hosts/ -ln -sf ${TRUEPREFIX}/share/browserpass/hosts/chromium/${APP_ID}.json \ - ${SYSCONFDIR}/$DIR/native-messaging-hosts/${APP_ID}.json - -For firefox based browsers, adjust the DIR variable and run: - -DIR=firefox -mkdir -p ${SYSCONFDIR}/$DIR/native-messaging-hosts/ -ln -sf ${TRUEPREFIX}/share/browserpass/hosts/firefox/${APP_ID}.json \ - ${SYSCONFDIR}/$DIR/native-messaging-hosts/${APP_ID}.json - -Step 3: Allow unveil to access the browserpass application and its - directory: - -Add the following entries to /etc/$DIR/unveil.main: - -${TRUEPREFIX}/share/browserpass/browserpass rx -${TRUEPREFIX}/share/browserpass r - diff --git a/sysutils/browserpass-native/Makefile b/sysutils/browserpass-native/Makefile deleted file mode 100644 index 2495d52..0000000 --- a/sysutils/browserpass-native/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -COMMENT = pass browser companion app - -MODGO_MODNAME = github.com/browserpass/browserpass-native -MODGO_VERSION = v0.0.0-20231004071550-ed246ee62824 - -DISTNAME = browserpass-native-${MODGO_VERSION} -PKGNAME = browserpass-native-20230304235613 - -CATEGORIES = sysutils - -# ISC -PERMIT_PACKAGE = yes - -MODULES = lang/go - -.include "modules.inc" - -.include diff --git a/sysutils/browserpass-native/distinfo b/sysutils/browserpass-native/distinfo deleted file mode 100644 index 360d654..0000000 --- a/sysutils/browserpass-native/distinfo +++ /dev/null @@ -1,46 +0,0 @@ -SHA256 (browserpass-native-v0.0.0-20231004071550-ed246ee62824.zip) = XIehrPpfv9bA7OL/CH0H7zw6r7Qvti9Ibs+3RRZBYYw= -SHA256 (go_modules/github.com/davecgh/go-spew/@v/v1.1.0.mod) = vLKTkyUSN7eaF7bBm/KRNPQ+j0OMMZiYj81GGhzfBcw= -SHA256 (go_modules/github.com/davecgh/go-spew/@v/v1.1.1.mod) = vLKTkyUSN7eaF7bBm/KRNPQ+j0OMMZiYj81GGhzfBcw= -SHA256 (go_modules/github.com/davecgh/go-spew/@v/v1.1.1.zip) = a0SoQ5UfNxtwEMdU7MPKvv6BXVztHFuUCfstaX6KiQ0= -SHA256 (go_modules/github.com/mattn/go-zglob/@v/v0.0.4.mod) = wRhbNd/8vntJVXBw49nXi5bGVclJr6k1FLg/z1C4jHM= -SHA256 (go_modules/github.com/mattn/go-zglob/@v/v0.0.4.zip) = KbEH083UUi1qf4kzWI/V0MoMpH5JoW2l1O7APpjP/VA= -SHA256 (go_modules/github.com/pmezard/go-difflib/@v/v1.0.0.mod) = dLLnZushU3eGTVh7rfV+lVIfaS0qeGCzx3WQk/nJvsI= -SHA256 (go_modules/github.com/pmezard/go-difflib/@v/v1.0.0.zip) = 3gTOzBpLjVPkNXBRAmeUvLxU8uaiYM+sUIzmnV1kV6A= -SHA256 (go_modules/github.com/rifflock/lfshook/@v/v0.0.0-20180920164130-b9218ef580f5.mod) = HJWM2VriA97XYkUNLpu1hn7Tt3xSRgEETQCW3njVsWs= -SHA256 (go_modules/github.com/rifflock/lfshook/@v/v0.0.0-20180920164130-b9218ef580f5.zip) = qHzc1tTw0HjGxw0rK0yv0Xr2j70JdaCLdbeIhILohMw= -SHA256 (go_modules/github.com/sirupsen/logrus/@v/v1.9.3.mod) = AeghItVH0SKBUaYj/mysxNepyzGKD2aM4Iu2tn/bKLE= -SHA256 (go_modules/github.com/sirupsen/logrus/@v/v1.9.3.zip) = RQH05rhYv92ZdnH83S9kejF4sptrTRNEyqfAdRcSHdA= -SHA256 (go_modules/github.com/stretchr/objx/@v/v0.1.0.mod) = E1A1TVLSKHpiM27MDVYjLUxHaZr5u6ScZ8K0glTamPE= -SHA256 (go_modules/github.com/stretchr/objx/@v/v0.1.0.zip) = H6ENq0BO1/yO0qAz+HhBh9XfNRPO04Qc455G03hQ6x0= -SHA256 (go_modules/github.com/stretchr/testify/@v/v1.7.0.mod) = //gWjZjmoHFWxFShtuklUJ8xd+lsFVUW1/lrQHnMo78= -SHA256 (go_modules/github.com/stretchr/testify/@v/v1.7.0.zip) = WkbM6+/1EN8+L204Qu550/aNDnsVVM1u6TOQ1otsazQ= -SHA256 (go_modules/golang.org/x/sys/@v/v0.0.0-20220715151400-c0bba94af5f8.mod) = 8DMzMJb+GY8xUd7tk/LeunTlC7/nc5E0BFvDt85KUCQ= -SHA256 (go_modules/golang.org/x/sys/@v/v0.12.0.mod) = 8DMzMJb+GY8xUd7tk/LeunTlC7/nc5E0BFvDt85KUCQ= -SHA256 (go_modules/golang.org/x/sys/@v/v0.12.0.zip) = iSJdnmYDwJD/2TKGt8oSSEn63+QyDDsYpr3MxKwIZyw= -SHA256 (go_modules/gopkg.in/check.v1/@v/v0.0.0-20161208181325-20d25e280405.mod) = XDBuDWM81moRtA4uX7vG2kIRDbfXLqPBUkzrRe5Awz8= -SHA256 (go_modules/gopkg.in/check.v1/@v/v0.0.0-20161208181325-20d25e280405.zip) = ThgX+WTKNOVFuBr9oDJaXonPWN4uQT2CB8Cv3dD9wVw= -SHA256 (go_modules/gopkg.in/yaml.v3/@v/v3.0.0-20200313102051-9f266ea9e77c.mod) = IVeYYKIDBvz0OxvSNNH7oxlJnHdhG3HAX5vzupDauTk= -SHA256 (go_modules/gopkg.in/yaml.v3/@v/v3.0.0-20200313102051-9f266ea9e77c.zip) = rPGcy0/KmDsjSjnvAy+vmrcOdZaAZzuz3/B353/uIP4= -SIZE (browserpass-native-v0.0.0-20231004071550-ed246ee62824.zip) = 36660 -SIZE (go_modules/github.com/davecgh/go-spew/@v/v1.1.0.mod) = 34 -SIZE (go_modules/github.com/davecgh/go-spew/@v/v1.1.1.mod) = 34 -SIZE (go_modules/github.com/davecgh/go-spew/@v/v1.1.1.zip) = 60320 -SIZE (go_modules/github.com/mattn/go-zglob/@v/v0.0.4.mod) = 42 -SIZE (go_modules/github.com/mattn/go-zglob/@v/v0.0.4.zip) = 12914 -SIZE (go_modules/github.com/pmezard/go-difflib/@v/v1.0.0.mod) = 37 -SIZE (go_modules/github.com/pmezard/go-difflib/@v/v1.0.0.zip) = 12433 -SIZE (go_modules/github.com/rifflock/lfshook/@v/v0.0.0-20180920164130-b9218ef580f5.mod) = 35 -SIZE (go_modules/github.com/rifflock/lfshook/@v/v0.0.0-20180920164130-b9218ef580f5.zip) = 4775 -SIZE (go_modules/github.com/sirupsen/logrus/@v/v1.9.3.mod) = 192 -SIZE (go_modules/github.com/sirupsen/logrus/@v/v1.9.3.zip) = 69937 -SIZE (go_modules/github.com/stretchr/objx/@v/v0.1.0.mod) = 32 -SIZE (go_modules/github.com/stretchr/objx/@v/v0.1.0.zip) = 34637 -SIZE (go_modules/github.com/stretchr/testify/@v/v1.7.0.mod) = 216 -SIZE (go_modules/github.com/stretchr/testify/@v/v1.7.0.zip) = 105564 -SIZE (go_modules/golang.org/x/sys/@v/v0.0.0-20220715151400-c0bba94af5f8.mod) = 33 -SIZE (go_modules/golang.org/x/sys/@v/v0.12.0.mod) = 33 -SIZE (go_modules/golang.org/x/sys/@v/v0.12.0.zip) = 1908262 -SIZE (go_modules/gopkg.in/check.v1/@v/v0.0.0-20161208181325-20d25e280405.mod) = 25 -SIZE (go_modules/gopkg.in/check.v1/@v/v0.0.0-20161208181325-20d25e280405.zip) = 39844 -SIZE (go_modules/gopkg.in/yaml.v3/@v/v3.0.0-20200313102051-9f266ea9e77c.mod) = 95 -SIZE (go_modules/gopkg.in/yaml.v3/@v/v3.0.0-20200313102051-9f266ea9e77c.zip) = 101467 diff --git a/sysutils/browserpass-native/modules.inc b/sysutils/browserpass-native/modules.inc deleted file mode 100644 index 2e54914..0000000 --- a/sysutils/browserpass-native/modules.inc +++ /dev/null @@ -1,16 +0,0 @@ -MODGO_MODULES = \ - github.com/davecgh/go-spew v1.1.1 \ - github.com/mattn/go-zglob v0.0.4 \ - github.com/pmezard/go-difflib v1.0.0 \ - github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 \ - github.com/sirupsen/logrus v1.9.3 \ - github.com/stretchr/objx v0.1.0 \ - github.com/stretchr/testify v1.7.0 \ - golang.org/x/sys v0.12.0 \ - gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 \ - gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c - -MODGO_MODFILES = \ - github.com/davecgh/go-spew v1.1.0 \ - golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 - diff --git a/sysutils/browserpass-native/pkg/DESCR b/sysutils/browserpass-native/pkg/DESCR deleted file mode 100644 index 1333ed7..0000000 --- a/sysutils/browserpass-native/pkg/DESCR +++ /dev/null @@ -1 +0,0 @@ -TODO diff --git a/sysutils/browserpass-native/pkg/PLIST b/sysutils/browserpass-native/pkg/PLIST deleted file mode 100644 index 433d4d4..0000000 --- a/sysutils/browserpass-native/pkg/PLIST +++ /dev/null @@ -1 +0,0 @@ -@bin bin/browserpass-native diff --git a/x11/st-sdk/Makefile b/x11/st-sdk/Makefile index 30a4c17..91b13b4 100644 --- a/x11/st-sdk/Makefile +++ b/x11/st-sdk/Makefile @@ -1,19 +1,19 @@ COMMENT= simple X terminal (personalized) -V= 0.9 +V= 0.9.2 DISTNAME= st-${V} PKGNAME= st-sdk-${V} +REVISION= 34 DIST_SUBDIR= st -SUPDISTFILES.p= scrollback/st-scrollback-0.8.5.diff \ - boxdraw/st-boxdraw_v2-0.8.5.diff \ +SUPDISTFILES.p= scrollback/st-scrollback-0.9.2.diff \ + scrollback/st-scrollback-reflow-0.9.2.diff \ charoffsets/st-charoffsets-20220311-0.8.5.diff \ - sync/st-appsync-20200618-b27a383.diff \ - disable_bold_italic_fonts/st-disable-bold-italic-fonts-0.8.2.diff \ - glyph_wide_support/st-glyph-wide-support-boxdraw-20220411-ef05519.diff \ - anysize/st-expected-anysize-0.9.diff \ - alpha/st-alpha-20220206-0.8.5.diff -REVISION= 47 + glyph_wide_support/st-glyph-wide-support-20230701-5770f2f.diff +# sync/st-appsync-20200618-b27a383.diff \ +# disable_bold_italic_fonts/st-disable-bold-italic-fonts-0.8.2.diff +# glyph_wide_support/st-glyph-wide-support-boxdraw-20220411-ef05519.diff +# boxdraw/st-boxdraw_v2-0.8.5.diff CATEGORIES= x11 @@ -44,8 +44,13 @@ PATCH_DIST_STRIP= -p1 post-extract: cp ${FILESDIR}/config.h ${WRKSRC}/config.h +# needs fixing for scrollback + boxdraw +# https://st.suckless.org/patches/ligatures/ +# post-patch: +# cd ${WRKSRC} && patch < ${FILESDIR}/ligatures.diff + post-patch: - cd ${WRKSRC} && patch < ${FILESDIR}/ligatures.diff + cd ${WRKSRC} && patch -p0 < ${FILESDIR}/pixel-geom.diff do-install: ${INSTALL_PROGRAM} ${WRKBUILD}/st ${PREFIX}/bin/ diff --git a/x11/st-sdk/distinfo b/x11/st-sdk/distinfo index 0498317..db24ba4 100644 --- a/x11/st-sdk/distinfo +++ b/x11/st-sdk/distinfo @@ -1,18 +1,10 @@ -SHA256 (st/alpha/st-alpha-20220206-0.8.5.diff) = QuSAPOKmeDX35TOnB6iijjgEomztFjFFEIlwua7l+4E= -SHA256 (st/anysize/st-expected-anysize-0.9.diff) = YosSUn9eALdCt/EsNwNVyOkakJvNnTq251FBCpCb+xE= -SHA256 (st/boxdraw/st-boxdraw_v2-0.8.5.diff) = BGRSYG/Otiq8jwaNiRxaXqPY0rinE9BTtWj5cQAYEIE= SHA256 (st/charoffsets/st-charoffsets-20220311-0.8.5.diff) = 5UV0fcvZkRMMuGkyohGcg5a1f0l1OPiD4bTFQvyL1OM= -SHA256 (st/disable_bold_italic_fonts/st-disable-bold-italic-fonts-0.8.2.diff) = baC7/mb3bQZChxPdrDJYlNvVoVrWJqQrQWHC1PyqSP4= -SHA256 (st/glyph_wide_support/st-glyph-wide-support-boxdraw-20220411-ef05519.diff) = MlVvieYzTX993ySoia378LLTyja8T3oJGavTd+B11lU= -SHA256 (st/scrollback/st-scrollback-0.8.5.diff) = 3H9SI7JvyBPZHUrjW9qlTWMCTK6fGK/Zs1lLozmd+lU= -SHA256 (st/st-0.9.tar.gz) = 82NZeZc06ueFvss3QGPwvoM88i+ItPFpzSUbmTJOCOc= -SHA256 (st/sync/st-appsync-20200618-b27a383.diff) = JP0d515EoPNTyv4rr4imEyvgc6OxJ7JecUZKcItZWPQ= -SIZE (st/alpha/st-alpha-20220206-0.8.5.diff) = 4339 -SIZE (st/anysize/st-expected-anysize-0.9.diff) = 441 -SIZE (st/boxdraw/st-boxdraw_v2-0.8.5.diff) = 17960 +SHA256 (st/glyph_wide_support/st-glyph-wide-support-20230701-5770f2f.diff) = YMd8dEvk0R/DzziCb0U3S6wKWUIS+9xua7ABgFTCqZ4= +SHA256 (st/scrollback/st-scrollback-0.9.2.diff) = jbY7+D3wbLoSzbAuV4y0mvx4nHJrTIX2bpWzclYrrHo= +SHA256 (st/scrollback/st-scrollback-reflow-0.9.2.diff) = AFFF65c+aKmBb7ZZIi2O+pEjgoCE95p30XRqV5ms3yc= +SHA256 (st/st-0.9.2.tar.gz) = ayFdT0crIdYjLzDyIRF6d34kvP7miVXd77dCZGf5SUs= SIZE (st/charoffsets/st-charoffsets-20220311-0.8.5.diff) = 1244 -SIZE (st/disable_bold_italic_fonts/st-disable-bold-italic-fonts-0.8.2.diff) = 2051 -SIZE (st/glyph_wide_support/st-glyph-wide-support-boxdraw-20220411-ef05519.diff) = 6352 -SIZE (st/scrollback/st-scrollback-0.8.5.diff) = 8914 -SIZE (st/st-0.9.tar.gz) = 48171 -SIZE (st/sync/st-appsync-20200618-b27a383.diff) = 7468 +SIZE (st/glyph_wide_support/st-glyph-wide-support-20230701-5770f2f.diff) = 7400 +SIZE (st/scrollback/st-scrollback-0.9.2.diff) = 8955 +SIZE (st/scrollback/st-scrollback-reflow-0.9.2.diff) = 43790 +SIZE (st/st-0.9.2.tar.gz) = 48381 diff --git a/x11/st-sdk/files/config.h b/x11/st-sdk/files/config.h index ec98171..65accbf 100644 --- a/x11/st-sdk/files/config.h +++ b/x11/st-sdk/files/config.h @@ -123,9 +123,6 @@ char *termname = "xterm-256color"; */ unsigned int tabspaces = 8; -/* bg opacity */ -float alpha = 0.65; - /* Terminal colors (16 first used in escape sequence) */ static const char *colorname[] = { /* 8 normal colors */ diff --git a/x11/st-sdk/patches/patch-config_def_h b/x11/st-sdk/patches/patch-config_def_h index 38a50d5..13419e3 100644 --- a/x11/st-sdk/patches/patch-config_def_h +++ b/x11/st-sdk/patches/patch-config_def_h @@ -1,7 +1,7 @@ Index: config.def.h --- config.def.h.orig +++ config.def.h -@@ -103,7 +103,7 @@ static const char *colorname[] = { +@@ -106,7 +106,7 @@ static const char *colorname[] = { "blue2", "magenta3", "cyan3", diff --git a/x11/st-sdk/patches/patch-config_mk b/x11/st-sdk/patches/patch-config_mk index 62866b2..8f125e9 100644 --- a/x11/st-sdk/patches/patch-config_mk +++ b/x11/st-sdk/patches/patch-config_mk @@ -1,7 +1,22 @@ Index: config.mk --- config.mk.orig +++ config.mk -@@ -26,11 +26,11 @@ STCFLAGS = $(INCS) $(STCPPFLAGS) $(CPPFLAGS) $(CFLAGS) +@@ -15,10 +15,12 @@ PKG_CONFIG = pkg-config + # includes and libs + INCS = -I$(X11INC) \ + `$(PKG_CONFIG) --cflags fontconfig` \ +- `$(PKG_CONFIG) --cflags freetype2` ++ `$(PKG_CONFIG) --cflags freetype2` \ ++ `$(PKG_CONFIG) --libs harfbuzz` + LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft \ + `$(PKG_CONFIG) --libs fontconfig` \ +- `$(PKG_CONFIG) --libs freetype2` ++ `$(PKG_CONFIG) --libs freetype2` \ ++ `$(PKG_CONFIG) --libs harfbuzz` + + # flags + STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 +@@ -26,11 +28,12 @@ STCFLAGS = $(INCS) $(STCPPFLAGS) $(CPPFLAGS) $(CFLAGS) STLDFLAGS = $(LIBS) $(LDFLAGS) # OpenBSD: @@ -13,7 +28,8 @@ Index: config.mk +CPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 -D_BSD_SOURCE +LIBS = -L$(X11LIB) -lm -lX11 -lutil -lXft \ + `$(PKG_CONFIG) --libs fontconfig` \ -+ `$(PKG_CONFIG) --libs freetype2` ++ `$(PKG_CONFIG) --libs freetype2` \ ++ `$(PKG_CONFIG) --libs harfbuzz` +MANPREFIX = ${PREFIX}/man # compiler and linker