Commit ddd4f675 authored by Max Kellermann's avatar Max Kellermann

pcm_export: implement 24 to 32 bit conversion

For 32 bit DSD-over-USB support.
parent d271dd2c
...@@ -634,7 +634,7 @@ alsa_setup_or_dsd(struct alsa_data *ad, struct audio_format *audio_format, ...@@ -634,7 +634,7 @@ alsa_setup_or_dsd(struct alsa_data *ad, struct audio_format *audio_format,
pcm_export_open(&ad->export, pcm_export_open(&ad->export,
audio_format->format, audio_format->channels, audio_format->format, audio_format->channels,
dsd_usb, packed, reverse_endian); dsd_usb, false, packed, reverse_endian);
return true; return true;
} }
......
...@@ -540,7 +540,7 @@ oss_probe_sample_format(int fd, enum sample_format sample_format, ...@@ -540,7 +540,7 @@ oss_probe_sample_format(int fd, enum sample_format sample_format,
*oss_format_r = oss_format; *oss_format_r = oss_format;
#ifdef AFMT_S24_PACKED #ifdef AFMT_S24_PACKED
pcm_export_open(export, sample_format, 0, false, pcm_export_open(export, sample_format, 0, false, false,
oss_format == AFMT_S24_PACKED, oss_format == AFMT_S24_PACKED,
oss_format == AFMT_S24_PACKED && oss_format == AFMT_S24_PACKED &&
G_BYTE_ORDER != G_LITTLE_ENDIAN); G_BYTE_ORDER != G_LITTLE_ENDIAN);
......
...@@ -41,7 +41,7 @@ void pcm_export_deinit(struct pcm_export_state *state) ...@@ -41,7 +41,7 @@ void pcm_export_deinit(struct pcm_export_state *state)
void void
pcm_export_open(struct pcm_export_state *state, pcm_export_open(struct pcm_export_state *state,
enum sample_format sample_format, unsigned channels, enum sample_format sample_format, unsigned channels,
bool dsd_usb, bool pack, bool reverse_endian) bool dsd_usb, bool shift8, bool pack, bool reverse_endian)
{ {
assert(audio_valid_sample_format(sample_format)); assert(audio_valid_sample_format(sample_format));
assert(!dsd_usb || audio_valid_channel_count(channels)); assert(!dsd_usb || audio_valid_channel_count(channels));
...@@ -53,8 +53,11 @@ pcm_export_open(struct pcm_export_state *state, ...@@ -53,8 +53,11 @@ pcm_export_open(struct pcm_export_state *state,
samples are stuffed inside fake 24 bit samples */ samples are stuffed inside fake 24 bit samples */
sample_format = SAMPLE_FORMAT_S24_P32; sample_format = SAMPLE_FORMAT_S24_P32;
state->shift8 = shift8 && sample_format == SAMPLE_FORMAT_S24_P32;
state->pack24 = pack && (sample_format == SAMPLE_FORMAT_S24_P32 || sample_format == SAMPLE_FORMAT_DSD_OVER_USB); state->pack24 = pack && (sample_format == SAMPLE_FORMAT_S24_P32 || sample_format == SAMPLE_FORMAT_DSD_OVER_USB);
assert(!state->shift8 || !state->pack24);
state->reverse_endian = 0; state->reverse_endian = 0;
if (reverse_endian) { if (reverse_endian) {
size_t sample_size = state->pack24 size_t sample_size = state->pack24
...@@ -90,8 +93,21 @@ pcm_export(struct pcm_export_state *state, const void *data, size_t size, ...@@ -90,8 +93,21 @@ pcm_export(struct pcm_export_state *state, const void *data, size_t size,
data = dest; data = dest;
size = dest_size; size = dest_size;
} else if (state->shift8) {
assert(size % 4 == 0);
const uint8_t *src8 = data, *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);
data = dest;
while (src < src_end)
*dest++ = *src++ << 8;
} }
if (state->reverse_endian > 0) { if (state->reverse_endian > 0) {
assert(state->reverse_endian >= 2); assert(state->reverse_endian >= 2);
......
...@@ -69,6 +69,12 @@ struct pcm_export_state { ...@@ -69,6 +69,12 @@ struct pcm_export_state {
bool dsd_usb; bool dsd_usb;
/** /**
* Convert (padded) 24 bit samples to 32 bit by shifting 8
* bits to the left?
*/
bool shift8;
/**
* Pack 24 bit samples? * Pack 24 bit samples?
*/ */
bool pack24; bool pack24;
...@@ -106,7 +112,7 @@ pcm_export_deinit(struct pcm_export_state *state); ...@@ -106,7 +112,7 @@ pcm_export_deinit(struct pcm_export_state *state);
void void
pcm_export_open(struct pcm_export_state *state, pcm_export_open(struct pcm_export_state *state,
enum sample_format sample_format, unsigned channels, enum sample_format sample_format, unsigned channels,
bool dsd_usb, bool pack, bool reverse_endian); bool dsd_usb, bool shift8, bool pack, bool reverse_endian);
/** /**
* Export a PCM buffer. * Export a PCM buffer.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment