Added stubs for PortAudio output plugin.

This commit is contained in:
casey langen 2022-12-29 13:37:38 -08:00
parent 1dc9096d9a
commit 0a27525573
6 changed files with 379 additions and 7 deletions

View File

@ -109,22 +109,23 @@ add_dependencies(musikcubed musikcore)
# tag readers
add_plugin("src/plugins/taglib_plugin" "taglibreader")
# outputs
add_plugin("src/plugins/nullout" "nullout")
add_plugin("src/plugins/alsaout" "alsaout")
add_plugin("src/plugins/pulseout" "pulseout")
add_plugin("src/plugins/pipewireout" "pipewireout")
add_plugin("src/plugins/sndioout" "sndioout")
add_plugin("src/plugins/coreaudioout" "coreaudioout")
add_plugin("src/plugins/nullout" "nullout")
add_plugin("src/plugins/pipewireout" "pipewireout")
add_plugin("src/plugins/portaudioout" "portaudioout")
add_plugin("src/plugins/pulseout" "pulseout")
add_plugin("src/plugins/sndioout" "sndioout")
# remotes
add_plugin("src/plugins/server" "server")
add_plugin("src/plugins/mpris" "mpris")
add_plugin("src/plugins/macosmediakeys" "macosmediakeys")
add_plugin("src/plugins/mpris" "mpris")
add_plugin("src/plugins/server" "server")
# streams
add_plugin("src/plugins/httpdatastream" "httpdatastream")
# decoders
add_plugin("src/plugins/ffmpegdecoder" "ffmpegdecoder")
add_plugin("src/plugins/libopenmptdecoder" "openmptdecoder")
add_plugin("src/plugins/gmedecoder" "gmedecoder")
add_plugin("src/plugins/libopenmptdecoder" "openmptdecoder")
# encoders
add_plugin("src/plugins/stockencoders" "stockencoders")
# dsps

View File

@ -0,0 +1,14 @@
set (portaudioout_SOURCES
portaudioout_plugin.cpp
PortAudioOut.cpp
)
find_library(LIBPORTAUDIO "portaudio")
if ("${LIBPORTAUDIO}" STREQUAL "LIBPORTAUDIO-NOTFOUND")
disable_plugin(portaudioout)
else()
add_library(portaudioout SHARED ${portaudioout_SOURCES})
target_link_libraries(portaudioout ${LIBPORTAUDIO})
message(STATUS "[portaudioout] using libportaudio at: ${LIBPORTAUDIO}")
endif()

View File

@ -0,0 +1,159 @@
//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004-2021 musikcube team
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#include "PortAudioOut.h"
#include <musikcore/sdk/constants.h>
#include <musikcore/sdk/IPreferences.h>
#include <musikcore/sdk/ISchema.h>
#include <musikcore/sdk/IDebug.h>
using namespace musik::core::sdk;
#ifdef WIN32
#include <Windows.h>
#define usleep(x) Sleep(x / 1000);
#define DLLEXPORT __declspec(dllexport)
#else
#include <unistd.h>
#define DLLEXPORT
#endif
#define PREF_DEFAULT_SAMPLE_RATE "default_sample_rate"
#define TAG "PortAudioOut"
static int defaultSampleRate = 48000;
static IPreferences* prefs = nullptr;
static IDebug* debug = nullptr;
static void reloadMultiplier() {
if (::prefs) {
::defaultSampleRate = prefs->GetInt(PREF_DEFAULT_SAMPLE_RATE, defaultSampleRate);
}
}
extern "C" DLLEXPORT void SetDebug(IDebug* debug) {
::debug = debug;
}
extern "C" DLLEXPORT void SetPreferences(IPreferences* prefs) {
::prefs = prefs;
}
extern "C" DLLEXPORT musik::core::sdk::ISchema* GetSchema() {
auto schema = new TSchema<>();
schema->AddInt(PREF_DEFAULT_SAMPLE_RATE, defaultSampleRate, 4096, 192000);
return schema;
}
static void logPaError(const std::string& method, PaError error) {
std::string err = method + "() return code: " + std::to_string(error);
if (error != 0) {
::debug->Warning(TAG, err.c_str());
}
else {
::debug->Info(TAG, err.c_str());
}
}
PortAudioOut::PortAudioOut() {
this->volume = 1.0f;
this->state = StateStopped;
logPaError("Pa_Initialize", Pa_Initialize());
}
PortAudioOut::~PortAudioOut() {
logPaError("Pa_Terminate", Pa_Terminate());
}
void PortAudioOut::Release() {
delete this;
}
void PortAudioOut::Pause() {
this->state = StatePaused;
}
void PortAudioOut::Resume() {
reloadMultiplier();
this->state = StatePlaying;
}
void PortAudioOut::SetVolume(double volume) {
this->volume = volume;
}
double PortAudioOut::GetVolume() {
return this->volume;
}
void PortAudioOut::Stop() {
this->state = StateStopped;
}
void PortAudioOut::Drain() {
}
IDeviceList* PortAudioOut::GetDeviceList() {
return nullptr;
}
bool PortAudioOut::SetDefaultDevice(const char* deviceId) {
return false;
}
IDevice* PortAudioOut::GetDefaultDevice() {
return nullptr;
}
OutputState PortAudioOut::Play(IBuffer *buffer, IBufferProvider *provider) {
if (this->state == StatePaused) {
return OutputState::InvalidState;
}
/* order of operations matters, otherwise overflow. */
int micros = ((buffer->Samples() * 1000) / buffer->SampleRate() * 1000) / buffer->Channels();
usleep((long)((float) micros));
provider->OnBufferProcessed(buffer);
return OutputState::BufferWritten;
}
double PortAudioOut::Latency() {
return 0.0;
}
int PortAudioOut::GetDefaultSampleRate() {
return defaultSampleRate;
}

View File

@ -0,0 +1,76 @@
//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004-2021 musikcube team
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#pragma once
#include "config.h"
#include <musikcore/sdk/IOutput.h>
#include <portaudio.h>
using namespace musik::core::sdk;
class PortAudioOut : public IOutput {
public:
PortAudioOut();
~PortAudioOut();
/* IPlugin */
const char* Name() override { return "PortAudio"; };
void Release() override;
/* IOutput */
void Pause() override;
void Resume() override;
void SetVolume(double volume) override;
double GetVolume() override;
void Stop() override;
OutputState Play(IBuffer *buffer, IBufferProvider *provider) override;
double Latency() override;
void Drain() override;
IDeviceList* GetDeviceList() override;
bool SetDefaultDevice(const char* deviceId) override;
IDevice* GetDefaultDevice() override;
int GetDefaultSampleRate() override;
private:
enum State {
StateStopped,
StatePaused,
StatePlaying
};
State state;
double volume;
};

View File

@ -0,0 +1,53 @@
//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004-2021 musikcube team
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#pragma once
#ifdef WIN32
#ifndef WINVER
#define WINVER 0x0601
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0601
#endif
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#define DLLEXPORT __declspec(dllexport)
#include <windows.h>
#else
#define DLLEXPORT
#endif

View File

@ -0,0 +1,69 @@
//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004-2021 musikcube team
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#include "config.h"
#include <musikcore/sdk/constants.h>
#include <musikcore/sdk/IPlugin.h>
#include <musikcore/sdk/ISchema.h>
#include "PortAudioOut.h"
class PortAudioPlugin : public musik::core::sdk::IPlugin {
public:
void Release() noexcept override { delete this; }
const char* Name() override { return "PortAudio IOutput"; }
const char* Version() override { return "0.1.0"; }
const char* Author() override { return "clangen"; }
const char* Guid() override { return "521934a5-2263-41a4-9852-937d0b63f196"; }
bool Configurable() override { return false; }
void Configure() override { }
void Reload() override { }
int SdkVersion() override { return musik::core::sdk::SdkVersion; }
};
#ifdef WIN32
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
return true;
}
#endif
extern "C" DLLEXPORT musik::core::sdk::IPlugin* GetPlugin() {
return new PortAudioPlugin();
}
extern "C" DLLEXPORT musik::core::sdk::IOutput* GetAudioOutput() {
return new PortAudioOut();
}
extern "C" DLLEXPORT musik::core::sdk::ISchema* GetSchema();