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
e7d32722
Commit
e7d32722
authored
Sep 09, 2016
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mixer: migrate to C++ exceptions
parent
ae1eb9cc
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
273 additions
and
342 deletions
+273
-342
ReplayGainFilterPlugin.cxx
src/filter/plugins/ReplayGainFilterPlugin.cxx
+5
-3
MixerAll.cxx
src/mixer/MixerAll.cxx
+17
-15
MixerControl.cxx
src/mixer/MixerControl.cxx
+29
-25
MixerControl.hxx
src/mixer/MixerControl.hxx
+18
-8
MixerInternal.hxx
src/mixer/MixerInternal.hxx
+10
-7
MixerPlugin.hxx
src/mixer/MixerPlugin.hxx
+4
-6
AlsaMixerPlugin.cxx
src/mixer/plugins/AlsaMixerPlugin.cxx
+48
-74
NullMixerPlugin.cxx
src/mixer/plugins/NullMixerPlugin.cxx
+4
-7
OssMixerPlugin.cxx
src/mixer/plugins/OssMixerPlugin.cxx
+40
-63
PulseMixerPlugin.cxx
src/mixer/plugins/PulseMixerPlugin.cxx
+17
-23
RoarMixerPlugin.cxx
src/mixer/plugins/RoarMixerPlugin.cxx
+8
-10
SoftwareMixerPlugin.cxx
src/mixer/plugins/SoftwareMixerPlugin.cxx
+6
-10
WinmmMixerPlugin.cxx
src/mixer/plugins/WinmmMixerPlugin.cxx
+14
-24
Init.cxx
src/output/Init.cxx
+12
-14
OutputControl.cxx
src/output/OutputControl.cxx
+7
-4
PulseOutputPlugin.cxx
src/output/plugins/PulseOutputPlugin.cxx
+12
-17
PulseOutputPlugin.hxx
src/output/plugins/PulseOutputPlugin.hxx
+2
-3
RoarOutputPlugin.cxx
src/output/plugins/RoarOutputPlugin.cxx
+9
-8
RoarOutputPlugin.hxx
src/output/plugins/RoarOutputPlugin.hxx
+1
-1
read_mixer.cxx
test/read_mixer.cxx
+8
-17
run_filter.cxx
test/run_filter.cxx
+2
-3
No files found.
src/filter/plugins/ReplayGainFilterPlugin.cxx
View file @
e7d32722
...
...
@@ -158,9 +158,11 @@ ReplayGainFilter::Update()
if
(
_volume
>
100
)
_volume
=
100
;
Error
error
;
if
(
!
mixer_set_volume
(
mixer
,
_volume
,
error
))
LogError
(
error
,
"Failed to update hardware mixer"
);
try
{
mixer_set_volume
(
mixer
,
_volume
);
}
catch
(
const
std
::
runtime_error
&
e
)
{
LogError
(
e
,
"Failed to update hardware mixer"
);
}
}
else
pv
.
SetVolume
(
volume
);
}
...
...
src/mixer/MixerAll.cxx
View file @
e7d32722
...
...
@@ -24,9 +24,10 @@
#include "MixerList.hxx"
#include "output/Internal.hxx"
#include "pcm/Volume.hxx"
#include "util/Error.hxx"
#include "Log.hxx"
#include <stdexcept>
#include <assert.h>
static
int
...
...
@@ -39,14 +40,14 @@ output_mixer_get_volume(const AudioOutput &ao)
if
(
mixer
==
nullptr
)
return
-
1
;
Error
error
;
int
volume
=
mixer_get_volume
(
mixer
,
erro
r
);
if
(
volume
<
0
&&
error
.
IsDefined
())
FormatError
(
e
rror
,
try
{
return
mixer_get_volume
(
mixe
r
);
}
catch
(
const
std
::
runtime_error
&
e
)
{
FormatError
(
e
,
"Failed to read mixer for '%s'"
,
ao
.
name
);
return
volume
;
return
-
1
;
}
}
int
...
...
@@ -81,14 +82,15 @@ output_mixer_set_volume(AudioOutput &ao, unsigned volume)
if
(
mixer
==
nullptr
)
return
false
;
Error
error
;
bool
success
=
mixer_set_volume
(
mixer
,
volume
,
error
);
if
(
!
success
&&
error
.
IsDefined
())
FormatError
(
error
,
try
{
mixer_set_volume
(
mixer
,
volume
);
return
true
;
}
catch
(
const
std
::
runtime_error
&
e
)
{
FormatError
(
e
,
"Failed to set mixer for '%s'"
,
ao
.
name
);
return
success
;
return
false
;
}
}
bool
...
...
@@ -114,7 +116,7 @@ output_mixer_get_software_volume(const AudioOutput &ao)
if
(
mixer
==
nullptr
||
!
mixer
->
IsPlugin
(
software_mixer_plugin
))
return
-
1
;
return
mixer_get_volume
(
mixer
,
IgnoreError
()
);
return
mixer_get_volume
(
mixer
);
}
int
...
...
@@ -148,6 +150,6 @@ MultipleOutputs::SetSoftwareVolume(unsigned volume)
if
(
mixer
!=
nullptr
&&
(
&
mixer
->
plugin
==
&
software_mixer_plugin
||
&
mixer
->
plugin
==
&
null_mixer_plugin
))
mixer_set_volume
(
mixer
,
volume
,
IgnoreError
()
);
mixer_set_volume
(
mixer
,
volume
);
}
}
src/mixer/MixerControl.cxx
View file @
e7d32722
...
...
@@ -20,7 +20,6 @@
#include "config.h"
#include "MixerControl.hxx"
#include "MixerInternal.hxx"
#include "util/Error.hxx"
#include <assert.h>
...
...
@@ -28,10 +27,9 @@ Mixer *
mixer_new
(
EventLoop
&
event_loop
,
const
MixerPlugin
&
plugin
,
AudioOutput
&
ao
,
MixerListener
&
listener
,
const
ConfigBlock
&
block
,
Error
&
error
)
const
ConfigBlock
&
block
)
{
Mixer
*
mixer
=
plugin
.
init
(
event_loop
,
ao
,
listener
,
block
,
error
);
Mixer
*
mixer
=
plugin
.
init
(
event_loop
,
ao
,
listener
,
block
);
assert
(
mixer
==
nullptr
||
mixer
->
IsPlugin
(
plugin
));
...
...
@@ -50,20 +48,24 @@ mixer_free(Mixer *mixer)
delete
mixer
;
}
bool
mixer_open
(
Mixer
*
mixer
,
Error
&
error
)
void
mixer_open
(
Mixer
*
mixer
)
{
bool
success
;
assert
(
mixer
!=
nullptr
);
const
ScopeLock
protect
(
mixer
->
mutex
);
success
=
mixer
->
open
||
(
mixer
->
open
=
mixer
->
Open
(
error
));
mixer
->
failed
=
!
success
;
return
success
;
if
(
mixer
->
open
)
return
;
try
{
mixer
->
Open
();
mixer
->
open
=
true
;
mixer
->
failed
=
false
;
}
catch
(...)
{
mixer
->
failed
=
true
;
throw
;
}
}
static
void
...
...
@@ -109,39 +111,41 @@ mixer_failed(Mixer *mixer)
}
int
mixer_get_volume
(
Mixer
*
mixer
,
Error
&
error
)
mixer_get_volume
(
Mixer
*
mixer
)
{
int
volume
;
assert
(
mixer
!=
nullptr
);
if
(
mixer
->
plugin
.
global
&&
!
mixer
->
failed
&&
!
mixer_open
(
mixer
,
error
))
return
-
1
;
if
(
mixer
->
plugin
.
global
&&
!
mixer
->
failed
)
mixer_open
(
mixer
);
const
ScopeLock
protect
(
mixer
->
mutex
);
if
(
mixer
->
open
)
{
volume
=
mixer
->
GetVolume
(
error
);
if
(
volume
<
0
&&
error
.
IsDefined
())
try
{
volume
=
mixer
->
GetVolume
();
}
catch
(...)
{
mixer_failed
(
mixer
);
throw
;
}
}
else
volume
=
-
1
;
return
volume
;
}
bool
mixer_set_volume
(
Mixer
*
mixer
,
unsigned
volume
,
Error
&
error
)
void
mixer_set_volume
(
Mixer
*
mixer
,
unsigned
volume
)
{
assert
(
mixer
!=
nullptr
);
assert
(
volume
<=
100
);
if
(
mixer
->
plugin
.
global
&&
!
mixer
->
failed
&&
!
mixer_open
(
mixer
,
error
))
return
false
;
if
(
mixer
->
plugin
.
global
&&
!
mixer
->
failed
)
mixer_open
(
mixer
);
const
ScopeLock
protect
(
mixer
->
mutex
);
return
mixer
->
open
&&
mixer
->
SetVolume
(
volume
,
error
);
if
(
mixer
->
open
)
mixer
->
SetVolume
(
volume
);
}
src/mixer/MixerControl.hxx
View file @
e7d32722
...
...
@@ -25,7 +25,6 @@
#ifndef MPD_MIXER_CONTROL_HXX
#define MPD_MIXER_CONTROL_HXX
class
Error
;
class
Mixer
;
class
EventLoop
;
struct
AudioOutput
;
...
...
@@ -33,17 +32,22 @@ struct MixerPlugin;
class
MixerListener
;
struct
ConfigBlock
;
/**
* Throws std::runtime_error on error.
*/
Mixer
*
mixer_new
(
EventLoop
&
event_loop
,
const
MixerPlugin
&
plugin
,
AudioOutput
&
ao
,
MixerListener
&
listener
,
const
ConfigBlock
&
block
,
Error
&
error
);
const
ConfigBlock
&
block
);
void
mixer_free
(
Mixer
*
mixer
);
bool
mixer_open
(
Mixer
*
mixer
,
Error
&
error
);
/**
* Throws std::runtime_error on error.
*/
void
mixer_open
(
Mixer
*
mixer
);
void
mixer_close
(
Mixer
*
mixer
);
...
...
@@ -55,10 +59,16 @@ mixer_close(Mixer *mixer);
void
mixer_auto_close
(
Mixer
*
mixer
);
/**
* Throws std::runtime_error on error.
*/
int
mixer_get_volume
(
Mixer
*
mixer
,
Error
&
error
);
mixer_get_volume
(
Mixer
*
mixer
);
bool
mixer_set_volume
(
Mixer
*
mixer
,
unsigned
volume
,
Error
&
error
);
/**
* Throws std::runtime_error on error.
*/
void
mixer_set_volume
(
Mixer
*
mixer
,
unsigned
volume
);
#endif
src/mixer/MixerInternal.hxx
View file @
e7d32722
...
...
@@ -67,9 +67,9 @@ public:
/**
* Open mixer device
*
*
@return true on success, false on error
*
Throws std::runtime_error on error.
*/
virtual
bool
Open
(
Error
&
error
)
=
0
;
virtual
void
Open
(
)
=
0
;
/**
* Close mixer device
...
...
@@ -79,19 +79,22 @@ public:
/**
* Reads the current volume.
*
* Throws std::runtime_error on error.
*
* @return the current volume (0..100 including) or -1 if
* unavailable
or on error (error set, mixer will be closed)
* unavailable
*/
gcc_pure
virtual
int
GetVolume
(
Error
&
error
)
=
0
;
virtual
int
GetVolume
()
=
0
;
/**
* Sets the volume.
*
* @param volume the new volume (0..100 including) @return
* true on success, false on error
* Throws std::runtime_error on error.
*
* @param volume the new volume (0..100 including)
*/
virtual
bool
SetVolume
(
unsigned
volume
,
Error
&
error
)
=
0
;
virtual
void
SetVolume
(
unsigned
volume
)
=
0
;
};
#endif
src/mixer/MixerPlugin.hxx
View file @
e7d32722
...
...
@@ -32,22 +32,20 @@ struct AudioOutput;
class
Mixer
;
class
MixerListener
;
class
EventLoop
;
class
Error
;
struct
MixerPlugin
{
/**
* Alocates and configures a mixer device.
*
* Throws std::runtime_error on error.
*
* @param ao the associated AudioOutput
* @param param the configuration section
* @param error_r location to store the error occurring, or
* nullptr to ignore errors
* @return a mixer object, or nullptr on error
* @return a mixer object
*/
Mixer
*
(
*
init
)(
EventLoop
&
event_loop
,
AudioOutput
&
ao
,
MixerListener
&
listener
,
const
ConfigBlock
&
block
,
Error
&
error
);
const
ConfigBlock
&
block
);
/**
* If true, then the mixer is automatically opened, even if
...
...
src/mixer/plugins/AlsaMixerPlugin.cxx
View file @
e7d32722
...
...
@@ -26,8 +26,8 @@
#include "util/ASCII.hxx"
#include "util/ReusableArray.hxx"
#include "util/Clamp.hxx"
#include "util/Error.hxx"
#include "util/Domain.hxx"
#include "util/RuntimeError.hxx"
#include "Log.hxx"
#include <algorithm>
...
...
@@ -82,13 +82,13 @@ public:
virtual
~
AlsaMixer
();
void
Configure
(
const
ConfigBlock
&
block
);
bool
Setup
(
Error
&
error
);
void
Setup
(
);
/* virtual methods from class Mixer */
v
irtual
bool
Open
(
Error
&
error
)
override
;
v
irtual
v
oid
Close
()
override
;
virtual
int
GetVolume
(
Error
&
error
)
override
;
v
irtual
bool
SetVolume
(
unsigned
volume
,
Error
&
error
)
override
;
v
oid
Open
(
)
override
;
void
Close
()
override
;
int
GetVolume
(
)
override
;
v
oid
SetVolume
(
unsigned
volume
)
override
;
};
static
constexpr
Domain
alsa_mixer_domain
(
"alsa_mixer"
);
...
...
@@ -148,8 +148,11 @@ alsa_mixer_elem_callback(snd_mixer_elem_t *elem, unsigned mask)
snd_mixer_elem_get_callback_private
(
elem
);
if
(
mask
&
SND_CTL_EVENT_MASK_VALUE
)
{
int
volume
=
mixer
.
GetVolume
(
IgnoreError
());
mixer
.
listener
.
OnMixerVolumeChanged
(
mixer
,
volume
);
try
{
int
volume
=
mixer
.
GetVolume
();
mixer
.
listener
.
OnMixerVolumeChanged
(
mixer
,
volume
);
}
catch
(
const
std
::
runtime_error
&
)
{
}
}
return
0
;
...
...
@@ -174,8 +177,7 @@ AlsaMixer::Configure(const ConfigBlock &block)
static
Mixer
*
alsa_mixer_init
(
EventLoop
&
event_loop
,
gcc_unused
AudioOutput
&
ao
,
MixerListener
&
listener
,
const
ConfigBlock
&
block
,
gcc_unused
Error
&
error
)
const
ConfigBlock
&
block
)
{
AlsaMixer
*
am
=
new
AlsaMixer
(
event_loop
,
listener
);
am
->
Configure
(
block
);
...
...
@@ -205,39 +207,26 @@ alsa_mixer_lookup_elem(snd_mixer_t *handle, const char *name, unsigned idx)
return
nullptr
;
}
inline
bool
AlsaMixer
::
Setup
(
Error
&
error
)
inline
void
AlsaMixer
::
Setup
()
{
int
err
;
if
((
err
=
snd_mixer_attach
(
handle
,
device
))
<
0
)
{
error
.
Format
(
alsa_mixer_domain
,
err
,
"failed to attach to %s: %s"
,
device
,
snd_strerror
(
err
));
return
false
;
}
if
((
err
=
snd_mixer_attach
(
handle
,
device
))
<
0
)
throw
FormatRuntimeError
(
"failed to attach to %s: %s"
,
device
,
snd_strerror
(
err
));
if
((
err
=
snd_mixer_selem_register
(
handle
,
nullptr
,
nullptr
))
<
0
)
{
error
.
Format
(
alsa_mixer_domain
,
err
,
"snd_mixer_selem_register() failed: %s"
,
snd_strerror
(
err
));
return
false
;
}
if
((
err
=
snd_mixer_selem_register
(
handle
,
nullptr
,
nullptr
))
<
0
)
throw
FormatRuntimeError
(
"snd_mixer_selem_register() failed: %s"
,
snd_strerror
(
err
));
if
((
err
=
snd_mixer_load
(
handle
))
<
0
)
{
error
.
Format
(
alsa_mixer_domain
,
err
,
"snd_mixer_load() failed: %s
\n
"
,
snd_strerror
(
err
));
return
false
;
}
if
((
err
=
snd_mixer_load
(
handle
))
<
0
)
throw
FormatRuntimeError
(
"snd_mixer_load() failed: %s
\n
"
,
snd_strerror
(
err
));
elem
=
alsa_mixer_lookup_elem
(
handle
,
control
,
index
);
if
(
elem
==
nullptr
)
{
error
.
Format
(
alsa_mixer_domain
,
0
,
"no such mixer control: %s"
,
control
);
return
false
;
}
if
(
elem
==
nullptr
)
throw
FormatRuntimeError
(
"no such mixer control: %s"
,
control
);
snd_mixer_selem_get_playback_volume_range
(
elem
,
&
volume_min
,
&
volume_max
);
...
...
@@ -246,33 +235,29 @@ AlsaMixer::Setup(Error &error)
snd_mixer_elem_set_callback
(
elem
,
alsa_mixer_elem_callback
);
monitor
=
new
AlsaMixerMonitor
(
event_loop
,
handle
);
return
true
;
}
inline
bool
AlsaMixer
::
Open
(
Error
&
error
)
void
AlsaMixer
::
Open
()
{
int
err
;
volume_set
=
-
1
;
err
=
snd_mixer_open
(
&
handle
,
0
);
if
(
err
<
0
)
{
error
.
Format
(
alsa_mixer_domain
,
err
,
"snd_mixer_open() failed: %s"
,
snd_strerror
(
err
));
return
false
;
}
if
(
err
<
0
)
throw
FormatRuntimeError
(
"snd_mixer_open() failed: %s"
,
snd_strerror
(
err
));
if
(
!
Setup
(
error
))
{
try
{
Setup
();
}
catch
(...)
{
snd_mixer_close
(
handle
);
return
false
;
throw
;
}
return
true
;
}
inline
void
void
AlsaMixer
::
Close
()
{
assert
(
handle
!=
nullptr
);
...
...
@@ -283,8 +268,8 @@ AlsaMixer::Close()
snd_mixer_close
(
handle
);
}
in
line
in
t
AlsaMixer
::
GetVolume
(
Error
&
error
)
int
AlsaMixer
::
GetVolume
()
{
int
err
;
int
ret
;
...
...
@@ -293,22 +278,16 @@ AlsaMixer::GetVolume(Error &error)
assert
(
handle
!=
nullptr
);
err
=
snd_mixer_handle_events
(
handle
);
if
(
err
<
0
)
{
error
.
Format
(
alsa_mixer_domain
,
err
,
"snd_mixer_handle_events() failed: %s"
,
snd_strerror
(
err
));
return
false
;
}
if
(
err
<
0
)
throw
FormatRuntimeError
(
"snd_mixer_handle_events() failed: %s"
,
snd_strerror
(
err
));
err
=
snd_mixer_selem_get_playback_volume
(
elem
,
SND_MIXER_SCHN_FRONT_LEFT
,
&
level
);
if
(
err
<
0
)
{
error
.
Format
(
alsa_mixer_domain
,
err
,
"failed to read ALSA volume: %s"
,
snd_strerror
(
err
));
return
false
;
}
if
(
err
<
0
)
throw
FormatRuntimeError
(
"failed to read ALSA volume: %s"
,
snd_strerror
(
err
));
ret
=
((
volume_set
/
100.0
)
*
(
volume_max
-
volume_min
)
+
volume_min
)
+
0.5
;
...
...
@@ -322,8 +301,8 @@ AlsaMixer::GetVolume(Error &error)
return
ret
;
}
inline
bool
AlsaMixer
::
SetVolume
(
unsigned
volume
,
Error
&
error
)
void
AlsaMixer
::
SetVolume
(
unsigned
volume
)
{
float
vol
;
long
level
;
...
...
@@ -340,14 +319,9 @@ AlsaMixer::SetVolume(unsigned volume, Error &error)
level
=
Clamp
(
level
,
volume_min
,
volume_max
);
err
=
snd_mixer_selem_set_playback_volume_all
(
elem
,
level
);
if
(
err
<
0
)
{
error
.
Format
(
alsa_mixer_domain
,
err
,
"failed to set ALSA volume: %s"
,
snd_strerror
(
err
));
return
false
;
}
return
true
;
if
(
err
<
0
)
throw
FormatRuntimeError
(
"failed to set ALSA volume: %s"
,
snd_strerror
(
err
));
}
const
MixerPlugin
alsa_mixer_plugin
=
{
...
...
src/mixer/plugins/NullMixerPlugin.cxx
View file @
e7d32722
...
...
@@ -34,20 +34,18 @@ public:
}
/* virtual methods from class Mixer */
bool
Open
(
gcc_unused
Error
&
error
)
override
{
return
true
;
void
Open
()
override
{
}
void
Close
()
override
{
}
int
GetVolume
(
gcc_unused
Error
&
error
)
override
{
int
GetVolume
()
override
{
return
volume
;
}
bool
SetVolume
(
unsigned
_volume
,
gcc_unused
Error
&
error
)
override
{
void
SetVolume
(
unsigned
_volume
)
override
{
volume
=
_volume
;
return
true
;
}
};
...
...
@@ -55,8 +53,7 @@ static Mixer *
null_mixer_init
(
gcc_unused
EventLoop
&
event_loop
,
gcc_unused
AudioOutput
&
ao
,
MixerListener
&
listener
,
gcc_unused
const
ConfigBlock
&
block
,
gcc_unused
Error
&
error
)
gcc_unused
const
ConfigBlock
&
block
)
{
return
new
NullMixer
(
listener
);
}
...
...
src/mixer/plugins/OssMixerPlugin.cxx
View file @
e7d32722
...
...
@@ -21,9 +21,10 @@
#include "mixer/MixerInternal.hxx"
#include "config/Block.hxx"
#include "system/fd_util.h"
#include "system/Error.hxx"
#include "util/ASCII.hxx"
#include "util/Error.hxx"
#include "util/Domain.hxx"
#include "util/RuntimeError.hxx"
#include "Log.hxx"
#include <assert.h>
...
...
@@ -49,16 +50,18 @@ class OssMixer final : public Mixer {
int
volume_control
;
public
:
OssMixer
(
MixerListener
&
_listener
)
:
Mixer
(
oss_mixer_plugin
,
_listener
)
{}
OssMixer
(
MixerListener
&
_listener
,
const
ConfigBlock
&
block
)
:
Mixer
(
oss_mixer_plugin
,
_listener
)
{
Configure
(
block
);
}
bool
Configure
(
const
ConfigBlock
&
block
,
Error
&
error
);
void
Configure
(
const
ConfigBlock
&
block
);
/* virtual methods from class Mixer */
v
irtual
bool
Open
(
Error
&
error
)
override
;
v
irtual
v
oid
Close
()
override
;
virtual
int
GetVolume
(
Error
&
error
)
override
;
v
irtual
bool
SetVolume
(
unsigned
volume
,
Error
&
error
)
override
;
v
oid
Open
(
)
override
;
void
Close
()
override
;
int
GetVolume
(
)
override
;
v
oid
SetVolume
(
unsigned
volume
)
override
;
};
static
constexpr
Domain
oss_mixer_domain
(
"oss_mixer"
);
...
...
@@ -78,39 +81,27 @@ oss_find_mixer(const char *name)
return
-
1
;
}
inline
bool
OssMixer
::
Configure
(
const
ConfigBlock
&
block
,
Error
&
error
)
inline
void
OssMixer
::
Configure
(
const
ConfigBlock
&
block
)
{
device
=
block
.
GetBlockValue
(
"mixer_device"
,
VOLUME_MIXER_OSS_DEFAULT
);
control
=
block
.
GetBlockValue
(
"mixer_control"
);
if
(
control
!=
NULL
)
{
volume_control
=
oss_find_mixer
(
control
);
if
(
volume_control
<
0
)
{
error
.
Format
(
oss_mixer_domain
,
0
,
"no such mixer control: %s"
,
control
);
return
false
;
}
if
(
volume_control
<
0
)
throw
FormatRuntimeError
(
"no such mixer control: %s"
,
control
);
}
else
volume_control
=
SOUND_MIXER_PCM
;
return
true
;
}
static
Mixer
*
oss_mixer_init
(
gcc_unused
EventLoop
&
event_loop
,
gcc_unused
AudioOutput
&
ao
,
MixerListener
&
listener
,
const
ConfigBlock
&
block
,
Error
&
error
)
const
ConfigBlock
&
block
)
{
OssMixer
*
om
=
new
OssMixer
(
listener
);
if
(
!
om
->
Configure
(
block
,
error
))
{
delete
om
;
return
nullptr
;
}
return
om
;
return
new
OssMixer
(
listener
,
block
);
}
void
...
...
@@ -121,38 +112,32 @@ OssMixer::Close()
close
(
device_fd
);
}
bool
OssMixer
::
Open
(
Error
&
error
)
void
OssMixer
::
Open
()
{
device_fd
=
open_cloexec
(
device
,
O_RDONLY
,
0
);
if
(
device_fd
<
0
)
{
error
.
FormatErrno
(
"failed to open %s"
,
device
);
return
false
;
}
if
(
device_fd
<
0
)
throw
FormatErrno
(
"failed to open %s"
,
device
);
if
(
control
)
{
int
devmask
=
0
;
try
{
if
(
control
)
{
int
devmask
=
0
;
if
(
ioctl
(
device_fd
,
SOUND_MIXER_READ_DEVMASK
,
&
devmask
)
<
0
)
{
error
.
SetErrno
(
"READ_DEVMASK failed"
);
Close
();
return
false
;
}
if
(
ioctl
(
device_fd
,
SOUND_MIXER_READ_DEVMASK
,
&
devmask
)
<
0
)
throw
MakeErrno
(
"READ_DEVMASK failed"
);
if
(((
1
<<
volume_control
)
&
devmask
)
==
0
)
{
error
.
Format
(
oss_mixer_domain
,
0
,
"mixer control
\"
%s
\"
not usable"
,
control
);
Close
();
return
false
;
if
(((
1
<<
volume_control
)
&
devmask
)
==
0
)
throw
FormatErrno
(
"mixer control
\"
%s
\"
not usable"
,
control
);
}
}
catch
(...)
{
Close
();
throw
;
}
return
true
;
}
int
OssMixer
::
GetVolume
(
Error
&
error
)
OssMixer
::
GetVolume
()
{
int
left
,
right
,
level
;
int
ret
;
...
...
@@ -160,10 +145,8 @@ OssMixer::GetVolume(Error &error)
assert
(
device_fd
>=
0
);
ret
=
ioctl
(
device_fd
,
MIXER_READ
(
volume_control
),
&
level
);
if
(
ret
<
0
)
{
error
.
SetErrno
(
"failed to read OSS volume"
);
return
false
;
}
if
(
ret
<
0
)
throw
MakeErrno
(
"failed to read OSS volume"
);
left
=
level
&
0xff
;
right
=
(
level
&
0xff00
)
>>
8
;
...
...
@@ -177,24 +160,18 @@ OssMixer::GetVolume(Error &error)
return
left
;
}
bool
OssMixer
::
SetVolume
(
unsigned
volume
,
Error
&
error
)
void
OssMixer
::
SetVolume
(
unsigned
volume
)
{
int
level
;
int
ret
;
assert
(
device_fd
>=
0
);
assert
(
volume
<=
100
);
level
=
(
volume
<<
8
)
+
volume
;
ret
=
ioctl
(
device_fd
,
MIXER_WRITE
(
volume_control
),
&
level
);
if
(
ret
<
0
)
{
error
.
SetErrno
(
"failed to set OSS volume"
);
return
false
;
}
return
true
;
if
(
ioctl
(
device_fd
,
MIXER_WRITE
(
volume_control
),
&
level
)
<
0
)
throw
MakeErrno
(
"failed to set OSS volume"
);
}
const
MixerPlugin
oss_mixer_plugin
=
{
...
...
src/mixer/plugins/PulseMixerPlugin.cxx
View file @
e7d32722
...
...
@@ -25,13 +25,14 @@
#include "mixer/MixerInternal.hxx"
#include "mixer/Listener.hxx"
#include "output/plugins/PulseOutputPlugin.hxx"
#include "util/Error.hxx"
#include <pulse/context.h>
#include <pulse/introspect.h>
#include <pulse/stream.h>
#include <pulse/subscribe.h>
#include <stdexcept>
#include <assert.h>
class
PulseMixer
final
:
public
Mixer
{
...
...
@@ -52,18 +53,17 @@ public:
void
Offline
();
void
VolumeCallback
(
const
pa_sink_input_info
*
i
,
int
eol
);
void
Update
(
pa_context
*
context
,
pa_stream
*
stream
);
int
GetVolumeInternal
(
Error
&
error
);
int
GetVolumeInternal
();
/* virtual methods from class Mixer */
bool
Open
(
gcc_unused
Error
&
error
)
override
{
return
true
;
void
Open
()
override
{
}
void
Close
()
override
{
}
int
GetVolume
(
Error
&
error
)
override
;
bool
SetVolume
(
unsigned
volume
,
Error
&
error
)
override
;
int
GetVolume
()
override
;
void
SetVolume
(
unsigned
volume
)
override
;
};
void
...
...
@@ -91,7 +91,7 @@ PulseMixer::VolumeCallback(const pa_sink_input_info *i, int eol)
online
=
true
;
volume
=
i
->
volume
;
listener
.
OnMixerVolumeChanged
(
*
this
,
GetVolumeInternal
(
IgnoreError
()
));
listener
.
OnMixerVolumeChanged
(
*
this
,
GetVolumeInternal
());
}
/**
...
...
@@ -163,8 +163,7 @@ pulse_mixer_on_change(PulseMixer &pm,
static
Mixer
*
pulse_mixer_init
(
gcc_unused
EventLoop
&
event_loop
,
AudioOutput
&
ao
,
MixerListener
&
listener
,
gcc_unused
const
ConfigBlock
&
block
,
gcc_unused
Error
&
error
)
gcc_unused
const
ConfigBlock
&
block
)
{
PulseOutput
&
po
=
(
PulseOutput
&
)
ao
;
PulseMixer
*
pm
=
new
PulseMixer
(
po
,
listener
);
...
...
@@ -180,42 +179,37 @@ PulseMixer::~PulseMixer()
}
int
PulseMixer
::
GetVolume
(
gcc_unused
Error
&
error
)
PulseMixer
::
GetVolume
()
{
Pulse
::
LockGuard
lock
(
pulse_output_get_mainloop
(
output
));
return
GetVolumeInternal
(
error
);
return
GetVolumeInternal
();
}
/**
* Pulse mainloop lock must be held by caller
*/
int
PulseMixer
::
GetVolumeInternal
(
gcc_unused
Error
&
error
)
PulseMixer
::
GetVolumeInternal
()
{
return
online
?
(
int
)((
100
*
(
pa_cvolume_avg
(
&
volume
)
+
1
))
/
PA_VOLUME_NORM
)
:
-
1
;
}
bool
PulseMixer
::
SetVolume
(
unsigned
new_volume
,
Error
&
error
)
void
PulseMixer
::
SetVolume
(
unsigned
new_volume
)
{
Pulse
::
LockGuard
lock
(
pulse_output_get_mainloop
(
output
));
if
(
!
online
)
{
error
.
Set
(
pulse_domain
,
"disconnected"
);
return
false
;
}
if
(
!
online
)
throw
std
::
runtime_error
(
"disconnected"
);
struct
pa_cvolume
cvolume
;
pa_cvolume_set
(
&
cvolume
,
volume
.
channels
,
(
new_volume
*
PA_VOLUME_NORM
+
50
)
/
100
);
bool
success
=
pulse_output_set_volume
(
output
,
&
cvolume
,
error
);
if
(
success
)
volume
=
cvolume
;
return
success
;
pulse_output_set_volume
(
output
,
&
cvolume
);
volume
=
cvolume
;
}
const
MixerPlugin
pulse_mixer_plugin
=
{
...
...
src/mixer/plugins/RoarMixerPlugin.cxx
View file @
e7d32722
...
...
@@ -34,36 +34,34 @@ public:
self
(
_output
)
{}
/* virtual methods from class Mixer */
virtual
bool
Open
(
gcc_unused
Error
&
error
)
override
{
return
true
;
void
Open
()
override
{
}
virtual
void
Close
()
override
{
}
virtual
int
GetVolume
(
Error
&
error
)
override
;
v
irtual
bool
SetVolume
(
unsigned
volume
,
Error
&
error
)
override
;
int
GetVolume
(
)
override
;
v
oid
SetVolume
(
unsigned
volume
)
override
;
};
static
Mixer
*
roar_mixer_init
(
gcc_unused
EventLoop
&
event_loop
,
AudioOutput
&
ao
,
MixerListener
&
listener
,
gcc_unused
const
ConfigBlock
&
block
,
gcc_unused
Error
&
error
)
gcc_unused
const
ConfigBlock
&
block
)
{
return
new
RoarMixer
((
RoarOutput
&
)
ao
,
listener
);
}
int
RoarMixer
::
GetVolume
(
gcc_unused
Error
&
error
)
RoarMixer
::
GetVolume
()
{
return
roar_output_get_volume
(
self
);
}
bool
RoarMixer
::
SetVolume
(
unsigned
volume
,
gcc_unused
Error
&
error
)
void
RoarMixer
::
SetVolume
(
unsigned
volume
)
{
r
eturn
r
oar_output_set_volume
(
self
,
volume
);
roar_output_set_volume
(
self
,
volume
);
}
const
MixerPlugin
roar_mixer_plugin
=
{
...
...
src/mixer/plugins/SoftwareMixerPlugin.cxx
View file @
e7d32722
...
...
@@ -26,7 +26,6 @@
#include "filter/plugins/VolumeFilterPlugin.hxx"
#include "pcm/Volume.hxx"
#include "config/Block.hxx"
#include "util/Error.hxx"
#include <assert.h>
#include <math.h>
...
...
@@ -48,26 +47,24 @@ public:
void
SetFilter
(
Filter
*
_filter
);
/* virtual methods from class Mixer */
virtual
bool
Open
(
gcc_unused
Error
&
error
)
override
{
return
true
;
void
Open
()
override
{
}
virtual
void
Close
()
override
{
}
virtual
int
GetVolume
(
gcc_unused
Error
&
error
)
override
{
int
GetVolume
(
)
override
{
return
volume
;
}
v
irtual
bool
SetVolume
(
unsigned
volume
,
Error
&
error
)
override
;
v
oid
SetVolume
(
unsigned
volume
)
override
;
};
static
Mixer
*
software_mixer_init
(
gcc_unused
EventLoop
&
event_loop
,
gcc_unused
AudioOutput
&
ao
,
MixerListener
&
listener
,
gcc_unused
const
ConfigBlock
&
block
,
gcc_unused
Error
&
error
)
gcc_unused
const
ConfigBlock
&
block
)
{
return
new
SoftwareMixer
(
listener
);
}
...
...
@@ -87,8 +84,8 @@ PercentVolumeToSoftwareVolume(unsigned volume)
return
0
;
}
bool
SoftwareMixer
::
SetVolume
(
unsigned
new_volume
,
gcc_unused
Error
&
error
)
void
SoftwareMixer
::
SetVolume
(
unsigned
new_volume
)
{
assert
(
new_volume
<=
100
);
...
...
@@ -96,7 +93,6 @@ SoftwareMixer::SetVolume(unsigned new_volume, gcc_unused Error &error)
if
(
filter
!=
nullptr
)
volume_filter_set
(
filter
,
PercentVolumeToSoftwareVolume
(
new_volume
));
return
true
;
}
const
MixerPlugin
software_mixer_plugin
=
{
...
...
src/mixer/plugins/WinmmMixerPlugin.cxx
View file @
e7d32722
...
...
@@ -21,11 +21,11 @@
#include "mixer/MixerInternal.hxx"
#include "output/OutputAPI.hxx"
#include "output/plugins/WinmmOutputPlugin.hxx"
#include "util/Error.hxx"
#include "util/Domain.hxx"
#include <mmsystem.h>
#include <stdexcept>
#include <assert.h>
#include <math.h>
#include <windows.h>
...
...
@@ -40,19 +40,16 @@ public:
}
/* virtual methods from class Mixer */
virtual
bool
Open
(
gcc_unused
Error
&
error
)
override
{
return
true
;
void
Open
()
override
{
}
v
irtual
v
oid
Close
()
override
{
void
Close
()
override
{
}
virtual
int
GetVolume
(
Error
&
error
)
override
;
v
irtual
bool
SetVolume
(
unsigned
volume
,
Error
&
error
)
override
;
int
GetVolume
(
)
override
;
v
oid
SetVolume
(
unsigned
volume
)
override
;
};
static
constexpr
Domain
winmm_mixer_domain
(
"winmm_mixer"
);
static
inline
int
winmm_volume_decode
(
DWORD
volume
)
{
...
...
@@ -69,40 +66,33 @@ winmm_volume_encode(int volume)
static
Mixer
*
winmm_mixer_init
(
gcc_unused
EventLoop
&
event_loop
,
AudioOutput
&
ao
,
MixerListener
&
listener
,
gcc_unused
const
ConfigBlock
&
block
,
gcc_unused
Error
&
error
)
gcc_unused
const
ConfigBlock
&
block
)
{
return
new
WinmmMixer
((
WinmmOutput
&
)
ao
,
listener
);
}
int
WinmmMixer
::
GetVolume
(
Error
&
error
)
WinmmMixer
::
GetVolume
()
{
DWORD
volume
;
HWAVEOUT
handle
=
winmm_output_get_handle
(
output
);
MMRESULT
result
=
waveOutGetVolume
(
handle
,
&
volume
);
if
(
result
!=
MMSYSERR_NOERROR
)
{
error
.
Set
(
winmm_mixer_domain
,
"Failed to get winmm volume"
);
return
-
1
;
}
if
(
result
!=
MMSYSERR_NOERROR
)
throw
std
::
runtime_error
(
"Failed to get winmm volume"
);
return
winmm_volume_decode
(
volume
);
}
bool
WinmmMixer
::
SetVolume
(
unsigned
volume
,
Error
&
error
)
void
WinmmMixer
::
SetVolume
(
unsigned
volume
)
{
DWORD
value
=
winmm_volume_encode
(
volume
);
HWAVEOUT
handle
=
winmm_output_get_handle
(
output
);
MMRESULT
result
=
waveOutSetVolume
(
handle
,
value
);
if
(
result
!=
MMSYSERR_NOERROR
)
{
error
.
Set
(
winmm_mixer_domain
,
"Failed to set winmm volume"
);
return
false
;
}
return
true
;
if
(
result
!=
MMSYSERR_NOERROR
)
throw
std
::
runtime_error
(
"Failed to set winmm volume"
);
}
const
MixerPlugin
winmm_mixer_plugin
=
{
...
...
src/output/Init.cxx
View file @
e7d32722
...
...
@@ -115,8 +115,7 @@ audio_output_load_mixer(EventLoop &event_loop, AudioOutput &ao,
const
ConfigBlock
&
block
,
const
MixerPlugin
*
plugin
,
PreparedFilter
&
filter_chain
,
MixerListener
&
listener
,
Error
&
error
)
MixerListener
&
listener
)
{
Mixer
*
mixer
;
...
...
@@ -127,20 +126,19 @@ audio_output_load_mixer(EventLoop &event_loop, AudioOutput &ao,
case
MixerType
:
:
NULL_
:
return
mixer_new
(
event_loop
,
null_mixer_plugin
,
ao
,
listener
,
block
,
error
);
block
);
case
MixerType
:
:
HARDWARE
:
if
(
plugin
==
nullptr
)
return
nullptr
;
return
mixer_new
(
event_loop
,
*
plugin
,
ao
,
listener
,
block
,
error
);
block
);
case
MixerType
:
:
SOFTWARE
:
mixer
=
mixer_new
(
event_loop
,
software_mixer_plugin
,
ao
,
listener
,
ConfigBlock
(),
IgnoreError
());
ConfigBlock
());
assert
(
mixer
!=
nullptr
);
filter_chain_append
(
filter_chain
,
"software_mixer"
,
...
...
@@ -246,16 +244,16 @@ audio_output_setup(EventLoop &event_loop, AudioOutput &ao,
/* set up the mixer */
Error
mixer_error
;
ao
.
mixer
=
audio_output_load_mixer
(
event_loop
,
ao
,
block
,
ao
.
plugin
.
mixer_plugin
,
*
ao
.
prepared_filter
,
mixer_listener
,
mixer_error
);
if
(
ao
.
mixer
==
nullptr
&&
mixer_error
.
IsDefined
())
FormatError
(
mixer_error
,
try
{
ao
.
mixer
=
audio_output_load_mixer
(
event_loop
,
ao
,
block
,
ao
.
plugin
.
mixer_plugin
,
*
ao
.
prepared_filter
,
mixer_listener
);
}
catch
(
const
std
::
runtime_error
&
e
)
{
FormatError
(
e
,
"Failed to initialize hardware mixer for '%s'"
,
ao
.
name
);
}
/* use the hardware mixer for replay gain? */
...
...
src/output/OutputControl.cxx
View file @
e7d32722
...
...
@@ -27,6 +27,8 @@
#include "util/Error.hxx"
#include "Log.hxx"
#include <stdexcept>
#include <assert.h>
/** after a failure, wait this number of seconds before
...
...
@@ -145,10 +147,11 @@ AudioOutput::Open(const AudioFormat audio_format, const MusicPipe &mp)
const
bool
open2
=
open
;
if
(
open2
&&
mixer
!=
nullptr
)
{
Error
error
;
if
(
!
mixer_open
(
mixer
,
error
))
FormatWarning
(
output_domain
,
"Failed to open mixer for '%s'"
,
name
);
try
{
mixer_open
(
mixer
);
}
catch
(
const
std
::
runtime_error
&
e
)
{
FormatError
(
e
,
"Failed to open mixer for '%s'"
,
name
);
}
}
return
open2
;
...
...
src/output/plugins/PulseOutputPlugin.cxx
View file @
e7d32722
...
...
@@ -37,6 +37,8 @@
#include <pulse/subscribe.h>
#include <pulse/version.h>
#include <stdexcept>
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
...
...
@@ -74,7 +76,7 @@ public:
mixer
=
nullptr
;
}
bool
SetVolume
(
const
pa_cvolume
&
volume
,
Error
&
error
);
void
SetVolume
(
const
pa_cvolume
&
volume
);
struct
pa_threaded_mainloop
*
GetMainloop
()
{
return
mainloop
;
...
...
@@ -217,34 +219,27 @@ pulse_output_clear_mixer(PulseOutput &po, PulseMixer &pm)
po
.
ClearMixer
(
pm
);
}
inline
bool
PulseOutput
::
SetVolume
(
const
pa_cvolume
&
volume
,
Error
&
error
)
inline
void
PulseOutput
::
SetVolume
(
const
pa_cvolume
&
volume
)
{
if
(
context
==
nullptr
||
stream
==
nullptr
||
pa_stream_get_state
(
stream
)
!=
PA_STREAM_READY
)
{
error
.
Set
(
pulse_domain
,
"disconnected"
);
return
false
;
}
pa_stream_get_state
(
stream
)
!=
PA_STREAM_READY
)
throw
std
::
runtime_error
(
"disconnected"
);
pa_operation
*
o
=
pa_context_set_sink_input_volume
(
context
,
pa_stream_get_index
(
stream
),
&
volume
,
nullptr
,
nullptr
);
if
(
o
==
nullptr
)
{
SetPulseError
(
error
,
context
,
"failed to set PulseAudio volume"
);
return
false
;
}
if
(
o
==
nullptr
)
throw
std
::
runtime_error
(
"failed to set PulseAudio volume"
);
pa_operation_unref
(
o
);
return
true
;
}
bool
pulse_output_set_volume
(
PulseOutput
&
po
,
const
pa_cvolume
*
volume
,
Error
&
error
)
void
pulse_output_set_volume
(
PulseOutput
&
po
,
const
pa_cvolume
*
volume
)
{
return
po
.
SetVolume
(
*
volume
,
error
);
return
po
.
SetVolume
(
*
volume
);
}
/**
...
...
src/output/plugins/PulseOutputPlugin.hxx
View file @
e7d32722
...
...
@@ -36,8 +36,7 @@ pulse_output_set_mixer(PulseOutput &po, PulseMixer &pm);
void
pulse_output_clear_mixer
(
PulseOutput
&
po
,
PulseMixer
&
pm
);
bool
pulse_output_set_volume
(
PulseOutput
&
po
,
const
pa_cvolume
*
volume
,
Error
&
error
);
void
pulse_output_set_volume
(
PulseOutput
&
po
,
const
pa_cvolume
*
volume
);
#endif
src/output/plugins/RoarOutputPlugin.cxx
View file @
e7d32722
...
...
@@ -29,6 +29,7 @@
#include "Log.hxx"
#include <string>
#include <stdexcept>
/* libroar/services.h declares roar_service_stream::new - work around
this C++ problem */
...
...
@@ -74,7 +75,7 @@ public:
void
Cancel
();
int
GetVolume
()
const
;
bool
SetVolume
(
unsigned
volume
);
void
SetVolume
(
unsigned
volume
);
};
static
constexpr
Domain
roar_output_domain
(
"roar_output"
);
...
...
@@ -90,7 +91,7 @@ RoarOutput::GetVolume() const
float
l
,
r
;
int
error
;
if
(
roar_vs_volume_get
(
vss
,
&
l
,
&
r
,
&
error
)
<
0
)
return
-
1
;
throw
std
::
runtime_error
(
roar_vs_strerr
(
error
))
;
return
(
l
+
r
)
*
50
;
}
...
...
@@ -101,26 +102,26 @@ roar_output_get_volume(RoarOutput &roar)
return
roar
.
GetVolume
();
}
bool
inline
void
RoarOutput
::
SetVolume
(
unsigned
volume
)
{
assert
(
volume
<=
100
);
const
ScopeLock
protect
(
mutex
);
if
(
vss
==
nullptr
||
!
alive
)
return
false
;
throw
std
::
runtime_error
(
"closed"
)
;
int
error
;
float
level
=
volume
/
100.0
;
roar_vs_volume_mono
(
vss
,
level
,
&
error
);
return
true
;
if
(
roar_vs_volume_mono
(
vss
,
level
,
&
error
)
<
0
)
throw
std
::
runtime_error
(
roar_vs_strerr
(
error
))
;
}
bool
void
roar_output_set_volume
(
RoarOutput
&
roar
,
unsigned
volume
)
{
r
eturn
r
oar
.
SetVolume
(
volume
);
roar
.
SetVolume
(
volume
);
}
inline
void
...
...
src/output/plugins/RoarOutputPlugin.hxx
View file @
e7d32722
...
...
@@ -27,7 +27,7 @@ extern const struct AudioOutputPlugin roar_output_plugin;
int
roar_output_get_volume
(
RoarOutput
&
roar
);
bool
void
roar_output_set_volume
(
RoarOutput
&
roar
,
unsigned
volume
);
#endif
test/read_mixer.cxx
View file @
e7d32722
...
...
@@ -41,7 +41,7 @@ filter_plugin_by_name(gcc_unused const char *name)
}
int
main
(
int
argc
,
gcc_unused
char
**
argv
)
{
try
{
int
volume
;
if
(
argc
!=
2
)
{
...
...
@@ -51,36 +51,27 @@ int main(int argc, gcc_unused char **argv)
EventLoop
event_loop
;
Error
error
;
Mixer
*
mixer
=
mixer_new
(
event_loop
,
alsa_mixer_plugin
,
*
(
AudioOutput
*
)
nullptr
,
*
(
MixerListener
*
)
nullptr
,
ConfigBlock
(),
error
);
if
(
mixer
==
NULL
)
{
LogError
(
error
,
"mixer_new() failed"
);
return
EXIT_FAILURE
;
}
ConfigBlock
());
if
(
!
mixer_open
(
mixer
,
error
))
{
mixer_free
(
mixer
);
LogError
(
error
,
"failed to open the mixer"
);
return
EXIT_FAILURE
;
}
mixer_open
(
mixer
);
volume
=
mixer_get_volume
(
mixer
,
error
);
volume
=
mixer_get_volume
(
mixer
);
mixer_close
(
mixer
);
mixer_free
(
mixer
);
assert
(
volume
>=
-
1
&&
volume
<=
100
);
if
(
volume
<
0
)
{
if
(
error
.
IsDefined
())
{
LogError
(
error
,
"failed to read volume"
);
}
else
fprintf
(
stderr
,
"failed to read volume
\n
"
);
fprintf
(
stderr
,
"failed to read volume
\n
"
);
return
EXIT_FAILURE
;
}
printf
(
"%d
\n
"
,
volume
);
return
0
;
}
catch
(
const
std
::
exception
&
e
)
{
LogError
(
e
);
return
EXIT_FAILURE
;
}
test/run_filter.cxx
View file @
e7d32722
...
...
@@ -41,11 +41,10 @@
#include <errno.h>
#include <unistd.h>
bool
void
mixer_set_volume
(
gcc_unused
Mixer
*
mixer
,
gcc_unused
unsigned
volume
,
gcc_unused
Error
&
error
)
gcc_unused
unsigned
volume
)
{
return
true
;
}
static
PreparedFilter
*
...
...
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