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
17293886
Commit
17293886
authored
Apr 09, 2013
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
pcm_export: convert to C++
parent
c654c763
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
122 additions
and
150 deletions
+122
-150
Makefile.am
Makefile.am
+2
-1
AlsaOutputPlugin.cxx
src/output/AlsaOutputPlugin.cxx
+11
-13
OssOutputPlugin.cxx
src/output/OssOutputPlugin.cxx
+11
-10
PcmExport.cxx
src/pcm/PcmExport.cxx
+48
-60
PcmExport.hxx
src/pcm/PcmExport.hxx
+50
-66
No files found.
Makefile.am
View file @
17293886
...
...
@@ -316,7 +316,7 @@ libevent_a_SOURCES = \
libpcm_a_SOURCES
=
\
src/pcm/pcm_buffer.c src/pcm/pcm_buffer.h
\
src/pcm/
pcm_export.c src/pcm/pcm_export.h
\
src/pcm/
PcmExport.cxx src/pcm/PcmExport.hxx
\
src/pcm/PcmConvert.cxx src/pcm/PcmConvert.hxx
\
src/pcm/dsd2pcm/dsd2pcm.c src/pcm/dsd2pcm/dsd2pcm.h
\
src/pcm/pcm_dsd.c src/pcm/pcm_dsd.h
\
...
...
@@ -1301,6 +1301,7 @@ test_run_convert_LDADD = \
$(GLIB_LIBS)
test_run_output_LDADD
=
$(MPD_LIBS)
\
$(PCM_LIBS)
\
$(OUTPUT_LIBS)
\
$(ENCODER_LIBS)
\
libmixer_plugins.a
\
...
...
src/output/AlsaOutputPlugin.cxx
View file @
17293886
...
...
@@ -21,7 +21,8 @@
#include "AlsaOutputPlugin.hxx"
#include "output_api.h"
#include "MixerList.hxx"
#include "pcm/pcm_export.h"
#include "pcm/PcmExport.hxx"
#include "util/Manual.hxx"
#include <glib.h>
#include <alsa/asoundlib.h>
...
...
@@ -48,7 +49,7 @@ typedef snd_pcm_sframes_t alsa_writei_t(snd_pcm_t * pcm, const void *buffer,
struct
AlsaOutput
{
struct
audio_output
base
;
struct
pcm_export_state
pcm_export
;
Manual
<
PcmExport
>
pcm_export
;
/**
* The configured name of the ALSA device; empty for the
...
...
@@ -202,7 +203,7 @@ alsa_output_enable(struct audio_output *ao, G_GNUC_UNUSED GError **error_r)
{
AlsaOutput
*
ad
=
(
AlsaOutput
*
)
ao
;
pcm_export_init
(
&
ad
->
pcm_export
);
ad
->
pcm_export
.
Construct
(
);
return
true
;
}
...
...
@@ -211,7 +212,7 @@ alsa_output_disable(struct audio_output *ao)
{
AlsaOutput
*
ad
=
(
AlsaOutput
*
)
ao
;
pcm_export_deinit
(
&
ad
->
pcm_export
);
ad
->
pcm_export
.
Destruct
(
);
}
static
bool
...
...
@@ -659,10 +660,9 @@ alsa_setup_or_dsd(AlsaOutput *ad, struct audio_format *audio_format,
if
(
!
success
)
return
false
;
pcm_export_open
(
&
ad
->
pcm_export
,
sample_format
(
audio_format
->
format
),
audio_format
->
channels
,
dsd_usb
,
shift8
,
packed
,
reverse_endian
);
ad
->
pcm_export
->
Open
(
sample_format
(
audio_format
->
format
),
audio_format
->
channels
,
dsd_usb
,
shift8
,
packed
,
reverse_endian
);
return
true
;
}
...
...
@@ -689,8 +689,7 @@ alsa_open(struct audio_output *ao, struct audio_format *audio_format, GError **e
}
ad
->
in_frame_size
=
audio_format_frame_size
(
audio_format
);
ad
->
out_frame_size
=
pcm_export_frame_size
(
&
ad
->
pcm_export
,
audio_format
);
ad
->
out_frame_size
=
ad
->
pcm_export
->
GetFrameSize
(
*
audio_format
);
return
true
;
}
...
...
@@ -809,7 +808,7 @@ alsa_play(struct audio_output *ao, const void *chunk, size_t size,
assert
(
size
%
ad
->
in_frame_size
==
0
);
chunk
=
pcm_export
(
&
ad
->
pcm_export
,
chunk
,
size
,
&
size
);
chunk
=
ad
->
pcm_export
->
Export
(
chunk
,
size
,
size
);
assert
(
size
%
ad
->
out_frame_size
==
0
);
...
...
@@ -822,8 +821,7 @@ alsa_play(struct audio_output *ao, const void *chunk, size_t size,
%
ad
->
period_frames
;
size_t
bytes_written
=
ret
*
ad
->
out_frame_size
;
return
pcm_export_source_size
(
&
ad
->
pcm_export
,
bytes_written
);
return
ad
->
pcm_export
->
CalcSourceSize
(
bytes_written
);
}
if
(
ret
<
0
&&
ret
!=
-
EAGAIN
&&
ret
!=
-
EINTR
&&
...
...
src/output/OssOutputPlugin.cxx
View file @
17293886
...
...
@@ -52,14 +52,15 @@
#endif
#ifdef AFMT_S24_PACKED
#include "pcm/pcm_export.h"
#include "pcm/PcmExport.hxx"
#include "util/Manual.hxx"
#endif
struct
oss_data
{
struct
audio_output
base
;
#ifdef AFMT_S24_PACKED
struct
pcm_export_state
pcm_export
;
Manual
<
PcmExport
>
pcm_export
;
#endif
int
fd
;
...
...
@@ -241,7 +242,7 @@ oss_output_enable(struct audio_output *ao, G_GNUC_UNUSED GError **error_r)
{
struct
oss_data
*
od
=
(
struct
oss_data
*
)
ao
;
pcm_export_init
(
&
od
->
pcm_export
);
od
->
pcm_export
.
Construct
(
);
return
true
;
}
...
...
@@ -250,7 +251,7 @@ oss_output_disable(struct audio_output *ao)
{
struct
oss_data
*
od
=
(
struct
oss_data
*
)
ao
;
pcm_export_deinit
(
&
od
->
pcm_export
);
od
->
pcm_export
.
Destruct
(
);
}
#endif
...
...
@@ -502,7 +503,7 @@ oss_probe_sample_format(int fd, enum sample_format sample_format,
enum
sample_format
*
sample_format_r
,
int
*
oss_format_r
,
#ifdef AFMT_S24_PACKED
struct
pcm_export_state
*
pcm_export
,
PcmExport
&
pcm_export
,
#endif
GError
**
error_r
)
{
...
...
@@ -537,7 +538,7 @@ oss_probe_sample_format(int fd, enum sample_format sample_format,
*
oss_format_r
=
oss_format
;
#ifdef AFMT_S24_PACKED
pcm_export
_open
(
pcm_export
,
sample_format
,
0
,
false
,
false
,
pcm_export
.
Open
(
sample_format
,
0
,
false
,
false
,
oss_format
==
AFMT_S24_PACKED
,
oss_format
==
AFMT_S24_PACKED
&&
G_BYTE_ORDER
!=
G_LITTLE_ENDIAN
);
...
...
@@ -554,7 +555,7 @@ static bool
oss_setup_sample_format
(
int
fd
,
struct
audio_format
*
audio_format
,
int
*
oss_format_r
,
#ifdef AFMT_S24_PACKED
struct
pcm_export_state
*
pcm_export
,
PcmExport
&
pcm_export
,
#endif
GError
**
error_r
)
{
...
...
@@ -633,7 +634,7 @@ oss_setup(struct oss_data *od, struct audio_format *audio_format,
oss_setup_sample_rate
(
od
->
fd
,
audio_format
,
error_r
)
&&
oss_setup_sample_format
(
od
->
fd
,
audio_format
,
&
od
->
oss_format
,
#ifdef AFMT_S24_PACKED
&
od
->
pcm_export
,
od
->
pcm_export
,
#endif
error_r
);
}
...
...
@@ -747,14 +748,14 @@ oss_output_play(struct audio_output *ao, const void *chunk, size_t size,
return
0
;
#ifdef AFMT_S24_PACKED
chunk
=
pcm_export
(
&
od
->
pcm_export
,
chunk
,
size
,
&
size
);
chunk
=
od
->
pcm_export
->
Export
(
chunk
,
size
,
size
);
#endif
while
(
true
)
{
ret
=
write
(
od
->
fd
,
chunk
,
size
);
if
(
ret
>
0
)
{
#ifdef AFMT_S24_PACKED
ret
=
pcm_export_source_size
(
&
od
->
pcm_export
,
ret
);
ret
=
od
->
pcm_export
->
CalcSourceSize
(
ret
);
#endif
return
ret
;
}
...
...
src/pcm/
pcm_export.c
→
src/pcm/
PcmExport.cxx
View file @
17293886
/*
* Copyright (C) 2003-201
2
The Music Player Daemon Project
* Copyright (C) 2003-201
3
The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
...
...
@@ -18,95 +18,79 @@
*/
#include "config.h"
#include "pcm_export.h"
#include "PcmExport.hxx"
extern
"C"
{
#include "pcm_dsd_usb.h"
#include "pcm_pack.h"
#include "util/byte_reverse.h"
void
pcm_export_init
(
struct
pcm_export_state
*
state
)
{
pcm_buffer_init
(
&
state
->
reverse_buffer
);
pcm_buffer_init
(
&
state
->
pack_buffer
);
pcm_buffer_init
(
&
state
->
dsd_buffer
);
}
void
pcm_export_deinit
(
struct
pcm_export_state
*
state
)
{
pcm_buffer_deinit
(
&
state
->
reverse_buffer
);
pcm_buffer_deinit
(
&
state
->
pack_buffer
);
pcm_buffer_deinit
(
&
state
->
dsd_buffer
);
}
void
pcm_export_open
(
struct
pcm_export_state
*
state
,
enum
sample_format
sample_format
,
unsigned
channels
,
bool
dsd_usb
,
bool
shift8
,
bool
pack
,
bool
reverse_endian
)
PcmExport
::
Open
(
enum
sample_format
sample_format
,
unsigned
_channels
,
bool
_dsd_usb
,
bool
_shift8
,
bool
_pack
,
bool
_reverse_endian
)
{
assert
(
audio_valid_sample_format
(
sample_format
));
assert
(
!
dsd_usb
||
audio_valid_channel_count
(
channels
));
assert
(
!
_dsd_usb
||
audio_valid_channel_count
(
_
channels
));
state
->
channels
=
channels
;
state
->
dsd_usb
=
dsd_usb
&&
sample_format
==
SAMPLE_FORMAT_DSD
;
if
(
state
->
dsd_usb
)
channels
=
_
channels
;
dsd_usb
=
_
dsd_usb
&&
sample_format
==
SAMPLE_FORMAT_DSD
;
if
(
dsd_usb
)
/* after the conversion to DSD-over-USB, the DSD
samples are stuffed inside fake 24 bit samples */
sample_format
=
SAMPLE_FORMAT_S24_P32
;
s
tate
->
shift8
=
shift8
&&
sample_format
==
SAMPLE_FORMAT_S24_P32
;
state
->
pack24
=
pack
&&
sample_format
==
SAMPLE_FORMAT_S24_P32
;
s
hift8
=
_
shift8
&&
sample_format
==
SAMPLE_FORMAT_S24_P32
;
pack24
=
_
pack
&&
sample_format
==
SAMPLE_FORMAT_S24_P32
;
assert
(
!
s
tate
->
shift8
||
!
state
->
pack24
);
assert
(
!
s
hift8
||
!
pack24
);
state
->
reverse_endian
=
0
;
if
(
reverse_endian
)
{
size_t
sample_size
=
state
->
pack24
reverse_endian
=
0
;
if
(
_
reverse_endian
)
{
size_t
sample_size
=
pack24
?
3
:
sample_format_size
(
sample_format
);
assert
(
sample_size
<=
0xff
);
if
(
sample_size
>
1
)
state
->
reverse_endian
=
sample_size
;
reverse_endian
=
sample_size
;
}
}
size_t
pcm_export_frame_size
(
const
struct
pcm_export_state
*
state
,
const
struct
audio_format
*
audio_format
)
PcmExport
::
GetFrameSize
(
const
struct
audio_format
&
audio_format
)
const
{
assert
(
state
!=
NULL
);
assert
(
audio_format
!=
NULL
);
if
(
state
->
pack24
)
if
(
pack24
)
/* packed 24 bit samples (3 bytes per sample) */
return
audio_format
->
channels
*
3
;
return
audio_format
.
channels
*
3
;
if
(
state
->
dsd_usb
)
if
(
dsd_usb
)
/* the DSD-over-USB draft says that DSD 1-bit samples
are enclosed within 24 bit samples, and MPD's
representation of 24 bit is padded to 32 bit (4
bytes per sample) */
return
audio_format
->
channels
*
4
;
return
channels
*
4
;
return
audio_format_frame_size
(
audio_format
);
return
audio_format_frame_size
(
&
audio_format
);
}
const
void
*
pcm_export
(
struct
pcm_export_state
*
state
,
const
void
*
data
,
size_t
size
,
size_t
*
dest_size_r
)
PcmExport
::
Export
(
const
void
*
data
,
size_t
size
,
size_t
&
dest_size_r
)
{
if
(
state
->
dsd_usb
)
data
=
pcm_dsd_to_usb
(
&
state
->
dsd_buffer
,
state
->
channels
,
data
,
size
,
&
size
);
if
(
dsd_usb
)
data
=
pcm_dsd_to_usb
(
&
dsd_buffer
,
channels
,
(
const
uint8_t
*
)
data
,
size
,
&
size
);
if
(
state
->
pack24
)
{
if
(
pack24
)
{
assert
(
size
%
4
==
0
);
const
size_t
num_samples
=
size
/
4
;
const
size_t
dest_size
=
num_samples
*
3
;
const
uint8_t
*
src8
=
data
,
*
src_end8
=
src8
+
size
;
uint8_t
*
dest
=
pcm_buffer_get
(
&
state
->
pack_buffer
,
dest_size
);
const
uint8_t
*
src8
=
(
const
uint8_t
*
)
data
;
const
uint8_t
*
src_end8
=
src8
+
size
;
uint8_t
*
dest
=
(
uint8_t
*
)
pcm_buffer_get
(
&
pack_buffer
,
dest_size
);
assert
(
dest
!=
NULL
);
pcm_pack_24
(
dest
,
(
const
int32_t
*
)
src8
,
...
...
@@ -114,14 +98,16 @@ pcm_export(struct pcm_export_state *state, const void *data, size_t size,
data
=
dest
;
size
=
dest_size
;
}
else
if
(
s
tate
->
s
hift8
)
{
}
else
if
(
shift8
)
{
assert
(
size
%
4
==
0
);
const
uint8_t
*
src8
=
data
,
*
src_end8
=
src8
+
size
;
const
uint8_t
*
src8
=
(
const
uint8_t
*
)
data
;
const
uint8_t
*
src_end8
=
src8
+
size
;
const
uint32_t
*
src
=
(
const
uint32_t
*
)
src8
;
const
uint32_t
*
const
src_end
=
(
const
uint32_t
*
)
src_end8
;
uint32_t
*
dest
=
pcm_buffer_get
(
&
state
->
pack_buffer
,
size
);
uint32_t
*
dest
=
(
uint32_t
*
)
pcm_buffer_get
(
&
pack_buffer
,
size
);
data
=
dest
;
while
(
src
<
src_end
)
...
...
@@ -129,30 +115,32 @@ pcm_export(struct pcm_export_state *state, const void *data, size_t size,
}
if
(
state
->
reverse_endian
>
0
)
{
assert
(
state
->
reverse_endian
>=
2
);
if
(
reverse_endian
>
0
)
{
assert
(
reverse_endian
>=
2
);
void
*
dest
=
pcm_buffer_get
(
&
state
->
reverse_buffer
,
size
);
uint8_t
*
dest
=
(
uint8_t
*
)
pcm_buffer_get
(
&
reverse_buffer
,
size
);
assert
(
dest
!=
NULL
);
const
uint8_t
*
src
=
data
,
*
src_end
=
src
+
size
;
reverse_bytes
(
dest
,
src
,
src_end
,
state
->
reverse_endian
);
const
uint8_t
*
src
=
(
const
uint8_t
*
)
data
;
const
uint8_t
*
src_end
=
src
+
size
;
reverse_bytes
(
dest
,
src
,
src_end
,
reverse_endian
);
data
=
dest
;
}
*
dest_size_r
=
size
;
dest_size_r
=
size
;
return
data
;
}
size_t
pcm_export_source_size
(
const
struct
pcm_export_state
*
state
,
size_t
size
)
PcmExport
::
CalcSourceSize
(
size_t
size
)
const
{
if
(
state
->
pack24
)
if
(
pack24
)
/* 32 bit to 24 bit conversion (4 to 3 bytes) */
size
=
(
size
/
3
)
*
4
;
if
(
state
->
dsd_usb
)
if
(
dsd_usb
)
/* DSD over USB doubles the transport size */
size
/=
2
;
...
...
src/pcm/
pcm_export.h
→
src/pcm/
PcmExport.hxx
View file @
17293886
/*
* Copyright (C) 2003-201
2
The Music Player Daemon Project
* Copyright (C) 2003-201
3
The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
...
...
@@ -17,15 +17,13 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef PCM_EXPORT_H
#define PCM_EXPORT_H
#ifndef PCM_EXPORT_H
XX
#define PCM_EXPORT_H
XX
#include "check.h"
#include "pcm_buffer.h"
#include "audio_format.h"
#include <stdbool.h>
struct
audio_format
;
/**
...
...
@@ -33,7 +31,7 @@ struct audio_format;
* outside of MPD. It has a few more options to tweak the binary
* representation which are not supported by the pcm_convert library.
*/
struct
pcm_export_state
{
struct
PcmExport
{
/**
* The buffer is used to convert DSD samples to the
* DSD-over-USB format.
...
...
@@ -85,71 +83,57 @@ struct pcm_export_state {
* sample (2 or bigger).
*/
uint8_t
reverse_endian
;
};
#ifdef __cplusplus
extern
"C"
{
#endif
/**
* Initialize a #pcm_export_state object.
*/
void
pcm_export_init
(
struct
pcm_export_state
*
state
);
/**
* Deinitialize a #pcm_export_state object and free allocated memory.
*/
void
pcm_export_deinit
(
struct
pcm_export_state
*
state
);
PcmExport
()
{
pcm_buffer_init
(
&
reverse_buffer
);
pcm_buffer_init
(
&
pack_buffer
);
pcm_buffer_init
(
&
dsd_buffer
);
}
/**
* Open the #pcm_export_state object.
*
* There is no "close" method. This function may be called multiple
* times to reuse the object, until pcm_export_deinit() is called.
*
* This function cannot fail.
*
* @param channels the number of channels; ignored unless dsd_usb is set
*/
void
pcm_export_open
(
struct
pcm_export_state
*
state
,
enum
sample_format
sample_format
,
unsigned
channels
,
bool
dsd_usb
,
bool
shift8
,
bool
pack
,
bool
reverse_endian
);
~
PcmExport
()
{
pcm_buffer_deinit
(
&
reverse_buffer
);
pcm_buffer_deinit
(
&
pack_buffer
);
pcm_buffer_deinit
(
&
dsd_buffer
);
}
/**
* Calculate the size of one output frame.
*/
G_GNUC_PURE
size_t
pcm_export_frame_size
(
const
struct
pcm_export_state
*
state
,
const
struct
audio_format
*
audio_format
);
/**
* Open the #pcm_export_state object.
*
* There is no "close" method. This function may be called multiple
* times to reuse the object, until pcm_export_deinit() is called.
*
* This function cannot fail.
*
* @param channels the number of channels; ignored unless dsd_usb is set
*/
void
Open
(
enum
sample_format
sample_format
,
unsigned
channels
,
bool
dsd_usb
,
bool
shift8
,
bool
pack
,
bool
reverse_endian
);
/**
* Export a PCM buffer.
*
* @param state an initialized and open pcm_export_state object
* @param src the source PCM buffer
* @param src_size the size of #src in bytes
* @param dest_size_r returns the number of bytes of the destination buffer
* @return the destination buffer (may be a pointer to the source buffer)
*/
const
void
*
pcm_export
(
struct
pcm_export_state
*
state
,
const
void
*
src
,
size_t
src_size
,
size_t
*
dest_size_r
);
/**
* Calculate the size of one output frame.
*/
gcc_pure
size_t
GetFrameSize
(
const
struct
audio_format
&
audio_format
)
const
;
/**
* Converts the number of consumed bytes from the pcm_export()
* destination buffer to the according number of bytes from the
* pcm_export() source buffer.
*/
G_GNUC_PURE
size_t
pcm_export_source_size
(
const
struct
pcm_export_state
*
state
,
size_t
dest_size
);
/**
* Export a PCM buffer.
*
* @param state an initialized and open pcm_export_state object
* @param src the source PCM buffer
* @param src_size the size of #src in bytes
* @param dest_size_r returns the number of bytes of the destination buffer
* @return the destination buffer (may be a pointer to the source buffer)
*/
const
void
*
Export
(
const
void
*
src
,
size_t
src_size
,
size_t
&
dest_size_r
);
#ifdef __cplusplus
}
#endif
/**
* Converts the number of consumed bytes from the pcm_export()
* destination buffer to the according number of bytes from the
* pcm_export() source buffer.
*/
gcc_pure
size_t
CalcSourceSize
(
size_t
dest_size
)
const
;
};
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment