summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Kellermann <max@musicpd.org>2021-08-05 15:07:27 +0200
committerMax Kellermann <max@musicpd.org>2021-08-05 15:11:54 +0200
commit17b0ac75ca9d8d81e4eabaa8f11bec68830eb9ba (patch)
treea7677346a8dc9e9e1ead33254daa9f2d7ea2d8f2
parentbde64a13e24f1bfc6d9319b916b304ad434cd027 (diff)
output/oss: always enable PcmExport for alsa_channel_order
We need this even when AFMT_S24_PACKED is not available, for the correct channel order in multi-channel files. Internally, MPD uses FLAC channel order, but OSS uses the same channel order as ALSA.
-rw-r--r--NEWS2
-rw-r--r--src/output/plugins/OssOutputPlugin.cxx65
2 files changed, 17 insertions, 50 deletions
diff --git a/NEWS b/NEWS
index f42c8545a..a56c573e9 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,8 @@ ver 0.22.10 (not yet released)
- tidal: remove defunct unmaintained plugin
* tags
- fix crash caused by bug in TagBuilder and a few potential reference leaks
+* output
+ - oss: fix channel order of multi-channel files
ver 0.22.9 (2021/06/23)
* database
diff --git a/src/output/plugins/OssOutputPlugin.cxx b/src/output/plugins/OssOutputPlugin.cxx
index 13dbcbcbe..5598140b4 100644
--- a/src/output/plugins/OssOutputPlugin.cxx
+++ b/src/output/plugins/OssOutputPlugin.cxx
@@ -20,11 +20,13 @@
#include "OssOutputPlugin.hxx"
#include "../OutputAPI.hxx"
#include "mixer/MixerList.hxx"
+#include "pcm/Export.hxx"
#include "io/UniqueFileDescriptor.hxx"
#include "system/Error.hxx"
#include "util/ConstBuffer.hxx"
#include "util/Domain.hxx"
#include "util/ByteOrder.hxx"
+#include "util/Manual.hxx"
#include "Log.hxx"
#include <cassert>
@@ -53,15 +55,8 @@
#undef AFMT_S24_NE
#endif
-#ifdef AFMT_S24_PACKED
-#include "pcm/Export.hxx"
-#include "util/Manual.hxx"
-#endif
-
class OssOutput final : AudioOutput {
-#ifdef AFMT_S24_PACKED
Manual<PcmExport> pcm_export;
-#endif
FileDescriptor fd = FileDescriptor::Undefined();
const char *device;
@@ -78,11 +73,7 @@ class OssOutput final : AudioOutput {
*/
int oss_format;
-#ifdef AFMT_S24_PACKED
static constexpr unsigned oss_flags = FLAG_ENABLE_DISABLE;
-#else
- static constexpr unsigned oss_flags = 0;
-#endif
public:
explicit OssOutput(const char *_device=nullptr)
@@ -92,7 +83,6 @@ public:
static AudioOutput *Create(EventLoop &event_loop,
const ConfigBlock &block);
-#ifdef AFMT_S24_PACKED
void Enable() override {
pcm_export.Construct();
}
@@ -100,7 +90,6 @@ public:
void Disable() noexcept override {
pcm_export.Destruct();
}
-#endif
void Open(AudioFormat &audio_format) override;
@@ -428,11 +417,8 @@ sample_format_from_oss(int format) noexcept
static bool
oss_probe_sample_format(FileDescriptor fd, SampleFormat sample_format,
SampleFormat *sample_format_r,
- int *oss_format_r
-#ifdef AFMT_S24_PACKED
- , PcmExport &pcm_export
-#endif
- )
+ int *oss_format_r,
+ PcmExport &pcm_export)
{
int oss_format = sample_format_to_oss(sample_format);
if (oss_format == AFMT_QUERY)
@@ -464,15 +450,15 @@ oss_probe_sample_format(FileDescriptor fd, SampleFormat sample_format,
*sample_format_r = sample_format;
*oss_format_r = oss_format;
-#ifdef AFMT_S24_PACKED
PcmExport::Params params;
params.alsa_channel_order = true;
+#ifdef AFMT_S24_PACKED
params.pack24 = oss_format == AFMT_S24_PACKED;
params.reverse_endian = oss_format == AFMT_S24_PACKED &&
!IsLittleEndian();
+#endif
pcm_export.Open(sample_format, 0, params);
-#endif
return true;
}
@@ -483,19 +469,13 @@ oss_probe_sample_format(FileDescriptor fd, SampleFormat sample_format,
*/
static void
oss_setup_sample_format(FileDescriptor fd, AudioFormat &audio_format,
- int *oss_format_r
-#ifdef AFMT_S24_PACKED
- , PcmExport &pcm_export
-#endif
- )
+ int *oss_format_r,
+ PcmExport &pcm_export)
{
SampleFormat mpd_format;
if (oss_probe_sample_format(fd, audio_format.format,
- &mpd_format, oss_format_r
-#ifdef AFMT_S24_PACKED
- , pcm_export
-#endif
- )) {
+ &mpd_format, oss_format_r,
+ pcm_export)) {
audio_format.format = mpd_format;
return;
}
@@ -518,11 +498,8 @@ oss_setup_sample_format(FileDescriptor fd, AudioFormat &audio_format,
continue;
if (oss_probe_sample_format(fd, mpd_format,
- &mpd_format, oss_format_r
-#ifdef AFMT_S24_PACKED
- , pcm_export
-#endif
- )) {
+ &mpd_format, oss_format_r,
+ pcm_export)) {
audio_format.format = mpd_format;
return;
}
@@ -536,11 +513,7 @@ OssOutput::Setup(AudioFormat &_audio_format)
{
oss_setup_channels(fd, _audio_format);
oss_setup_sample_rate(fd, _audio_format);
- oss_setup_sample_format(fd, _audio_format, &oss_format
-#ifdef AFMT_S24_PACKED
- , pcm_export
-#endif
- );
+ oss_setup_sample_format(fd, _audio_format, &oss_format, pcm_export);
}
/**
@@ -595,9 +568,7 @@ OssOutput::Cancel() noexcept
DoClose();
}
-#ifdef AFMT_S24_PACKED
pcm_export->Reset();
-#endif
}
size_t
@@ -611,23 +582,17 @@ OssOutput::Play(const void *chunk, size_t size)
if (!fd.IsDefined())
Reopen();
-#ifdef AFMT_S24_PACKED
const auto e = pcm_export->Export({chunk, size});
if (e.empty())
return size;
chunk = e.data;
size = e.size;
-#endif
while (true) {
ret = fd.Write(chunk, size);
- if (ret > 0) {
-#ifdef AFMT_S24_PACKED
- ret = pcm_export->CalcInputSize(ret);
-#endif
- return ret;
- }
+ if (ret > 0)
+ return pcm_export->CalcInputSize(ret);
if (ret < 0 && errno != EINTR)
throw FormatErrno("Write error on %s", device);