Virtual
This commit is contained in:
parent
96e1a5cbdb
commit
ecfb59501a
5 changed files with 146 additions and 4 deletions
|
|
@ -19,6 +19,7 @@
|
|||
#include <spa/param/audio/format-utils.h>
|
||||
#include <spa/param/audio/raw.h>
|
||||
#include <spa/utils/dict.h>
|
||||
#include <spa/utils/defs.h>
|
||||
#include <spa/utils/type-info.h>
|
||||
|
||||
namespace Potato {
|
||||
|
|
@ -76,6 +77,56 @@ static bool readRingLatest(spa_ringbuffer *ring, std::vector<uint8_t> &buffer, f
|
|||
return true;
|
||||
}
|
||||
|
||||
bool PipeWireController::createVirtualDevice(const QString &name,
|
||||
const QString &description,
|
||||
const char *factoryName,
|
||||
const char *mediaClass,
|
||||
int channels,
|
||||
int rate)
|
||||
{
|
||||
if (!m_threadLoop || !m_core || name.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
channels = channels > 0 ? channels : 2;
|
||||
rate = rate > 0 ? rate : 48000;
|
||||
|
||||
const QByteArray nameBytes = name.toUtf8();
|
||||
const QByteArray descBytes = description.isEmpty() ? nameBytes : description.toUtf8();
|
||||
const QByteArray channelsBytes = QByteArray::number(channels);
|
||||
const QByteArray rateBytes = QByteArray::number(rate);
|
||||
|
||||
struct spa_dict_item items[] = {
|
||||
{ PW_KEY_FACTORY_NAME, factoryName },
|
||||
{ PW_KEY_NODE_NAME, nameBytes.constData() },
|
||||
{ PW_KEY_NODE_DESCRIPTION, descBytes.constData() },
|
||||
{ PW_KEY_MEDIA_CLASS, mediaClass },
|
||||
{ PW_KEY_AUDIO_CHANNELS, channelsBytes.constData() },
|
||||
{ PW_KEY_AUDIO_RATE, rateBytes.constData() },
|
||||
{ "object.linger", "true" },
|
||||
{ PW_KEY_APP_NAME, "Potato-Manager" }
|
||||
};
|
||||
|
||||
struct spa_dict dict = SPA_DICT_INIT(items, SPA_N_ELEMENTS(items));
|
||||
|
||||
lock();
|
||||
auto *proxy = static_cast<struct pw_proxy*>(pw_core_create_object(
|
||||
m_core,
|
||||
"adapter",
|
||||
PW_TYPE_INTERFACE_Node,
|
||||
PW_VERSION_NODE,
|
||||
&dict,
|
||||
0));
|
||||
unlock();
|
||||
|
||||
if (!proxy) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_virtualDevices.push_back(proxy);
|
||||
return true;
|
||||
}
|
||||
|
||||
static QString toQString(const char *value)
|
||||
{
|
||||
if (!value) {
|
||||
|
|
@ -382,6 +433,13 @@ void PipeWireController::shutdown()
|
|||
}
|
||||
m_nodeMeters.clear();
|
||||
}
|
||||
|
||||
for (auto *proxy : m_virtualDevices) {
|
||||
if (proxy) {
|
||||
pw_proxy_destroy(proxy);
|
||||
}
|
||||
}
|
||||
m_virtualDevices.clear();
|
||||
|
||||
if (m_core) {
|
||||
pw_core_disconnect(m_core);
|
||||
|
|
@ -480,6 +538,16 @@ bool PipeWireController::setNodeVolume(uint32_t nodeId, float volume, bool mute)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool PipeWireController::createVirtualSink(const QString &name, const QString &description, int channels, int rate)
|
||||
{
|
||||
return createVirtualDevice(name, description, "support.null-audio-sink", "Audio/Sink", channels, rate);
|
||||
}
|
||||
|
||||
bool PipeWireController::createVirtualSource(const QString &name, const QString &description, int channels, int rate)
|
||||
{
|
||||
return createVirtualDevice(name, description, "support.null-audio-source", "Audio/Source", channels, rate);
|
||||
}
|
||||
|
||||
float PipeWireController::nodeMeterPeak(uint32_t nodeId) const
|
||||
{
|
||||
QMutexLocker lock(&m_meterMutex);
|
||||
|
|
@ -829,10 +897,12 @@ void PipeWireController::handlePortInfo(uint32_t id, const struct spa_dict *prop
|
|||
uint32_t nodeId = nodeIdStr ? static_cast<uint32_t>(atoi(nodeIdStr)) : 0;
|
||||
PortInfo port(id, nodeId, portName, direction);
|
||||
|
||||
bool emitChanged = false;
|
||||
NodeInfo nodeSnapshot;
|
||||
{
|
||||
QMutexLocker lock(&m_nodesMutex);
|
||||
m_ports.insert(id, port);
|
||||
|
||||
|
||||
if (nodeId != 0 && m_nodes.contains(nodeId)) {
|
||||
NodeInfo &node = m_nodes[nodeId];
|
||||
auto &ports = (direction == PW_DIRECTION_INPUT) ? node.inputPorts : node.outputPorts;
|
||||
|
|
@ -843,9 +913,15 @@ void PipeWireController::handlePortInfo(uint32_t id, const struct spa_dict *prop
|
|||
}
|
||||
}
|
||||
ports.append(port);
|
||||
nodeSnapshot = node;
|
||||
emitChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (emitChanged) {
|
||||
emit nodeChanged(nodeSnapshot);
|
||||
}
|
||||
|
||||
qDebug() << "Port added:" << id << portName << "direction:" << direction;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue