@@ -83,6 +83,7 @@ PipewireEnumerator::~PipewireEnumerator() {
8383 pw_thread_loop_stop (m_pPwThreadLoop);
8484
8585 if (m_pPwFilter) {
86+ spa_hook_remove (&m_pwFilterListener);
8687 pw_filter_destroy (m_pPwFilter);
8788 }
8889
@@ -110,7 +111,6 @@ PipewireEnumerator::~PipewireEnumerator() {
110111
111112void PipewireEnumerator::initialize () {
112113 if (m_initialized) {
113- qWarning () << " PipewireEnumerator::initialize already initialized" ;
114114 return ;
115115 }
116116
@@ -158,6 +158,16 @@ void PipewireEnumerator::initialize() {
158158
159159 pw_filter_add_listener (m_pPwFilter, &m_pwFilterListener, &filter_events, this );
160160
161+ const auto registeredOutputs = m_pSoundManager->registeredOutputs ();
162+ for (const auto & output : registeredOutputs) {
163+ createOutputPorts (output);
164+ }
165+
166+ const auto registeredInputs = m_pSoundManager->registeredInputs ();
167+ for (const auto & input : registeredInputs) {
168+ createInputPorts (input);
169+ }
170+
161171 int res = pw_filter_connect (m_pPwFilter,
162172 PW_FILTER_FLAG_RT_PROCESS ,
163173 nullptr ,
@@ -491,10 +501,11 @@ void PipewireEnumerator::callback(const spa_io_position* pos) {
491501 const uint64_t framesPerBuffer = pos->clock .duration ;
492502
493503 if (sampleRate != m_sampleRate || framesPerBuffer != m_framesPerBuffer) {
494- qWarning () << " PipewireEnumerator::callback rate requested"
495- << m_sampleRate << " provided" << sampleRate
496- << " buffer size requested" << m_framesPerBuffer << " provided"
497- << framesPerBuffer;
504+ qWarning () << " PipewireEnumerator::callback"
505+ " requested"
506+ << m_framesPerBuffer << " samples at" << m_sampleRate << " hz,"
507+ " provided"
508+ << framesPerBuffer << " samples at" << sampleRate << " hz" ;
498509 setLatency (sampleRate, framesPerBuffer);
499510 }
500511
@@ -504,7 +515,7 @@ void PipewireEnumerator::callback(const spa_io_position* pos) {
504515 for (uint32_t deviceId : m_openedDevices) {
505516 QSharedPointer<SoundDevicePipewire> device = m_soundDevices.at (deviceId);
506517 QList<AudioInputBuffer> deviceInputs = device->inputs ();
507- for (AudioInputBuffer input : deviceInputs) {
518+ for (const AudioInputBuffer& input : deviceInputs) {
508519 ChannelGroup channelGroup = input.getChannelGroup ();
509520 const int iChannelCount = channelGroup.getChannelCount ();
510521 const int iChannelBase = channelGroup.getChannelBase ();
@@ -543,7 +554,7 @@ void PipewireEnumerator::callback(const spa_io_position* pos) {
543554
544555 for (uint32_t deviceId : m_openedDevices) {
545556 QSharedPointer<SoundDevicePipewire> device = m_soundDevices.at (deviceId);
546- for (AudioOutputBuffer output : device->outputs ()) {
557+ for (const AudioOutputBuffer& output : device->outputs ()) {
547558 ChannelGroup chanGroup = output.getChannelGroup ();
548559 const int iChannelCount = chanGroup.getChannelCount ();
549560 const int iChannelBase = chanGroup.getChannelBase ();
@@ -637,72 +648,71 @@ void PipewireEnumerator::registerInput(const AudioInput& input, AudioDestination
637648 return ;
638649 }
639650
640- pw_thread_loop_lock (m_pPwThreadLoop);
641- pw_properties* props = pw_properties_new (
642- // see pipewire/keys.h header
643- PW_KEY_FORMAT_DSP ,
644- " 32 bit float mono audio" ,
645- nullptr );
646- pw_properties_setf (props, PW_KEY_PORT_NAME , " %s:FL" , input.getString ().toStdString ().c_str ());
647- void * portFL = pw_filter_add_port (m_pPwFilter,
648- SPA_DIRECTION_INPUT ,
649- PW_FILTER_PORT_FLAG_MAP_BUFFERS ,
650- sizeof (uint32_t ),
651- props,
652- nullptr ,
653- 0 );
654-
655- props = pw_properties_new (
656- // see pipewire/keys.h header
657- PW_KEY_FORMAT_DSP ,
658- " 32 bit float mono audio" ,
659- nullptr );
660- pw_properties_setf (props, PW_KEY_PORT_NAME , " %s:FR" , input.getString ().toStdString ().c_str ());
661- void * portFR = pw_filter_add_port (m_pPwFilter,
662- SPA_DIRECTION_INPUT ,
663- PW_FILTER_PORT_FLAG_MAP_BUFFERS ,
664- sizeof (uint32_t ),
665- props,
666- nullptr ,
667- 0 );
668- pw_thread_loop_unlock (m_pPwThreadLoop);
669- m_inputs.insert (input,
670- std::pair{static_cast <uint32_t *>(portFL),
671- static_cast <uint32_t *>(portFR)});
651+ if (m_initialized) {
652+ pw_thread_loop_lock (m_pPwThreadLoop);
653+ createInputPorts (input);
654+ pw_thread_loop_unlock (m_pPwThreadLoop);
655+ }
672656}
673657
674658void PipewireEnumerator::registerOutput (const AudioOutput& output, AudioSource*) {
675- pw_thread_loop_lock (m_pPwThreadLoop);
659+ if (m_initialized) {
660+ pw_thread_loop_lock (m_pPwThreadLoop);
661+ createOutputPorts (output);
662+ pw_thread_loop_unlock (m_pPwThreadLoop);
663+ }
664+ }
665+
666+ // need to pw_thread_loop_lock before calling this
667+ uint32_t * PipewireEnumerator::createPorts (const AudioPath& path, bool channel) {
668+ spa_direction direction;
669+ switch (path.getType ()) {
670+ case AudioPathType::Main:
671+ case AudioPathType::Headphones:
672+ case AudioPathType::Booth:
673+ case AudioPathType::Bus:
674+ case AudioPathType::Deck:
675+ direction = SPA_DIRECTION_OUTPUT ;
676+ break ;
677+ case AudioPathType::VinylControl:
678+ case AudioPathType::Microphone:
679+ case AudioPathType::Auxiliary:
680+ case AudioPathType::RecordBroadcast:
681+ direction = SPA_DIRECTION_INPUT ;
682+ break ;
683+ default :
684+ qWarning () << " PipewireEnumerator::createPorts path type AudioPathType::Invalid" ;
685+ return nullptr ;
686+ }
687+
676688 pw_properties* props = pw_properties_new (
677689 // see pipewire/keys.h header
678690 PW_KEY_FORMAT_DSP ,
679691 " 32 bit float mono audio" ,
680692 nullptr );
681- pw_properties_setf (props, PW_KEY_PORT_NAME , " %s:FL" , output.getString ().toStdString ().c_str ());
682- void * portFL = pw_filter_add_port (m_pPwFilter,
683- SPA_DIRECTION_OUTPUT ,
693+ pw_properties_setf (props,
694+ PW_KEY_PORT_NAME ,
695+ channel ? " %s:FR" : " %s:FL" ,
696+ path.getString ().toStdString ().c_str ());
697+ return static_cast <uint32_t *>(pw_filter_add_port (m_pPwFilter,
698+ direction,
684699 PW_FILTER_PORT_FLAG_MAP_BUFFERS ,
685700 sizeof (uint32_t ),
686701 props,
687702 nullptr ,
688- 0 );
689- props = pw_properties_new (
690- // see pipewire/keys.h header
691- PW_KEY_FORMAT_DSP ,
692- " 32 bit float mono audio" ,
693- nullptr );
694- pw_properties_setf (props, PW_KEY_PORT_NAME , " %s:FR" , output.getString ().toStdString ().c_str ());
695- void * portFR = pw_filter_add_port (m_pPwFilter,
696- SPA_DIRECTION_OUTPUT ,
697- PW_FILTER_PORT_FLAG_MAP_BUFFERS ,
698- sizeof (uint32_t ),
699- props,
700- nullptr ,
701- 0 );
702- pw_thread_loop_unlock (m_pPwThreadLoop);
703- m_outputs.insert (output,
704- std::pair{static_cast <uint32_t *>(portFL),
705- static_cast <uint32_t *>(portFR)});
703+ 0 ));
704+ }
705+
706+ // need to pw_thread_loop_lock before calling this
707+ void PipewireEnumerator::createInputPorts (const AudioInput& input) {
708+ auto ports = std::pair{createPorts (input, false ), createPorts (input, true )};
709+ m_inputs.insert (input, ports);
710+ }
711+
712+ // need to pw_thread_loop_lock before calling this
713+ void PipewireEnumerator::createOutputPorts (const AudioOutput& output) {
714+ auto ports = std::pair{createPorts (output, false ), createPorts (output, true )};
715+ m_outputs.insert (output, ports);
706716}
707717
708718void PipewireEnumerator::setLatency (unsigned int sampleRate, unsigned int framesPerBuffer) {
0 commit comments