Files
haikuports/media-libs/libao/patches/libao-1.2.2.patchset
2017-02-16 22:42:28 +01:00

437 lines
12 KiB
Plaintext

From e8e1c83dd8c8593921201152278fa7d9ab093ba4 Mon Sep 17 00:00:00 2001
From: Julian Harnath <julian.harnath@rwth-aachen.de>
Date: Mon, 24 Mar 2014 21:30:27 +0100
Subject: Add Haiku Media Kit audio output driver.
diff --git a/configure.ac b/configure.ac
index 67a06f8..8f2de8e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -30,13 +30,15 @@ dnl Check for programs
dnl ====================================
cflags_save="$CFLAGS"
+cppflags_save="$CPPFLAGS"
AC_PROG_CC
+AC_PROG_CXX
AC_LIBTOOL_WIN32_DLL
AC_LIBTOOL_DLOPEN
AM_PROG_LIBTOOL
dnl ====================================
-dnl Check dlopen
+dnl Check dlopen
dnl ====================================
dnl Currently use this to disable plugin support dlfcn.h
@@ -68,6 +70,7 @@ if test -z "$GCC"; then
PLUGIN_LDFLAGS="-export-dynamic -avoid-version"
DEBUG="-g"
CFLAGS="-O"
+ CPPFLAGS="-O"
PROFILE="-g -p" ;;
esac
else
@@ -92,10 +95,12 @@ else
PLUGIN_LDFLAGS="-export-dynamic -avoid-version"
DEBUG="-g -Wall -D__NO_MATH_INLINES -fsigned-char"
CFLAGS="-O20 -D__NO_MATH_INLINES -fsigned-char"
+ CPPFLAGS="-O20 -D__NO_MATH_INLINES -fsigned-char"
PROFILE="-O20 -g -pg -D__NO_MATH_INLINES -fsigned-char" ;;
esac
fi
CFLAGS="$CFLAGS $cflags_save -DAO_BUILDING_LIBAO"
+CPPFLAGS="$CPPFLAGS $cppflags_save -DAO_BUILDING_LIBAO"
DEBUG="$DEBUG $cflags_save -DAO_BUILDING_LIBAO"
PROFILE="$PROFILE $cflags_save -DAO_BUILDING_LIBAO"
@@ -111,7 +116,7 @@ case $host in
*-mingw*|*-cygwin*)
LIBAO_LA_LDFLAGS="-no-undefined"
;;
- *)
+ *)
LIBAO_LA_LDFLAGS=""
;;
esac
@@ -151,7 +156,7 @@ case $host in
*hpux*)
DLOPEN_FLAG='(RTLD_LAZY)'
SHARED_LIB_EXT='.sl'
- ;;
+ ;;
*openbsd* | *netbsd* | *solaris2.7 | *darwin*)
DLOPEN_FLAG='(RTLD_LAZY)'
SHARED_LIB_EXT='.so'
@@ -194,7 +199,7 @@ AC_SUBST(SIZE16)
AC_SUBST(SIZE32)
dnl ======================================
-dnl Disable default use of SLP in roar
+dnl Disable default use of SLP in roar
dnl until such time as SLP doesn't block
dnl indefinitely
dnl ======================================
@@ -212,7 +217,7 @@ fi
AC_SUBST([SLP_DEF])
dnl ======================================
-dnl Detect possible output devices
+dnl Detect possible output devices
dnl ======================================
dnl Check for WMM
@@ -309,7 +314,7 @@ if test "x$enable_broken_oss" = "xyes"; then
AC_DEFINE(BROKEN_OSS)
AC_MSG_WARN(Broken OSS API workaround enabled. See README for details.)
fi
-
+
dnl Check for Sun audio
have_sun="no";
@@ -424,7 +429,7 @@ if test "$BUILD_NAS" = "yes"; then
AC_PATH_XTRA
AC_CHECK_LIB(Xau, XauFileName, have_nas=yes, have_nas=no, $X_LIBS)
AC_CHECK_LIB(audio, AuOpenServer, dummy="no-op", have_nas=no, -lXau $X_LIBS)
-
+
ac_save_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $X_CFLAGS"
AC_CHECK_HEADER(audio/audiolib.h, dummy="no-op", have_nas=no)
@@ -457,6 +462,12 @@ AC_SUBST(PULSE_LIBS)
AM_CONDITIONAL(HAVE_PULSE,test "x$have_pulse" = xyes)
+dnl Check for Haiku audio
+
+have_haiku="no";
+AC_CHECK_HEADERS(MediaDefs.h, have_haiku=yes)
+AM_CONDITIONAL(HAVE_HAIKU,test "${have_haiku}" = yes)
+
dnl Orphaned driver. We'll probably dump it soon.
AM_CONDITIONAL(HAVE_SOLARIS,test "x$have_solaris" = xyes)
@@ -464,7 +475,7 @@ dnl Plugins get special LDFLAGS
AC_SUBST(PLUGIN_LDFLAGS)
-AC_OUTPUT([Makefile src/Makefile doc/Makefile include/Makefile include/ao/Makefile include/ao/os_types.h src/plugins/Makefile src/plugins/esd/Makefile src/plugins/oss/Makefile src/plugins/alsa/Makefile src/plugins/sun/Makefile src/plugins/irix/Makefile src/plugins/arts/Makefile src/plugins/macosx/Makefile src/plugins/nas/Makefile src/plugins/pulse/Makefile src/plugins/sndio/Makefile src/plugins/roar/Makefile ao.pc])
+AC_OUTPUT([Makefile src/Makefile doc/Makefile include/Makefile include/ao/Makefile include/ao/os_types.h src/plugins/Makefile src/plugins/esd/Makefile src/plugins/oss/Makefile src/plugins/alsa/Makefile src/plugins/sun/Makefile src/plugins/irix/Makefile src/plugins/arts/Makefile src/plugins/macosx/Makefile src/plugins/nas/Makefile src/plugins/pulse/Makefile src/plugins/sndio/Makefile src/plugins/roar/Makefile src/plugins/haiku/Makefile ao.pc])
AS_AC_EXPAND(LIBDIR, ${libdir})
AS_AC_EXPAND(INCLUDEDIR, ${includedir})
@@ -485,6 +496,7 @@ AC_MSG_RESULT([
ALSA live output: ............ ${have_alsa}
ARTS live output: ............ ${have_arts}
ESD live output: ............. ${have_esd}
+ HAIKU live output: ........... ${have_haiku}
IRIX live output: ............ ${have_irix}
MACOSX live output: .......... ${have_macosx}
NAS live output: ............. ${have_nas}
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 1af2303..1b417d4 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -1,4 +1,4 @@
## Process this file with automake to produce Makefile.in
AUTOMAKE_OPTIONS = foreign
-SUBDIRS = oss esd arts alsa sun irix macosx nas pulse sndio roar
+SUBDIRS = oss esd arts alsa sun irix macosx nas pulse sndio roar haiku
diff --git a/src/plugins/haiku/Makefile.am b/src/plugins/haiku/Makefile.am
new file mode 100644
index 0000000..596c664
--- /dev/null
+++ b/src/plugins/haiku/Makefile.am
@@ -0,0 +1,25 @@
+## Process this file with automake to produce Makefile.in
+
+AUTOMAKE_OPTIONS = foreign
+
+if HAVE_HAIKU
+
+haikultlibs = libhaiku.la
+haikusources = ao_haiku.cpp
+
+else
+
+haikultlibs =
+haikusources =
+
+endif
+
+INCLUDES = -I$(top_builddir)/include/ao -I$(top_srcdir)/include
+
+libdir = $(plugindir)
+lib_LTLIBRARIES = $(haikultlibs)
+
+libhaiku_la_LDFLAGS = @PLUGIN_LDFLAGS@ -lbe -lmedia
+libhaiku_la_SOURCES = $(haikusources)
+
+EXTRA_DIST = ao_haiku.cpp
diff --git a/src/plugins/haiku/ao_haiku.cpp b/src/plugins/haiku/ao_haiku.cpp
new file mode 100644
index 0000000..58d9dcb
--- /dev/null
+++ b/src/plugins/haiku/ao_haiku.cpp
@@ -0,0 +1,254 @@
+/*
+ * ao_haiku.cpp
+ *
+ * Copyright (C) Julian Harnath - March 2014
+ *
+ * This file is part of libao, a cross-platform audio output library. See
+ * README for a history of this source code.
+ *
+ * libao is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * libao is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ********************************************************************/
+
+#include <algorithm>
+#include <string.h>
+#include <stdio.h>
+
+#include <MediaDefs.h>
+#include <MediaRoster.h>
+#include <OS.h>
+#include <SoundPlayer.h>
+
+#include <ao/ao.h>
+#include <ao/plugin.h>
+
+
+static char* ao_haiku_options[] = {
+ "matrix"
+};
+
+
+struct ao_info ao_haiku_info = {
+ AO_TYPE_LIVE,
+ "Haiku Media Kit Output",
+ "haiku",
+ "Julian Harnath <julian.harnath@rwth-aachen.de>",
+ "Outputs to the Haiku Media Kit",
+ AO_FMT_NATIVE,
+ 30,
+ ao_haiku_options,
+ sizeof(ao_haiku_options) / sizeof(*ao_haiku_options)
+};
+
+
+typedef struct ao_haiku_internal {
+ media_raw_audio_format* format;
+ BSoundPlayer* sound_player;
+
+ sem_id new_buffer;
+ sem_id buffer_done;
+
+ uint8* buffer;
+ size_t buffer_size;
+ size_t buffer_filled;
+} ao_haiku_internal;
+
+
+int
+ao_plugin_test()
+{
+ BSoundPlayer testPlayer;
+ return testPlayer.InitCheck() == B_OK ? 1 :0;
+}
+
+
+ao_info*
+ao_plugin_driver_info()
+{
+ return &ao_haiku_info;
+}
+
+
+int
+ao_plugin_device_init(ao_device* device)
+{
+ ao_haiku_internal* const internal = (ao_haiku_internal*)calloc(1,
+ sizeof(ao_haiku_internal));
+ if (internal == NULL)
+ return 0;
+
+ internal->format = (media_raw_audio_format*)malloc(
+ sizeof(media_raw_audio_format));
+ if (internal->format == NULL) {
+ free(internal);
+ return 0;
+ }
+
+ internal->new_buffer = create_sem(0, "New buffer request");
+ internal->buffer_done = create_sem(1, "Buffer done");
+
+ device->output_matrix_order = AO_OUTPUT_MATRIX_FIXED;
+ device->internal = internal;
+
+ return 1;
+}
+
+
+int
+ao_plugin_set_option(ao_device* device, const char* key, const char* value)
+{
+ return 1;
+}
+
+
+static void
+fill_buffer(void* cookie, void* buffer, size_t size,
+ const media_raw_audio_format& format)
+{
+ ao_haiku_internal* const internal = (ao_haiku_internal*)cookie;
+
+ internal->buffer = (uint8*)buffer;
+ internal->buffer_size = size;
+ internal->buffer_filled = 0;
+ release_sem(internal->new_buffer);
+ acquire_sem(internal->buffer_done);
+}
+
+
+int
+ao_plugin_open(ao_device* device, ao_sample_format* format)
+{
+ ao_haiku_internal* const internal = (ao_haiku_internal*)device->internal;
+ media_raw_audio_format* const mediaRawFormat = internal->format;
+
+ mediaRawFormat->frame_rate = format->rate;
+ mediaRawFormat->channel_count = device->output_channels;
+
+ switch (format->bits) {
+ case 8:
+ mediaRawFormat->format = media_raw_audio_format::B_AUDIO_CHAR;
+ break;
+ case 16:
+ mediaRawFormat->format = media_raw_audio_format::B_AUDIO_SHORT;
+ break;
+ case 32:
+ mediaRawFormat->format = media_raw_audio_format::B_AUDIO_INT;
+ break;
+ default:
+ aerror("Unsupported sample bit depth");
+ return 0;
+ }
+
+ device->driver_byte_format = AO_FMT_NATIVE;
+ if (B_HOST_IS_LENDIAN)
+ mediaRawFormat->byte_order = B_MEDIA_LITTLE_ENDIAN;
+ else
+ mediaRawFormat->byte_order = B_MEDIA_BIG_ENDIAN;
+
+ mediaRawFormat->buffer_size = BMediaRoster::Roster()->AudioBufferSizeFor(
+ mediaRawFormat->channel_count, mediaRawFormat->format,
+ mediaRawFormat->frame_rate, B_UNKNOWN_BUS) * 2;
+
+ internal->sound_player = new BSoundPlayer(mediaRawFormat, "ao player",
+ fill_buffer, NULL, internal);
+
+ if (internal->sound_player->InitCheck() != B_OK) {
+ delete internal->sound_player;
+ internal->sound_player = NULL;
+ return 0;
+ }
+
+ internal->sound_player->SetVolume(1.0);
+ internal->sound_player->Start();
+ internal->sound_player->SetHasData(false);
+
+ if (device->inter_matrix == NULL) {
+ if (device->output_channels <= 2)
+ device->inter_matrix = strdup("L,R");
+ }
+
+ return 1;
+}
+
+
+int
+ao_plugin_play(ao_device* device, const char* output_samples,
+ uint_32 num_bytes)
+{
+ ao_haiku_internal* const internal = (ao_haiku_internal*)device->internal;
+ BSoundPlayer* const soundPlayer = internal->sound_player;
+
+ if (num_bytes == 0) {
+ soundPlayer->SetHasData(false);
+ return 1;
+ }
+
+ soundPlayer->SetHasData(true);
+ acquire_sem(internal->new_buffer);
+
+ size_t bytesLeft = num_bytes;
+ while (bytesLeft > 0) {
+ if (internal->buffer_filled == internal->buffer_size) {
+ // Request another buffer from BSoundPlayer
+ release_sem(internal->buffer_done);
+ acquire_sem(internal->new_buffer);
+ }
+
+ const size_t copyBytes = std::min(bytesLeft, internal->buffer_size
+ - internal->buffer_filled);
+ memcpy(internal->buffer + internal->buffer_filled, output_samples,
+ copyBytes);
+ internal->buffer_filled += copyBytes;
+ output_samples += copyBytes;
+ bytesLeft -= copyBytes;
+ }
+
+ if (internal->buffer_filled < internal->buffer_size) {
+ // Continue filling this buffer the next time this function is called
+ release_sem(internal->new_buffer);
+ } else {
+ // Buffer is full
+ release_sem(internal->buffer_done);
+ soundPlayer->SetHasData(false);
+ }
+
+ return 1;
+}
+
+
+int
+ao_plugin_close(ao_device* device)
+{
+ ao_haiku_internal* const internal = (ao_haiku_internal*)device->internal;
+
+ release_sem(internal->buffer_done);
+ internal->sound_player->SetHasData(false);
+ internal->sound_player->Stop();
+ delete internal->sound_player;
+
+ return 1;
+}
+
+
+void
+ao_plugin_device_clear(ao_device* device)
+{
+ ao_haiku_internal* const internal = (ao_haiku_internal*)device->internal;
+
+ free(internal->format);
+ delete_sem(internal->new_buffer);
+ delete_sem(internal->buffer_done);
+ free(internal);
+}
--
1.8.3.4