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
ae1eb9cc
You need to sign in or sign up before continuing.
Commit
ae1eb9cc
authored
Sep 05, 2016
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
pcm/Convert: migrate from class Error to C++ exceptions
parent
860064c8
Show whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
183 additions
and
291 deletions
+183
-291
Main.cxx
src/Main.cxx
+1
-4
DecoderAPI.cxx
src/decoder/DecoderAPI.cxx
+12
-13
ConvertFilterPlugin.cxx
src/filter/plugins/ConvertFilterPlugin.cxx
+2
-10
ReplayGainFilterPlugin.cxx
src/filter/plugins/ReplayGainFilterPlugin.cxx
+1
-3
VolumeFilterPlugin.cxx
src/filter/plugins/VolumeFilterPlugin.cxx
+1
-4
ChannelsConverter.cxx
src/pcm/ChannelsConverter.cxx
+5
-9
ChannelsConverter.hxx
src/pcm/ChannelsConverter.hxx
+8
-10
ConfiguredResampler.cxx
src/pcm/ConfiguredResampler.cxx
+13
-23
ConfiguredResampler.hxx
src/pcm/ConfiguredResampler.hxx
+2
-3
FallbackResampler.cxx
src/pcm/FallbackResampler.cxx
+2
-3
FallbackResampler.hxx
src/pcm/FallbackResampler.hxx
+3
-5
FormatConverter.cxx
src/pcm/FormatConverter.cxx
+5
-10
FormatConverter.hxx
src/pcm/FormatConverter.hxx
+7
-9
GlueResampler.cxx
src/pcm/GlueResampler.cxx
+11
-19
GlueResampler.hxx
src/pcm/GlueResampler.hxx
+2
-4
LibsamplerateResampler.cxx
src/pcm/LibsamplerateResampler.cxx
+16
-36
LibsamplerateResampler.hxx
src/pcm/LibsamplerateResampler.hxx
+6
-8
PcmConvert.cxx
src/pcm/PcmConvert.cxx
+29
-40
PcmConvert.hxx
src/pcm/PcmConvert.hxx
+9
-8
Resampler.hxx
src/pcm/Resampler.hxx
+8
-11
SoxrResampler.cxx
src/pcm/SoxrResampler.cxx
+11
-20
SoxrResampler.hxx
src/pcm/SoxrResampler.hxx
+5
-7
Volume.cxx
src/pcm/Volume.cxx
+4
-7
Volume.hxx
src/pcm/Volume.hxx
+3
-4
run_convert.cxx
test/run_convert.cxx
+8
-12
software_volume.cxx
test/software_volume.cxx
+7
-6
test_pcm_volume.cxx
test/test_pcm_volume.cxx
+2
-3
No files found.
src/Main.cxx
View file @
ae1eb9cc
...
...
@@ -520,10 +520,7 @@ try {
archive_plugin_init_all
();
#endif
if
(
!
pcm_convert_global_init
(
error
))
{
LogError
(
error
);
return
EXIT_FAILURE
;
}
pcm_convert_global_init
();
decoder_plugin_init_all
();
...
...
src/decoder/DecoderAPI.cxx
View file @
ae1eb9cc
...
...
@@ -73,11 +73,12 @@ decoder_initialized(Decoder &decoder,
decoder
.
convert
=
new
PcmConvert
();
Error
error
;
if
(
!
decoder
.
convert
->
Open
(
dc
.
in_audio_format
,
dc
.
out_audio_format
,
error
))
decoder
.
error
=
std
::
make_exception_ptr
(
std
::
move
(
error
));
try
{
decoder
.
convert
->
Open
(
dc
.
in_audio_format
,
dc
.
out_audio_format
);
}
catch
(...)
{
decoder
.
error
=
std
::
current_exception
();
}
}
const
ScopeLock
protect
(
dc
.
mutex
);
...
...
@@ -484,19 +485,17 @@ decoder_data(Decoder &decoder,
if
(
decoder
.
convert
!=
nullptr
)
{
assert
(
dc
.
in_audio_format
!=
dc
.
out_audio_format
);
Error
error
;
auto
result
=
decoder
.
convert
->
Convert
({
data
,
length
},
error
);
if
(
data
==
nullptr
)
{
try
{
auto
result
=
decoder
.
convert
->
Convert
({
data
,
length
});
data
=
result
.
data
;
length
=
result
.
size
;
}
catch
(
const
std
::
runtime_error
&
e
)
{
/* the PCM conversion has failed - stop
playback, since we have no better way to
bail out */
LogError
(
e
rror
);
LogError
(
e
);
return
DecoderCommand
::
STOP
;
}
data
=
result
.
data
;
length
=
result
.
size
;
}
else
{
assert
(
dc
.
in_audio_format
==
dc
.
out_audio_format
);
}
...
...
src/filter/plugins/ConvertFilterPlugin.cxx
View file @
ae1eb9cc
...
...
@@ -25,7 +25,6 @@
#include "pcm/PcmConvert.hxx"
#include "util/Manual.hxx"
#include "util/ConstBuffer.hxx"
#include "util/Error.hxx"
#include "AudioFormat.hxx"
#include "poison.h"
...
...
@@ -88,9 +87,7 @@ ConvertFilter::Set(const AudioFormat &_out_audio_format)
/* optimized special case: no-op */
return
;
Error
error
;
if
(
!
state
.
Open
(
in_audio_format
,
_out_audio_format
,
error
))
throw
std
::
runtime_error
(
error
.
GetMessage
());
state
.
Open
(
in_audio_format
,
_out_audio_format
);
out_audio_format
=
_out_audio_format
;
}
...
...
@@ -125,12 +122,7 @@ ConvertFilter::FilterPCM(ConstBuffer<void> src)
/* optimized special case: no-op */
return
src
;
Error
error
;
auto
result
=
state
.
Convert
(
src
,
error
);
if
(
result
.
IsNull
())
throw
std
::
runtime_error
(
error
.
GetMessage
());
return
result
;
return
state
.
Convert
(
src
);
}
const
struct
filter_plugin
convert_filter_plugin
=
{
...
...
src/filter/plugins/ReplayGainFilterPlugin.cxx
View file @
ae1eb9cc
...
...
@@ -76,9 +76,7 @@ public:
mixer
(
_mixer
),
base
(
_base
),
mode
(
REPLAY_GAIN_OFF
)
{
info
.
Clear
();
Error
error
;
if
(
!
pv
.
Open
(
out_audio_format
.
format
,
error
))
throw
std
::
runtime_error
(
error
.
GetMessage
());
pv
.
Open
(
out_audio_format
.
format
);
}
void
SetInfo
(
const
ReplayGainInfo
*
_info
)
{
...
...
src/filter/plugins/VolumeFilterPlugin.cxx
View file @
ae1eb9cc
...
...
@@ -25,7 +25,6 @@
#include "pcm/Volume.hxx"
#include "AudioFormat.hxx"
#include "util/ConstBuffer.hxx"
#include "util/Error.hxx"
#include <stdexcept>
...
...
@@ -35,9 +34,7 @@ class VolumeFilter final : public Filter {
public
:
explicit
VolumeFilter
(
const
AudioFormat
&
audio_format
)
:
Filter
(
audio_format
)
{
Error
error
;
if
(
!
pv
.
Open
(
out_audio_format
.
format
,
error
))
throw
std
::
runtime_error
(
error
.
GetMessage
());
pv
.
Open
(
out_audio_format
.
format
);
}
unsigned
GetVolume
()
const
{
...
...
src/pcm/ChannelsConverter.cxx
View file @
ae1eb9cc
...
...
@@ -22,14 +22,13 @@
#include "PcmChannels.hxx"
#include "Domain.hxx"
#include "util/ConstBuffer.hxx"
#include "util/Error.hxx"
#include "util/
Runtime
Error.hxx"
#include <assert.h>
bool
void
PcmChannelsConverter
::
Open
(
SampleFormat
_format
,
unsigned
_src_channels
,
unsigned
_dest_channels
,
gcc_unused
Error
&
error
)
unsigned
_src_channels
,
unsigned
_dest_channels
)
{
assert
(
_format
!=
SampleFormat
::
UNDEFINED
);
...
...
@@ -41,16 +40,13 @@ PcmChannelsConverter::Open(SampleFormat _format,
break
;
default
:
error
.
Format
(
pcm_domain
,
"PCM channel conversion for %s is not implemented"
,
throw
FormatRuntimeError
(
"PCM channel conversion for %s is not implemented"
,
sample_format_to_string
(
_format
));
return
false
;
}
format
=
_format
;
src_channels
=
_src_channels
;
dest_channels
=
_dest_channels
;
return
true
;
}
void
...
...
@@ -62,7 +58,7 @@ PcmChannelsConverter::Close()
}
ConstBuffer
<
void
>
PcmChannelsConverter
::
Convert
(
ConstBuffer
<
void
>
src
,
gcc_unused
Error
&
error
)
PcmChannelsConverter
::
Convert
(
ConstBuffer
<
void
>
src
)
{
switch
(
format
)
{
case
SampleFormat
:
:
UNDEFINED
:
...
...
src/pcm/ChannelsConverter.hxx
View file @
ae1eb9cc
...
...
@@ -28,7 +28,6 @@
#include <assert.h>
#endif
class
Error
;
template
<
typename
T
>
struct
ConstBuffer
;
/**
...
...
@@ -53,15 +52,14 @@ public:
/**
* Opens the object, prepare for Convert().
*
* Throws std::runtime_error on error.
*
* @param format the sample format
* @param src_channels the number of source channels
* @param dest_channels the number of destination channels
* @param error location to store the error
* @return true on success
*/
bool
Open
(
SampleFormat
format
,
unsigned
src_channels
,
unsigned
dest_channels
,
Error
&
error
);
void
Open
(
SampleFormat
format
,
unsigned
src_channels
,
unsigned
dest_channels
);
/**
* Closes the object. After that, you may call Open() again.
...
...
@@ -71,13 +69,13 @@ public:
/**
* Convert a block of PCM data.
*
* Throws std::runtime_error on error.
*
* @param src the input buffer
* @param error location to store the error
* @return the destination buffer on success,
* ConstBuffer::Null() on error
* @return the destination buffer
*/
gcc_pure
ConstBuffer
<
void
>
Convert
(
ConstBuffer
<
void
>
src
,
Error
&
error
);
ConstBuffer
<
void
>
Convert
(
ConstBuffer
<
void
>
src
);
};
#endif
src/pcm/ConfiguredResampler.cxx
View file @
ae1eb9cc
...
...
@@ -25,7 +25,7 @@
#include "config/ConfigError.hxx"
#include "config/Block.hxx"
#include "config/Param.hxx"
#include "util/Error.hxx"
#include "util/
Runtime
Error.hxx"
#ifdef ENABLE_LIBSAMPLERATE
#include "LibsamplerateResampler.hxx"
...
...
@@ -112,7 +112,7 @@ MigrateResamplerConfig(const config_param *param, ConfigBlock &buffer)
}
static
const
ConfigBlock
*
GetResamplerConfig
(
ConfigBlock
&
buffer
,
Error
&
error
)
GetResamplerConfig
(
ConfigBlock
&
buffer
)
{
const
auto
*
old_param
=
config_get_param
(
ConfigOption
::
SAMPLERATE_CONVERTER
);
...
...
@@ -120,49 +120,39 @@ GetResamplerConfig(ConfigBlock &buffer, Error &error)
if
(
block
==
nullptr
)
return
MigrateResamplerConfig
(
old_param
,
buffer
);
if
(
old_param
!=
nullptr
)
{
error
.
Format
(
config_domain
,
"Cannot use both 'resampler' (line %d) and 'samplerate_converter' (line %d)"
,
if
(
old_param
!=
nullptr
)
throw
FormatRuntimeError
(
"Cannot use both 'resampler' (line %d) and 'samplerate_converter' (line %d)"
,
block
->
line
,
old_param
->
line
);
return
nullptr
;
}
return
block
;
}
bool
pcm_resampler_global_init
(
Error
&
error
)
void
pcm_resampler_global_init
()
{
ConfigBlock
buffer
;
const
auto
*
block
=
GetResamplerConfig
(
buffer
,
error
);
if
(
block
==
nullptr
)
return
false
;
const
auto
*
block
=
GetResamplerConfig
(
buffer
);
const
char
*
plugin_name
=
block
->
GetBlockValue
(
"plugin"
);
if
(
plugin_name
==
nullptr
)
{
error
.
Format
(
config_domain
,
"'plugin' missing in line %d"
,
block
->
line
);
return
false
;
}
if
(
plugin_name
==
nullptr
)
throw
FormatRuntimeError
(
"'plugin' missing in line %d"
,
block
->
line
);
if
(
strcmp
(
plugin_name
,
"internal"
)
==
0
)
{
selected_resampler
=
SelectedResampler
::
FALLBACK
;
return
true
;
#ifdef ENABLE_SOXR
}
else
if
(
strcmp
(
plugin_name
,
"soxr"
)
==
0
)
{
selected_resampler
=
SelectedResampler
::
SOXR
;
return
pcm_resample_soxr_global_init
(
*
block
,
error
);
pcm_resample_soxr_global_init
(
*
block
);
#endif
#ifdef ENABLE_LIBSAMPLERATE
}
else
if
(
strcmp
(
plugin_name
,
"libsamplerate"
)
==
0
)
{
selected_resampler
=
SelectedResampler
::
LIBSAMPLERATE
;
return
pcm_resample_lsr_global_init
(
*
block
,
error
);
pcm_resample_lsr_global_init
(
*
block
);
#endif
}
else
{
error
.
Format
(
config_domain
,
"No such resampler plugin: %s"
,
throw
FormatRuntimeError
(
"No such resampler plugin: %s"
,
plugin_name
);
return
false
;
}
}
...
...
src/pcm/ConfiguredResampler.hxx
View file @
ae1eb9cc
...
...
@@ -22,11 +22,10 @@
#include "check.h"
class
Error
;
class
PcmResampler
;
bool
pcm_resampler_global_init
(
Error
&
error
);
void
pcm_resampler_global_init
();
/**
* Create a #PcmResampler instance from the implementation class
...
...
src/pcm/FallbackResampler.cxx
View file @
ae1eb9cc
...
...
@@ -23,8 +23,7 @@
#include <assert.h>
AudioFormat
FallbackPcmResampler
::
Open
(
AudioFormat
&
af
,
unsigned
new_sample_rate
,
gcc_unused
Error
&
error
)
FallbackPcmResampler
::
Open
(
AudioFormat
&
af
,
unsigned
new_sample_rate
)
{
assert
(
af
.
IsValid
());
assert
(
audio_valid_sample_rate
(
new_sample_rate
));
...
...
@@ -116,7 +115,7 @@ pcm_resample_fallback_void(PcmBuffer &buffer,
}
ConstBuffer
<
void
>
FallbackPcmResampler
::
Resample
(
ConstBuffer
<
void
>
src
,
gcc_unused
Error
&
error
)
FallbackPcmResampler
::
Resample
(
ConstBuffer
<
void
>
src
)
{
switch
(
format
.
format
)
{
case
SampleFormat
:
:
UNDEFINED
:
...
...
src/pcm/FallbackResampler.hxx
View file @
ae1eb9cc
...
...
@@ -36,11 +36,9 @@ class FallbackPcmResampler final : public PcmResampler {
PcmBuffer
buffer
;
public
:
virtual
AudioFormat
Open
(
AudioFormat
&
af
,
unsigned
new_sample_rate
,
Error
&
error
)
override
;
virtual
void
Close
()
override
;
virtual
ConstBuffer
<
void
>
Resample
(
ConstBuffer
<
void
>
src
,
Error
&
error
)
override
;
AudioFormat
Open
(
AudioFormat
&
af
,
unsigned
new_sample_rate
)
override
;
void
Close
()
override
;
ConstBuffer
<
void
>
Resample
(
ConstBuffer
<
void
>
src
)
override
;
};
#endif
src/pcm/FormatConverter.cxx
View file @
ae1eb9cc
...
...
@@ -20,15 +20,13 @@
#include "config.h"
#include "FormatConverter.hxx"
#include "PcmFormat.hxx"
#include "Domain.hxx"
#include "util/ConstBuffer.hxx"
#include "util/Error.hxx"
#include "util/
Runtime
Error.hxx"
#include <assert.h>
bool
PcmFormatConverter
::
Open
(
SampleFormat
_src_format
,
SampleFormat
_dest_format
,
Error
&
error
)
void
PcmFormatConverter
::
Open
(
SampleFormat
_src_format
,
SampleFormat
_dest_format
)
{
assert
(
_src_format
!=
SampleFormat
::
UNDEFINED
);
assert
(
_dest_format
!=
SampleFormat
::
UNDEFINED
);
...
...
@@ -40,11 +38,9 @@ PcmFormatConverter::Open(SampleFormat _src_format, SampleFormat _dest_format,
case
SampleFormat
:
:
S8
:
case
SampleFormat
:
:
DSD
:
error
.
Format
(
pcm_domain
,
"PCM conversion from %s to %s is not implemented"
,
throw
FormatRuntimeError
(
"PCM conversion from %s to %s is not implemented"
,
sample_format_to_string
(
_src_format
),
sample_format_to_string
(
_dest_format
));
return
false
;
case
SampleFormat
:
:
S16
:
case
SampleFormat
:
:
S24_P32
:
...
...
@@ -55,7 +51,6 @@ PcmFormatConverter::Open(SampleFormat _src_format, SampleFormat _dest_format,
src_format
=
_src_format
;
dest_format
=
_dest_format
;
return
true
;
}
void
...
...
@@ -68,7 +63,7 @@ PcmFormatConverter::Close()
}
ConstBuffer
<
void
>
PcmFormatConverter
::
Convert
(
ConstBuffer
<
void
>
src
,
gcc_unused
Error
&
error
)
PcmFormatConverter
::
Convert
(
ConstBuffer
<
void
>
src
)
{
switch
(
dest_format
)
{
case
SampleFormat
:
:
UNDEFINED
:
...
...
src/pcm/FormatConverter.hxx
View file @
ae1eb9cc
...
...
@@ -29,7 +29,6 @@
#include <assert.h>
#endif
class
Error
;
template
<
typename
T
>
struct
ConstBuffer
;
/**
...
...
@@ -56,13 +55,12 @@ public:
/**
* Opens the object, prepare for Convert().
*
* Throws std::runtime_error on error.
*
* @param src_format the sample format of incoming data
* @param dest_format the sample format of outgoing data
* @param error location to store the error
* @return true on success
*/
bool
Open
(
SampleFormat
src_format
,
SampleFormat
dest_format
,
Error
&
error
);
void
Open
(
SampleFormat
src_format
,
SampleFormat
dest_format
);
/**
* Closes the object. After that, you may call Open() again.
...
...
@@ -72,13 +70,13 @@ public:
/**
* Convert a block of PCM data.
*
* Throws std::runtime_error on error.
*
* @param src the input buffer
* @param error location to store the error
* @return the destination buffer on success,
* ConstBuffer::Null() on error
* @return the destination buffer
*/
gcc_pure
ConstBuffer
<
void
>
Convert
(
ConstBuffer
<
void
>
src
,
Error
&
error
);
ConstBuffer
<
void
>
Convert
(
ConstBuffer
<
void
>
src
);
};
#endif
src/pcm/GlueResampler.cxx
View file @
ae1eb9cc
...
...
@@ -32,33 +32,28 @@ GluePcmResampler::~GluePcmResampler()
delete
resampler
;
}
bool
GluePcmResampler
::
Open
(
AudioFormat
src_format
,
unsigned
new_sample_rate
,
Error
&
error
)
void
GluePcmResampler
::
Open
(
AudioFormat
src_format
,
unsigned
new_sample_rate
)
{
assert
(
src_format
.
IsValid
());
assert
(
audio_valid_sample_rate
(
new_sample_rate
));
AudioFormat
requested_format
=
src_format
;
AudioFormat
dest_format
=
resampler
->
Open
(
requested_format
,
new_sample_rate
,
error
);
if
(
!
dest_format
.
IsValid
())
return
false
;
new_sample_rate
);
assert
(
dest_format
.
IsValid
());
assert
(
requested_format
.
channels
==
src_format
.
channels
);
assert
(
dest_format
.
channels
==
src_format
.
channels
);
assert
(
dest_format
.
sample_rate
==
new_sample_rate
);
if
(
requested_format
.
format
!=
src_format
.
format
&&
!
format_converter
.
Open
(
src_format
.
format
,
requested_format
.
format
,
error
))
return
false
;
if
(
requested_format
.
format
!=
src_format
.
format
)
format_converter
.
Open
(
src_format
.
format
,
requested_format
.
format
);
src_sample_format
=
src_format
.
format
;
requested_sample_format
=
requested_format
.
format
;
output_sample_format
=
dest_format
.
format
;
return
true
;
}
void
...
...
@@ -71,15 +66,12 @@ GluePcmResampler::Close()
}
ConstBuffer
<
void
>
GluePcmResampler
::
Resample
(
ConstBuffer
<
void
>
src
,
Error
&
error
)
GluePcmResampler
::
Resample
(
ConstBuffer
<
void
>
src
)
{
assert
(
!
src
.
IsNull
());
if
(
requested_sample_format
!=
src_sample_format
)
{
src
=
format_converter
.
Convert
(
src
,
error
);
if
(
src
.
IsNull
())
return
nullptr
;
}
if
(
requested_sample_format
!=
src_sample_format
)
src
=
format_converter
.
Convert
(
src
);
return
resampler
->
Resample
(
src
,
error
);
return
resampler
->
Resample
(
src
);
}
src/pcm/GlueResampler.hxx
View file @
ae1eb9cc
...
...
@@ -24,7 +24,6 @@
#include "AudioFormat.hxx"
#include "FormatConverter.hxx"
class
Error
;
class
PcmResampler
;
template
<
typename
T
>
struct
ConstBuffer
;
...
...
@@ -49,15 +48,14 @@ public:
GluePcmResampler
();
~
GluePcmResampler
();
bool
Open
(
AudioFormat
src_format
,
unsigned
new_sample_rate
,
Error
&
error
);
void
Open
(
AudioFormat
src_format
,
unsigned
new_sample_rate
);
void
Close
();
SampleFormat
GetOutputSampleFormat
()
const
{
return
output_sample_format
;
}
ConstBuffer
<
void
>
Resample
(
ConstBuffer
<
void
>
src
,
Error
&
error
);
ConstBuffer
<
void
>
Resample
(
ConstBuffer
<
void
>
src
);
};
#endif
src/pcm/LibsamplerateResampler.cxx
View file @
ae1eb9cc
...
...
@@ -21,7 +21,7 @@
#include "LibsamplerateResampler.hxx"
#include "config/Block.hxx"
#include "util/ASCII.hxx"
#include "util/Error.hxx"
#include "util/
Runtime
Error.hxx"
#include "util/Domain.hxx"
#include "Log.hxx"
...
...
@@ -63,26 +63,21 @@ lsr_parse_converter(const char *s)
return
false
;
}
bool
pcm_resample_lsr_global_init
(
const
ConfigBlock
&
block
,
Error
&
error
)
void
pcm_resample_lsr_global_init
(
const
ConfigBlock
&
block
)
{
const
char
*
converter
=
block
.
GetBlockValue
(
"type"
,
"2"
);
if
(
!
lsr_parse_converter
(
converter
))
{
error
.
Format
(
libsamplerate_domain
,
"unknown samplerate converter '%s'"
,
converter
);
return
false
;
}
if
(
!
lsr_parse_converter
(
converter
))
throw
FormatRuntimeError
(
"unknown samplerate converter '%s'"
,
converter
);
FormatDebug
(
libsamplerate_domain
,
"libsamplerate converter '%s'"
,
src_get_name
(
lsr_converter
));
return
true
;
}
AudioFormat
LibsampleratePcmResampler
::
Open
(
AudioFormat
&
af
,
unsigned
new_sample_rate
,
Error
&
error
)
LibsampleratePcmResampler
::
Open
(
AudioFormat
&
af
,
unsigned
new_sample_rate
)
{
assert
(
af
.
IsValid
());
assert
(
audio_valid_sample_rate
(
new_sample_rate
));
...
...
@@ -96,12 +91,9 @@ LibsampleratePcmResampler::Open(AudioFormat &af, unsigned new_sample_rate,
int
src_error
;
state
=
src_new
(
lsr_converter
,
channels
,
&
src_error
);
if
(
!
state
)
{
error
.
Format
(
libsamplerate_domain
,
src_error
,
"libsamplerate initialization has failed: %s"
,
if
(
!
state
)
throw
FormatRuntimeError
(
"libsamplerate initialization has failed: %s"
,
src_strerror
(
src_error
));
return
AudioFormat
::
Undefined
();
}
memset
(
&
data
,
0
,
sizeof
(
data
));
...
...
@@ -122,22 +114,8 @@ LibsampleratePcmResampler::Close()
state
=
src_delete
(
state
);
}
static
bool
src_process
(
SRC_STATE
*
state
,
SRC_DATA
*
data
,
Error
&
error
)
{
int
result
=
src_process
(
state
,
data
);
if
(
result
!=
0
)
{
error
.
Format
(
libsamplerate_domain
,
result
,
"libsamplerate has failed: %s"
,
src_strerror
(
result
));
return
false
;
}
return
true
;
}
inline
ConstBuffer
<
float
>
LibsampleratePcmResampler
::
Resample2
(
ConstBuffer
<
float
>
src
,
Error
&
error
)
LibsampleratePcmResampler
::
Resample2
(
ConstBuffer
<
float
>
src
)
{
assert
(
src
.
size
%
channels
==
0
);
...
...
@@ -151,15 +129,17 @@ LibsampleratePcmResampler::Resample2(ConstBuffer<float> src, Error &error)
data
.
input_frames
=
src_frames
;
data
.
output_frames
=
dest_frames
;
if
(
!
src_process
(
state
,
&
data
,
error
))
return
nullptr
;
int
result
=
src_process
(
state
,
&
data
);
if
(
result
!=
0
)
throw
FormatRuntimeError
(
"libsamplerate has failed: %s"
,
src_strerror
(
result
));
return
ConstBuffer
<
float
>
(
data
.
data_out
,
data
.
output_frames_gen
*
channels
);
}
ConstBuffer
<
void
>
LibsampleratePcmResampler
::
Resample
(
ConstBuffer
<
void
>
src
,
Error
&
error
)
LibsampleratePcmResampler
::
Resample
(
ConstBuffer
<
void
>
src
)
{
return
Resample2
(
ConstBuffer
<
float
>::
FromVoid
(
src
)
,
error
).
ToVoid
();
return
Resample2
(
ConstBuffer
<
float
>::
FromVoid
(
src
)).
ToVoid
();
}
src/pcm/LibsamplerateResampler.hxx
View file @
ae1eb9cc
...
...
@@ -42,17 +42,15 @@ class LibsampleratePcmResampler final : public PcmResampler {
PcmBuffer
buffer
;
public
:
virtual
AudioFormat
Open
(
AudioFormat
&
af
,
unsigned
new_sample_rate
,
Error
&
error
)
override
;
virtual
void
Close
()
override
;
virtual
ConstBuffer
<
void
>
Resample
(
ConstBuffer
<
void
>
src
,
Error
&
error
)
override
;
AudioFormat
Open
(
AudioFormat
&
af
,
unsigned
new_sample_rate
)
override
;
void
Close
()
override
;
ConstBuffer
<
void
>
Resample
(
ConstBuffer
<
void
>
src
)
override
;
private
:
ConstBuffer
<
float
>
Resample2
(
ConstBuffer
<
float
>
src
,
Error
&
error
);
ConstBuffer
<
float
>
Resample2
(
ConstBuffer
<
float
>
src
);
};
bool
pcm_resample_lsr_global_init
(
const
ConfigBlock
&
block
,
Error
&
error
);
void
pcm_resample_lsr_global_init
(
const
ConfigBlock
&
block
);
#endif
src/pcm/PcmConvert.cxx
View file @
ae1eb9cc
...
...
@@ -22,15 +22,14 @@
#include "Domain.hxx"
#include "ConfiguredResampler.hxx"
#include "AudioFormat.hxx"
#include "util/Error.hxx"
#include "util/ConstBuffer.hxx"
#include <assert.h>
bool
pcm_convert_global_init
(
Error
&
error
)
void
pcm_convert_global_init
()
{
return
pcm_resampler_global_init
(
error
);
pcm_resampler_global_init
(
);
}
PcmConvert
::
PcmConvert
()
...
...
@@ -47,9 +46,8 @@ PcmConvert::~PcmConvert()
assert
(
!
dest_format
.
IsValid
());
}
bool
PcmConvert
::
Open
(
const
AudioFormat
_src_format
,
const
AudioFormat
_dest_format
,
Error
&
error
)
void
PcmConvert
::
Open
(
const
AudioFormat
_src_format
,
const
AudioFormat
_dest_format
)
{
assert
(
!
src_format
.
IsValid
());
assert
(
!
dest_format
.
IsValid
());
...
...
@@ -62,39 +60,42 @@ PcmConvert::Open(const AudioFormat _src_format, const AudioFormat _dest_format,
enable_resampler
=
format
.
sample_rate
!=
_dest_format
.
sample_rate
;
if
(
enable_resampler
)
{
if
(
!
resampler
.
Open
(
format
,
_dest_format
.
sample_rate
,
error
))
return
false
;
resampler
.
Open
(
format
,
_dest_format
.
sample_rate
);
format
.
format
=
resampler
.
GetOutputSampleFormat
();
format
.
sample_rate
=
_dest_format
.
sample_rate
;
}
enable_format
=
format
.
format
!=
_dest_format
.
format
;
if
(
enable_format
&&
!
format_converter
.
Open
(
format
.
format
,
_dest_format
.
format
,
error
))
{
if
(
enable_format
)
{
try
{
format_converter
.
Open
(
format
.
format
,
_dest_format
.
format
);
}
catch
(...)
{
if
(
enable_resampler
)
resampler
.
Close
();
return
false
;
throw
;
}
}
format
.
format
=
_dest_format
.
format
;
enable_channels
=
format
.
channels
!=
_dest_format
.
channels
;
if
(
enable_channels
&&
!
channels_converter
.
Open
(
format
.
format
,
format
.
channels
,
_dest_format
.
channels
,
error
))
{
if
(
enable_channels
)
{
try
{
channels_converter
.
Open
(
format
.
format
,
format
.
channels
,
_dest_format
.
channels
);
}
catch
(...)
{
if
(
enable_format
)
format_converter
.
Close
();
if
(
enable_resampler
)
resampler
.
Close
();
return
false
;
throw
;
}
}
src_format
=
_src_format
;
dest_format
=
_dest_format
;
return
true
;
}
void
...
...
@@ -118,39 +119,27 @@ PcmConvert::Close()
}
ConstBuffer
<
void
>
PcmConvert
::
Convert
(
ConstBuffer
<
void
>
buffer
,
Error
&
error
)
PcmConvert
::
Convert
(
ConstBuffer
<
void
>
buffer
)
{
#ifdef ENABLE_DSD
if
(
src_format
.
format
==
SampleFormat
::
DSD
)
{
auto
s
=
ConstBuffer
<
uint8_t
>::
FromVoid
(
buffer
);
auto
d
=
dsd
.
ToFloat
(
src_format
.
channels
,
s
);
if
(
d
.
IsNull
())
{
error
.
Set
(
pcm_domain
,
"DSD to PCM conversion failed"
);
return
nullptr
;
}
if
(
d
.
IsNull
())
throw
std
::
runtime_error
(
"DSD to PCM conversion failed"
);
buffer
=
d
.
ToVoid
();
}
#endif
if
(
enable_resampler
)
{
buffer
=
resampler
.
Resample
(
buffer
,
error
);
if
(
buffer
.
IsNull
())
return
nullptr
;
}
if
(
enable_resampler
)
buffer
=
resampler
.
Resample
(
buffer
);
if
(
enable_format
)
{
buffer
=
format_converter
.
Convert
(
buffer
,
error
);
if
(
buffer
.
IsNull
())
return
nullptr
;
}
if
(
enable_format
)
buffer
=
format_converter
.
Convert
(
buffer
);
if
(
enable_channels
)
{
buffer
=
channels_converter
.
Convert
(
buffer
,
error
);
if
(
buffer
.
IsNull
())
return
nullptr
;
}
if
(
enable_channels
)
buffer
=
channels_converter
.
Convert
(
buffer
);
return
buffer
;
}
src/pcm/PcmConvert.hxx
View file @
ae1eb9cc
...
...
@@ -31,7 +31,6 @@
#endif
template
<
typename
T
>
struct
ConstBuffer
;
class
Error
;
/**
* This object is statically allocated (within another struct), and
...
...
@@ -57,9 +56,10 @@ public:
/**
* Prepare the object. Call Close() when done.
*
* Throws std::runtime_error on error.
*/
bool
Open
(
AudioFormat
_src_format
,
AudioFormat
_dest_format
,
Error
&
error
);
void
Open
(
AudioFormat
_src_format
,
AudioFormat
_dest_format
);
/**
* Close the object after it was prepared with Open(). After
...
...
@@ -70,14 +70,15 @@ public:
/**
* Converts PCM data between two audio formats.
*
* Throws std::runtime_error on error.
*
* @param src the source PCM buffer
* @param error location to store the error occurring
* @return the destination buffer, or nullptr on error
* @return the destination buffer
*/
ConstBuffer
<
void
>
Convert
(
ConstBuffer
<
void
>
src
,
Error
&
error
);
ConstBuffer
<
void
>
Convert
(
ConstBuffer
<
void
>
src
);
};
bool
pcm_convert_global_init
(
Error
&
error
);
void
pcm_convert_global_init
();
#endif
src/pcm/Resampler.hxx
View file @
ae1eb9cc
...
...
@@ -24,7 +24,6 @@
#include "Compiler.h"
struct
AudioFormat
;
class
Error
;
/**
* This is an interface for plugins that convert PCM data to a
...
...
@@ -37,16 +36,17 @@ public:
/**
* Opens the resampler, preparing it for Resample().
*
* Throws std::runtime_error on error.
*
* @param af the audio format of incoming data; the plugin may
* modify the object to enforce another input format (however,
* it may not request a different input sample rate)
* @param new_sample_rate the requested output sample rate
* @param error location to store the error
* @return the format of outgoing data or
* AudioFormat::Undefined() on error
* @return the format of outgoing data
*/
virtual
AudioFormat
Open
(
AudioFormat
&
af
,
unsigned
new_sample_rate
,
Error
&
error
)
=
0
;
virtual
AudioFormat
Open
(
AudioFormat
&
af
,
unsigned
new_sample_rate
)
=
0
;
/**
* Closes the resampler. After that, you may call Open()
...
...
@@ -58,14 +58,11 @@ public:
* Resamples a block of PCM data.
*
* @param src the input buffer
* @param error location to store the error occurring
* @return the destination buffer on success (will be
* invalidated by filter_close() or filter_filter()), nullptr on
* error
* @return the destination buffer (will be invalidated by
* filter_close() or filter_filter())
*/
gcc_pure
virtual
ConstBuffer
<
void
>
Resample
(
ConstBuffer
<
void
>
src
,
Error
&
error
)
=
0
;
virtual
ConstBuffer
<
void
>
Resample
(
ConstBuffer
<
void
>
src
)
=
0
;
};
#endif
src/pcm/SoxrResampler.cxx
View file @
ae1eb9cc
...
...
@@ -21,7 +21,7 @@
#include "SoxrResampler.hxx"
#include "AudioFormat.hxx"
#include "config/Block.hxx"
#include "util/Error.hxx"
#include "util/
Runtime
Error.hxx"
#include "util/Domain.hxx"
#include "Log.hxx"
...
...
@@ -80,18 +80,16 @@ soxr_parse_quality(const char *quality)
return
SOXR_INVALID_RECIPE
;
}
bool
pcm_resample_soxr_global_init
(
const
ConfigBlock
&
block
,
Error
&
error
)
void
pcm_resample_soxr_global_init
(
const
ConfigBlock
&
block
)
{
const
char
*
quality_string
=
block
.
GetBlockValue
(
"quality"
);
unsigned
long
recipe
=
soxr_parse_quality
(
quality_string
);
if
(
recipe
==
SOXR_INVALID_RECIPE
)
{
assert
(
quality_string
!=
nullptr
);
error
.
Format
(
soxr_domain
,
"unknown quality setting '%s' in line %d"
,
throw
FormatRuntimeError
(
"unknown quality setting '%s' in line %d"
,
quality_string
,
block
.
line
);
return
false
;
}
soxr_quality
=
soxr_quality_spec
(
recipe
,
0
);
...
...
@@ -102,13 +100,10 @@ pcm_resample_soxr_global_init(const ConfigBlock &block, Error &error)
const
unsigned
n_threads
=
block
.
GetBlockValue
(
"threads"
,
1
);
soxr_runtime
=
soxr_runtime_spec
(
n_threads
);
return
true
;
}
AudioFormat
SoxrPcmResampler
::
Open
(
AudioFormat
&
af
,
unsigned
new_sample_rate
,
Error
&
error
)
SoxrPcmResampler
::
Open
(
AudioFormat
&
af
,
unsigned
new_sample_rate
)
{
assert
(
af
.
IsValid
());
assert
(
audio_valid_sample_rate
(
new_sample_rate
));
...
...
@@ -117,11 +112,9 @@ SoxrPcmResampler::Open(AudioFormat &af, unsigned new_sample_rate,
soxr
=
soxr_create
(
af
.
sample_rate
,
new_sample_rate
,
af
.
channels
,
&
e
,
nullptr
,
&
soxr_quality
,
&
soxr_runtime
);
if
(
soxr
==
nullptr
)
{
error
.
Format
(
soxr_domain
,
"soxr initialization has failed: %s"
,
e
);
return
AudioFormat
::
Undefined
();
}
if
(
soxr
==
nullptr
)
throw
FormatRuntimeError
(
"soxr initialization has failed: %s"
,
e
);
FormatDebug
(
soxr_domain
,
"soxr engine '%s'"
,
soxr_engine
(
soxr
));
...
...
@@ -147,7 +140,7 @@ SoxrPcmResampler::Close()
}
ConstBuffer
<
void
>
SoxrPcmResampler
::
Resample
(
ConstBuffer
<
void
>
src
,
Error
&
error
)
SoxrPcmResampler
::
Resample
(
ConstBuffer
<
void
>
src
)
{
const
size_t
frame_size
=
channels
*
sizeof
(
float
);
assert
(
src
.
size
%
frame_size
==
0
);
...
...
@@ -162,10 +155,8 @@ SoxrPcmResampler::Resample(ConstBuffer<void> src, Error &error)
size_t
i_done
,
o_done
;
soxr_error_t
e
=
soxr_process
(
soxr
,
src
.
data
,
n_frames
,
&
i_done
,
output_buffer
,
o_frames
,
&
o_done
);
if
(
e
!=
nullptr
)
{
error
.
Format
(
soxr_domain
,
"soxr error: %s"
,
e
);
return
nullptr
;
}
if
(
e
!=
nullptr
)
throw
FormatRuntimeError
(
"soxr error: %s"
,
e
);
return
{
output_buffer
,
o_done
*
frame_size
};
}
src/pcm/SoxrResampler.hxx
View file @
ae1eb9cc
...
...
@@ -39,14 +39,12 @@ class SoxrPcmResampler final : public PcmResampler {
PcmBuffer
buffer
;
public
:
virtual
AudioFormat
Open
(
AudioFormat
&
af
,
unsigned
new_sample_rate
,
Error
&
error
)
override
;
virtual
void
Close
()
override
;
virtual
ConstBuffer
<
void
>
Resample
(
ConstBuffer
<
void
>
src
,
Error
&
error
)
override
;
AudioFormat
Open
(
AudioFormat
&
af
,
unsigned
new_sample_rate
)
override
;
void
Close
()
override
;
ConstBuffer
<
void
>
Resample
(
ConstBuffer
<
void
>
src
)
override
;
};
bool
pcm_resample_soxr_global_init
(
const
ConfigBlock
&
block
,
Error
&
error
);
void
pcm_resample_soxr_global_init
(
const
ConfigBlock
&
block
);
#endif
src/pcm/Volume.cxx
View file @
ae1eb9cc
...
...
@@ -24,7 +24,7 @@
#include "Traits.hxx"
#include "util/ConstBuffer.hxx"
#include "util/WritableBuffer.hxx"
#include "util/Error.hxx"
#include "util/
Runtime
Error.hxx"
#include "PcmDither.cxx" // including the .cxx file to get inlined templates
...
...
@@ -97,17 +97,15 @@ pcm_volume_change_float(float *dest, const float *src, size_t n,
dest
[
i
]
=
src
[
i
]
*
volume
;
}
bool
PcmVolume
::
Open
(
SampleFormat
_format
,
Error
&
error
)
void
PcmVolume
::
Open
(
SampleFormat
_format
)
{
assert
(
format
==
SampleFormat
::
UNDEFINED
);
switch
(
_format
)
{
case
SampleFormat
:
:
UNDEFINED
:
error
.
Format
(
pcm_domain
,
"Software volume for %s is not implemented"
,
throw
FormatRuntimeError
(
"Software volume for %s is not implemented"
,
sample_format_to_string
(
_format
));
return
false
;
case
SampleFormat
:
:
S8
:
case
SampleFormat
:
:
S16
:
...
...
@@ -122,7 +120,6 @@ PcmVolume::Open(SampleFormat _format, Error &error)
}
format
=
_format
;
return
true
;
}
ConstBuffer
<
void
>
...
...
src/pcm/Volume.hxx
View file @
ae1eb9cc
...
...
@@ -28,7 +28,6 @@
#include <assert.h>
#endif
class
Error
;
template
<
typename
T
>
struct
ConstBuffer
;
/**
...
...
@@ -93,11 +92,11 @@ public:
/**
* Opens the object, prepare for Apply().
*
* Throws std::runtime_error on error.
*
* @param format the sample format
* @param error location to store the error
* @return true on success
*/
bool
Open
(
SampleFormat
format
,
Error
&
error
);
void
Open
(
SampleFormat
format
);
/**
* Closes the object. After that, you may call Open() again.
...
...
test/run_convert.cxx
View file @
ae1eb9cc
...
...
@@ -38,8 +38,9 @@
#include <stdio.h>
#include <unistd.h>
int
main
(
int
argc
,
char
**
argv
)
{
int
main
(
int
argc
,
char
**
argv
)
try
{
AudioFormat
in_audio_format
,
out_audio_format
;
if
(
argc
!=
3
)
{
...
...
@@ -68,10 +69,7 @@ int main(int argc, char **argv)
const
size_t
in_frame_size
=
in_audio_format
.
GetFrameSize
();
PcmConvert
state
;
if
(
!
state
.
Open
(
in_audio_format
,
out_audio_format_mask
,
error
))
{
LogError
(
error
,
"Failed to open PcmConvert"
);
return
EXIT_FAILURE
;
}
state
.
Open
(
in_audio_format
,
out_audio_format_mask
);
StaticFifoBuffer
<
uint8_t
,
4096
>
buffer
;
...
...
@@ -96,12 +94,7 @@ int main(int argc, char **argv)
buffer
.
Consume
(
src
.
size
);
auto
output
=
state
.
Convert
({
src
.
data
,
src
.
size
},
error
);
if
(
output
.
IsNull
())
{
state
.
Close
();
LogError
(
error
,
"Failed to convert"
);
return
EXIT_FAILURE
;
}
auto
output
=
state
.
Convert
({
src
.
data
,
src
.
size
});
gcc_unused
ssize_t
ignored
=
write
(
1
,
output
.
data
,
output
.
size
);
...
...
@@ -110,4 +103,7 @@ int main(int argc, char **argv)
state
.
Close
();
return
EXIT_SUCCESS
;
}
catch
(
const
std
::
exception
&
e
)
{
LogError
(
e
);
return
EXIT_FAILURE
;
}
test/software_volume.cxx
View file @
ae1eb9cc
...
...
@@ -36,8 +36,9 @@
#include <stdlib.h>
#include <unistd.h>
int
main
(
int
argc
,
char
**
argv
)
{
int
main
(
int
argc
,
char
**
argv
)
try
{
static
char
buffer
[
4096
];
ssize_t
nbytes
;
...
...
@@ -56,10 +57,7 @@ int main(int argc, char **argv)
}
PcmVolume
pv
;
if
(
!
pv
.
Open
(
audio_format
.
format
,
error
))
{
fprintf
(
stderr
,
"%s
\n
"
,
error
.
GetMessage
());
return
EXIT_FAILURE
;
}
pv
.
Open
(
audio_format
.
format
);
while
((
nbytes
=
read
(
0
,
buffer
,
sizeof
(
buffer
)))
>
0
)
{
auto
dest
=
pv
.
Apply
({
buffer
,
size_t
(
nbytes
)});
...
...
@@ -67,4 +65,7 @@ int main(int argc, char **argv)
}
pv
.
Close
();
}
catch
(
const
std
::
exception
&
e
)
{
LogError
(
e
);
return
EXIT_FAILURE
;
}
test/test_pcm_volume.cxx
View file @
ae1eb9cc
...
...
@@ -22,7 +22,6 @@
#include "pcm/Volume.hxx"
#include "pcm/Traits.hxx"
#include "util/ConstBuffer.hxx"
#include "util/Error.hxx"
#include "test_pcm_util.hxx"
#include <algorithm>
...
...
@@ -37,7 +36,7 @@ TestVolume(G g=G())
typedef
typename
Traits
::
value_type
value_type
;
PcmVolume
pv
;
CPPUNIT_ASSERT
(
pv
.
Open
(
F
,
IgnoreError
())
);
pv
.
Open
(
F
);
constexpr
size_t
N
=
509
;
static
value_type
zero
[
N
];
...
...
@@ -96,7 +95,7 @@ void
PcmVolumeTest
::
TestVolumeFloat
()
{
PcmVolume
pv
;
CPPUNIT_ASSERT
(
pv
.
Open
(
SampleFormat
::
FLOAT
,
IgnoreError
())
);
pv
.
Open
(
SampleFormat
::
FLOAT
);
constexpr
size_t
N
=
509
;
static
float
zero
[
N
];
...
...
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