diff --git a/CMakeLists.txt b/CMakeLists.txt index e5825fc98..d6248b562 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -155,6 +155,10 @@ add_dependencies(musikcubed musikcube) if (CMAKE_SYSTEM_NAME MATCHES "Linux") add_subdirectory(src/plugins/alsaout) add_subdirectory(src/plugins/pulseout) + if (${ENABLE_PIPEWIRE} MATCHES "true") + add_subdirectory(src/plugins/pipewireout) + add_dependencies(musikcube pipewireout) + endif() if (${ENABLE_MPRIS} MATCHES "true") add_subdirectory(src/plugins/mpris) add_dependencies(musikcube mpris) diff --git a/src/plugins/pipewireout/CMakeLists.txt b/src/plugins/pipewireout/CMakeLists.txt new file mode 100644 index 000000000..fcd67615c --- /dev/null +++ b/src/plugins/pipewireout/CMakeLists.txt @@ -0,0 +1,9 @@ +set (pipewireout_SOURCES + pipewireout_plugin.cpp + PipeWireOut.cpp +) + +message(STATUS "[pipewireout] plugin enabled") + +add_library(pipewireout SHARED ${pipewireout_SOURCES}) +target_link_libraries(pipewireout ${musikcube_LINK_LIBS} pipewire-0.3) diff --git a/src/plugins/pipewireout/PipeWireOut.cpp b/src/plugins/pipewireout/PipeWireOut.cpp new file mode 100644 index 000000000..12884c869 --- /dev/null +++ b/src/plugins/pipewireout/PipeWireOut.cpp @@ -0,0 +1,114 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004-2020 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 "PipeWireOut.h" + +#include +#include +#include +#include + +static IPreferences* prefs = nullptr; + +extern "C" void SetPreferences(IPreferences* prefs) { + ::prefs = prefs; +} + +extern "C" musik::core::sdk::ISchema* GetSchema() { + auto schema = new TSchema<>(); + return schema; +} + +PipeWireOut::PipeWireOut() { + this->volume = 1.0f; + this->state = StateStopped; +} + +PipeWireOut::~PipeWireOut() { +} + +void PipeWireOut::Release() { + delete this; +} + +void PipeWireOut::Pause() { + this->state = StatePaused; +} + +void PipeWireOut::Resume() { + this->state = StatePlaying; +} + +void PipeWireOut::SetVolume(double volume) { + this->volume = volume; +} + +double PipeWireOut::GetVolume() { + return this->volume; +} + +void PipeWireOut::Stop() { + this->state = StateStopped; +} + +void PipeWireOut::Drain() { +} + +IDeviceList* PipeWireOut::GetDeviceList() { + return nullptr; +} + +bool PipeWireOut::SetDefaultDevice(const char* deviceId) { + return false; +} + +IDevice* PipeWireOut::GetDefaultDevice() { + return nullptr; +} + +OutputState PipeWireOut::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 PipeWireOut::Latency() { + return 0.0; +} \ No newline at end of file diff --git a/src/plugins/pipewireout/PipeWireOut.h b/src/plugins/pipewireout/PipeWireOut.h new file mode 100644 index 000000000..6de47b565 --- /dev/null +++ b/src/plugins/pipewireout/PipeWireOut.h @@ -0,0 +1,72 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004-2020 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 + +using namespace musik::core::sdk; + +class PipeWireOut : public IOutput { + public: + PipeWireOut(); + ~PipeWireOut(); + + /* IPlugin */ + const char* Name() override { return "PipeWire"; }; + 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; + + private: + enum State { + StateStopped, + StatePaused, + StatePlaying + }; + + State state; + double volume; +}; diff --git a/src/plugins/pipewireout/pipewireout_plugin.cpp b/src/plugins/pipewireout/pipewireout_plugin.cpp new file mode 100644 index 000000000..23193902b --- /dev/null +++ b/src/plugins/pipewireout/pipewireout_plugin.cpp @@ -0,0 +1,63 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004-2020 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 +#include +#include +#include "PipeWireOut.h" + +class PipeWirePlugin : public musik::core::sdk::IPlugin { + public: + void Release() noexcept override { delete this; } + const char* Name() override { return "PipeWire IOutput"; } + const char* Version() override { return "0.1.0"; } + const char* Author() override { return "clangen"; } + const char* Guid() override { return "ab79e0f2-53d8-4774-ad00-266a30c50427"; } + bool Configurable() override { return false; } + void Configure() override { } + void Reload() override { } + int SdkVersion() override { return musik::core::sdk::SdkVersion; } +}; + +extern "C" musik::core::sdk::IPlugin* GetPlugin() { + return new PipeWirePlugin(); +} + +extern "C" musik::core::sdk::IOutput* GetAudioOutput() { + return new PipeWireOut(); +} + +extern "C" musik::core::sdk::ISchema* GetSchema(); \ No newline at end of file