spa: add interleave DSD param

And make alsa report the interleaving.
This commit is contained in:
Wim Taymans 2021-09-17 18:04:21 +02:00
parent 25d39a5ea1
commit af6e887077
6 changed files with 33 additions and 8 deletions

View file

@ -45,23 +45,24 @@ extern "C" {
/* DSD bits are transfered in a buffer grouped in bytes with the bitorder
* defined by \a bitorder.
*
* Channels are placed in separate planes or interleaved using the stride
* field of the buffer. The stride is then the number of bytes grouped per
* channel.
* Channels are placed in separate planes (interleave = 0) or interleaved
* using the interleave value. A negative interleave value means that the
* bytes need to be reversed in the group.
*
* Planar:
* Planar (interleave = 0):
* plane1: l1 l2 l3 l4 l5 ...
* plane2: r1 r2 r3 r4 r5 ...
*
* Interleaved stride 4:
* Interleaved 4:
* plane1: l1 l2 l3 l4 r1 r2 r3 r4 l5 l6 l7 l8 r5 r6 r7 r8 l9 ...
*
* Interleaved stride 2:
* Interleaved 2:
* plane1: l1 l2 r1 r2 l3 l4 r3 r4 ...
*/
struct spa_audio_info_dsd {
enum spa_param_bitorder bitorder; /*< the order of the bits */
uint32_t flags; /*< extra flags */
int32_t interleave; /*< interleave bytes */
uint32_t rate; /*< sample rate (in bits per second) */
uint32_t channels; /*< channels */
uint32_t position[SPA_AUDIO_MAX_CHANNELS]; /*< channel position from enum spa_audio_channel */

View file

@ -88,6 +88,7 @@ spa_format_audio_dsd_parse(const struct spa_pod *format, struct spa_audio_info_d
res = spa_pod_parse_object(format,
SPA_TYPE_OBJECT_Format, NULL,
SPA_FORMAT_AUDIO_bitorder, SPA_POD_Id(&info->bitorder),
SPA_FORMAT_AUDIO_interleave, SPA_POD_Int(&info->interleave),
SPA_FORMAT_AUDIO_rate, SPA_POD_Int(&info->rate),
SPA_FORMAT_AUDIO_channels, SPA_POD_Int(&info->channels),
SPA_FORMAT_AUDIO_position, SPA_POD_OPT_Pod(&position));
@ -167,8 +168,13 @@ spa_format_audio_dsd_build(struct spa_pod_builder *builder, uint32_t id, struct
spa_pod_builder_add(builder,
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio),
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_dsd),
SPA_FORMAT_AUDIO_bitorder, SPA_POD_Id(info->bitorder),
0);
if (info->bitorder != SPA_PARAM_BITORDER_unknown)
spa_pod_builder_add(builder,
SPA_FORMAT_AUDIO_bitorder, SPA_POD_Id(info->bitorder), 0);
if (info->interleave != 0)
spa_pod_builder_add(builder,
SPA_FORMAT_AUDIO_interleave, SPA_POD_Int(info->interleave), 0);
if (info->rate != 0)
spa_pod_builder_add(builder,
SPA_FORMAT_AUDIO_rate, SPA_POD_Int(info->rate), 0);

View file

@ -115,6 +115,7 @@ enum spa_format {
SPA_FORMAT_AUDIO_iec958Codec, /**< codec used (IEC958) (Id enum spa_audio_iec958_codec) */
SPA_FORMAT_AUDIO_bitorder, /**< bit order (Id enum spa_param_bitorder) */
SPA_FORMAT_AUDIO_interleave, /**< Interleave bytes (Int) */
/* Video Format keys */
SPA_FORMAT_START_Video = 0x20000,

View file

@ -195,6 +195,7 @@ enum spa_param_process_latency {
};
enum spa_param_bitorder {
SPA_PARAM_BITORDER_unknown, /**< unknown bitorder */
SPA_PARAM_BITORDER_msb, /**< most significant bit */
SPA_PARAM_BITORDER_lsb, /**< least significant bit */
};

View file

@ -94,6 +94,7 @@ static const struct spa_type_info spa_type_prop_iec958_codec[] = {
#define SPA_TYPE_INFO_PARAM_BITORDER_BASE SPA_TYPE_INFO_ParamBitorder ":"
static const struct spa_type_info spa_type_param_bitorder[] = {
{ SPA_PARAM_BITORDER_unknown, SPA_TYPE_Int, SPA_TYPE_INFO_PARAM_BITORDER_BASE "unknown", NULL },
{ SPA_PARAM_BITORDER_msb, SPA_TYPE_Int, SPA_TYPE_INFO_PARAM_BITORDER_BASE "msb", NULL },
{ SPA_PARAM_BITORDER_lsb, SPA_TYPE_Int, SPA_TYPE_INFO_PARAM_BITORDER_BASE "lsb", NULL },
{ 0, 0, NULL, NULL },
@ -280,6 +281,7 @@ static const struct spa_type_info spa_type_format[] = {
{ SPA_FORMAT_AUDIO_bitorder, SPA_TYPE_Id, SPA_TYPE_INFO_FORMAT_AUDIO_BASE "bitorder",
spa_type_param_bitorder },
{ SPA_FORMAT_AUDIO_interleave, SPA_TYPE_Int, SPA_TYPE_INFO_FORMAT_AUDIO_BASE "interleave", NULL },
{ SPA_FORMAT_VIDEO_format, SPA_TYPE_Id, SPA_TYPE_INFO_FORMAT_VIDEO_BASE "format",
spa_type_video_format, },