chuck - with sndio backend

This commit is contained in:
c0dev0id 2026-03-15 22:48:20 +01:00
parent 00a181d185
commit a5b8d40661
49 changed files with 2191 additions and 271 deletions

40
audio/chuck/Makefile Normal file
View File

@ -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 <bsd.port.mk>

2
audio/chuck/distinfo Normal file
View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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__)
//-------------------------------------------

View File

@ -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 <stdarg.h>
#include <stdio.h>

View File

@ -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

View File

@ -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 <sys/types.h> does not define. */
/* #undef size_t */
-#endif // defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__)
+#endif // defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)

View File

@ -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))))

View File

@ -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

View File

@ -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 <string>
#include <map>

View File

@ -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 );
}

View File

@ -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

View File

@ -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

View File

@ -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<float>(ck_factorial32(order - abs(degree))) / static_cast<float>(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;
+ }
+ }
}

View File

@ -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)
}

View File

@ -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) );

View File

@ -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

View File

@ -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

View File

@ -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 <glob.h>
+#if !defined(__OpenBSD__) && !defined(__NetBSD__)
#include <wordexp.h>
+#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;

View File

@ -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)

View File

@ -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<typename T> 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 <pthread.h>
#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 );

View File

@ -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 <sndio.h>
+#include <poll.h>
+#include <pthread.h>
+#include <cerrno>
+
+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
// *************************************************** //
//

View File

@ -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 <sndio.h>
+#include <poll.h>
+#include <pthread.h>
+#include <cerrno>
+
+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
// *************************************************** //
//

View File

@ -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 */;

View File

@ -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",

View File

@ -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__

View File

@ -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))))

0
audio/chuck/peg Normal file
View File

15
audio/chuck/pkg/DESCR Normal file
View File

@ -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/

1
audio/chuck/pkg/PLIST Normal file
View File

@ -0,0 +1 @@
bin/chuck

View File

@ -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

View File

@ -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 <bsd.port.mk>

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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}

View File

@ -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

View File

@ -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 <bsd.port.mk>

View File

@ -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

View File

@ -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

View File

@ -1 +0,0 @@
TODO

View File

@ -1 +0,0 @@
@bin bin/browserpass-native

View File

@ -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/

View File

@ -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

View File

@ -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 */

View File

@ -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",

View File

@ -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