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
d2679f59
Commit
d2679f59
authored
Nov 11, 2013
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
PcmConvert: add methods Open(), Close()
Replaces Reset() and eliminates the AudioFormat parameters from the Convert() method.
parent
4ee147ea
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
151 additions
and
74 deletions
+151
-74
DecoderAPI.cxx
src/DecoderAPI.cxx
+7
-3
DecoderInternal.cxx
src/DecoderInternal.cxx
+5
-1
OutputThread.cxx
src/OutputThread.cxx
+12
-4
AutoConvertFilterPlugin.cxx
src/filter/AutoConvertFilterPlugin.cxx
+5
-1
ConvertFilterPlugin.cxx
src/filter/ConvertFilterPlugin.cxx
+48
-17
ConvertFilterPlugin.hxx
src/filter/ConvertFilterPlugin.hxx
+4
-2
PcmConvert.cxx
src/pcm/PcmConvert.cxx
+44
-24
PcmConvert.hxx
src/pcm/PcmConvert.hxx
+16
-20
run_convert.cxx
test/run_convert.cxx
+10
-2
No files found.
src/DecoderAPI.cxx
View file @
d2679f59
...
...
@@ -71,6 +71,12 @@ decoder_initialized(Decoder &decoder,
&
af_string
));
decoder
.
convert
=
new
PcmConvert
();
Error
error
;
if
(
!
decoder
.
convert
->
Open
(
dc
.
in_audio_format
,
dc
.
out_audio_format
,
error
))
decoder
.
error
=
std
::
move
(
error
);
}
dc
.
Lock
();
...
...
@@ -401,9 +407,7 @@ decoder_data(Decoder &decoder,
assert
(
dc
.
in_audio_format
!=
dc
.
out_audio_format
);
Error
error
;
data
=
decoder
.
convert
->
Convert
(
dc
.
in_audio_format
,
data
,
length
,
dc
.
out_audio_format
,
data
=
decoder
.
convert
->
Convert
(
data
,
length
,
&
length
,
error
);
if
(
data
==
nullptr
)
{
...
...
src/DecoderInternal.cxx
View file @
d2679f59
...
...
@@ -33,7 +33,11 @@ Decoder::~Decoder()
/* caller must flush the chunk */
assert
(
chunk
==
nullptr
);
delete
convert
;
if
(
convert
!=
nullptr
)
{
convert
->
Close
();
delete
convert
;
}
delete
song_tag
;
delete
stream_tag
;
delete
decoder_tag
;
...
...
src/OutputThread.cxx
View file @
d2679f59
...
...
@@ -184,7 +184,15 @@ ao_open(struct audio_output *ao)
return
;
}
convert_filter_set
(
ao
->
convert_filter
,
ao
->
out_audio_format
);
if
(
!
convert_filter_set
(
ao
->
convert_filter
,
ao
->
out_audio_format
,
error
))
{
FormatError
(
error
,
"Failed to convert for
\"
%s
\"
[%s]"
,
ao
->
name
,
ao
->
plugin
->
name
);
ao_filter_close
(
ao
);
ao
->
fail_timer
=
g_timer_new
();
return
;
}
ao
->
open
=
true
;
...
...
@@ -233,7 +241,9 @@ ao_reopen_filter(struct audio_output *ao)
ao_filter_close
(
ao
);
const
AudioFormat
filter_audio_format
=
ao_filter_open
(
ao
,
ao
->
in_audio_format
,
error
);
if
(
!
filter_audio_format
.
IsDefined
())
{
if
(
!
filter_audio_format
.
IsDefined
()
||
!
convert_filter_set
(
ao
->
convert_filter
,
ao
->
out_audio_format
,
error
))
{
FormatError
(
error
,
"Failed to open filter for
\"
%s
\"
[%s]"
,
ao
->
name
,
ao
->
plugin
->
name
);
...
...
@@ -254,8 +264,6 @@ ao_reopen_filter(struct audio_output *ao)
return
;
}
convert_filter_set
(
ao
->
convert_filter
,
ao
->
out_audio_format
);
}
static
void
...
...
src/filter/AutoConvertFilterPlugin.cxx
View file @
d2679f59
...
...
@@ -88,7 +88,11 @@ AutoConvertFilter::Open(AudioFormat &in_audio_format, Error &error)
assert
(
audio_format2
==
in_audio_format
);
convert_filter_set
(
convert
,
child_audio_format
);
if
(
!
convert_filter_set
(
convert
,
child_audio_format
,
error
))
{
delete
convert
;
filter
->
Close
();
return
AudioFormat
::
Undefined
();
}
}
else
/* no */
convert
=
nullptr
;
...
...
src/filter/ConvertFilterPlugin.cxx
View file @
d2679f59
...
...
@@ -39,21 +39,18 @@ class ConvertFilter final : public Filter {
/**
* The output audio format; the consumer of this plugin
* expects PCM data in this format. This defaults to
* #in_audio_format, and can be set with convert_filter_set().
* expects PCM data in this format.
*
* If this is AudioFormat::Undefined(), then the #PcmConvert
* attribute is not open. This can mean that Set() has failed
* or that no conversion is necessary.
*/
AudioFormat
out_audio_format
;
Manual
<
PcmConvert
>
state
;
public
:
void
Set
(
const
AudioFormat
&
_out_audio_format
)
{
assert
(
in_audio_format
.
IsValid
());
assert
(
out_audio_format
.
IsValid
());
assert
(
_out_audio_format
.
IsValid
());
out_audio_format
=
_out_audio_format
;
}
bool
Set
(
const
AudioFormat
&
_out_audio_format
,
Error
&
error
);
virtual
AudioFormat
Open
(
AudioFormat
&
af
,
Error
&
error
)
override
;
virtual
void
Close
()
override
;
...
...
@@ -69,12 +66,40 @@ convert_filter_init(gcc_unused const config_param ¶m,
return
new
ConvertFilter
();
}
bool
ConvertFilter
::
Set
(
const
AudioFormat
&
_out_audio_format
,
Error
&
error
)
{
assert
(
in_audio_format
.
IsValid
());
assert
(
_out_audio_format
.
IsValid
());
if
(
_out_audio_format
==
out_audio_format
)
/* no change */
return
true
;
if
(
out_audio_format
.
IsValid
())
{
out_audio_format
.
Clear
();
state
->
Close
();
}
if
(
_out_audio_format
==
in_audio_format
)
/* optimized special case: no-op */
return
true
;
if
(
!
state
->
Open
(
in_audio_format
,
_out_audio_format
,
error
))
return
false
;
out_audio_format
=
_out_audio_format
;
return
true
;
}
AudioFormat
ConvertFilter
::
Open
(
AudioFormat
&
audio_format
,
gcc_unused
Error
&
error
)
{
assert
(
audio_format
.
IsValid
());
in_audio_format
=
out_audio_format
=
audio_format
;
in_audio_format
=
audio_format
;
out_audio_format
.
Clear
();
state
.
Construct
();
return
in_audio_format
;
...
...
@@ -83,6 +108,11 @@ ConvertFilter::Open(AudioFormat &audio_format, gcc_unused Error &error)
void
ConvertFilter
::
Close
()
{
assert
(
in_audio_format
.
IsValid
());
if
(
out_audio_format
.
IsValid
())
state
->
Close
();
state
.
Destruct
();
poison_undefined
(
&
in_audio_format
,
sizeof
(
in_audio_format
));
...
...
@@ -93,15 +123,15 @@ const void *
ConvertFilter
::
FilterPCM
(
const
void
*
src
,
size_t
src_size
,
size_t
*
dest_size_r
,
Error
&
error
)
{
if
(
in_audio_format
==
out_audio_format
)
{
assert
(
in_audio_format
.
IsValid
());
if
(
!
out_audio_format
.
IsValid
())
{
/* optimized special case: no-op */
*
dest_size_r
=
src_size
;
return
src
;
}
return
state
->
Convert
(
in_audio_format
,
src
,
src_size
,
out_audio_format
,
dest_size_r
,
return
state
->
Convert
(
src
,
src_size
,
dest_size_r
,
error
);
}
...
...
@@ -110,10 +140,11 @@ const struct filter_plugin convert_filter_plugin = {
convert_filter_init
,
};
void
convert_filter_set
(
Filter
*
_filter
,
const
AudioFormat
out_audio_format
)
bool
convert_filter_set
(
Filter
*
_filter
,
AudioFormat
out_audio_format
,
Error
&
error
)
{
ConvertFilter
*
filter
=
(
ConvertFilter
*
)
_filter
;
filter
->
Set
(
out_audio_format
);
return
filter
->
Set
(
out_audio_format
,
error
);
}
src/filter/ConvertFilterPlugin.hxx
View file @
d2679f59
...
...
@@ -21,6 +21,7 @@
#define MPD_CONVERT_FILTER_PLUGIN_HXX
class
Filter
;
class
Error
;
struct
AudioFormat
;
/**
...
...
@@ -29,7 +30,8 @@ struct AudioFormat;
* format switch is a violation of the filter API, this filter must be
* the last in a chain.
*/
void
convert_filter_set
(
Filter
*
filter
,
AudioFormat
out_audio_format
);
bool
convert_filter_set
(
Filter
*
filter
,
AudioFormat
out_audio_format
,
Error
&
error
);
#endif
src/pcm/PcmConvert.cxx
View file @
d2679f59
...
...
@@ -32,23 +32,48 @@ const Domain pcm_convert_domain("pcm_convert");
PcmConvert
::
PcmConvert
()
{
#ifndef NDEBUG
src_format
.
Clear
();
dest_format
.
Clear
();
#endif
}
PcmConvert
::~
PcmConvert
()
{
assert
(
!
src_format
.
IsValid
());
assert
(
!
dest_format
.
IsValid
());
}
bool
PcmConvert
::
Open
(
AudioFormat
_src_format
,
AudioFormat
_dest_format
,
gcc_unused
Error
&
error
)
{
assert
(
!
src_format
.
IsValid
());
assert
(
!
dest_format
.
IsValid
());
assert
(
_src_format
.
IsValid
());
assert
(
_dest_format
.
IsValid
());
src_format
=
_src_format
;
dest_format
=
_dest_format
;
return
true
;
}
void
PcmConvert
::
Reset
()
PcmConvert
::
Close
()
{
dsd
.
Reset
();
resampler
.
Reset
();
#ifndef NDEBUG
src_format
.
Clear
();
dest_format
.
Clear
();
#endif
}
inline
const
int16_t
*
PcmConvert
::
Convert16
(
const
AudioFormat
src_format
,
const
void
*
src_buffer
,
size_t
src_size
,
const
AudioFormat
dest_format
,
size_t
*
dest_size_r
,
PcmConvert
::
Convert16
(
const
void
*
src_buffer
,
size_t
src_size
,
size_t
*
dest_size_r
,
Error
&
error
)
{
const
int16_t
*
buf
;
...
...
@@ -96,9 +121,8 @@ PcmConvert::Convert16(const AudioFormat src_format,
}
inline
const
int32_t
*
PcmConvert
::
Convert24
(
const
AudioFormat
src_format
,
const
void
*
src_buffer
,
size_t
src_size
,
const
AudioFormat
dest_format
,
size_t
*
dest_size_r
,
PcmConvert
::
Convert24
(
const
void
*
src_buffer
,
size_t
src_size
,
size_t
*
dest_size_r
,
Error
&
error
)
{
const
int32_t
*
buf
;
...
...
@@ -145,9 +169,8 @@ PcmConvert::Convert24(const AudioFormat src_format,
}
inline
const
int32_t
*
PcmConvert
::
Convert32
(
const
AudioFormat
src_format
,
const
void
*
src_buffer
,
size_t
src_size
,
const
AudioFormat
dest_format
,
size_t
*
dest_size_r
,
PcmConvert
::
Convert32
(
const
void
*
src_buffer
,
size_t
src_size
,
size_t
*
dest_size_r
,
Error
&
error
)
{
const
int32_t
*
buf
;
...
...
@@ -194,9 +217,8 @@ PcmConvert::Convert32(const AudioFormat src_format,
}
inline
const
float
*
PcmConvert
::
ConvertFloat
(
const
AudioFormat
src_format
,
const
void
*
src_buffer
,
size_t
src_size
,
const
AudioFormat
dest_format
,
size_t
*
dest_size_r
,
PcmConvert
::
ConvertFloat
(
const
void
*
src_buffer
,
size_t
src_size
,
size_t
*
dest_size_r
,
Error
&
error
)
{
const
float
*
buffer
=
(
const
float
*
)
src_buffer
;
...
...
@@ -251,9 +273,7 @@ PcmConvert::ConvertFloat(const AudioFormat src_format,
}
const
void
*
PcmConvert
::
Convert
(
AudioFormat
src_format
,
const
void
*
src
,
size_t
src_size
,
const
AudioFormat
dest_format
,
PcmConvert
::
Convert
(
const
void
*
src
,
size_t
src_size
,
size_t
*
dest_size_r
,
Error
&
error
)
{
...
...
@@ -279,23 +299,23 @@ PcmConvert::Convert(AudioFormat src_format,
switch
(
dest_format
.
format
)
{
case
SampleFormat
:
:
S16
:
return
Convert16
(
src
_format
,
src
,
src_size
,
dest_
format
,
dest_
size_r
,
return
Convert16
(
src
,
src_size
,
dest_size_r
,
error
);
case
SampleFormat
:
:
S24_P32
:
return
Convert24
(
src
_format
,
src
,
src_size
,
dest_
format
,
dest_
size_r
,
return
Convert24
(
src
,
src_size
,
dest_size_r
,
error
);
case
SampleFormat
:
:
S32
:
return
Convert32
(
src
_format
,
src
,
src_size
,
dest_
format
,
dest_
size_r
,
return
Convert32
(
src
,
src_size
,
dest_size_r
,
error
);
case
SampleFormat
:
:
FLOAT
:
return
ConvertFloat
(
src
_format
,
src
,
src_size
,
dest_
format
,
dest_
size_r
,
return
ConvertFloat
(
src
,
src_size
,
dest_size_r
,
error
);
default
:
...
...
src/pcm/PcmConvert.hxx
View file @
d2679f59
...
...
@@ -24,10 +24,10 @@
#include "PcmDsd.hxx"
#include "PcmResample.hxx"
#include "PcmBuffer.hxx"
#include "AudioFormat.hxx"
#include <stddef.h>
struct
AudioFormat
;
class
Error
;
/**
...
...
@@ -48,17 +48,23 @@ class PcmConvert {
/** the buffer for converting the channel count */
PcmBuffer
channels_buffer
;
AudioFormat
src_format
,
dest_format
;
public
:
PcmConvert
();
~
PcmConvert
();
/**
* Prepare the object. Call Close() when done.
*/
bool
Open
(
AudioFormat
_src_format
,
AudioFormat
_dest_format
,
Error
&
error
);
/**
* Reset the pcm_convert_state object. Use this at the
* boundary between two distinct songs and each time the
* format changes.
* Close the object after it was prepared with Open(). After
* that, it may be reused by calling Open() again.
*/
void
Reset
();
void
Close
();
/**
* Converts PCM data between two audio formats.
...
...
@@ -72,34 +78,24 @@ public:
* ignore errors
* @return the destination buffer, or NULL on error
*/
const
void
*
Convert
(
AudioFormat
src_format
,
const
void
*
src
,
size_t
src_size
,
AudioFormat
dest_format
,
const
void
*
Convert
(
const
void
*
src
,
size_t
src_size
,
size_t
*
dest_size_r
,
Error
&
error
);
private
:
const
int16_t
*
Convert16
(
AudioFormat
src_format
,
const
void
*
src_buffer
,
size_t
src_size
,
AudioFormat
dest_format
,
const
int16_t
*
Convert16
(
const
void
*
src_buffer
,
size_t
src_size
,
size_t
*
dest_size_r
,
Error
&
error
);
const
int32_t
*
Convert24
(
AudioFormat
src_format
,
const
void
*
src_buffer
,
size_t
src_size
,
AudioFormat
dest_format
,
const
int32_t
*
Convert24
(
const
void
*
src_buffer
,
size_t
src_size
,
size_t
*
dest_size_r
,
Error
&
error
);
const
int32_t
*
Convert32
(
AudioFormat
src_format
,
const
void
*
src_buffer
,
size_t
src_size
,
AudioFormat
dest_format
,
const
int32_t
*
Convert32
(
const
void
*
src_buffer
,
size_t
src_size
,
size_t
*
dest_size_r
,
Error
&
error
);
const
float
*
ConvertFloat
(
AudioFormat
src_format
,
const
void
*
src_buffer
,
size_t
src_size
,
AudioFormat
dest_format
,
const
float
*
ConvertFloat
(
const
void
*
src_buffer
,
size_t
src_size
,
size_t
*
dest_size_r
,
Error
&
error
);
};
...
...
test/run_convert.cxx
View file @
d2679f59
...
...
@@ -90,6 +90,11 @@ 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
))
{
g_printerr
(
"Failed to open PcmConvert: %s
\n
"
,
error
.
GetMessage
());
return
EXIT_FAILURE
;
}
FifoBuffer
<
uint8_t
,
4096
>
buffer
;
...
...
@@ -115,9 +120,10 @@ int main(int argc, char **argv)
buffer
.
Consume
(
src
.
size
);
size_t
length
;
output
=
state
.
Convert
(
in_audio_format
,
src
.
data
,
src
.
size
,
out_audio_format
,
&
length
,
error
);
output
=
state
.
Convert
(
src
.
data
,
src
.
size
,
&
length
,
error
);
if
(
output
==
NULL
)
{
state
.
Close
();
g_printerr
(
"Failed to convert: %s
\n
"
,
error
.
GetMessage
());
return
2
;
}
...
...
@@ -125,5 +131,7 @@ int main(int argc, char **argv)
gcc_unused
ssize_t
ignored
=
write
(
1
,
output
,
length
);
}
state
.
Close
();
return
EXIT_SUCCESS
;
}
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