Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
b941a7df
Commit
b941a7df
authored
Oct 18, 2021
by
Nicolai Syvertsen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement volume updates for pipewire output
parent
31151cec
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
109 additions
and
13 deletions
+109
-13
PipeWireMixerPlugin.cxx
src/mixer/plugins/PipeWireMixerPlugin.cxx
+10
-1
PipeWireOutputPlugin.cxx
src/output/plugins/PipeWireOutputPlugin.cxx
+92
-12
PipeWireOutputPlugin.hxx
src/output/plugins/PipeWireOutputPlugin.hxx
+7
-0
No files found.
src/mixer/plugins/PipeWireMixerPlugin.cxx
View file @
b941a7df
...
...
@@ -37,6 +37,8 @@ public:
{
}
~
PipeWireMixer
()
override
;
PipeWireMixer
(
const
PipeWireMixer
&
)
=
delete
;
PipeWireMixer
&
operator
=
(
const
PipeWireMixer
&
)
=
delete
;
...
...
@@ -82,7 +84,14 @@ pipewire_mixer_init([[maybe_unused]] EventLoop &event_loop, AudioOutput &ao,
const
ConfigBlock
&
)
{
auto
&
po
=
(
PipeWireOutput
&
)
ao
;
return
new
PipeWireMixer
(
po
,
listener
);
auto
*
pm
=
new
PipeWireMixer
(
po
,
listener
);
pipewire_output_set_mixer
(
po
,
*
pm
);
return
pm
;
}
PipeWireMixer
::~
PipeWireMixer
()
{
pipewire_output_clear_mixer
(
output
,
*
this
);
}
const
MixerPlugin
pipewire_mixer_plugin
=
{
...
...
src/output/plugins/PipeWireOutputPlugin.cxx
View file @
b941a7df
...
...
@@ -41,6 +41,9 @@
#include <spa/param/audio/format-utils.h>
#include <spa/param/props.h>
#include <cmath>
#include <iostream>
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
...
...
@@ -75,6 +78,9 @@ class PipeWireOutput final : AudioOutput {
float
volume
=
1.0
;
PipeWireMixer
*
mixer
=
nullptr
;
int
channels
;
/**
* The active sample format, needed for PcmSilence().
*/
...
...
@@ -124,11 +130,21 @@ public:
events
.
state_changed
=
StateChanged
;
events
.
process
=
Process
;
events
.
drained
=
Drained
;
events
.
control_info
=
ControlInfo
;
events
.
param_changed
=
ParamChanged
;
return
events
;
}
void
SetVolume
(
float
volume
);
void
SetMixer
(
PipeWireMixer
&
_mixer
);
void
ClearMixer
([[
maybe_unused
]]
PipeWireMixer
&
old_mixer
)
{
assert
(
mixer
==
&
old_mixer
);
mixer
=
nullptr
;
}
private
:
void
CheckThrowError
()
{
if
(
disconnected
)
...
...
@@ -163,6 +179,46 @@ private:
o
.
Drained
();
}
void
ControlInfo
(
const
struct
pw_stream_control
*
control
)
{
float
sum
=
0
;
unsigned
c
;
for
(
c
=
0
;
c
<
control
->
n_values
;
c
++
)
sum
+=
control
->
values
[
c
];
sum
/=
control
->
n_values
;
if
(
mixer
!=
nullptr
)
pipewire_mixer_on_change
(
*
mixer
,
std
::
cbrt
(
sum
));
pw_thread_loop_signal
(
thread_loop
,
false
);
}
static
void
ControlInfo
(
void
*
data
,
[[
maybe_unused
]]
uint32_t
id
,
const
struct
pw_stream_control
*
control
)
noexcept
{
auto
&
o
=
*
(
PipeWireOutput
*
)
data
;
if
(
StringIsEqual
(
control
->
name
,
"Channel Volumes"
))
o
.
ControlInfo
(
control
);
}
void
ParamChanged
()
{
if
(
restore_volume
)
{
SetVolume
(
volume
);
restore_volume
=
false
;
}
}
static
void
ParamChanged
(
void
*
data
,
uint32_t
id
,
const
struct
spa_pod
*
param
)
{
if
(
id
!=
SPA_PARAM_Format
||
param
==
NULL
)
return
;
auto
&
o
=
*
(
PipeWireOutput
*
)
data
;
o
.
ParamChanged
();
}
/* virtual methods from class AudioOutput */
void
Enable
()
override
;
void
Disable
()
noexcept
override
;
...
...
@@ -214,11 +270,20 @@ PipeWireOutput::SetVolume(float _volume)
{
const
PipeWire
::
ThreadLoopLock
lock
(
thread_loop
);
if
(
stream
!=
nullptr
&&
!
restore_volume
&&
pw_stream_set_control
(
stream
,
SPA_PROP_volume
,
1
,
&
_volume
,
float
newvol
=
_volume
*
_volume
*
_volume
;
if
(
stream
!=
nullptr
&&
!
restore_volume
)
{
float
vol
[
SPA_AUDIO_MAX_CHANNELS
];
int
i
;
for
(
i
=
0
;
i
<
channels
;
i
++
)
{
vol
[
i
]
=
newvol
;
}
if
(
pw_stream_set_control
(
stream
,
SPA_PROP_channelVolumes
,
channels
,
vol
,
0
)
!=
0
)
throw
std
::
runtime_error
(
"pw_stream_set_control() failed"
);
throw
std
::
runtime_error
(
"pw_stream_set_control() failed"
);
}
volume
=
_volume
;
}
...
...
@@ -404,6 +469,7 @@ PipeWireOutput::Open(AudioFormat &audio_format)
frame_size
=
audio_format
.
GetFrameSize
();
sample_format
=
audio_format
.
format
;
channels
=
audio_format
.
channels
;
interrupted
=
false
;
/* allocate a ring buffer of 0.5 seconds */
...
...
@@ -451,14 +517,6 @@ PipeWireOutput::StateChanged(enum pw_stream_state state,
if
(
!
was_disconnected
&&
disconnected
)
pw_thread_loop_signal
(
thread_loop
,
false
);
if
(
state
==
PW_STREAM_STATE_STREAMING
&&
restore_volume
)
{
/* restore the last known volume after creating a new
pw_stream */
restore_volume
=
false
;
pw_stream_set_control
(
stream
,
SPA_PROP_volume
,
1
,
&
volume
,
0
);
}
}
inline
void
...
...
@@ -585,6 +643,28 @@ PipeWireOutput::Pause() noexcept
return
true
;
}
inline
void
PipeWireOutput
::
SetMixer
(
PipeWireMixer
&
_mixer
)
{
assert
(
mixer
==
nullptr
);
mixer
=
&
_mixer
;
// TODO: Check if context and stream is ready and trigger a volume update...
}
void
pipewire_output_set_mixer
(
PipeWireOutput
&
po
,
PipeWireMixer
&
pm
)
{
po
.
SetMixer
(
pm
);
}
void
pipewire_output_clear_mixer
(
PipeWireOutput
&
po
,
PipeWireMixer
&
pm
)
{
po
.
ClearMixer
(
pm
);
}
const
struct
AudioOutputPlugin
pipewire_output_plugin
=
{
"pipewire"
,
nullptr
,
...
...
src/output/plugins/PipeWireOutputPlugin.hxx
View file @
b941a7df
...
...
@@ -21,10 +21,17 @@
#define MPD_PIPEWIRE_OUTPUT_PLUGIN_HXX
class
PipeWireOutput
;
class
PipeWireMixer
;
extern
const
struct
AudioOutputPlugin
pipewire_output_plugin
;
void
pipewire_output_set_mixer
(
PipeWireOutput
&
po
,
PipeWireMixer
&
pm
);
void
pipewire_output_clear_mixer
(
PipeWireOutput
&
po
,
PipeWireMixer
&
pm
);
void
pipewire_output_set_volume
(
PipeWireOutput
&
output
,
float
volume
);
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment