pkgsrc-Changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

CVS commit: pkgsrc/www/seamonkey



Module Name:    pkgsrc
Committed By:   nia
Date:           Thu Jun 13 10:53:12 UTC 2019

Modified Files:
        pkgsrc/www/seamonkey: Makefile distinfo options.mk
        pkgsrc/www/seamonkey/patches: patch-mozilla_media_libcubeb_src_cubeb.c
            patch-mozilla_media_libcubeb_src_moz.build
            patch-mozilla_media_libcubeb_update.sh
            patch-mozilla_old-configure.in
Added Files:
        pkgsrc/www/seamonkey/files: cubeb_sun.c

Log Message:
seamonkey: sun audio support for NetBSD/SunOS, use gtk3 by default

cubeb_sun replaces cubeb_oss, adding support for additional channels
on NetBSD, passing tests, and recording support (more useful on firefox
where WebRTC works)

upstream's official builds use gtk3 over gtk2 and doing so enables
support for hidpi displays.

me and several others have been using this for the past ~week, see
https://github.com/kinetiknz/cubeb/pull/510

bump PKGREVISION.


To generate a diff of this commit:
cvs rdiff -u -r1.191 -r1.192 pkgsrc/www/seamonkey/Makefile
cvs rdiff -u -r1.157 -r1.158 pkgsrc/www/seamonkey/distinfo
cvs rdiff -u -r1.40 -r1.41 pkgsrc/www/seamonkey/options.mk
cvs rdiff -u -r0 -r1.1 pkgsrc/www/seamonkey/files/cubeb_sun.c
cvs rdiff -u -r1.3 -r1.4 \
    pkgsrc/www/seamonkey/patches/patch-mozilla_media_libcubeb_src_cubeb.c
cvs rdiff -u -r1.7 -r1.8 \
    pkgsrc/www/seamonkey/patches/patch-mozilla_media_libcubeb_src_moz.build
cvs rdiff -u -r1.1 -r1.2 \
    pkgsrc/www/seamonkey/patches/patch-mozilla_media_libcubeb_update.sh
cvs rdiff -u -r1.4 -r1.5 \
    pkgsrc/www/seamonkey/patches/patch-mozilla_old-configure.in

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: pkgsrc/www/seamonkey/Makefile
diff -u pkgsrc/www/seamonkey/Makefile:1.191 pkgsrc/www/seamonkey/Makefile:1.192
--- pkgsrc/www/seamonkey/Makefile:1.191 Sat Jun  1 23:54:51 2019
+++ pkgsrc/www/seamonkey/Makefile       Thu Jun 13 10:53:11 2019
@@ -1,8 +1,8 @@
-# $NetBSD: Makefile,v 1.191 2019/06/01 23:54:51 nia Exp $
+# $NetBSD: Makefile,v 1.192 2019/06/13 10:53:11 nia Exp $
 
 DISTNAME=      seamonkey-${SM_VER}.source
 PKGNAME=       seamonkey-${SM_VER:S/b/beta/}
-PKGREVISION=   9
+PKGREVISION=   10
 SM_VER=                2.49.4
 CATEGORIES=    www
 MASTER_SITES=  ${MASTER_SITE_MOZILLA:=seamonkey/releases/${SM_VER}/source/}
@@ -63,6 +63,7 @@ CHECK_WRKREF_SKIP=    lib/seamonkey/chrome/
 
 post-extract:
        mv ${WRKSRC}/mozilla/gfx/ycbcr/yuv_row_arm.s ${WRKSRC}/mozilla/gfx/ycbcr/yuv_row_arm.S
+       ${CP} ${FILESDIR}/cubeb_sun.c ${WRKSRC}/mozilla/media/libcubeb/src
 
 pre-configure:
        cd ${WRKSRC} && mkdir ${OBJDIR}

Index: pkgsrc/www/seamonkey/distinfo
diff -u pkgsrc/www/seamonkey/distinfo:1.157 pkgsrc/www/seamonkey/distinfo:1.158
--- pkgsrc/www/seamonkey/distinfo:1.157 Sat Jun  1 23:54:51 2019
+++ pkgsrc/www/seamonkey/distinfo       Thu Jun 13 10:53:11 2019
@@ -1,4 +1,4 @@
-$NetBSD: distinfo,v 1.157 2019/06/01 23:54:51 nia Exp $
+$NetBSD: distinfo,v 1.158 2019/06/13 10:53:11 nia Exp $
 
 SHA1 (seamonkey-2.49.4.source.tar.xz) = e9fa6d1c57e9141a299f6ec093683fb105ea6657
 RMD160 (seamonkey-2.49.4.source.tar.xz) = 072caadf376b7726356d6121abff87cc1fb62144
@@ -63,12 +63,12 @@ SHA1 (patch-mozilla_js_src_moz.build) = 
 SHA1 (patch-mozilla_js_src_old-configure.in) = 5aed3a3e211aaa8e49fe97f406f94c6975648e9d
 SHA1 (patch-mozilla_js_xpconnect_src_XPCConvert.cpp) = d866b89d5d741125430c0e3ac900c7ead401a495
 SHA1 (patch-mozilla_js_xpconnect_src_xpcprivate.h) = 6a836224fa46f2b30d337a7893c668ab0cf807cd
-SHA1 (patch-mozilla_media_libcubeb_src_cubeb.c) = b760a10ef1fdff5360b2644913df34d60f2ffbf6
+SHA1 (patch-mozilla_media_libcubeb_src_cubeb.c) = f936368fc7c54c4a808737068fd2f15cf2450fd0
 SHA1 (patch-mozilla_media_libcubeb_src_cubeb__alsa.c) = 06d21721261b85412085b3336aa8c3712c0d5551
 SHA1 (patch-mozilla_media_libcubeb_src_cubeb__oss.c) = 2c4a7cf4253ad098245edd91c2fa5207fe9b9c53
-SHA1 (patch-mozilla_media_libcubeb_src_moz.build) = 20cd45532c053be8b57177c4161537047e365be3
+SHA1 (patch-mozilla_media_libcubeb_src_moz.build) = 71d1e95ecb888905fe50b9900ed929253b0dd231
 SHA1 (patch-mozilla_media_libcubeb_tests_moz.build) = af24f693c6cf0cd7c6dfb2d7ca4ad17d6a77cc97
-SHA1 (patch-mozilla_media_libcubeb_update.sh) = 2ff28e8691e97787ba881b836065b6e4eecd72af
+SHA1 (patch-mozilla_media_libcubeb_update.sh) = 4bb209f62be383733104ddb58b978e9892629881
 SHA1 (patch-mozilla_media_libsoundtouch_src_cpu__detect__x86.cpp) = 1029bc985d6eadf3f030492a8aa51d008fa27740
 SHA1 (patch-mozilla_media_libsoundtouch_src_soundtouch__perms.h) = f04b476a0652aa125c89954bb962528a25b9e962
 SHA1 (patch-mozilla_media_libtheora_lib_arm_armcpu.c) = 544bbb808bbecb24b519a96358c956dcacdfd5be
@@ -88,7 +88,7 @@ SHA1 (patch-mozilla_modules_libjar_nsZip
 SHA1 (patch-mozilla_mozglue_build_arm.cpp) = 592ae5ce1a404227cc2ab6a06418cc813c5743c9
 SHA1 (patch-mozilla_mozglue_build_arm.h) = 94e2b1a1a9ebf20bfa8a542066aa0dad475db320
 SHA1 (patch-mozilla_netwerk_dns_moz.build) = d87c07ebfa01d32ca826932af733b37ce586e9f7
-SHA1 (patch-mozilla_old-configure.in) = 100f03e97fb362defbf4d26b82b64508855debbe
+SHA1 (patch-mozilla_old-configure.in) = e98e393a90c8283259d7c6fe2a2fff03f2747e4d
 SHA1 (patch-mozilla_toolkit_components_osfile_modules_osfile__unix__back.jsm) = db4084f6a7dba2fc5d35cd256c6f149fabbf7bc7
 SHA1 (patch-mozilla_toolkit_components_osfile_modules_osfile__unix__front.jsm) = 1e8d0883d3cc12541020c7df0b1d67f60e7391f5
 SHA1 (patch-mozilla_toolkit_components_protobuf_src_google_protobuf_stubs_atomicops.h) = 0b5cad33bc9a90f4ae2d6346065707b642aba3a9

Index: pkgsrc/www/seamonkey/options.mk
diff -u pkgsrc/www/seamonkey/options.mk:1.40 pkgsrc/www/seamonkey/options.mk:1.41
--- pkgsrc/www/seamonkey/options.mk:1.40        Sat Jun  1 20:41:45 2019
+++ pkgsrc/www/seamonkey/options.mk     Thu Jun 13 10:53:11 2019
@@ -1,4 +1,4 @@
-# $NetBSD: options.mk,v 1.40 2019/06/01 20:41:45 nia Exp $
+# $NetBSD: options.mk,v 1.41 2019/06/13 10:53:11 nia Exp $
 
 PKG_OPTIONS_VAR=       PKG_OPTIONS.seamonkey
 
@@ -9,7 +9,7 @@ PKG_SUPPORTED_OPTIONS+= webrtc pulseaudi
 
 PLIST_VARS+=   debug gnome jemalloc
 
-PKG_SUGGESTED_OPTIONS= gtk2
+PKG_SUGGESTED_OPTIONS= gtk3
 
 PKG_SUGGESTED_OPTIONS.Linux+=  mozilla-jemalloc
 PKG_SUGGESTED_OPTIONS.SunOS+=  mozilla-jemalloc

Index: pkgsrc/www/seamonkey/patches/patch-mozilla_media_libcubeb_src_cubeb.c
diff -u pkgsrc/www/seamonkey/patches/patch-mozilla_media_libcubeb_src_cubeb.c:1.3 pkgsrc/www/seamonkey/patches/patch-mozilla_media_libcubeb_src_cubeb.c:1.4
--- pkgsrc/www/seamonkey/patches/patch-mozilla_media_libcubeb_src_cubeb.c:1.3   Fri Nov 10 22:45:27 2017
+++ pkgsrc/www/seamonkey/patches/patch-mozilla_media_libcubeb_src_cubeb.c       Thu Jun 13 10:53:11 2019
@@ -1,8 +1,18 @@
-$NetBSD: patch-mozilla_media_libcubeb_src_cubeb.c,v 1.3 2017/11/10 22:45:27 ryoon Exp $
+$NetBSD: patch-mozilla_media_libcubeb_src_cubeb.c,v 1.4 2019/06/13 10:53:11 nia Exp $
 
---- mozilla/media/libcubeb/src/cubeb.c.orig    2017-10-16 07:19:00.000000000 +0000
+--- mozilla/media/libcubeb/src/cubeb.c.orig    2018-07-12 02:17:30.000000000 +0000
 +++ mozilla/media/libcubeb/src/cubeb.c
-@@ -54,6 +54,9 @@ int audiotrack_init(cubeb ** context, ch
+@@ -45,6 +45,9 @@ int wasapi_init(cubeb ** context, char c
+ #if defined(USE_SNDIO)
+ int sndio_init(cubeb ** context, char const * context_name);
+ #endif
++#if defined(USE_SUN)
++int sun_init(cubeb ** context, char const * context_name);
++#endif
+ #if defined(USE_OPENSL)
+ int opensl_init(cubeb ** context, char const * context_name);
+ #endif
+@@ -54,6 +57,9 @@ int audiotrack_init(cubeb ** context, ch
  #if defined(USE_KAI)
  int kai_init(cubeb ** context, char const * context_name);
  #endif
@@ -12,7 +22,17 @@ $NetBSD: patch-mozilla_media_libcubeb_sr
  
  
  static int
-@@ -141,6 +144,9 @@ cubeb_init(cubeb ** context, char const 
+@@ -132,6 +138,9 @@ cubeb_init(cubeb ** context, char const 
+ #if defined(USE_SNDIO)
+     sndio_init,
+ #endif
++#if defined(USE_SUN)
++    sun_init,
++#endif
+ #if defined(USE_OPENSL)
+     opensl_init,
+ #endif
+@@ -141,6 +150,9 @@ cubeb_init(cubeb ** context, char const 
  #if defined(USE_KAI)
      kai_init,
  #endif

Index: pkgsrc/www/seamonkey/patches/patch-mozilla_media_libcubeb_src_moz.build
diff -u pkgsrc/www/seamonkey/patches/patch-mozilla_media_libcubeb_src_moz.build:1.7 pkgsrc/www/seamonkey/patches/patch-mozilla_media_libcubeb_src_moz.build:1.8
--- pkgsrc/www/seamonkey/patches/patch-mozilla_media_libcubeb_src_moz.build:1.7 Fri Aug 18 23:55:07 2017
+++ pkgsrc/www/seamonkey/patches/patch-mozilla_media_libcubeb_src_moz.build     Thu Jun 13 10:53:11 2019
@@ -1,8 +1,8 @@
-$NetBSD: patch-mozilla_media_libcubeb_src_moz.build,v 1.7 2017/08/18 23:55:07 ryoon Exp $
+$NetBSD: patch-mozilla_media_libcubeb_src_moz.build,v 1.8 2019/06/13 10:53:11 nia Exp $
 
---- mozilla/media/libcubeb/src/moz.build.orig  2017-07-07 05:37:16.000000000 +0000
+--- mozilla/media/libcubeb/src/moz.build.orig  2018-07-12 02:17:29.000000000 +0000
 +++ mozilla/media/libcubeb/src/moz.build
-@@ -24,6 +24,12 @@ if CONFIG['MOZ_PULSEAUDIO'] or CONFIG['M
+@@ -24,6 +24,18 @@ if CONFIG['MOZ_PULSEAUDIO'] or CONFIG['M
          'cubeb_resampler.cpp',
      ]
  
@@ -12,10 +12,16 @@ $NetBSD: patch-mozilla_media_libcubeb_sr
 +    ]
 +    DEFINES['USE_OSS'] = True
 +
++if CONFIG['MOZ_SUNAUDIO']:
++    SOURCES += [
++        'cubeb_sun.c',
++    ]
++    DEFINES['USE_SUN'] = True
++
  if CONFIG['MOZ_PULSEAUDIO']:
      SOURCES += [
          'cubeb_pulse.c',
-@@ -81,6 +87,7 @@ if CONFIG['OS_TARGET'] == 'Android':
+@@ -81,6 +93,7 @@ if CONFIG['OS_TARGET'] == 'Android':
  
  FINAL_LIBRARY = 'gkmedias'
  

Index: pkgsrc/www/seamonkey/patches/patch-mozilla_media_libcubeb_update.sh
diff -u pkgsrc/www/seamonkey/patches/patch-mozilla_media_libcubeb_update.sh:1.1 pkgsrc/www/seamonkey/patches/patch-mozilla_media_libcubeb_update.sh:1.2
--- pkgsrc/www/seamonkey/patches/patch-mozilla_media_libcubeb_update.sh:1.1     Fri Aug 18 23:55:07 2017
+++ pkgsrc/www/seamonkey/patches/patch-mozilla_media_libcubeb_update.sh Thu Jun 13 10:53:11 2019
@@ -1,8 +1,8 @@
-$NetBSD: patch-mozilla_media_libcubeb_update.sh,v 1.1 2017/08/18 23:55:07 ryoon Exp $
+$NetBSD: patch-mozilla_media_libcubeb_update.sh,v 1.2 2019/06/13 10:53:11 nia Exp $
 
---- mozilla/media/libcubeb/update.sh.orig      2017-07-07 05:37:16.000000000 +0000
+--- mozilla/media/libcubeb/update.sh.orig      2018-07-12 02:17:34.000000000 +0000
 +++ mozilla/media/libcubeb/update.sh
-@@ -16,6 +16,7 @@ cp $1/src/cubeb_audiounit.cpp src
+@@ -17,6 +17,7 @@ cp $1/src/cubeb_audiounit.cpp src
  cp $1/src/cubeb_osx_run_loop.h src
  cp $1/src/cubeb_jack.cpp src
  cp $1/src/cubeb_opensl.c src
@@ -10,3 +10,11 @@ $NetBSD: patch-mozilla_media_libcubeb_up
  cp $1/src/cubeb_panner.cpp src
  cp $1/src/cubeb_panner.h src
  cp $1/src/cubeb_pulse.c src
+@@ -25,6 +26,7 @@ cp $1/src/cubeb_resampler.h src
+ cp $1/src/cubeb_resampler_internal.h src
+ cp $1/src/cubeb_ring_array.h src
+ cp $1/src/cubeb_sndio.c src
++cp $1/src/cubeb_sun.c src
+ cp $1/src/cubeb_utils.h src
+ cp $1/src/cubeb_utils_unix.h src
+ cp $1/src/cubeb_utils_win.h src

Index: pkgsrc/www/seamonkey/patches/patch-mozilla_old-configure.in
diff -u pkgsrc/www/seamonkey/patches/patch-mozilla_old-configure.in:1.4 pkgsrc/www/seamonkey/patches/patch-mozilla_old-configure.in:1.5
--- pkgsrc/www/seamonkey/patches/patch-mozilla_old-configure.in:1.4     Sat Jun  1 20:41:45 2019
+++ pkgsrc/www/seamonkey/patches/patch-mozilla_old-configure.in Thu Jun 13 10:53:11 2019
@@ -1,4 +1,4 @@
-$NetBSD: patch-mozilla_old-configure.in,v 1.4 2019/06/01 20:41:45 nia Exp $
+$NetBSD: patch-mozilla_old-configure.in,v 1.5 2019/06/13 10:53:11 nia Exp $
 
 --- mozilla/old-configure.in.orig      2018-07-12 02:18:02.000000000 +0000
 +++ mozilla/old-configure.in
@@ -146,18 +146,21 @@ $NetBSD: patch-mozilla_old-configure.in,
  dnl system libvpx Support
  dnl ========================================================
  MOZ_ARG_WITH_BOOL(system-libvpx,
-@@ -3208,6 +3312,67 @@ AC_DEFINE(MOZ_WEBM_ENCODER)
+@@ -3208,6 +3312,71 @@ AC_DEFINE(MOZ_WEBM_ENCODER)
  AC_SUBST(MOZ_WEBM_ENCODER)
  
  dnl ==================================
-+dnl = Check OSS availability
++dnl = Check OSS/sunaudio availability
 +dnl ==================================
 +
-+dnl If using Linux, Solaris or BSDs, ensure that OSS is available
++dnl If using Linux, Solaris or BSDs, ensure that OSS or sunaudio is available
 +case "$OS_TARGET" in
-+Linux|SunOS|DragonFly|FreeBSD|NetBSD|GNU/kFreeBSD)
++Linux|DragonFly|FreeBSD|GNU/kFreeBSD)
 +    MOZ_OSS=1
 +    ;;
++SunOS|NetBSD)
++    MOZ_SUNAUDIO=1
++    ;;
 +esac
 +
 +MOZ_ARG_WITH_STRING(oss,
@@ -209,12 +212,13 @@ $NetBSD: patch-mozilla_old-configure.in,
 +AC_SUBST(MOZ_OSS)
 +AC_SUBST_LIST(MOZ_OSS_CFLAGS)
 +AC_SUBST_LIST(MOZ_OSS_LIBS)
++AC_SUBST(MOZ_SUNAUDIO)
 +
 +dnl ==================================
  dnl = Check alsa availability on Linux
  dnl ==================================
  
-@@ -5023,6 +5188,27 @@ if test "$USE_FC_FREETYPE"; then
+@@ -5023,6 +5192,27 @@ if test "$USE_FC_FREETYPE"; then
  fi
  
  dnl ========================================================

Added files:

Index: pkgsrc/www/seamonkey/files/cubeb_sun.c
diff -u /dev/null pkgsrc/www/seamonkey/files/cubeb_sun.c:1.1
--- /dev/null   Thu Jun 13 10:53:12 2019
+++ pkgsrc/www/seamonkey/files/cubeb_sun.c      Thu Jun 13 10:53:11 2019
@@ -0,0 +1,777 @@
+/*
+ * Copyright © 2019 Nia Alarie
+ *
+ * This program is made available under an ISC-style license.  See the
+ * accompanying file LICENSE for details.
+ */
+#include <sys/audioio.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <poll.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "cubeb/cubeb.h"
+#include "cubeb-internal.h"
+
+#define CUBEB_OLD_API /* seamonkey and older firefox */
+
+#define BYTES_TO_FRAMES(bytes, channels) \
+  (bytes / (channels * sizeof(int16_t)))
+
+#define FRAMES_TO_BYTES(frames, channels) \
+  (frames * (channels * sizeof(int16_t)))
+
+/* Default to 4 + 1 for the default device. */
+#ifndef SUN_DEVICE_COUNT
+#define SUN_DEVICE_COUNT (5)
+#endif
+
+/* Supported well by most hardware. */
+#ifndef SUN_PREFER_RATE
+#define SUN_PREFER_RATE (48000)
+#endif
+
+/* Standard acceptable minimum. */
+#ifndef SUN_LATENCY_MS
+#define SUN_LATENCY_MS (40)
+#endif
+
+#ifndef SUN_DEFAULT_DEVICE
+#define SUN_DEFAULT_DEVICE "/dev/audio"
+#endif
+
+#ifndef SUN_POLL_TIMEOUT
+#define SUN_POLL_TIMEOUT (1000)
+#endif
+
+#ifndef SUN_BUFFER_FRAMES
+#define SUN_BUFFER_FRAMES (32)
+#endif
+
+/*
+ * Supported on NetBSD regardless of hardware.
+ */
+
+#ifndef SUN_MAX_CHANNELS
+# ifdef __NetBSD__
+#  define SUN_MAX_CHANNELS (12)
+# else
+#  define SUN_MAX_CHANNELS (2)
+# endif
+#endif
+
+#ifndef SUN_MIN_RATE
+#define SUN_MIN_RATE (1000)
+#endif
+
+#ifndef SUN_MAX_RATE
+#define SUN_MAX_RATE (192000)
+#endif
+
+static struct cubeb_ops const sun_ops;
+
+struct cubeb {
+  struct cubeb_ops const * ops;
+};
+
+struct cubeb_stream {
+  struct cubeb * context;
+  void * user_ptr;
+  pthread_t thread;
+  pthread_mutex_t mutex; /* protects running, volume, frames_written */
+  int floating;
+  int running;
+  int play_fd;
+  int record_fd;
+  float volume;
+  struct audio_info p_info; /* info for the play fd */
+  struct audio_info r_info; /* info for the record fd */
+  cubeb_data_callback data_cb;
+  cubeb_state_callback state_cb;
+  int16_t * play_buf;
+  int16_t * record_buf;
+  float * f_play_buf;
+  float * f_record_buf;
+  char input_name[32];
+  char output_name[32];
+  uint64_t frames_written;
+};
+
+int
+sun_init(cubeb ** context, char const * context_name)
+{
+  cubeb * c;
+
+  (void)context_name;
+  if ((c = calloc(1, sizeof(cubeb))) == NULL) {
+    return CUBEB_ERROR;
+  }
+  c->ops = &sun_ops;
+  *context = c;
+  return CUBEB_OK;
+}
+
+static void
+sun_destroy(cubeb * context)
+{
+  free(context);
+}
+
+static char const *
+sun_get_backend_id(cubeb * context)
+{
+  return "sun";
+}
+
+static int
+sun_get_preferred_sample_rate(cubeb * context, uint32_t * rate)
+{
+  (void)context;
+
+  *rate = SUN_PREFER_RATE;
+  return CUBEB_OK;
+}
+
+static int
+sun_get_max_channel_count(cubeb * context, uint32_t * max_channels)
+{
+  (void)context;
+
+  *max_channels = SUN_MAX_CHANNELS;
+  return CUBEB_OK;
+}
+
+static int
+sun_get_min_latency(cubeb * context, cubeb_stream_params params,
+                    uint32_t * latency_frames)
+{
+  (void)context;
+
+  *latency_frames = SUN_LATENCY_MS * params.rate / 1000;
+  return CUBEB_OK;
+}
+
+static int
+sun_get_hwinfo(const char * device, struct audio_info * format,
+               int * props, struct audio_device * dev)
+{
+  int fd = -1;
+
+  if ((fd = open(device, O_RDONLY)) == -1) {
+    goto error;
+  }
+#ifdef AUDIO_GETFORMAT
+  if (ioctl(fd, AUDIO_GETFORMAT, format) != 0) {
+    goto error;
+  }
+#endif
+#ifdef AUDIO_GETPROPS
+  if (ioctl(fd, AUDIO_GETPROPS, props) != 0) {
+    goto error;
+  }
+#endif
+  if (ioctl(fd, AUDIO_GETDEV, dev) != 0) {
+    goto error;
+  }
+  close(fd);
+  return CUBEB_OK;
+error:
+  if (fd != -1) {
+    close(fd);
+  }
+  return CUBEB_ERROR;
+}
+
+/*
+ * XXX: PR kern/54264
+ */
+static int
+sun_prinfo_verify_sanity(struct audio_prinfo * prinfo)
+{
+   return prinfo->precision >= 8 && prinfo->precision <= 32 &&
+     prinfo->channels >= 1 && prinfo->channels < SUN_MAX_CHANNELS &&
+     prinfo->sample_rate < SUN_MAX_RATE && prinfo->sample_rate > SUN_MIN_RATE;
+}
+
+#ifndef CUBEB_OLD_API
+static int
+sun_enumerate_devices(cubeb * context, cubeb_device_type type,
+                      cubeb_device_collection * collection)
+{
+  unsigned i;
+  cubeb_device_info device = {0};
+  char dev[16] = SUN_DEFAULT_DEVICE;
+  char dev_friendly[64];
+  struct audio_info hwfmt;
+  struct audio_device hwname;
+  struct audio_prinfo *prinfo = NULL;
+  int hwprops;
+
+  collection->device = calloc(SUN_DEVICE_COUNT, sizeof(cubeb_device_info));
+  if (collection->device == NULL) {
+    return CUBEB_ERROR;
+  }
+  collection->count = 0;
+
+  for (i = 0; i < SUN_DEVICE_COUNT; ++i) {
+    if (i > 0) {
+      (void)snprintf(dev, sizeof(dev), "/dev/audio%u", i - 1);
+    }
+    if (sun_get_hwinfo(dev, &hwfmt, &hwprops, &hwname) != CUBEB_OK) {
+      continue;
+    }
+#ifdef AUDIO_GETPROPS
+    device.type = 0;
+    if ((hwprops & AUDIO_PROP_CAPTURE) != 0 &&
+        sun_prinfo_verify_sanity(&hwfmt.record)) {
+      /* the device supports recording, probably */
+      device.type |= CUBEB_DEVICE_TYPE_INPUT;
+    }
+    if ((hwprops & AUDIO_PROP_PLAYBACK) != 0 &&
+        sun_prinfo_verify_sanity(&hwfmt.play)) {
+      /* the device supports playback, probably */
+      device.type |= CUBEB_DEVICE_TYPE_OUTPUT;
+    }
+    switch (device.type) {
+    case 0:
+      /* device doesn't do input or output, aliens probably involved */
+      continue;
+    case CUBEB_DEVICE_TYPE_INPUT:
+      if ((type & CUBEB_DEVICE_TYPE_INPUT) == 0) {
+        /* this device is input only, not scanning for those, skip it */
+        continue;
+      }
+      break;
+    case CUBEB_DEVICE_TYPE_OUTPUT:
+      if ((type & CUBEB_DEVICE_TYPE_OUTPUT) == 0) {
+        /* this device is output only, not scanning for those, skip it */
+        continue;
+      }
+      break;
+    }
+    if ((type & CUBEB_DEVICE_TYPE_INPUT) != 0) {
+      prinfo = &hwfmt.record;
+    }
+    if ((type & CUBEB_DEVICE_TYPE_OUTPUT) != 0) {
+      prinfo = &hwfmt.play;
+    }
+#endif
+    if (i > 0) {
+      (void)snprintf(dev_friendly, sizeof(dev_friendly), "%s %s %s (%d)",
+                     hwname.name, hwname.version, hwname.config, i - 1);
+    } else {
+      (void)snprintf(dev_friendly, sizeof(dev_friendly), "%s %s %s (default)",
+                     hwname.name, hwname.version, hwname.config);
+    }
+    device.devid = (void *)(uintptr_t)i;
+    device.device_id = strdup(dev);
+    device.friendly_name = strdup(dev_friendly);
+    device.group_id = strdup(dev);
+    device.vendor_name = strdup(hwname.name);
+    device.type = type;
+    device.state = CUBEB_DEVICE_STATE_ENABLED;
+    device.preferred = (i == 0) ? CUBEB_DEVICE_PREF_ALL : CUBEB_DEVICE_PREF_NONE;
+#ifdef AUDIO_GETFORMAT
+    device.max_channels = prinfo->channels;
+    device.default_rate = prinfo->sample_rate;
+#else
+    device.max_channels = 2;
+    device.default_rate = SUN_PREFER_RATE;
+#endif
+    device.default_format = CUBEB_DEVICE_FMT_S16NE;
+    device.format = CUBEB_DEVICE_FMT_S16NE;
+    device.min_rate = SUN_MIN_RATE;
+    device.max_rate = SUN_MAX_RATE;
+    device.latency_lo = SUN_LATENCY_MS * SUN_MIN_RATE / 1000;
+    device.latency_hi = SUN_LATENCY_MS * SUN_MAX_RATE / 1000;
+    collection->device[collection->count++] = device;
+  }
+  return CUBEB_OK;
+}
+#endif
+
+#ifndef CUBEB_OLD_API
+static int
+sun_device_collection_destroy(cubeb * context,
+                              cubeb_device_collection * collection)
+{
+  unsigned i;
+
+  for (i = 0; i < collection->count; ++i) {
+    free((char *)collection->device[i].device_id);
+    free((char *)collection->device[i].friendly_name);
+    free((char *)collection->device[i].group_id);
+    free((char *)collection->device[i].vendor_name);
+  }
+  free(collection->device);
+  return CUBEB_OK;
+}
+#endif
+
+static int
+sun_copy_params(int fd, cubeb_stream * stream, cubeb_stream_params * params,
+                struct audio_info * info, struct audio_prinfo * prinfo)
+{
+  prinfo->channels = params->channels;
+  prinfo->sample_rate = params->rate;
+  prinfo->precision = 16;
+#ifdef AUDIO_ENCODING_SLINEAR_LE
+  switch (params->format) {
+  case CUBEB_SAMPLE_S16LE:
+    prinfo->encoding = AUDIO_ENCODING_SLINEAR_LE;
+    break;
+  case CUBEB_SAMPLE_S16BE:
+    prinfo->encoding = AUDIO_ENCODING_SLINEAR_BE;
+    break;
+  case CUBEB_SAMPLE_FLOAT32NE:
+    stream->floating = 1;
+    prinfo->encoding = AUDIO_ENCODING_SLINEAR;
+    break;
+  default:
+    LOG("Unsupported format");
+    return CUBEB_ERROR_INVALID_FORMAT;
+  }
+#else
+  switch (params->format) {
+  case CUBEB_SAMPLE_S16NE:
+    prinfo->encoding = AUDIO_ENCODING_LINEAR;
+    break;
+  case CUBEB_SAMPLE_FLOAT32NE:
+    stream->floating = 1;
+    prinfo->encoding = AUDIO_ENCODING_LINEAR;
+    break;
+  default:
+    LOG("Unsupported format");
+    return CUBEB_ERROR_INVALID_FORMAT;
+  }
+#endif
+  if (ioctl(fd, AUDIO_SETINFO, info) == -1) {
+    return CUBEB_ERROR;
+  }
+  if (ioctl(fd, AUDIO_GETINFO, info) == -1) {
+    return CUBEB_ERROR;
+  }
+  return CUBEB_OK;
+}
+
+static int
+sun_stream_stop(cubeb_stream * s)
+{
+  pthread_mutex_lock(&s->mutex);
+  if (s->running) {
+    s->running = 0;
+    pthread_mutex_unlock(&s->mutex);
+    pthread_join(s->thread, NULL);
+  } else {
+    pthread_mutex_unlock(&s->mutex);
+  }
+  return CUBEB_OK;
+}
+
+static void
+sun_stream_destroy(cubeb_stream * s)
+{
+  pthread_mutex_destroy(&s->mutex);
+  sun_stream_stop(s);
+  if (s->play_fd != -1) {
+    close(s->play_fd);
+  }
+  if (s->record_fd != -1) {
+    close(s->record_fd);
+  }
+  free(s->f_play_buf);
+  free(s->f_record_buf);
+  free(s->play_buf);
+  free(s->record_buf);
+  free(s);
+}
+
+static void
+sun_float_to_linear(float * in, int16_t * out,
+                    unsigned channels, long frames, float vol)
+{
+  unsigned i, sample_count = frames * channels;
+  float multiplier = vol * 0x8000;
+
+  for (i = 0; i < sample_count; ++i) {
+    int32_t sample = lrintf(in[i] * multiplier);
+    if (sample < -0x8000) {
+      out[i] = -0x8000;
+    } else if (sample > 0x7fff) {
+      out[i] = 0x7fff;
+    } else {
+      out[i] = sample;
+    }
+  }
+}
+
+static void
+sun_linear_to_float(int16_t * in, float * out,
+                    unsigned channels, long frames)
+{
+  unsigned i, sample_count = frames * channels;
+
+  for (i = 0; i < sample_count; ++i) {
+    out[i] = (1.0 / 0x8000) * in[i];
+  }
+}
+
+static void
+sun_linear_set_vol(int16_t * buf, unsigned channels, long frames, float vol)
+{
+  unsigned i, sample_count = frames * channels;
+  int32_t multiplier = vol * 0x8000;
+
+  for (i = 0; i < sample_count; ++i) {
+    buf[i] = (buf[i] * multiplier) >> 15;
+  }
+}
+
+static void *
+sun_io_routine(void * arg)
+{
+  cubeb_stream *s = arg;
+  cubeb_state state = CUBEB_STATE_STARTED;
+  size_t to_read = 0;
+  long to_write = 0;
+  size_t write_ofs = 0;
+  size_t read_ofs = 0;
+  struct pollfd pfds[1];
+  int drain = 0;
+
+  s->state_cb(s, s->user_ptr, CUBEB_STATE_STARTED);
+  while (state != CUBEB_STATE_ERROR) {
+    pthread_mutex_lock(&s->mutex);
+    if (!s->running) {
+      pthread_mutex_unlock(&s->mutex);
+      state = CUBEB_STATE_STOPPED;
+      break;
+    }
+    pthread_mutex_unlock(&s->mutex);
+    if (s->floating) {
+      if (s->record_fd != -1) {
+        sun_linear_to_float(s->record_buf, s->f_record_buf,
+                            s->r_info.record.channels, SUN_BUFFER_FRAMES);
+      }
+      to_write = s->data_cb(s, s->user_ptr,
+                            s->f_record_buf, s->f_play_buf, SUN_BUFFER_FRAMES);
+      if (to_write == CUBEB_ERROR) {
+        state = CUBEB_STATE_ERROR;
+        break;
+      }
+      if (s->play_fd != -1) {
+        pthread_mutex_lock(&s->mutex);
+        sun_float_to_linear(s->f_play_buf, s->play_buf,
+                            s->p_info.play.channels, to_write, s->volume);
+        pthread_mutex_unlock(&s->mutex);
+      }
+    } else {
+      to_write = s->data_cb(s, s->user_ptr,
+                            s->record_buf, s->play_buf, SUN_BUFFER_FRAMES);
+      if (to_write == CUBEB_ERROR) {
+        state = CUBEB_STATE_ERROR;
+        break;
+      }
+      if (s->play_fd != -1) {
+        pthread_mutex_lock(&s->mutex);
+        sun_linear_set_vol(s->play_buf, s->p_info.play.channels, to_write, s->volume);
+        pthread_mutex_unlock(&s->mutex);
+      }
+    }
+    if (to_write < SUN_BUFFER_FRAMES) {
+      drain = 1;
+    }
+    pfds[0].fd = s->play_fd;
+    if (s->play_fd != -1) {
+      if (to_write > 0) {
+        pfds[0].events = POLLOUT;
+      }
+    } else {
+      pfds[0].events = 0;
+      to_write = 0;
+    }
+    to_read = s->record_fd != -1 ? SUN_BUFFER_FRAMES : 0;
+    write_ofs = 0;
+    read_ofs = 0;
+    while (to_write > 0 || to_read > 0) {
+      size_t bytes;
+      ssize_t n, frames;
+
+      if (pfds[0].events != 0 && poll(pfds, 1, SUN_POLL_TIMEOUT) == -1) {
+        LOG("poll failed");
+        state = CUBEB_STATE_ERROR;
+        break;
+      }
+      if ((pfds[0].revents & POLLHUP) || (pfds[0].revents & POLLERR)) {
+        LOG("audio device disconnected");
+        state = CUBEB_STATE_ERROR;
+        break;
+      }
+      if (to_write > 0 && (pfds[0].revents & POLLOUT)) {
+        bytes = FRAMES_TO_BYTES(to_write, s->p_info.play.channels);
+        if ((n = write(s->play_fd, s->play_buf + write_ofs, bytes)) < 0) {
+          state = CUBEB_STATE_ERROR;
+          break;
+        }
+        frames = BYTES_TO_FRAMES(n, s->p_info.play.channels);
+        pthread_mutex_lock(&s->mutex);
+        s->frames_written += frames;
+        pthread_mutex_unlock(&s->mutex);
+        to_write -= frames;
+        write_ofs += frames;
+        if (to_write == 0) {
+          pfds[0].events = 0;
+        }
+      }
+      if (to_read > 0) {
+        bytes = FRAMES_TO_BYTES(to_read, s->r_info.record.channels);
+        if ((n = read(s->record_fd, s->record_buf + read_ofs, bytes)) < 0) {
+          state = CUBEB_STATE_ERROR;
+          break;
+        }
+        frames = BYTES_TO_FRAMES(n, s->r_info.record.channels);
+        to_read -= frames;
+        read_ofs += frames;
+      }
+    }
+    if (drain && state != CUBEB_STATE_ERROR) {
+      state = CUBEB_STATE_DRAINED;
+      break;
+    }
+  }
+  s->state_cb(s, s->user_ptr, state);
+  return NULL;
+}
+
+static int
+sun_stream_init(cubeb * context,
+                cubeb_stream ** stream,
+                char const * stream_name,
+                cubeb_devid input_device,
+                cubeb_stream_params * input_stream_params,
+                cubeb_devid output_device,
+                cubeb_stream_params * output_stream_params,
+                unsigned latency_frames,
+                cubeb_data_callback data_callback,
+                cubeb_state_callback state_callback,
+                void * user_ptr)
+{
+  int ret = CUBEB_OK;
+  cubeb_stream *s = NULL;
+
+  (void)stream_name;
+  (void)latency_frames;
+  if ((s = calloc(1, sizeof(cubeb_stream))) == NULL) {
+    ret = CUBEB_ERROR;
+    goto error;
+  }
+  s->record_fd = -1;
+  s->play_fd = -1;
+  if (input_device != 0) {
+    snprintf(s->input_name, sizeof(s->input_name),
+      "/dev/audio%zu", (uintptr_t)input_device - 1);
+  } else {
+    snprintf(s->input_name, sizeof(s->input_name), "%s", SUN_DEFAULT_DEVICE);
+  }
+  if (output_device != 0) {
+    snprintf(s->output_name, sizeof(s->output_name),
+      "/dev/audio%zu", (uintptr_t)output_device - 1);
+  } else {
+    snprintf(s->output_name, sizeof(s->output_name), "%s", SUN_DEFAULT_DEVICE);
+  }
+  if (input_stream_params != NULL) {
+#ifndef CUBEB_OLD_API
+    if (input_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK) {
+      LOG("Loopback not supported");
+      ret = CUBEB_ERROR_NOT_SUPPORTED;
+      goto error;
+    }
+#endif
+    if (s->record_fd == -1) {
+      if ((s->record_fd = open(s->input_name, O_RDONLY)) == -1) {
+        LOG("Audio device cannot be opened as read-only");
+        ret = CUBEB_ERROR_DEVICE_UNAVAILABLE;
+        goto error;
+      }
+    }
+    AUDIO_INITINFO(&s->r_info);
+#ifdef AUMODE_RECORD
+    s->r_info.mode = AUMODE_RECORD;
+#endif
+    if ((ret = sun_copy_params(s->record_fd, s, input_stream_params,
+                               &s->r_info, &s->r_info.record)) != CUBEB_OK) {
+      LOG("Setting record params failed");
+      goto error;
+    }
+  }
+  if (output_stream_params != NULL) {
+#ifndef CUBEB_OLD_API
+    if (output_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK) {
+      LOG("Loopback not supported");
+      ret = CUBEB_ERROR_NOT_SUPPORTED;
+      goto error;
+    }
+#endif
+    if (s->play_fd == -1) {
+      if ((s->play_fd = open(s->output_name, O_WRONLY | O_NONBLOCK)) == -1) {
+        LOG("Audio device cannot be opened as write-only");
+        ret = CUBEB_ERROR_DEVICE_UNAVAILABLE;
+        goto error;
+      }
+    }
+    AUDIO_INITINFO(&s->p_info);
+#ifdef AUMODE_PLAY
+    s->p_info.mode = AUMODE_PLAY;
+#endif
+    if ((ret = sun_copy_params(s->play_fd, s, output_stream_params,
+                               &s->p_info, &s->p_info.play)) != CUBEB_OK) {
+      LOG("Setting play params failed");
+      goto error;
+    }
+  }
+  s->context = context;
+  s->volume = 1.0;
+  s->state_cb = state_callback;
+  s->data_cb = data_callback;
+  s->user_ptr = user_ptr;
+  if (pthread_mutex_init(&s->mutex, NULL) != 0) {
+    LOG("Failed to create mutex");
+    goto error;
+  }
+  if (s->play_fd != -1 && (s->play_buf = calloc(SUN_BUFFER_FRAMES,
+      s->p_info.play.channels * sizeof(int16_t))) == NULL) {
+    ret = CUBEB_ERROR;
+    goto error;
+  }
+  if (s->record_fd != -1 && (s->record_buf = calloc(SUN_BUFFER_FRAMES,
+      s->r_info.record.channels * sizeof(int16_t))) == NULL) {
+    ret = CUBEB_ERROR;
+    goto error;
+  }
+  if (s->floating) {
+    if (s->play_fd != -1 && (s->f_play_buf = calloc(SUN_BUFFER_FRAMES,
+        s->p_info.play.channels * sizeof(float))) == NULL) {
+      ret = CUBEB_ERROR;
+      goto error;
+    }
+    if (s->record_fd != -1 && (s->f_record_buf = calloc(SUN_BUFFER_FRAMES,
+        s->r_info.record.channels * sizeof(float))) == NULL) {
+      ret = CUBEB_ERROR;
+      goto error;
+    }
+  }
+  *stream = s;
+  return CUBEB_OK;
+error:
+  if (s != NULL) {
+    sun_stream_destroy(s);
+  }
+  return ret;
+}
+
+static int
+sun_stream_start(cubeb_stream * s)
+{
+  s->running = 1;
+  if (pthread_create(&s->thread, NULL, sun_io_routine, s) != 0) {
+    LOG("Couldn't create thread");
+    return CUBEB_ERROR;
+  }
+  return CUBEB_OK;
+}
+
+static int
+sun_stream_get_position(cubeb_stream * s, uint64_t * position)
+{
+  pthread_mutex_lock(&s->mutex);
+  *position = s->frames_written;
+  pthread_mutex_unlock(&s->mutex);
+  return CUBEB_OK;
+}
+
+static int
+sun_stream_get_latency(cubeb_stream * stream, uint32_t * latency)
+{
+#ifdef AUDIO_GETBUFINFO
+  struct audio_info info;
+
+  if (ioctl(stream->play_fd, AUDIO_GETBUFINFO, &info) == -1) {
+    return CUBEB_ERROR;
+  }
+
+  *latency = BYTES_TO_FRAMES(info.play.seek + info.blocksize,
+                             info.play.channels);
+  return CUBEB_OK;
+#else
+  cubeb_params params;
+
+  params.rate = stream->p_info.play.sample_rate;
+
+  return sun_get_min_latency(NULL, params, latency);
+#endif
+}
+
+static int
+sun_stream_set_volume(cubeb_stream * stream, float volume)
+{
+  pthread_mutex_lock(&stream->mutex);
+  stream->volume = volume;
+  pthread_mutex_unlock(&stream->mutex);
+  return CUBEB_OK;
+}
+
+static int
+sun_get_current_device(cubeb_stream * stream, cubeb_device ** const device)
+{
+  *device = calloc(1, sizeof(cubeb_device));
+  if (*device == NULL) {
+    return CUBEB_ERROR;
+  }
+  (*device)->input_name = stream->record_fd != -1 ?
+    strdup(stream->input_name) : NULL;
+  (*device)->output_name = stream->play_fd != -1 ?
+    strdup(stream->output_name) : NULL;
+  return CUBEB_OK;
+}
+
+static int
+sun_stream_device_destroy(cubeb_stream * stream, cubeb_device * device)
+{
+  (void)stream;
+  free(device->input_name);
+  free(device->output_name);
+  free(device);
+  return CUBEB_OK;
+}
+
+static struct cubeb_ops const sun_ops = {
+  .init = sun_init,
+  .get_backend_id = sun_get_backend_id,
+  .get_max_channel_count = sun_get_max_channel_count,
+  .get_min_latency = sun_get_min_latency,
+  .get_preferred_sample_rate = sun_get_preferred_sample_rate,
+#ifndef CUBEB_OLD_API
+  .enumerate_devices = sun_enumerate_devices,
+  .device_collection_destroy = sun_device_collection_destroy,
+#endif
+  .destroy = sun_destroy,
+  .stream_init = sun_stream_init,
+  .stream_destroy = sun_stream_destroy,
+  .stream_start = sun_stream_start,
+  .stream_stop = sun_stream_stop,
+#ifndef CUBEB_OLD_API
+  .stream_reset_default_device = NULL,
+#endif
+  .stream_get_position = sun_stream_get_position,
+  .stream_get_latency = sun_stream_get_latency,
+  .stream_set_volume = sun_stream_set_volume,
+  .stream_set_panning = NULL,
+  .stream_get_current_device = sun_get_current_device,
+  .stream_device_destroy = sun_stream_device_destroy,
+  .stream_register_device_changed_callback = NULL,
+  .register_device_collection_changed = NULL
+};



Home | Main Index | Thread Index | Old Index