pkgsrc-Changes archive

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

CVS commit: pkgsrc/www/firefox60



Module Name:    pkgsrc
Committed By:   nia
Date:           Thu Jun 13 14:16:37 UTC 2019

Modified Files:
        pkgsrc/www/firefox60: Makefile distinfo mozilla-common.mk
        pkgsrc/www/firefox60/patches: patch-aa patch-media_libcubeb_src_cubeb.c
            patch-media_libcubeb_src_moz.build patch-media_libcubeb_update.sh
Added Files:
        pkgsrc/www/firefox60/files: cubeb_sun.c

Log Message:
firefox60: Add sun audio backend and make it a default where supported.

This replaces the OSS backend with something that passes the unit tests,
supports additional channels, and supports recording. It will be included
with future versions of Firefox.

Tested with:

* YouTube audio-video sync test
* about:support device detection
* WebRTC microphone recording (using an USB microphone)

While here, fix WebRTC builds.

Note: you can select an audio backend using the about:config variable
media.cubeb.backend. This can be set to options such as sun/pulse/oss.

Let me know if you still need to use the oss backend. It's very
incomplete, buggy, and FreeBSD has already removed it - ideally we
should eventually.

Bump PKGREVISION.


To generate a diff of this commit:
cvs rdiff -u -r1.26 -r1.27 pkgsrc/www/firefox60/Makefile
cvs rdiff -u -r1.15 -r1.16 pkgsrc/www/firefox60/distinfo
cvs rdiff -u -r1.4 -r1.5 pkgsrc/www/firefox60/mozilla-common.mk
cvs rdiff -u -r0 -r1.1 pkgsrc/www/firefox60/files/cubeb_sun.c
cvs rdiff -u -r1.2 -r1.3 pkgsrc/www/firefox60/patches/patch-aa
cvs rdiff -u -r1.1 -r1.2 \
    pkgsrc/www/firefox60/patches/patch-media_libcubeb_src_cubeb.c \
    pkgsrc/www/firefox60/patches/patch-media_libcubeb_src_moz.build \
    pkgsrc/www/firefox60/patches/patch-media_libcubeb_update.sh

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

Modified files:

Index: pkgsrc/www/firefox60/Makefile
diff -u pkgsrc/www/firefox60/Makefile:1.26 pkgsrc/www/firefox60/Makefile:1.27
--- pkgsrc/www/firefox60/Makefile:1.26  Sat Jun  1 19:11:28 2019
+++ pkgsrc/www/firefox60/Makefile       Thu Jun 13 14:16:37 2019
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.26 2019/06/01 19:11:28 maya Exp $
+# $NetBSD: Makefile,v 1.27 2019/06/13 14:16:37 nia Exp $
 
 FIREFOX_VER=           ${MOZ_BRANCH}${MOZ_BRANCH_MINOR}
 MOZ_BRANCH=            60.7
@@ -6,7 +6,7 @@ MOZ_BRANCH_MINOR=       .0esr
 
 DISTNAME=      firefox-${FIREFOX_VER}.source
 PKGNAME=       firefox${MOZ_BRANCH:C/\..*$//}-${MOZ_BRANCH}${MOZ_BRANCH_MINOR:S/b/beta/:S/esr//}
-PKGREVISION=   3
+PKGREVISION=   4
 CATEGORIES=    www
 MASTER_SITES+= ${MASTER_SITE_MOZILLA:=firefox/releases/${FIREFOX_VER}/source/}
 EXTRACT_SUFX=  .tar.xz
@@ -75,6 +75,7 @@ SUBST_VARS.sys-dic=   PREFIX
 
 post-extract:
        mv ${WRKSRC}/gfx/ycbcr/yuv_row_arm.s ${WRKSRC}/gfx/ycbcr/yuv_row_arm.S
+       ${CP} ${FILESDIR}/cubeb_sun.c ${WRKSRC}/media/libcubeb/src/cubeb_sun.c
 
 pre-configure:
        cd ${WRKSRC} && autoconf

Index: pkgsrc/www/firefox60/distinfo
diff -u pkgsrc/www/firefox60/distinfo:1.15 pkgsrc/www/firefox60/distinfo:1.16
--- pkgsrc/www/firefox60/distinfo:1.15  Sat Jun  1 19:11:28 2019
+++ pkgsrc/www/firefox60/distinfo       Thu Jun 13 14:16:37 2019
@@ -1,10 +1,10 @@
-$NetBSD: distinfo,v 1.15 2019/06/01 19:11:28 maya Exp $
+$NetBSD: distinfo,v 1.16 2019/06/13 14:16:37 nia Exp $
 
 SHA1 (firefox-60.7.0esr.source.tar.xz) = 733187de6b20f8902fa207f08ec85f952a2c2e40
 RMD160 (firefox-60.7.0esr.source.tar.xz) = 21176def2d22c83042d36844c5d148d324199ac6
 SHA512 (firefox-60.7.0esr.source.tar.xz) = c2152857f5f1c816a12fcf5c450268025ee47ee9299ae3355650d86c7c97191b731123a4964154222ca5ba1edc44fee0d1d5f803ae9515841283ecaff6dc9a55
 Size (firefox-60.7.0esr.source.tar.xz) = 268497160 bytes
-SHA1 (patch-aa) = 17ea1093941cabc3dac1c653ba9edd92ec9877da
+SHA1 (patch-aa) = 5e07d1a01762b7face950ca41c71447106341f0d
 SHA1 (patch-browser_app_profile_firefox.js) = 9a43095d94f83f315b9a3ce4a7b0a4301e9c40e6
 SHA1 (patch-build_moz.configure_old.configure) = 1df6867eaf73a350fbe8fcd5bd34e1fcab09d707
 SHA1 (patch-build_moz.configure_rust.configure) = 2818454ba4df3cbd85174edc4828206b3bf0a82b
@@ -23,11 +23,11 @@ SHA1 (patch-js_src_threading_posix_Threa
 SHA1 (patch-js_src_util_NativeStack.cpp) = 3af7d3c90ce9299f0a95b938ca903488e7809d0a
 SHA1 (patch-js_src_wasm_WasmSignalHandlers.cpp) = 5442266a05721a9f4a3c9d12429bd1d59ecd936a
 SHA1 (patch-media_libcubeb_gtest_moz.build) = 921a001726cda9e9782df5e59ae02b19d76ef47e
-SHA1 (patch-media_libcubeb_src_cubeb.c) = 1b1b8d57eb710cad13518ded79a0ddee2681881b
+SHA1 (patch-media_libcubeb_src_cubeb.c) = 90c1b484ce9db2dade2c92b36f4978fbdc5dbea7
 SHA1 (patch-media_libcubeb_src_cubeb__alsa.c) = 3ee36f58bb525767c7d2b9e814ba4ccaa4868717
 SHA1 (patch-media_libcubeb_src_cubeb__oss.c) = 103f751d5a7bc14a81a6ed43e1afc722bc092f7e
-SHA1 (patch-media_libcubeb_src_moz.build) = f243068c8908dcb16434221edef8c65db3bb0c83
-SHA1 (patch-media_libcubeb_update.sh) = 3a322de06bbe9aafba9da349954ef022bd094992
+SHA1 (patch-media_libcubeb_src_moz.build) = 1a3c0e484da83acabf30f7fad6b43fe94411d8b8
+SHA1 (patch-media_libcubeb_update.sh) = d10633a378b68f91eb39d6572d857edd9b07dc9b
 SHA1 (patch-media_libpng_pngpriv.h) = c8084332560017cd7c9b519b61d125fa28af0dbc
 SHA1 (patch-media_webrtc_trunk_webrtc_modules_audio__device_linux_audio__device__alsa__linux.cc) = 91e8ce496c1f4dbbd0a463d83cb033afd1de3f49
 SHA1 (patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_device__info__linux.cc) = 0141dd1372c13ea1fce6e2f5ffb65e0cb0f3a13e

Index: pkgsrc/www/firefox60/mozilla-common.mk
diff -u pkgsrc/www/firefox60/mozilla-common.mk:1.4 pkgsrc/www/firefox60/mozilla-common.mk:1.5
--- pkgsrc/www/firefox60/mozilla-common.mk:1.4  Sat May 11 04:02:29 2019
+++ pkgsrc/www/firefox60/mozilla-common.mk      Thu Jun 13 14:16:37 2019
@@ -1,4 +1,4 @@
-# $NetBSD: mozilla-common.mk,v 1.4 2019/05/11 04:02:29 ryoon Exp $
+# $NetBSD: mozilla-common.mk,v 1.5 2019/06/13 14:16:37 nia Exp $
 #
 # common Makefile fragment for mozilla packages based on gecko 2.0.
 #
@@ -59,7 +59,8 @@ CONFIGURE_ARGS+=      --with-pthreads
 # Mozilla Bug 1432751
 #CONFIGURE_ARGS+=      --enable-system-cairo
 CONFIGURE_ARGS+=       --enable-system-pixman
-CONFIGURE_ARGS+=       --with-system-libvpx
+# too new to build with webrtc?
+#CONFIGURE_ARGS+=      --with-system-libvpx
 # textproc/hunspell 1.3 is too old
 #CONFIGURE_ARGS+=      --enable-system-hunspell
 CONFIGURE_ARGS+=       --enable-system-ffi
@@ -205,8 +206,8 @@ BUILDLINK_DEPMETHOD.clang=  build
 BUILDLINK_API_DEPENDS.rust+=   rust>=1.23.0
 BUILDLINK_DEPMETHOD.rust=      build
 .include "../../lang/rust/buildlink3.mk"
-BUILDLINK_API_DEPENDS.libvpx+= libvpx>=1.3.0
-.include "../../multimedia/libvpx/buildlink3.mk"
+#BUILDLINK_API_DEPENDS.libvpx+=        libvpx>=1.3.0
+#.include "../../multimedia/libvpx/buildlink3.mk"
 .include "../../net/libIDL/buildlink3.mk"
 # textproc/hunspell 1.3 is too old
 #.include "../../textproc/hunspell/buildlink3.mk"

Index: pkgsrc/www/firefox60/patches/patch-aa
diff -u pkgsrc/www/firefox60/patches/patch-aa:1.2 pkgsrc/www/firefox60/patches/patch-aa:1.3
--- pkgsrc/www/firefox60/patches/patch-aa:1.2   Sat Jun  1 19:11:28 2019
+++ pkgsrc/www/firefox60/patches/patch-aa       Thu Jun 13 14:16:37 2019
@@ -1,12 +1,13 @@
-$NetBSD: patch-aa,v 1.2 2019/06/01 19:11:28 maya Exp $
+$NetBSD: patch-aa,v 1.3 2019/06/13 14:16:37 nia Exp $
 
 * Disable libjpeg-turbo check
 * Add system libraries option
 * Add OSS audio support
+* Add Sun audio support
 
---- old-configure.in.orig      2018-05-03 16:58:31.000000000 +0000
+--- old-configure.in.orig      2019-05-14 19:13:24.000000000 +0000
 +++ old-configure.in
-@@ -1804,11 +1804,7 @@ if test "$MOZ_SYSTEM_JPEG" = 1; then
+@@ -1785,11 +1785,7 @@ if test "$MOZ_SYSTEM_JPEG" = 1; then
                       #include <jpeglib.h> ],
                     [ #if JPEG_LIB_VERSION < $MOZJPEG
                       #error "Insufficient JPEG library version ($MOZJPEG required)."
@@ -19,7 +20,7 @@ $NetBSD: patch-aa,v 1.2 2019/06/01 19:11
                     MOZ_SYSTEM_JPEG=1,
                     AC_MSG_ERROR([Insufficient JPEG library version for --with-system-jpeg]))
  fi
-@@ -2596,6 +2592,67 @@ AC_DEFINE(MOZ_WEBM_ENCODER)
+@@ -2577,6 +2573,71 @@ AC_DEFINE(MOZ_WEBM_ENCODER)
  AC_SUBST(MOZ_WEBM_ENCODER)
  
  dnl ==================================
@@ -28,9 +29,12 @@ $NetBSD: patch-aa,v 1.2 2019/06/01 19:11
 +
 +dnl If using Linux, Solaris or BSDs, ensure that OSS is available
 +case "$OS_TARGET" in
-+Linux|SunOS|DragonFly|FreeBSD|NetBSD|GNU/kFreeBSD)
++Linux|DragonFly|FreeBSD|GNU/kFreeBSD)
 +    MOZ_OSS=1
 +    ;;
++SunOS|NetBSD)
++    MOZ_SUN=1
++    ;;
 +esac
 +
 +MOZ_ARG_WITH_STRING(oss,
@@ -80,6 +84,7 @@ $NetBSD: patch-aa,v 1.2 2019/06/01 19:11
 +LIBS=$_SAVE_LIBS
 +
 +AC_SUBST(MOZ_OSS)
++AC_SUBST(MOZ_SUN)
 +AC_SUBST_LIST(MOZ_OSS_CFLAGS)
 +AC_SUBST_LIST(MOZ_OSS_LIBS)
 +

Index: pkgsrc/www/firefox60/patches/patch-media_libcubeb_src_cubeb.c
diff -u pkgsrc/www/firefox60/patches/patch-media_libcubeb_src_cubeb.c:1.1 pkgsrc/www/firefox60/patches/patch-media_libcubeb_src_cubeb.c:1.2
--- pkgsrc/www/firefox60/patches/patch-media_libcubeb_src_cubeb.c:1.1   Thu Jun 28 14:04:10 2018
+++ pkgsrc/www/firefox60/patches/patch-media_libcubeb_src_cubeb.c       Thu Jun 13 14:16:37 2019
@@ -1,10 +1,21 @@
-$NetBSD: patch-media_libcubeb_src_cubeb.c,v 1.1 2018/06/28 14:04:10 ryoon Exp $
+$NetBSD: patch-media_libcubeb_src_cubeb.c,v 1.2 2019/06/13 14:16:37 nia Exp $
 
 * Support OSS audio
+* Support Sun audio
 
---- media/libcubeb/src/cubeb.c.orig    2017-07-31 16:20:49.000000000 +0000
+--- media/libcubeb/src/cubeb.c.orig    2019-05-14 19:13:23.000000000 +0000
 +++ media/libcubeb/src/cubeb.c
-@@ -55,6 +55,9 @@ int audiotrack_init(cubeb ** context, ch
+@@ -51,6 +51,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
+@@ -60,6 +63,9 @@ int audiotrack_init(cubeb ** context, ch
  #if defined(USE_KAI)
  int kai_init(cubeb ** context, char const * context_name);
  #endif
@@ -14,7 +25,18 @@ $NetBSD: patch-media_libcubeb_src_cubeb.
  
  static int
  validate_stream_params(cubeb_stream_params * input_stream_params,
-@@ -155,6 +158,10 @@ cubeb_init(cubeb ** context, char const 
+@@ -148,6 +154,10 @@ cubeb_init(cubeb ** context, char const 
+ #if defined(USE_SNDIO)
+       init_oneshot = sndio_init;
+ #endif
++    } else if (!strcmp(backend_name, "sun")) {
++#if defined(USE_SUN)
++      init_oneshot = sun_init;
++#endif
+     } else if (!strcmp(backend_name, "opensl")) {
+ #if defined(USE_OPENSL)
+       init_oneshot = opensl_init;
+@@ -160,6 +170,10 @@ cubeb_init(cubeb ** context, char const 
  #if defined(USE_KAI)
        init_oneshot = kai_init;
  #endif
@@ -25,7 +47,17 @@ $NetBSD: patch-media_libcubeb_src_cubeb.
      } else {
        /* Already set */
      }
-@@ -199,6 +206,9 @@ cubeb_init(cubeb ** context, char const 
+@@ -195,6 +209,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
+@@ -204,6 +221,9 @@ cubeb_init(cubeb ** context, char const 
  #if defined(USE_KAI)
      kai_init,
  #endif
Index: pkgsrc/www/firefox60/patches/patch-media_libcubeb_src_moz.build
diff -u pkgsrc/www/firefox60/patches/patch-media_libcubeb_src_moz.build:1.1 pkgsrc/www/firefox60/patches/patch-media_libcubeb_src_moz.build:1.2
--- pkgsrc/www/firefox60/patches/patch-media_libcubeb_src_moz.build:1.1 Thu Jun 28 14:04:10 2018
+++ pkgsrc/www/firefox60/patches/patch-media_libcubeb_src_moz.build     Thu Jun 13 14:16:37 2019
@@ -1,11 +1,11 @@
-$NetBSD: patch-media_libcubeb_src_moz.build,v 1.1 2018/06/28 14:04:10 ryoon Exp $
+$NetBSD: patch-media_libcubeb_src_moz.build,v 1.2 2019/06/13 14:16:37 nia Exp $
 
 * Add OSS audio support
 * Support system library
 
---- media/libcubeb/src/moz.build.orig  2018-05-03 16:58:30.000000000 +0000
+--- media/libcubeb/src/moz.build.orig  2019-05-14 19:13:22.000000000 +0000
 +++ media/libcubeb/src/moz.build
-@@ -22,6 +22,12 @@ if CONFIG['MOZ_ALSA']:
+@@ -22,6 +22,18 @@ if CONFIG['MOZ_ALSA']:
      ]
      DEFINES['USE_ALSA'] = True
  
@@ -15,10 +15,16 @@ $NetBSD: patch-media_libcubeb_src_moz.bu
 +    ]
 +    DEFINES['USE_OSS'] = True
 +
++if CONFIG['MOZ_SUN']:
++    SOURCES += [
++        'cubeb_sun.c',
++    ]
++    DEFINES['USE_SUN'] = True
++
  if CONFIG['MOZ_PULSEAUDIO'] or CONFIG['MOZ_JACK']:
      SOURCES += [
          'cubeb_resampler.cpp',
-@@ -87,6 +93,7 @@ if CONFIG['OS_TARGET'] == 'Android':
+@@ -87,6 +99,7 @@ if CONFIG['OS_TARGET'] == 'Android':
  FINAL_LIBRARY = 'gkmedias'
  
  CFLAGS += CONFIG['MOZ_ALSA_CFLAGS']
Index: pkgsrc/www/firefox60/patches/patch-media_libcubeb_update.sh
diff -u pkgsrc/www/firefox60/patches/patch-media_libcubeb_update.sh:1.1 pkgsrc/www/firefox60/patches/patch-media_libcubeb_update.sh:1.2
--- pkgsrc/www/firefox60/patches/patch-media_libcubeb_update.sh:1.1     Thu Jun 28 14:04:10 2018
+++ pkgsrc/www/firefox60/patches/patch-media_libcubeb_update.sh Thu Jun 13 14:16:37 2019
@@ -1,12 +1,13 @@
-$NetBSD: patch-media_libcubeb_update.sh,v 1.1 2018/06/28 14:04:10 ryoon Exp $
+$NetBSD: patch-media_libcubeb_update.sh,v 1.2 2019/06/13 14:16:37 nia Exp $
 
---- media/libcubeb/update.sh.orig      2018-05-03 16:58:30.000000000 +0000
+--- media/libcubeb/update.sh.orig      2019-05-14 19:13:23.000000000 +0000
 +++ media/libcubeb/update.sh
-@@ -20,6 +20,7 @@ cp $1/src/cubeb_log.h src
+@@ -20,6 +20,8 @@ cp $1/src/cubeb_log.h src
  cp $1/src/cubeb_mixer.cpp src
  cp $1/src/cubeb_mixer.h src
  cp $1/src/cubeb_opensl.c src
 +cp $1/src/cubeb_oss.c src
++cp $1/src/cubeb_sun.c src
  cp $1/src/cubeb-jni.cpp src
  cp $1/src/cubeb-jni.h src
  cp $1/src/android/cubeb-output-latency.h src/android

Added files:

Index: pkgsrc/www/firefox60/files/cubeb_sun.c
diff -u /dev/null pkgsrc/www/firefox60/files/cubeb_sun.c:1.1
--- /dev/null   Thu Jun 13 14:16:38 2019
+++ pkgsrc/www/firefox60/files/cubeb_sun.c      Thu Jun 13 14:16:37 2019
@@ -0,0 +1,763 @@
+/*
+ * 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 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;
+}
+
+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;
+}
+
+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;
+}
+
+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) {
+    if (input_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK) {
+      LOG("Loopback not supported");
+      ret = CUBEB_ERROR_NOT_SUPPORTED;
+      goto error;
+    }
+    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) {
+    if (output_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK) {
+      LOG("Loopback not supported");
+      ret = CUBEB_ERROR_NOT_SUPPORTED;
+      goto error;
+    }
+    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,
+  .enumerate_devices = sun_enumerate_devices,
+  .device_collection_destroy = sun_device_collection_destroy,
+  .destroy = sun_destroy,
+  .stream_init = sun_stream_init,
+  .stream_destroy = sun_stream_destroy,
+  .stream_start = sun_stream_start,
+  .stream_stop = sun_stream_stop,
+  .stream_reset_default_device = NULL,
+  .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