OpenAL: bump version

* rework haiku output backend, fix crash on stop
* add haiku input backend
* move commandline tools to separate subpackage
* add to build openal configurator (Qt5 gui)
This commit is contained in:
Gerasim Troeglazov
2021-02-24 17:45:22 +10:00
parent 1672441c77
commit de3c36296f
5 changed files with 875 additions and 523 deletions

View File

@@ -0,0 +1,85 @@
resource app_flags B_SINGLE_LAUNCH;
resource app_version {
major = @MAJOR@,
middle = @MIDDLE@,
minor = @MINOR@,
variety = B_APPV_FINAL,
internal = 0,
short_info = "OpenAL Soft Configuration",
long_info = "@LONG_INFO@"
};
resource app_signature "@APP_SIGNATURE@";
resource vector_icon {
$"6E6369660C020012023750A4380AE1B80AE13750A44C02514B34CC0000FFFF00"
$"00050003FFD78903FFAA0002001203A9D70039FAE1B9FAE1A9D7004A84A34B81"
$"1E0000FFA900FFFF000002000204268F403BAEB8BBAEB8268F404B90284B1266"
$"427F909CFF79FFFFFFFFD1C5CCD1FFFFC5CCD10002000203A9332F39EF5CB9EF"
$"5CA9332F4B26004B815C007F4C00FFA9AE9159FFFF7A909C000200060337D333"
$"38EFFFB8EFFF37D33349F2E14A591E00FFEF0075FFFFFFFFFFDD00020106023A"
$"45853ADE45B8E1DF38485F48DAF84B31EB73FFAA00FF7F4C0002000602BA047A"
$"3C0AB8BC0AB8BA047A48397047D75C00FFF5B3FFFFAA00020106023AAF8D3E08"
$"41BB87AC3855214AB904479D4600FFDE06FF7F4C0002010602B866733DC7C2BC"
$"5876B6FA7D49389E460CC200FFFFFFFFFFA7002D0004405240524452485C425C"
$"4E5C54565052C8C8C9945C5EC9D7CAA35C5E0607FE1F2E532C4D2A51B84FC3DD"
$"3045B8D8C2CE324636483447344C30543250B91BC7962E53B8D8C7732E535306"
$"07FE1F2E532C4D2A51B84FC3DD3045B8D8C2CE324636483447344C30543250B9"
$"1BC7962E53B8D8C7732E53530607EF1F3E4C3E4C3C4E38523A50345630542E4E"
$"2C52B91BC4433246B9A3C33436483E4C3A4A3E4C4C0607FE1F3A4F324B36492E"
$"4D2E512E512E562E602E5B32603A6036603ACA3D3A4F3AC7FC3A4F4F0607FE1F"
$"3A4F324B36492E4D2E512E512E562E602E5B32603A6036603ACA3D3A4F3AC7FC"
$"3A4F4F0607FF1B3253325332C90B326032CAC6BB3B603A60BC4C603ACA3D3A4F"
$"3AC7FC3A4F364D3A4B324F3253530607EF1F424E424EC004C6643E56BF7CC773"
$"3C5A385836523456BC4CC5DB3A4ABCD3C4CCBE6BC443424EBF7CC4CC424E4E00"
$"0730453045BB3BC2AB3E4CBD18C39A3C5038583A54BC4CC92E3657BC07C90B36"
$"5734513255BB3BC5FE364DBB80C575344C304A324B304A000730453045BB3BC2"
$"AB3E4CBD18C39A3C5038583A54BC4CC92E3657BC07C90B365734513255BB3BC5"
$"FE364DBB80C575344C304A324B304A0607EF1F424E424EC004C6643E56BF7CC7"
$"733C5A385836523456BC4CC5DB3A4ABCD3C4CCBE6BC443424EBF7CC4CC424E4E"
$"0606FF073C553C553CC88E3A57BDCC57BCEA57385538C88E38C7AC3A53BCEA53"
$"BDCC533C553CC7AC3C55550606FF07502950294E274524C3C6B500BF7CB93E34"
$"47BD39BDE3BC4CC3343E4CBD9FC3DD44BFE150294ABB3C502929020A50295029"
$"4E274A2A4B28C1DFBAB33C46C004BE6C3B483E4C3C4BC004C50F4650C113C598"
$"48514C4E4B5050465836543E5934572F5931C7FC2D5029C70D2B502950295029"
$"5029020A3C223C22382133263522B93EB80B293AB7E9BAB4273E2C432841B8D8"
$"C1793447B9E8C20238493D443B48413C492C45344B284524492542B4533C223F"
$"B4103C223C223C223C220606FF07502950294E274524C3C6B500BF7CB93E3447"
$"BD39BDE3BC4CC3343E4CBD9FC3DD44BFE150294ABB3C502929020A502950294E"
$"274A2A4B28C1DFBAB33C46C004BE6C3B483E4C3C4BC004C50F4650C113C59848"
$"514C4E4B5050465836543E5934572F5931C7FC2D5029C70D2B50295029502950"
$"29020A3C223C22382133263522B93EB80B293AB7E9BAB4273E2C432841B8D8C1"
$"793447B9E8C20238493D443B48413C492C45344B284524492542B4533C223FB4"
$"103C223C223C223C220002C03AB6E2C03AB6E2C09CB617C161B482C0FEB54DC1"
$"61B4820002BA7FBF6ABA7FBF6ABA1FC0303045B9BFC0F730450002BAA6C260BA"
$"A6C260BB07C197BBCBC005BB69C0CEBBCBC0050002BED7B678BED7B678BF35B5"
$"B6BFF323BF94B4F4BFF3230002BE82B3E0BE82B3E03CB49ABD74B60EBDCEB554"
$"BD74B60E0002B935BECFB935BECFB8D6BF93B819C11AB878C056B819C11A0002"
$"BB00BA4BBB00BA4BBA31B9FD2E30B962B9AE2E300002B7FB33B7FB33B8C8BAE5"
$"BA64BB8DB996BB39BA64BB8D0002B9C8BCD1B9C8BCD1B8FBBC772B362DBC1D2B"
$"360002B6C939B6C939B794BD55B92ABE13B85FBDB4B92ABE1300024F484F48C5"
$"3AC2A5C43AC210C4BAC25BC43AC2100002C397C34DC397C34DC41AC394C5214B"
$"C49DC3DBC5214B0002BA5F27BA5F27BB31B608BCD5B685BC03B647BCD5B68500"
$"03C04CB78EC04CB78EC136B7D4C309B861C21FB81AC38CB8CAC491B99DC40EB9"
$"33C491B99D0002C767BBE6C767BBE6C7D7BC41C8B739C847BC9BC8B739000255"
$"3C553CC7ABBDD0C6C5BD21C738BD79C6C5BD210002C622BE5EC622BE5EC698BE"
$"B2C7853FC70EBF06C7853F000252425242C672C03BC57FBF99C5F9BFEAC57FBF"
$"990002C4DDC0D5C4DDC0D5C55AC122C65345C5D6C170C653450003BC65BF98BC"
$"65BF98BD36BFFABEDAC0BFBE08C05CBF63C108C074C19BBFEBC151C074C19B00"
$"03C123C045C123C045C09CBFF7BF8D3FC014BFA8BEB7BEFCBD0CBE40BDE1BE9E"
$"BD0CBE400002B92D2DB92D2DB9FDB877BB9DB909BACDB8C0BB9DB9090002BC38"
$"2CBC382CBB67B783312ABA96B740312A0003C3E1BAF0C3E1BAF0C35EBA8DC257"
$"31C2DABA29C171B97BBFA6B8E542B930BFA6B8E50003BF00BA3CBF00BA3CBFE1"
$"BA8BC1A4BB2BC0C3BADBC229BB89C332BC46C2ADBBE8C332BC460003BDB2BCE9"
$"BDB2BCE9BE8CBD42C03FBDF5BF65BD9BC0C6BE48C1D3BEEFC14CBE9CC1D3BEEF"
$"0003C282BD9BC282BD9BC1FDBD424338C177BCE9C014BC3BBE58BB93BF36BBE7"
$"BE58BB93110A0001001001178400040A0101011001178400040A020102000A03"
$"0103000A0401041001178400040A050105000A060106000A0102070810011784"
$"00040A070109000A08010A000A01010B000A01030C0D0E1001178400040A0901"
$"0F000A0A0110000A0B0111000A01061213141516171001178200040A01151819"
$"1A1B1C1D1E1F202122232425262728292A2B2C100117820004"
};

View File

@@ -1,71 +0,0 @@
SUMMARY="A software implementation of the OpenAL 3D audio API"
DESCRIPTION="OpenAL stands for (Open Audio Library), a cross-platform audio application \
programming interface written in C. It is an environmental 3D audio \
library that aims to provide a replacement for proprietary 3D audio systems \
such as EAX and A3D. Openal is designed for efficient rendering of \
multichannel 3D positional audio."
HOMEPAGE="https://kcat.strangesoft.net/openal.html"
COPYRIGHT="1999-2000 Loki Software
2005-2018 OpenAL Soft team"
LICENSE="GNU LGPL v2.1"
REVISION="1"
SOURCE_URI="https://github.com/kcat/openal-soft/archive/openal-soft-$portVersion.tar.gz"
CHECKSUM_SHA256="9f3536ab2bb7781dbafabc6a61e0b34b17edd16bd6c2eaf2ae71bc63078f98c7"
SOURCE_DIR="openal-soft-openal-soft-$portVersion"
PATCHES="openal-$portVersion.patchset"
ARCHITECTURES="!x86_gcc2 x86_64"
SECONDARY_ARCHITECTURES="x86"
PROVIDES="
openal$secondaryArchSuffix = $portVersion compat >= 1
cmd:openal_info$secondaryArchSuffix
cmd:alrecord$secondaryArchSuffix
cmd:altonegen$secondaryArchSuffix
cmd:makehrtf$secondaryArchSuffix
lib:libopenal$secondaryArchSuffix = $portVersion compat >= 1
"
REQUIRES="
haiku$secondaryArchSuffix
lib:libatomic$secondaryArchSuffix
"
PROVIDES_devel="
openal${secondaryArchSuffix}_devel = $portVersion compat >= 1
devel:libopenal$secondaryArchSuffix = $portVersion compat >= 0
"
REQUIRES_devel="
haiku$secondaryArchSuffix
lib:libopenal$secondaryArchSuffix == $portVersion base
"
BUILD_REQUIRES="
haiku${secondaryArchSuffix}_devel
"
BUILD_PREREQUIRES="
cmd:cmake
cmd:gcc$secondaryArchSuffix
cmd:ld$secondaryArchSuffix
cmd:make
cmd:pkg_config$secondaryArchSuffix
"
BUILD()
{
mkdir -p build
cd build
cmake .. $cmakeDirArgs
make $jobArgs
}
INSTALL()
{
cd build
make install
prepareInstalledDevelLib libopenal
fixPkgconfig
# devel package
packageEntries devel $developDir
}

View File

@@ -0,0 +1,121 @@
SUMMARY="A software implementation of the OpenAL 3D audio API"
DESCRIPTION="OpenAL stands for (Open Audio Library), a cross-platform audio application \
programming interface written in C. It is an environmental 3D audio \
library that aims to provide a replacement for proprietary 3D audio systems \
such as EAX and A3D. Openal is designed for efficient rendering of \
multichannel 3D positional audio."
HOMEPAGE="https://kcat.strangesoft.net/openal.html"
COPYRIGHT="1999-2000 Loki Software
2005-2021 OpenAL Soft team"
LICENSE="GNU LGPL v2.1"
REVISION="1"
SOURCE_URI="https://www.openal-soft.org/openal-releases/openal-soft-$portVersion.tar.bz2"
CHECKSUM_SHA256="c8ad767e9a3230df66756a21cc8ebf218a9d47288f2514014832204e666af5d8"
SOURCE_DIR="openal-soft-$portVersion"
PATCHES="openal-$portVersion.patchset"
ADDITIONAL_FILES="openal.rdef.in"
ARCHITECTURES="!x86_gcc2 x86_64"
SECONDARY_ARCHITECTURES="x86"
commandBinDir=$binDir
commandSuffix=$secondaryArchSuffix
if [ "$targetArchitecture" = x86_gcc2 ]
then
commandBinDir=$prefix/bin
commandSuffix=
fi
PROVIDES="
openal$secondaryArchSuffix = $portVersion compat >= 1
lib:libopenal$secondaryArchSuffix = $portVersion compat >= 1
"
REQUIRES="
haiku$secondaryArchSuffix
lib:libatomic$secondaryArchSuffix
"
PROVIDES_devel="
openal${secondaryArchSuffix}_devel = $portVersion compat >= 1
devel:libopenal$secondaryArchSuffix = $portVersion compat >= 0
"
REQUIRES_devel="
haiku$secondaryArchSuffix
lib:libopenal$secondaryArchSuffix == $portVersion base
"
PROVIDES_tools="
openal${secondaryArchSuffix}_tools = $portVersion
cmd:openal_info$commandSuffix
cmd:alsoft_config$commandSuffix
cmd:alrecord$commandSuffix
cmd:altonegen$commandSuffix
cmd:makehrtf$commandSuffix
"
REQUIRES_tools="
$REQUIRES
lib:libopenal$secondaryArchSuffix
lib:libQt5Core$secondaryArchSuffix
lib:libQt5Gui$secondaryArchSuffix
lib:libQt5Widgets$secondaryArchSuffix
"
BUILD_REQUIRES="
haiku${secondaryArchSuffix}_devel
devel:libQt5Core$secondaryArchSuffix
devel:libQt5Gui$secondaryArchSuffix
devel:libQt5Widgets$secondaryArchSuffix
"
BUILD_PREREQUIRES="
cmd:cmake
cmd:gcc$secondaryArchSuffix
cmd:ld$secondaryArchSuffix
cmd:make
cmd:pkg_config$secondaryArchSuffix
"
BUILD()
{
mkdir -p build
cd build
cmake .. $cmakeDirArgs \
-DCMAKE_INSTALL_BINDIR=$commandBinDir
make $jobArgs
}
INSTALL()
{
cd build
make install
prepareInstalledDevelLib libopenal
fixPkgconfig
local APP_SIGNATURE="application/x-vnd.openal-soft-configuration"
local MAJOR="`echo "$portVersion" | cut -d. -f1`"
local MIDDLE="`echo "$portVersion" | cut -d. -f2`"
local MINOR="`echo "$portVersion" | cut -d. -f3`"
local LONG_INFO="$SUMMARY"
sed \
-e "s|@APP_SIGNATURE@|$APP_SIGNATURE|" \
-e "s|@MAJOR@|$MAJOR|" \
-e "s|@MIDDLE@|$MIDDLE|" \
-e "s|@MINOR@|$MINOR|" \
-e "s|@LONG_INFO@|$LONG_INFO|" \
$portDir/additional-files/openal.rdef.in > openal.rdef
addResourcesToBinaries openal.rdef $commandBinDir/alsoft-config
addPreferencesDeskbarSymlink $commandBinDir/alsoft-config "OpenAL Soft Configuration"
# tools package
packageEntries tools \
$commandBinDir \
$dataDir/deskbar
# devel package
packageEntries devel \
$developDir \
$libDir/cmake
}

View File

@@ -1,452 +0,0 @@
From ef88dd777531ce065d3b468ee1229e06bd662c58 Mon Sep 17 00:00:00 2001
From: Gerasim Troeglazov <3dEyes@gmail.com>
Date: Thu, 11 Oct 2018 21:55:36 +1000
Subject: Add Haiku backend
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 8bf2e1d..c4b11d9 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -90,6 +90,9 @@ static struct BackendInfo BackendList[] = {
#ifdef HAVE_WASAPI
{ "wasapi", ALCwasapiBackendFactory_getFactory },
#endif
+#ifdef HAVE_HAIKU
+ { "haiku", ALChaikuBackendFactory_getFactory },
+#endif
#ifdef HAVE_DSOUND
{ "dsound", ALCdsoundBackendFactory_getFactory },
#endif
diff --git a/Alc/backends/base.h b/Alc/backends/base.h
index 03db56e..13e3346 100644
--- a/Alc/backends/base.h
+++ b/Alc/backends/base.h
@@ -151,6 +151,7 @@ ALCbackendFactory *ALCwinmmBackendFactory_getFactory(void);
ALCbackendFactory *ALCportBackendFactory_getFactory(void);
ALCbackendFactory *ALCopenslBackendFactory_getFactory(void);
ALCbackendFactory *ALCnullBackendFactory_getFactory(void);
+ALCbackendFactory *ALChaikuBackendFactory_getFactory(void);
ALCbackendFactory *ALCwaveBackendFactory_getFactory(void);
ALCbackendFactory *ALCsdl2BackendFactory_getFactory(void);
ALCbackendFactory *ALCloopbackFactory_getFactory(void);
diff --git a/Alc/backends/haiku.c b/Alc/backends/haiku.c
new file mode 100644
index 0000000..e3c1ada
--- /dev/null
+++ b/Alc/backends/haiku.c
@@ -0,0 +1,177 @@
+#include "config.h"
+
+#include <stdlib.h>
+
+#include "alMain.h"
+#include "alu.h"
+#include "threads.h"
+#include "compat.h"
+
+#include "backends/base.h"
+
+bool haikuSoundPlayerInit(int channels, int samplerate, \
+ void (*soundproc) (void* , void* buffer, size_t size), void *cookie);
+bool haikuSoundPlayerStart(void);
+bool haikuSoundPlayerStop(void);
+bool haikuSoundPlayerDelete(void);
+const char *haikuProcessName(void);
+
+typedef struct ALChaikuBackend {
+ DERIVE_FROM_TYPE(ALCbackend);
+ ALvoid *mix_data;
+ ALsizei data_size;
+ ALsizei frameSize;
+} ALChaikuBackend;
+
+static void ALChaikuBackend_Construct(ALChaikuBackend *self, ALCdevice *device);
+static void ALChaikuBackend_Destruct(ALChaikuBackend *self);
+static ALCenum ALChaikuBackend_open(ALChaikuBackend *self, const ALCchar *name);
+static ALCboolean ALChaikuBackend_reset(ALChaikuBackend *self);
+static ALCboolean ALChaikuBackend_start(ALChaikuBackend *self);
+static void ALChaikuBackend_stop(ALChaikuBackend *self);
+static DECLARE_FORWARD2(ALChaikuBackend, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
+static DECLARE_FORWARD(ALChaikuBackend, ALCbackend, ALCuint, availableSamples)
+static DECLARE_FORWARD(ALChaikuBackend, ALCbackend, ClockLatency, getClockLatency)
+static DECLARE_FORWARD(ALChaikuBackend, ALCbackend, void, lock)
+static DECLARE_FORWARD(ALChaikuBackend, ALCbackend, void, unlock)
+DECLARE_DEFAULT_ALLOCATORS(ALChaikuBackend)
+
+DEFINE_ALCBACKEND_VTABLE(ALChaikuBackend);
+
+
+static const ALCchar haikuDevice[] = "Haiku MediaKit";
+
+static void ALChaikuBackend_audioCallback(void *cookie, void *buffer, size_t len)
+{
+ ALChaikuBackend *self = (ALChaikuBackend*)cookie;
+ ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
+ assert((len % self->frameSize) == 0);
+ aluMixData(device, buffer, len / self->frameSize);
+}
+
+static void ALChaikuBackend_Construct(ALChaikuBackend *self, ALCdevice *device)
+{
+ ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device);
+ SET_VTABLE2(ALChaikuBackend, ALCbackend, self);
+ self->mix_data = NULL;
+ self->frameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType, device->AmbiOrder);
+}
+
+static void ALChaikuBackend_Destruct(ALChaikuBackend *self)
+{
+ haikuSoundPlayerDelete();
+ ALCbackend_Destruct(STATIC_CAST(ALCbackend, self));
+}
+
+static ALCenum ALChaikuBackend_open(ALChaikuBackend *self, const ALCchar *name)
+{
+ ALCdevice *device;
+
+ if(!name)
+ name = haikuDevice;
+ else if(strcmp(name, haikuDevice) != 0)
+ return ALC_INVALID_VALUE;
+
+ device = STATIC_CAST(ALCbackend, self)->mDevice;
+ alstr_copy_cstr(&device->DeviceName, name);
+
+ return ALC_NO_ERROR;
+}
+
+static ALCboolean ALChaikuBackend_reset(ALChaikuBackend *self)
+{
+ SetDefaultWFXChannelOrder(STATIC_CAST(ALCbackend, self)->mDevice);
+ ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice;
+
+ if(device->FmtChans != DevFmtMono)
+ device->FmtChans = DevFmtStereo;
+
+ ALsizei numChannels = ChannelsFromDevFmt(device->FmtChans, device->AmbiOrder);
+ device->FmtType = DevFmtShort;
+ self->frameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType, device->AmbiOrder);
+
+ if (haikuSoundPlayerInit(numChannels, device->Frequency, ALChaikuBackend_audioCallback, (void*)self))
+ return ALC_TRUE;
+
+ return ALC_FALSE;
+}
+
+static ALCboolean ALChaikuBackend_start(ALChaikuBackend *self)
+{
+ ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice;
+
+ self->data_size = device->UpdateSize * FrameSizeFromDevFmt(
+ device->FmtChans, device->FmtType, device->AmbiOrder
+ );
+ al_free(self->mix_data);
+ self->mix_data = al_calloc(16, self->data_size);
+
+ if (haikuSoundPlayerStart())
+ return ALC_TRUE;
+
+ return ALC_FALSE;
+}
+
+static void ALChaikuBackend_stop(ALChaikuBackend *self)
+{
+ haikuSoundPlayerStop();
+ al_free(self->mix_data);
+ self->mix_data = NULL;
+}
+
+typedef struct ALChaikuBackendFactory {
+ DERIVE_FROM_TYPE(ALCbackendFactory);
+} ALChaikuBackendFactory;
+#define ALChaikuBACKENDFACTORY_INITIALIZER { { GET_VTABLE2(ALChaikuBackendFactory, ALCbackendFactory) } }
+
+ALCbackendFactory *ALChaikuBackendFactory_getFactory(void);
+
+static ALCboolean ALChaikuBackendFactory_init(ALChaikuBackendFactory *self);
+static DECLARE_FORWARD(ALChaikuBackendFactory, ALCbackendFactory, void, deinit)
+static ALCboolean ALChaikuBackendFactory_querySupport(ALChaikuBackendFactory *self, ALCbackend_Type type);
+static void ALChaikuBackendFactory_probe(ALChaikuBackendFactory *self, enum DevProbe type);
+static ALCbackend* ALChaikuBackendFactory_createBackend(ALChaikuBackendFactory *self, ALCdevice *device, ALCbackend_Type type);
+DEFINE_ALCBACKENDFACTORY_VTABLE(ALChaikuBackendFactory);
+
+ALCbackendFactory *ALChaikuBackendFactory_getFactory(void)
+{
+ static ALChaikuBackendFactory factory = ALChaikuBACKENDFACTORY_INITIALIZER;
+ return STATIC_CAST(ALCbackendFactory, &factory);
+}
+
+static ALCboolean ALChaikuBackendFactory_init(ALChaikuBackendFactory* UNUSED(self))
+{
+ return ALC_TRUE;
+}
+
+static ALCboolean ALChaikuBackendFactory_querySupport(ALChaikuBackendFactory* UNUSED(self), ALCbackend_Type type)
+{
+ if(type == ALCbackend_Playback)
+ return ALC_TRUE;
+ return ALC_FALSE;
+}
+
+static void ALChaikuBackendFactory_probe(ALChaikuBackendFactory* UNUSED(self), enum DevProbe type)
+{
+ switch(type)
+ {
+ case ALL_DEVICE_PROBE:
+ AppendAllDevicesList(haikuDevice);
+ break;
+ case CAPTURE_DEVICE_PROBE:
+ break;
+ }
+}
+
+static ALCbackend* ALChaikuBackendFactory_createBackend(ALChaikuBackendFactory* UNUSED(self), ALCdevice *device, ALCbackend_Type type)
+{
+ if(type == ALCbackend_Playback)
+ {
+ ALChaikuBackend *backend;
+ NEW_OBJ(backend, ALChaikuBackend)(device);
+ if(!backend) return NULL;
+ return STATIC_CAST(ALCbackend, backend);
+ }
+
+ return NULL;
+}
\ No newline at end of file
diff --git a/Alc/backends/haikusnd.cpp b/Alc/backends/haikusnd.cpp
new file mode 100644
index 0000000..538b3f0
--- /dev/null
+++ b/Alc/backends/haikusnd.cpp
@@ -0,0 +1,91 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <Application.h>
+#include <Roster.h>
+#include <OS.h>
+#include <Path.h>
+#include <SoundPlayer.h>
+
+#define HAIKU_PLAYER_BUFFER_SIZE 4096
+
+static BSoundPlayer *haikuSoundPlayer = NULL;
+static void (*haikuMixerProcFunc) (void *cookie, void *buffer, size_t len) = NULL;
+static BPath selfProcessPath;
+static const char *defualtProcessName = "OpenAL";
+
+static void haikuPlayerProc(void *cookie, void *buffer, size_t len, const media_raw_audio_format &)
+{
+ if (haikuMixerProcFunc != NULL)
+ haikuMixerProcFunc(cookie, buffer, len);
+}
+
+extern "C" {
+
+const char *haikuProcessName(void)
+{
+ app_info appInfo;
+ if (be_app->GetAppInfo(&appInfo) == B_OK) {
+ BPath path(&appInfo.ref);
+ selfProcessPath = path;
+ return selfProcessPath.Leaf();
+ } else {
+ return defualtProcessName;
+ }
+}
+
+bool haikuSoundPlayerInit(int channels, int samplerate, \
+ void (*soundproc) (void* , void* buffer, size_t size), void *cookie)
+{
+ haikuMixerProcFunc = soundproc;
+
+ media_raw_audio_format format = {
+ (float)samplerate,
+ (uint32)channels,
+ media_raw_audio_format::B_AUDIO_SHORT,
+ B_MEDIA_LITTLE_ENDIAN,
+ HAIKU_PLAYER_BUFFER_SIZE * sizeof(short)
+ };
+
+ haikuSoundPlayer = new BSoundPlayer(&format, haikuProcessName(), haikuPlayerProc, NULL, cookie);
+
+ if(haikuSoundPlayer->InitCheck() != B_OK) {
+ delete haikuSoundPlayer;
+ haikuSoundPlayer = NULL;
+ return false;
+ }
+ return true;
+}
+
+bool haikuSoundPlayerStart(void)
+{
+ if(haikuSoundPlayer) {
+ haikuSoundPlayer->Start();
+ haikuSoundPlayer->SetHasData(true);
+ return true;
+ }
+ return false;
+}
+
+bool haikuSoundPlayerStop(void)
+{
+ if(haikuSoundPlayer) {
+ haikuSoundPlayer->Stop();
+ return true;
+ }
+ return false;
+}
+
+bool haikuSoundPlayerDelete(void)
+{
+ if(haikuSoundPlayer) {
+ haikuSoundPlayer->Stop();
+ delete haikuSoundPlayer;
+ haikuSoundPlayer = NULL;
+ return true;
+ }
+ return true;
+}
+
+}
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 39b8025..9c44960 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,7 +2,7 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.0.2)
-PROJECT(OpenAL)
+PROJECT(OpenAL C CXX)
IF(COMMAND CMAKE_POLICY)
CMAKE_POLICY(SET CMP0003 NEW)
@@ -28,6 +28,7 @@ INCLUDE(CheckIncludeFiles)
INCLUDE(CheckSymbolExists)
INCLUDE(CheckCCompilerFlag)
INCLUDE(CheckCXXCompilerFlag)
+INCLUDE(CheckCXXSourceCompiles)
INCLUDE(CheckCSourceCompiles)
INCLUDE(CheckTypeSize)
include(CheckStructHasMember)
@@ -849,6 +850,7 @@ SET(HAVE_NEON 0)
SET(HAVE_ALSA 0)
SET(HAVE_OSS 0)
SET(HAVE_SOLARIS 0)
+SET(HAVE_HAIKU 0)
SET(HAVE_SNDIO 0)
SET(HAVE_QSA 0)
SET(HAVE_DSOUND 0)
@@ -1034,6 +1036,22 @@ IF(ALSOFT_REQUIRE_SOLARIS AND NOT HAVE_SOLARIS)
MESSAGE(FATAL_ERROR "Failed to enabled required Solaris backend")
ENDIF()
+# Check Haiku backend
+OPTION(ALSOFT_REQUIRE_HAIKU "Require Haiku backend" OFF)
+IF(HAIKU)
+ OPTION(ALSOFT_BACKEND_HAIKU "Enable Haiku backend" ON)
+ IF(ALSOFT_BACKEND_HAIKU)
+ SET(HAVE_HAIKU 1)
+ SET(BACKENDS "${BACKENDS} Haiku,")
+ SET(ALC_OBJS ${ALC_OBJS} Alc/backends/haiku.c Alc/backends/haikusnd.cpp)
+ SET(EXTRA_LIBS be ${EXTRA_LIBS})
+ SET(EXTRA_LIBS media ${EXTRA_LIBS})
+ ENDIF()
+ENDIF()
+IF(ALSOFT_REQUIRE_HAIKU AND NOT HAVE_HAIKU)
+ MESSAGE(FATAL_ERROR "Failed to enabled required Haiku backend")
+ENDIF()
+
# Check SndIO backend
OPTION(ALSOFT_REQUIRE_SNDIO "Require SndIO backend" OFF)
FIND_PACKAGE(SoundIO)
diff --git a/config.h.in b/config.h.in
index 9cc6c16..16abf3f 100644
--- a/config.h.in
+++ b/config.h.in
@@ -47,6 +47,9 @@
/* Define if we have the Solaris backend */
#cmakedefine HAVE_SOLARIS
+/* Define if we have the Haiku backend */
+#cmakedefine HAVE_HAIKU
+
/* Define if we have the SndIO backend */
#cmakedefine HAVE_SNDIO
--
2.19.1
From 064eb5bf45dcfdde845160b20da93d5862b98ff7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zolt=C3=A1n=20Mizsei?= <zmizsei@extrowerk.com>
Date: Wed, 2 Jan 2019 08:09:32 +0100
Subject: Build fix for 1.19.1
diff --git a/Alc/backends/haiku.c b/Alc/backends/haiku.c
index e3c1ada..50dd077 100644
--- a/Alc/backends/haiku.c
+++ b/Alc/backends/haiku.c
@@ -81,7 +81,7 @@ static ALCenum ALChaikuBackend_open(ALChaikuBackend *self, const ALCchar *name)
static ALCboolean ALChaikuBackend_reset(ALChaikuBackend *self)
{
SetDefaultWFXChannelOrder(STATIC_CAST(ALCbackend, self)->mDevice);
- ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice;
+ ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice;
if(device->FmtChans != DevFmtMono)
device->FmtChans = DevFmtStereo;
@@ -129,7 +129,7 @@ ALCbackendFactory *ALChaikuBackendFactory_getFactory(void);
static ALCboolean ALChaikuBackendFactory_init(ALChaikuBackendFactory *self);
static DECLARE_FORWARD(ALChaikuBackendFactory, ALCbackendFactory, void, deinit)
static ALCboolean ALChaikuBackendFactory_querySupport(ALChaikuBackendFactory *self, ALCbackend_Type type);
-static void ALChaikuBackendFactory_probe(ALChaikuBackendFactory *self, enum DevProbe type);
+static void ALChaikuBackendFactory_probe(ALChaikuBackendFactory *self, enum DevProbe type, al_string *outnames);
static ALCbackend* ALChaikuBackendFactory_createBackend(ALChaikuBackendFactory *self, ALCdevice *device, ALCbackend_Type type);
DEFINE_ALCBACKENDFACTORY_VTABLE(ALChaikuBackendFactory);
@@ -151,7 +151,7 @@ static ALCboolean ALChaikuBackendFactory_querySupport(ALChaikuBackendFactory* UN
return ALC_FALSE;
}
-static void ALChaikuBackendFactory_probe(ALChaikuBackendFactory* UNUSED(self), enum DevProbe type)
+static void ALChaikuBackendFactory_probe(ALChaikuBackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames)
{
switch(type)
{
@@ -174,4 +174,4 @@ static ALCbackend* ALChaikuBackendFactory_createBackend(ALChaikuBackendFactory*
}
return NULL;
-}
\ No newline at end of file
+}
--
2.19.1
From a66535985a8286c7a96d6200c2fb0dee0411c25f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zolt=C3=A1n=20Mizsei?= <zmizsei@extrowerk.com>
Date: Wed, 2 Jan 2019 09:16:26 +0100
Subject: AppendAllDevicesList not required anymore
diff --git a/Alc/backends/haiku.c b/Alc/backends/haiku.c
index 50dd077..9962a89 100644
--- a/Alc/backends/haiku.c
+++ b/Alc/backends/haiku.c
@@ -156,7 +156,6 @@ static void ALChaikuBackendFactory_probe(ALChaikuBackendFactory* UNUSED(self), e
switch(type)
{
case ALL_DEVICE_PROBE:
- AppendAllDevicesList(haikuDevice);
break;
case CAPTURE_DEVICE_PROBE:
break;
--
2.19.1

View File

@@ -0,0 +1,669 @@
From 0e3f49ceeb5f4a26e4df02055b87ba5eb647e814 Mon Sep 17 00:00:00 2001
From: Gerasim Troeglazov <3dEyes@gmail.com>
Date: Wed, 24 Feb 2021 14:13:58 +1000
Subject: Add Haiku backend
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0cf0613..47280e7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -790,6 +790,7 @@ set(HAVE_OPENSL 0)
set(HAVE_OBOE 0)
set(HAVE_WAVE 0)
set(HAVE_SDL2 0)
+set(HAVE_HAIKU 0)
if(WIN32 OR HAVE_DLFCN_H)
set(IS_LINKED "")
@@ -865,6 +866,22 @@ if(ALSOFT_REQUIRE_SOLARIS AND NOT HAVE_SOLARIS)
message(FATAL_ERROR "Failed to enabled required Solaris backend")
endif()
+# Check Haiku backend
+option(ALSOFT_REQUIRE_HAIKU "Require Haiku backend" OFF)
+if(HAIKU)
+ option(ALSOFT_BACKEND_HAIKU "Enable Haiku backend" ON)
+ if(ALSOFT_BACKEND_HAIKU)
+ SET(HAVE_HAIKU 1)
+ SET(BACKENDS "${BACKENDS} Haiku,")
+ SET(ALC_OBJS ${ALC_OBJS} alc/backends/haiku.cpp alc/backends/haiku.h)
+ SET(EXTRA_LIBS be ${EXTRA_LIBS})
+ SET(EXTRA_LIBS media ${EXTRA_LIBS})
+ endif()
+endif()
+if(ALSOFT_REQUIRE_HAIKU AND NOT HAVE_HAIKU)
+ MESSAGE(FATAL_ERROR "Failed to enabled required Haiku backend")
+endif()
+
# Check SndIO backend
option(ALSOFT_REQUIRE_SNDIO "Require SndIO backend" OFF)
find_package(SoundIO)
diff --git a/alc/alc.cpp b/alc/alc.cpp
index a755e67..fd23820 100644
--- a/alc/alc.cpp
+++ b/alc/alc.cpp
@@ -149,6 +149,9 @@
#ifdef HAVE_SDL2
#include "backends/sdl2.h"
#endif
+#ifdef HAVE_HAIKU
+#include "backends/haiku.h"
+#endif
#ifdef HAVE_WAVE
#include "backends/wave.h"
#endif
@@ -214,7 +217,9 @@ BackendInfo BackendList[] = {
#ifdef HAVE_SDL2
{ "sdl2", SDL2BackendFactory::getFactory },
#endif
-
+#ifdef HAVE_HAIKU
+ { "haiku", HaikuBackendFactory::getFactory },
+#endif
{ "null", NullBackendFactory::getFactory },
#ifdef HAVE_WAVE
{ "wave", WaveBackendFactory::getFactory },
diff --git a/alc/backends/haiku.cpp b/alc/backends/haiku.cpp
new file mode 100644
index 0000000..0052a64
--- /dev/null
+++ b/alc/backends/haiku.cpp
@@ -0,0 +1,453 @@
+/**
+ * OpenAL cross platform audio library
+ * Copyright (C) 2020-2021 by Gerasim Troeglazov
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * Or go to http://www.gnu.org/copyleft/lgpl.html
+ */
+
+#include "config.h"
+
+#include "backends/haiku.h"
+
+#include <exception>
+#include <atomic>
+#include <chrono>
+#include <cstdint>
+#include <cstring>
+#include <functional>
+#include <thread>
+
+#include "alcmain.h"
+#include "almalloc.h"
+#include "alu.h"
+#include "threads.h"
+#include "ringbuffer.h"
+#include "converter.h"
+
+#include <OS.h>
+#include <Path.h>
+#include <Roster.h>
+#include <Application.h>
+#include <SoundPlayer.h>
+#include <MediaAddOn.h>
+#include <MediaFile.h>
+#include <MediaNode.h>
+#include <MediaRecorder.h>
+#include <MediaRoster.h>
+#include <MediaTrack.h>
+#include <TimeSource.h>
+#include <NodeInfo.h>
+
+namespace {
+
+constexpr char defaultDeviceName[] = "Haiku Default";
+constexpr char defualtProcessName[] = "OpenAL";
+
+struct HaikuPlayback final : public BackendBase {
+ HaikuPlayback(ALCdevice *device) noexcept : BackendBase{device} { }
+ ~HaikuPlayback() override;
+
+ void audioCallback(void *stream, size_t len) noexcept;
+ static void audioCallbackC(void *cookie, void *buffer, size_t len, const media_raw_audio_format &) noexcept
+ {
+ static_cast<HaikuPlayback*>(cookie)->audioCallback(buffer, len);
+ }
+
+ void open(const char *name) override;
+ bool reset() override;
+ void start() override;
+ void stop() override;
+
+ BSoundPlayer *haikuSoundPlayer{0u};
+
+ DEF_NEWDEL(HaikuPlayback)
+};
+
+HaikuPlayback::~HaikuPlayback()
+{
+ if(haikuSoundPlayer) {
+ haikuSoundPlayer->SetHasData(false);
+ haikuSoundPlayer->Stop();
+ delete haikuSoundPlayer;
+ }
+ haikuSoundPlayer = 0;
+}
+
+void HaikuPlayback::audioCallback(void *stream, size_t len) noexcept
+{
+ const auto ulen = static_cast<unsigned int>(len);
+ mDevice->renderSamples(stream, ulen / mDevice->frameSizeFromFmt(), mDevice->channelsFromFmt());
+}
+
+void HaikuPlayback::open(const char *name)
+{
+ if(!name)
+ name = defaultDeviceName;
+ else if(strcmp(name, defaultDeviceName) != 0) {
+ throw al::backend_exception{al::backend_error::NoDevice, "Device name \"%s\" not found",
+ name};
+ }
+
+ media_raw_audio_format format = {
+ static_cast<float>(mDevice->Frequency),
+ mDevice->channelsFromFmt(),
+ media_raw_audio_format::B_AUDIO_SHORT,
+ B_MEDIA_LITTLE_ENDIAN,
+ mDevice->UpdateSize * sizeof(short)
+ };
+
+ switch(mDevice->FmtType)
+ {
+ case DevFmtUByte:
+ format.format = media_raw_audio_format::B_AUDIO_UCHAR;
+ break;
+ case DevFmtByte:
+ format.format = media_raw_audio_format::B_AUDIO_CHAR;
+ break;
+ case DevFmtUShort:
+ mDevice->FmtType = DevFmtShort;
+ format.format = media_raw_audio_format::B_AUDIO_SHORT;
+ break;
+ case DevFmtShort:
+ format.format = media_raw_audio_format::B_AUDIO_SHORT;
+ break;
+ case DevFmtUInt:
+ mDevice->FmtType = DevFmtInt;
+ format.format = media_raw_audio_format::B_AUDIO_INT;
+ break;
+ case DevFmtInt:
+ format.format = media_raw_audio_format::B_AUDIO_INT;
+ break;
+ case DevFmtFloat:
+ format.format = media_raw_audio_format::B_AUDIO_FLOAT;
+ break;
+ default:
+ mDevice->FmtType = DevFmtShort;
+ format.format = media_raw_audio_format::B_AUDIO_SHORT;
+ break;
+ }
+
+ format.buffer_size = mDevice->UpdateSize * mDevice->frameSizeFromFmt();
+
+ BString processName(defualtProcessName);
+ app_info appInfo;
+ if (be_app->GetAppInfo(&appInfo) == B_OK) {
+ BPath path(&appInfo.ref);
+ processName.SetTo(path.Leaf());
+ }
+
+ haikuSoundPlayer = new BSoundPlayer(&format, processName.String(), audioCallbackC, NULL, static_cast<void*>(this));
+ if(haikuSoundPlayer->InitCheck() != B_OK)
+ throw al::backend_exception{al::backend_error::NoDevice, "Failed to create BSoundPlayer"};
+
+ mDevice->DeviceName = name;
+}
+
+bool HaikuPlayback::reset()
+{
+ setDefaultWFXChannelOrder();
+ return true;
+}
+
+void HaikuPlayback::start()
+{
+ if(haikuSoundPlayer) {
+ haikuSoundPlayer->Start();
+ haikuSoundPlayer->SetHasData(true);
+ }
+}
+
+void HaikuPlayback::stop()
+{
+ if(haikuSoundPlayer) {
+ haikuSoundPlayer->SetHasData(false);
+ haikuSoundPlayer->Stop();
+ }
+}
+
+struct HaikuCapture final : public BackendBase {
+ HaikuCapture(ALCdevice *device) noexcept : BackendBase{device} { }
+ ~HaikuCapture() override;
+
+ void readCallback(void* data, size_t size, const media_format &format) noexcept;
+ static void readCallbackC(void* cookie, bigtime_t, void* data, size_t size, const media_format &format) noexcept
+ {
+ return static_cast<HaikuCapture*>(cookie)->readCallback(data, size, format);
+ }
+
+ static void notifyCallbackC(void * cookie, BMediaRecorder::notification code, ...)
+ {
+ HaikuCapture *haikuCapture = static_cast<HaikuCapture*>(cookie);
+ if (code == BMediaRecorder::B_WILL_STOP) {
+ if (haikuCapture->isRecording) {
+ haikuCapture->fRecorder->Stop();
+ haikuCapture->isRecording = false;
+ }
+ }
+ }
+
+ void open(const char *name) override;
+ void start() override;
+ void stop() override;
+ void captureSamples(al::byte *buffer, uint samples) override;
+ uint availableSamples() override;
+
+ RingBufferPtr mRing{nullptr};
+ ChannelConverter mChannelConv{};
+ SampleConverterPtr mSampleConv;
+
+ bool isRecording{false};
+
+ BMediaRoster *fRoster{0u};
+ BMediaRecorder *fRecorder{0u};
+ media_format fRecordFormat;
+ media_node fAudioInputNode;
+ media_node fAudioMixerNode;
+
+ DEF_NEWDEL(HaikuCapture)
+};
+
+HaikuCapture::~HaikuCapture()
+{
+ if (fRecorder) {
+ if (fRecorder->InitCheck() == B_OK) {
+ if (fRecorder->IsConnected())
+ fRecorder->Disconnect();
+ }
+ delete fRecorder;
+ fRecorder = NULL;
+ }
+}
+
+void HaikuCapture::readCallback(void* data, size_t size, const media_format &format) noexcept
+{
+ uint numsamples = static_cast<uint>(size) / format.AudioFrameSize();
+ void *rdata = data;
+
+ al::vector<float> samples;
+ if (mChannelConv.is_active()) {
+ samples.resize(numsamples*2);
+ mChannelConv.convert(rdata, samples.data(), numsamples);
+ rdata = reinterpret_cast<void*>(samples.data());
+ }
+
+ auto dstdata = mRing->getWriteVector();
+ size_t dstframes;
+ if (mSampleConv) {
+ const void *srcdata{rdata};
+ uint srcframes{numsamples};
+ dstframes = mSampleConv->convert(&srcdata, &srcframes, dstdata.first.buf,
+ static_cast<uint>(minz(dstdata.first.len, INT_MAX)));
+ } else {
+ const uint framesize{mDevice->frameSizeFromFmt()};
+ size_t len1{minz(dstdata.first.len, numsamples)};
+ size_t len2{minz(dstdata.second.len, numsamples - len1)};
+ memcpy(dstdata.first.buf, rdata, len1 * framesize);
+ if(len2 > 0)
+ memcpy(dstdata.second.buf, static_cast<unsigned char*>(rdata) + len1 * framesize, len2 * framesize);
+ dstframes = len1 + len2;
+ }
+
+ mRing->writeAdvance(dstframes);
+}
+
+void HaikuCapture::open(const char *name)
+{
+ if(!name)
+ name = defaultDeviceName;
+ else if(strcmp(name, defaultDeviceName) != 0) {
+ throw al::backend_exception{al::backend_error::NoDevice, "Device name \"%s\" not found",
+ name};
+ }
+
+ status_t error;
+
+ fRoster = BMediaRoster::Roster(&error);
+ if (!fRoster)
+ throw al::backend_exception{al::backend_error::NoDevice, "Failed to open BMediaRoster"};
+
+ error = fRoster->GetAudioInput(&fAudioInputNode);
+ if (error < B_OK)
+ throw al::backend_exception{al::backend_error::NoDevice, "Failed to get audio input node"};
+
+ error = fRoster->GetAudioMixer(&fAudioMixerNode);
+ if (error < B_OK)
+ throw al::backend_exception{al::backend_error::NoDevice, "Failed to open audio mixer"};
+
+ fRecorder = new BMediaRecorder(defualtProcessName, B_MEDIA_RAW_AUDIO);
+ if (fRecorder->InitCheck() < B_OK)
+ throw al::backend_exception{al::backend_error::NoDevice, "Failed to create BMediaRecorder"};
+
+ media_format output_format;
+ output_format.type = B_MEDIA_RAW_AUDIO;
+ output_format.u.raw_audio = media_raw_audio_format::wildcard;
+ output_format.u.raw_audio.channel_count = static_cast<int>(mDevice->channelsFromFmt());
+ fRecorder->SetAcceptedFormat(output_format);
+
+ const int maxInputCount = 64;
+ dormant_node_info dni[maxInputCount];
+
+ int32 real_count = maxInputCount;
+
+ error = fRoster->GetDormantNodes(dni, &real_count, 0, &output_format, 0, B_BUFFER_PRODUCER | B_PHYSICAL_INPUT);
+ if (real_count > maxInputCount)
+ real_count = maxInputCount;
+ char selected_name[B_MEDIA_NAME_LENGTH] = "Default input";
+
+ for (int i = 0; i < real_count; i++) {
+ media_node_id ni[12];
+ int32 ni_count = 12;
+ error = fRoster->GetInstancesFor(dni[i].addon, dni[i].flavor_id, ni, &ni_count);
+ if (error == B_OK) {
+ for (int j = 0; j < ni_count; j++) {
+ if (ni[j] == fAudioInputNode.node) {
+ strcpy(selected_name, dni[i].name);
+ break;
+ }
+ }
+ }
+ }
+
+ media_output audioOutput;
+ if (!fRecorder->IsConnected()) {
+ int32 count = 0;
+ error = fRoster->GetFreeOutputsFor(fAudioInputNode, &audioOutput, 1, &count, B_MEDIA_RAW_AUDIO);
+ if (error < B_OK || count < 1)
+ throw al::backend_exception{al::backend_error::NoDevice, "Failed to get free outputs"};
+
+ fRecordFormat.u.raw_audio = audioOutput.format.u.raw_audio;
+ } else {
+ fRecordFormat.u.raw_audio = fRecorder->AcceptedFormat().u.raw_audio;
+ }
+
+ fRecordFormat.type = B_MEDIA_RAW_AUDIO;
+
+ error = fRecorder->SetHooks(readCallbackC, notifyCallbackC, this);
+ if (error < B_OK)
+ throw al::backend_exception{al::backend_error::NoDevice, "Failed to set recorder hooks"};
+
+ if (!fRecorder->IsConnected()) {
+ error = fRecorder->Connect(fAudioInputNode, &audioOutput, &fRecordFormat);
+ if (error < B_OK) {
+ fRecorder->SetHooks(NULL, NULL, NULL);
+ throw al::backend_exception{al::backend_error::NoDevice, "Failed connection to BMediaRecorder"};
+ }
+ }
+
+ mRing = RingBuffer::Create(mDevice->BufferSize, mDevice->frameSizeFromFmt(), false);
+
+ DevFmtType srcType{};
+ switch(fRecordFormat.u.raw_audio.format) {
+ case media_raw_audio_format::B_AUDIO_UCHAR:
+ srcType = DevFmtUByte;
+ break;
+ case media_raw_audio_format::B_AUDIO_CHAR:
+ srcType = DevFmtByte;
+ break;
+ case media_raw_audio_format::B_AUDIO_SHORT:
+ srcType = DevFmtShort;
+ break;
+ case media_raw_audio_format::B_AUDIO_INT:
+ srcType = DevFmtInt;
+ break;
+ case media_raw_audio_format::B_AUDIO_FLOAT:
+ srcType = DevFmtFloat;
+ break;
+ }
+
+ mSampleConv = nullptr;
+ mChannelConv = {};
+
+ if(mDevice->FmtChans == DevFmtMono && fRecordFormat.u.raw_audio.channel_count != 1) {
+ uint chanmask{(1u<<fRecordFormat.u.raw_audio.channel_count) - 1u};
+ mChannelConv = ChannelConverter{srcType, fRecordFormat.u.raw_audio.channel_count, chanmask, mDevice->FmtChans};
+ srcType = DevFmtFloat;
+ } else if(mDevice->FmtChans == DevFmtStereo && fRecordFormat.u.raw_audio.channel_count == 1) {
+ mChannelConv = ChannelConverter{srcType, 1, 0x1, mDevice->FmtChans};
+ srcType = DevFmtFloat;
+ }
+
+ if(static_cast<uint>(fRecordFormat.u.raw_audio.frame_rate) != mDevice->Frequency || mDevice->FmtType != srcType) {
+ mSampleConv = CreateSampleConverter(srcType, mDevice->FmtType,
+ mDevice->channelsFromFmt(), static_cast<int>(fRecordFormat.u.raw_audio.frame_rate),
+ mDevice->Frequency, Resampler::FastBSinc24);
+ }
+
+ mDevice->DeviceName = name;
+}
+
+void HaikuCapture::start()
+{
+ isRecording = true;
+ fRecorder->Start();
+}
+
+void HaikuCapture::stop()
+{
+ isRecording = false;
+ fRecorder->Stop();
+}
+
+uint HaikuCapture::availableSamples()
+{
+ return static_cast<uint>(mRing->readSpace());
+}
+
+void HaikuCapture::captureSamples(al::byte *buffer, uint samples)
+{
+ mRing->read(buffer, samples);
+}
+
+} // namespace
+
+
+bool HaikuBackendFactory::init()
+{
+ return true;
+}
+
+bool HaikuBackendFactory::querySupport(BackendType type)
+{
+ return (type == BackendType::Playback || type == BackendType::Capture);
+}
+
+std::string HaikuBackendFactory::probe(BackendType type)
+{
+ std::string outnames;
+ switch(type)
+ {
+ case BackendType::Playback:
+ case BackendType::Capture:
+ outnames.append(defaultDeviceName, sizeof(defaultDeviceName));
+ break;
+ }
+ return outnames;
+}
+
+BackendPtr HaikuBackendFactory::createBackend(ALCdevice *device, BackendType type)
+{
+ if(type == BackendType::Playback)
+ return BackendPtr{new HaikuPlayback{device}};
+ if(type == BackendType::Capture)
+ return BackendPtr{new HaikuCapture{device}};
+ return nullptr;
+}
+
+BackendFactory &HaikuBackendFactory::getFactory()
+{
+ static HaikuBackendFactory factory{};
+ return factory;
+}
diff --git a/alc/backends/haiku.h b/alc/backends/haiku.h
new file mode 100644
index 0000000..3e20db8
--- /dev/null
+++ b/alc/backends/haiku.h
@@ -0,0 +1,19 @@
+#ifndef BACKENDS_HAIKU_H
+#define BACKENDS_HAIKU_H
+
+#include "backends/base.h"
+
+struct HaikuBackendFactory final : public BackendFactory {
+public:
+ bool init() override;
+
+ bool querySupport(BackendType type) override;
+
+ std::string probe(BackendType type) override;
+
+ BackendPtr createBackend(ALCdevice *device, BackendType type) override;
+
+ static BackendFactory &getFactory();
+};
+
+#endif /* BACKENDS_HAIKU_H */
diff --git a/config.h.in b/config.h.in
index a28204e..c37065c 100644
--- a/config.h.in
+++ b/config.h.in
@@ -71,6 +71,9 @@
/* Define if we have the SDL2 backend */
#cmakedefine HAVE_SDL2
+/* Define if we have the Haiku backend */
+#cmakedefine HAVE_HAIKU
+
/* Define if we have dlfcn.h */
#cmakedefine HAVE_DLFCN_H
--
2.30.0
From fd9fc3b3967e354076fc1b1bda47ef79d7a52267 Mon Sep 17 00:00:00 2001
From: Gerasim Troeglazov <3dEyes@gmail.com>
Date: Wed, 24 Feb 2021 17:06:13 +1000
Subject: Move config file to settings dir
diff --git a/alc/alconfig.cpp b/alc/alconfig.cpp
index 634679a..e6eba16 100644
--- a/alc/alconfig.cpp
+++ b/alc/alconfig.cpp
@@ -32,6 +32,9 @@
#ifdef __APPLE__
#include <CoreFoundation/CoreFoundation.h>
#endif
+#ifdef __HAIKU__
+#include <FindDirectory.h>
+#endif
#include <algorithm>
#include <cstdio>
@@ -314,6 +317,27 @@ void ReadALConfig()
}
}
+#elif defined(__HAIKU__)
+void ReadALConfig()
+{
+ char confpath[PATH_MAX] = "";
+ if (find_directory(B_USER_SETTINGS_DIRECTORY, -1, false, confpath, sizeof(confpath)) == B_OK) {
+ std::string confname{confpath};
+ confname += "/alsoft.conf";
+
+ TRACE("Loading config %s...\n", confname.c_str());
+ al::ifstream f{confname};
+ if(f.is_open())
+ LoadConfigFromFile(f);
+ }
+ if(auto confname = al::getenv("ALSOFT_CONF"))
+ {
+ TRACE("Loading config %s...\n", confname->c_str());
+ al::ifstream f{*confname};
+ if(f.is_open())
+ LoadConfigFromFile(f);
+ }
+}
#else
void ReadALConfig()
diff --git a/utils/alsoft-config/mainwindow.cpp b/utils/alsoft-config/mainwindow.cpp
index 8e6c7be..5454a3f 100644
--- a/utils/alsoft-config/mainwindow.cpp
+++ b/utils/alsoft-config/mainwindow.cpp
@@ -19,6 +19,10 @@
#include <shlobj.h>
#endif
+#ifdef __HAIKU__
+#include <FindDirectory.h>
+#endif
+
namespace {
static const struct {
@@ -64,6 +68,9 @@ static const struct {
#ifdef HAVE_OPENSL
{ "opensl", "OpenSL" },
#endif
+#ifdef HAVE_HAIKU
+ { "haiku", "Haiku" },
+#endif
{ "null", "Null Output" },
#ifdef HAVE_WAVE
@@ -152,6 +159,12 @@ static QString getDefaultConfigName()
return QString();
};
QString base = get_appdata_path();
+#elif defined(Q_OS_HAIKU)
+ static const char fname[] = "alsoft.conf";
+ QString base;
+ char confpath[PATH_MAX] = "";
+ if (find_directory(B_USER_SETTINGS_DIRECTORY, -1, false, confpath, sizeof(confpath)) == B_OK)
+ base = QString::fromUtf8(confpath);
#else
static const char fname[] = "alsoft.conf";
QByteArray base = qgetenv("XDG_CONFIG_HOME");
@@ -178,6 +191,11 @@ static QString getBaseDataPath()
return QString();
};
QString base = get_appdata_path();
+#elif defined(Q_OS_HAIKU)
+ QString base;
+ char datapath[PATH_MAX] = "";
+ if (find_directory(B_SYSTEM_DATA_DIRECTORY, -1, false, datapath, sizeof(datapath)) == B_OK)
+ base = QString::fromUtf8(datapath);
#else
QByteArray base = qgetenv("XDG_DATA_HOME");
if(base.isEmpty())
--
2.30.0