Commit 1c84f324 authored by Max Kellermann's avatar Max Kellermann

output/oss: always receive host byte order samples

Don't use audio_format.reverse_endian.
parent 3dba09f3
...@@ -51,9 +51,23 @@ ...@@ -51,9 +51,23 @@
#undef AFMT_S24_NE #undef AFMT_S24_NE
#endif #endif
#ifdef AFMT_S24_PACKED
#include "pcm_buffer.h"
#include "pcm_byteswap.h"
#endif
struct oss_data { struct oss_data {
struct audio_output base; struct audio_output base;
#ifdef AFMT_S24_PACKED
/**
* The buffer used to reverse the byte order.
*
* @see #reverse_endian
*/
struct pcm_buffer reverse_buffer;
#endif
int fd; int fd;
const char *device; const char *device;
...@@ -62,6 +76,16 @@ struct oss_data { ...@@ -62,6 +76,16 @@ struct oss_data {
* the device after cancel(). * the device after cancel().
*/ */
struct audio_format audio_format; struct audio_format audio_format;
#ifdef AFMT_S24_PACKED
/**
* Does OSS expect samples in reverse byte order? (i.e. not
* host byte order)
*
* This attribute is only valid while the device is open.
*/
bool reverse_endian;
#endif
}; };
/** /**
...@@ -221,6 +245,27 @@ oss_output_finish(struct audio_output *ao) ...@@ -221,6 +245,27 @@ oss_output_finish(struct audio_output *ao)
oss_data_free(od); oss_data_free(od);
} }
#ifdef AFMT_S24_PACKED
static bool
oss_output_enable(struct audio_output *ao, G_GNUC_UNUSED GError **error_r)
{
struct oss_data *od = (struct oss_data *)ao;
pcm_buffer_init(&od->reverse_buffer);
return true;
}
static void
oss_output_disable(struct audio_output *ao)
{
struct oss_data *od = (struct oss_data *)ao;
pcm_buffer_deinit(&od->reverse_buffer);
}
#endif
static void static void
oss_close(struct oss_data *od) oss_close(struct oss_data *od)
{ {
...@@ -471,6 +516,9 @@ sample_format_from_oss(int format) ...@@ -471,6 +516,9 @@ sample_format_from_oss(int format)
*/ */
static bool static bool
oss_setup_sample_format(int fd, struct audio_format *audio_format, oss_setup_sample_format(int fd, struct audio_format *audio_format,
#ifdef AFMT_S24_PACKED
bool *reverse_endian_r,
#endif
GError **error_r) GError **error_r)
{ {
const char *const msg = "Failed to set sample format"; const char *const msg = "Failed to set sample format";
...@@ -489,9 +537,8 @@ oss_setup_sample_format(int fd, struct audio_format *audio_format, ...@@ -489,9 +537,8 @@ oss_setup_sample_format(int fd, struct audio_format *audio_format,
audio_format->format = mpd_format; audio_format->format = mpd_format;
#ifdef AFMT_S24_PACKED #ifdef AFMT_S24_PACKED
if (oss_format == AFMT_S24_PACKED) *reverse_endian_r = oss_format == AFMT_S24_PACKED &&
audio_format->reverse_endian = G_BYTE_ORDER != G_LITTLE_ENDIAN;
G_BYTE_ORDER != G_LITTLE_ENDIAN;
#endif #endif
return true; return true;
...@@ -536,9 +583,8 @@ oss_setup_sample_format(int fd, struct audio_format *audio_format, ...@@ -536,9 +583,8 @@ oss_setup_sample_format(int fd, struct audio_format *audio_format,
audio_format->format = mpd_format; audio_format->format = mpd_format;
#ifdef AFMT_S24_PACKED #ifdef AFMT_S24_PACKED
if (oss_format == AFMT_S24_PACKED) *reverse_endian_r = oss_format == AFMT_S24_PACKED &&
audio_format->reverse_endian = G_BYTE_ORDER != G_LITTLE_ENDIAN;
G_BYTE_ORDER != G_LITTLE_ENDIAN;
#endif #endif
return true; return true;
...@@ -563,7 +609,11 @@ oss_setup(struct oss_data *od, struct audio_format *audio_format, ...@@ -563,7 +609,11 @@ oss_setup(struct oss_data *od, struct audio_format *audio_format,
{ {
return oss_setup_channels(od->fd, audio_format, error_r) && return oss_setup_channels(od->fd, audio_format, error_r) &&
oss_setup_sample_rate(od->fd, audio_format, error_r) && oss_setup_sample_rate(od->fd, audio_format, error_r) &&
oss_setup_sample_format(od->fd, audio_format, error_r); oss_setup_sample_format(od->fd, audio_format,
#ifdef AFMT_S24_PACKED
&od->reverse_endian,
#endif
error_r);
} }
/** /**
...@@ -675,6 +725,13 @@ oss_output_play(struct audio_output *ao, const void *chunk, size_t size, ...@@ -675,6 +725,13 @@ oss_output_play(struct audio_output *ao, const void *chunk, size_t size,
if (od->fd < 0 && !oss_reopen(od, error)) if (od->fd < 0 && !oss_reopen(od, error))
return 0; return 0;
#ifdef AFMT_S24_PACKED
if (od->reverse_endian)
chunk = pcm_byteswap(&od->reverse_buffer,
od->audio_format.format,
chunk, size);
#endif
while (true) { while (true) {
ret = write(od->fd, chunk, size); ret = write(od->fd, chunk, size);
if (ret > 0) if (ret > 0)
...@@ -694,6 +751,10 @@ const struct audio_output_plugin oss_output_plugin = { ...@@ -694,6 +751,10 @@ const struct audio_output_plugin oss_output_plugin = {
.test_default_device = oss_output_test_default_device, .test_default_device = oss_output_test_default_device,
.init = oss_output_init, .init = oss_output_init,
.finish = oss_output_finish, .finish = oss_output_finish,
#ifdef AFMT_S24_PACKED
.enable = oss_output_enable,
.disable = oss_output_disable,
#endif
.open = oss_output_open, .open = oss_output_open,
.close = oss_output_close, .close = oss_output_close,
.play = oss_output_play, .play = oss_output_play,
......
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