44 std::optional<int32_t> hardwareBufferFrames,
61 Q_UNREACHABLE_RETURN();
64 stream_events.state_changed = [](
void *userData, pw_stream_state old, pw_stream_state state,
69 std::vector<spa_dict_item> properties{
70 { PW_KEY_MEDIA_TYPE,
"Audio" },
72 properties.insert(properties.end(), extraProperties.begin(), extraProperties.end());
74 if (hardwareBufferFrames)
75 properties.push_back({
77 std::to_string(*hardwareBufferFrames).data(),
81 m_stream = PwStreamHandle{
82 pw_stream_new_simple(QAudioContextManager::getEventLoop(), streamName,
83 makeProperties(properties).release(), &stream_events,
this),
94 QAudioContextManager::deviceMonitor().findObjectId(target);
99 if (!deviceAlreadyRemoved)
102 std::array<uint8_t, 1024> buffer;
105 QT_WARNING_DISABLE_CLANG(
"-Wmissing-field-initializers")
106 struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer.data(), uint32_t(buffer.size()));
108 spa_audio_info_raw audioInfo = asSpaAudioInfoRaw(m_format);
110 std::array<
const struct spa_pod *, 1> params{
111 spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat, &audioInfo),
114 return pw_stream_connect(
115 m_stream.get(), direction, targetNodeId->value,
116 pw_stream_flags(PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_MAP_BUFFERS
117 | PW_STREAM_FLAG_RT_PROCESS | PW_STREAM_FLAG_DONT_RECONNECT),
118 params.data(), params.size());
172 m_deviceRemovalObserver = std::make_shared<ObjectRemoveObserver>(nodeSerial);
173 QObject::connect(m_deviceRemovalObserver.get(), &ObjectRemoveObserver::objectRemoved,
174 m_deviceRemovalObserver.get(), [
this] {
175 handleDeviceRemoved();
178 return QAudioContextManager::deviceMonitor().registerObserver(m_deviceRemovalObserver);