From b600c27b3dbeb7664035766a03f4574adefd7e2a 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 +#include +#include +#include +#include +#include +#include + +#include "alcmain.h" +#include "almalloc.h" +#include "alu.h" +#include "threads.h" +#include "ringbuffer.h" +#include "converter.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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(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(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(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(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(cookie)->readCallback(data, size, format); + } + + static void notifyCallbackC(void * cookie, BMediaRecorder::notification code, ...) + { + HaikuCapture *haikuCapture = static_cast(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(size) / format.AudioFrameSize(); + void *rdata = data; + + al::vector samples; + if (mChannelConv.is_active()) { + samples.resize(numsamples*2); + mChannelConv.convert(rdata, samples.data(), numsamples); + rdata = reinterpret_cast(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(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(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(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<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(fRecordFormat.u.raw_audio.frame_rate) != mDevice->Frequency || mDevice->FmtType != srcType) { + mSampleConv = CreateSampleConverter(srcType, mDevice->FmtType, + mDevice->channelsFromFmt(), static_cast(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(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.2 From 4d275ab94a2d3de13f28a496759a8e224b81d596 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 #endif +#ifdef __HAIKU__ +#include +#endif #include #include @@ -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 #endif +#ifdef __HAIKU__ +#include +#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.2 From 7a3ec72da52e2341a90a8c08a2e7f793a84aa1a5 Mon Sep 17 00:00:00 2001 From: Gerasim Troeglazov <3dEyes@gmail.com> Date: Wed, 24 Feb 2021 18:14:20 +1000 Subject: Add missing include diff --git a/alc/backends/haiku.cpp b/alc/backends/haiku.cpp index 0052a64..0159c0e 100644 --- a/alc/backends/haiku.cpp +++ b/alc/backends/haiku.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include -- 2.30.2 From 2f213bfd3f3c470ad768fe05453fc900ff49690b Mon Sep 17 00:00:00 2001 From: Gerasim Troeglazov <3dEyes@gmail.com> Date: Sat, 27 Feb 2021 23:49:01 +1000 Subject: Move create/delete BSoundPlayer to play()/stop() funcs diff --git a/alc/backends/haiku.cpp b/alc/backends/haiku.cpp index 0159c0e..08ebf48 100644 --- a/alc/backends/haiku.cpp +++ b/alc/backends/haiku.cpp @@ -73,18 +73,15 @@ struct HaikuPlayback final : public BackendBase { void stop() override; BSoundPlayer *haikuSoundPlayer{0u}; + BString processName; + media_raw_audio_format format; DEF_NEWDEL(HaikuPlayback) }; HaikuPlayback::~HaikuPlayback() { - if(haikuSoundPlayer) { - haikuSoundPlayer->SetHasData(false); - haikuSoundPlayer->Stop(); - delete haikuSoundPlayer; - } - haikuSoundPlayer = 0; + stop(); } void HaikuPlayback::audioCallback(void *stream, size_t len) noexcept @@ -102,7 +99,14 @@ void HaikuPlayback::open(const char *name) name}; } - media_raw_audio_format format = { + processName.SetTo(defualtProcessName); + app_info appInfo; + if (be_app->GetAppInfo(&appInfo) == B_OK) { + BPath path(&appInfo.ref); + processName.SetTo(path.Leaf()); + } + + format = { static_cast(mDevice->Frequency), mDevice->channelsFromFmt(), media_raw_audio_format::B_AUDIO_SHORT, @@ -143,17 +147,6 @@ void HaikuPlayback::open(const char *name) 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(this)); - if(haikuSoundPlayer->InitCheck() != B_OK) - throw al::backend_exception{al::backend_error::NoDevice, "Failed to create BSoundPlayer"}; - mDevice->DeviceName = name; } @@ -165,10 +158,15 @@ bool HaikuPlayback::reset() void HaikuPlayback::start() { - if(haikuSoundPlayer) { - haikuSoundPlayer->Start(); - haikuSoundPlayer->SetHasData(true); - } + if (haikuSoundPlayer) + stop(); + + haikuSoundPlayer = new BSoundPlayer(&format, processName.String(), audioCallbackC, NULL, static_cast(this)); + if(haikuSoundPlayer->InitCheck() != B_OK) + throw al::backend_exception{al::backend_error::NoDevice, "Failed to create BSoundPlayer"}; + + haikuSoundPlayer->Start(); + haikuSoundPlayer->SetHasData(true); } void HaikuPlayback::stop() @@ -176,7 +174,9 @@ void HaikuPlayback::stop() if(haikuSoundPlayer) { haikuSoundPlayer->SetHasData(false); haikuSoundPlayer->Stop(); + delete haikuSoundPlayer; } + haikuSoundPlayer = 0; } struct HaikuCapture final : public BackendBase { @@ -212,6 +212,7 @@ struct HaikuCapture final : public BackendBase { bool isRecording{false}; + BString processName; BMediaRoster *fRoster{0u}; BMediaRecorder *fRecorder{0u}; media_format fRecordFormat; @@ -274,6 +275,13 @@ void HaikuCapture::open(const char *name) name}; } + processName.SetTo(defualtProcessName); + app_info appInfo; + if (be_app->GetAppInfo(&appInfo) == B_OK) { + BPath path(&appInfo.ref); + processName.SetTo(path.Leaf()); + } + status_t error; fRoster = BMediaRoster::Roster(&error); @@ -288,7 +296,7 @@ void HaikuCapture::open(const char *name) 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); + fRecorder = new BMediaRecorder(processName, B_MEDIA_RAW_AUDIO); if (fRecorder->InitCheck() < B_OK) throw al::backend_exception{al::backend_error::NoDevice, "Failed to create BMediaRecorder"}; -- 2.30.2 From c7c83004d39f8e446f2bbdcd44ea6d65c0e71a96 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 6 Jul 2021 09:34:40 +0200 Subject: Make OpenALConfig.cmake compatible with CMake's FindOpenAL.cmake (#581) * Make OpenALConfig.cmake compatible with CMake's FindOpenAL.cmake * Create and install OpenALConfigVersion.cmake * cmake: drop creating of OpenALConfigVersion.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 47280e7..f2c7414 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,6 +69,7 @@ include(CheckCXXCompilerFlag) include(CheckCSourceCompiles) include(CheckCXXSourceCompiles) include(CheckStructHasMember) +include(CMakePackageConfigHelpers) include(GNUInstallDirs) @@ -1255,7 +1256,7 @@ else() target_include_directories(OpenAL PUBLIC $ - $ + $ PRIVATE ${OpenAL_SOURCE_DIR}/common ${OpenAL_BINARY_DIR} @@ -1320,7 +1321,10 @@ endif() target_include_directories(${IMPL_TARGET} PUBLIC $ - $ + INTERFACE + $ + $ + $ PRIVATE ${INC_PATHS} ${OpenAL_BINARY_DIR} @@ -1387,6 +1391,8 @@ endif() # Install main library if(ALSOFT_INSTALL) + configure_package_config_file(OpenALConfig.cmake.in OpenALConfig.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/OpenAL) install(TARGETS OpenAL EXPORT OpenAL RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} @@ -1395,15 +1401,17 @@ if(ALSOFT_INSTALL) INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ${CMAKE_INSTALL_INCLUDEDIR}/AL) export(TARGETS OpenAL NAMESPACE OpenAL:: - FILE OpenALConfig.cmake) + FILE OpenALTargets.cmake) install(EXPORT OpenAL DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/OpenAL NAMESPACE OpenAL:: - FILE OpenALConfig.cmake) + FILE OpenALTargets.cmake) install(DIRECTORY include/AL DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(FILES "${OpenAL_BINARY_DIR}/openal.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") + install(FILES "${OpenAL_BINARY_DIR}/OpenALConfig.cmake" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/OpenAL") if(TARGET soft_oal) install(TARGETS soft_oal RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/OpenALConfig.cmake.in b/OpenALConfig.cmake.in new file mode 100644 index 0000000..128c1a4 --- /dev/null +++ b/OpenALConfig.cmake.in @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.1) + +include("${CMAKE_CURRENT_LIST_DIR}/OpenALTargets.cmake") + +set(OPENAL_FOUND ON) +set(OPENAL_INCLUDE_DIR $) +set(OPENAL_LIBRARY $) +set(OPENAL_DEFINITIONS $) +set(OPENAL_VERSION_STRING @PACKAGE_VERSION@) -- 2.30.2