42 std::optional<int32_t> hardwareBufferFrames,
59 Q_UNREACHABLE_RETURN();
62 stream_events.state_changed = [](
void *userData, pw_stream_state old, pw_stream_state state,
67 std::vector<spa_dict_item> properties{
68 { PW_KEY_MEDIA_TYPE,
"Audio" },
70 properties.insert(properties.end(), extraProperties.begin(), extraProperties.end());
72 std::string quantumStr;
73 if (hardwareBufferFrames) {
74 quantumStr = std::to_string(*hardwareBufferFrames);
75 properties.push_back({
81 QAudioContextManager::withEventLoopLock([&] {
82 m_stream = PwStreamHandle{
83 pw_stream_new_simple(QAudioContextManager::getEventLoop(), streamName,
84 makeProperties(properties).release(), &stream_events,
this),
88 qWarning() <<
"pw_stream_new_simple failed" << make_error_code().message();
93 int status = QAudioContextManager::withEventLoopLock([&] {
94 std::optional<ObjectId> targetNodeId =
95 QAudioContextManager::deviceMonitor().findObjectId(target);
99 bool deviceAlreadyRemoved = registerDeviceObserver(target);
100 if (!deviceAlreadyRemoved)
103 std::array<uint8_t, 1024> buffer;
106 QT_WARNING_DISABLE_CLANG(
"-Wmissing-field-initializers")
107 struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer.data(), uint32_t(buffer.size()));
109 spa_audio_info_raw audioInfo = asSpaAudioInfoRaw(m_format);
111 std::array<
const struct spa_pod *, 1> params{
112 spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat, &audioInfo),
115 return pw_stream_connect(
116 m_stream.get(), direction, targetNodeId->value,
117 pw_stream_flags(PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_MAP_BUFFERS
118 | PW_STREAM_FLAG_RT_PROCESS | PW_STREAM_FLAG_DONT_RECONNECT),
119 params.data(), params.size());
123 qWarning() <<
"pw_stream_connect failed" << make_error_code(-status).message();
176 m_deviceRemovalObserver = std::make_shared<ObjectRemoveObserver>(nodeSerial);
177 QObject::connect(m_deviceRemovalObserver.get(), &ObjectRemoveObserver::objectRemoved,
178 m_deviceRemovalObserver.get(), [
this] {
179 handleDeviceRemoved();
182 return QAudioContextManager::deviceMonitor().registerObserver(m_deviceRemovalObserver);