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
Commit
ae1eb9cc
authored
8 years ago
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
pcm/Convert: migrate from class Error to C++ exceptions
parent
860064c8
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
197 additions
and
305 deletions
+197
-305
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
+6
-10
ChannelsConverter.hxx
src/pcm/ChannelsConverter.hxx
+8
-10
ConfiguredResampler.cxx
src/pcm/ConfiguredResampler.cxx
+15
-25
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
+7
-12
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
+17
-37
LibsamplerateResampler.hxx
src/pcm/LibsamplerateResampler.hxx
+6
-8
PcmConvert.cxx
src/pcm/PcmConvert.cxx
+35
-46
PcmConvert.hxx
src/pcm/PcmConvert.hxx
+9
-8
Resampler.hxx
src/pcm/Resampler.hxx
+8
-11
SoxrResampler.cxx
src/pcm/SoxrResampler.cxx
+12
-21
SoxrResampler.hxx
src/pcm/SoxrResampler.hxx
+5
-7
Volume.cxx
src/pcm/Volume.cxx
+5
-8
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
();
...
...
This diff is collapsed.
Click to expand it.
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
);
}
...
...
This diff is collapsed.
Click to expand it.
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
=
{
...
...
This diff is collapsed.
Click to expand it.
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
)
{
...
...
This diff is collapsed.
Click to expand it.
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
{
...
...
This diff is collapsed.
Click to expand it.
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"
,
sample_format_to_string
(
_format
));
return
false
;
throw
FormatRuntimeError
(
"PCM channel conversion for %s is not implemented"
,
sample_format_to_string
(
_format
));
}
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
:
...
...
This diff is collapsed.
Click to expand it.
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
This diff is collapsed.
Click to expand it.
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)"
,
block
->
line
,
old_param
->
line
);
return
nullptr
;
}
if
(
old_param
!=
nullptr
)
throw
FormatRuntimeError
(
"Cannot use both 'resampler' (line %d) and 'samplerate_converter' (line %d)"
,
block
->
line
,
old_param
->
line
);
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"
,
plugin_name
);
return
false
;
throw
FormatRuntimeError
(
"No such resampler plugin: %s"
,
plugin_name
);
}
}
...
...
This diff is collapsed.
Click to expand it.
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
...
...
This diff is collapsed.
Click to expand it.
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
:
...
...
This diff is collapsed.
Click to expand it.
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
This diff is collapsed.
Click to expand it.
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"
,
sample_format_to_string
(
_src_format
),
sample_format_to_string
(
_dest_format
));
return
false
;
throw
FormatRuntimeError
(
"PCM conversion from %s to %s is not implemented"
,
sample_format_to_string
(
_src_format
),
sample_format_to_string
(
_dest_format
));
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
:
...
...
This diff is collapsed.
Click to expand it.
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
This diff is collapsed.
Click to expand it.
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
);
}
This diff is collapsed.
Click to expand it.
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
This diff is collapsed.
Click to expand it.
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"
,
src_strerror
(
src_error
));
return
AudioFormat
::
Undefined
();
}
if
(
!
state
)
throw
FormatRuntimeError
(
"libsamplerate initialization has failed: %s"
,
src_strerror
(
src_error
));
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
();
}
This diff is collapsed.
Click to expand it.
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
This diff is collapsed.
Click to expand it.
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_resampler
)
resampler
.
Close
();
return
false
;
if
(
enable_format
)
{
try
{
format_converter
.
Open
(
format
.
format
,
_dest_format
.
format
);
}
catch
(...)
{
if
(
enable_resampler
)
resampler
.
Close
();
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_format
)
format_converter
.
Close
();
if
(
enable_resampler
)
resampler
.
Close
();
return
false
;
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
();
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
;
}
This diff is collapsed.
Click to expand it.
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
This diff is collapsed.
Click to expand it.
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
This diff is collapsed.
Click to expand it.
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"
,
quality_string
,
block
.
line
);
return
false
;
throw
FormatRuntimeError
(
"unknown quality setting '%s' in line %d"
,
quality_string
,
block
.
line
);
}
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
};
}
This diff is collapsed.
Click to expand it.
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
This diff is collapsed.
Click to expand it.
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"
,
sample_format_to_string
(
_format
));
return
false
;
throw
FormatRuntimeError
(
"Software volume for %s is not implemented"
,
sample_format_to_string
(
_format
));
case
SampleFormat
:
:
S8
:
case
SampleFormat
:
:
S16
:
...
...
@@ -122,7 +120,6 @@ PcmVolume::Open(SampleFormat _format, Error &error)
}
format
=
_format
;
return
true
;
}
ConstBuffer
<
void
>
...
...
This diff is collapsed.
Click to expand it.
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.
...
...
This diff is collapsed.
Click to expand it.
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
;
}
This diff is collapsed.
Click to expand it.
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
;
}
This diff is collapsed.
Click to expand it.
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
];
...
...
This diff is collapsed.
Click to expand it.
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