audacious-media-player / audacious

A lightweight and versatile audio player
https://audacious-media-player.org
Other
812 stars 108 forks source link

CoreAudio does not work on Big-endian: outputs only hiss #1440

Open barracuda156 opened 1 month ago

barracuda156 commented 1 month ago

Describe the bug Choosing CoreAudio sound output on powerpc, I only get hiss, no music. SDL output works normally.

Steps to reproduce Build and try to use CoreAudio output on Darwin ppc.

Expected behavior CoreAudio is supported in 10.5–10.6, so it should be certainly possible to make it work correctly.

Additional information

P. S. I had to comment out a chunk using blocks, since it does not build with gcc, but I do not think it is relevant to the issue. For the record though:

--- src/coreaudio/coreaudio.cc
+++ src/coreaudio/coreaudio.cc
@@ -306,6 +306,7 @@ void CoreAudioPlugin::handle_new_default_device(AudioObjectID newID)
     output_instance = nullptr;

     init();
+#ifdef __clang__
     if (currentPosition > 0 && currentTime > 0)
     {
         dispatch_block_t restart_playback = ^{
@@ -331,6 +332,7 @@ void CoreAudioPlugin::handle_new_default_device(AudioObjectID newID)
             restart_playback();
         }
     }
+#endif
 }

 void CoreAudioPlugin::cleanup ()

@RJVB If you could help with this, would be great. I think endianness is assumed wrong somewhere. Could be a trivial fix, we just need to know where it goes wrong. I do not know whether block stuff can have a compat fallback. In the worst case conditional disabling is fine, IMO.

radioactiveman commented 1 month ago

Please try my Meson patches from https://github.com/audacious-media-player/audacious-plugins/pull/166.

I guess on your Big-endian system the wrong defines are used in audio.h.in. Check the generated header {build dir}/libaudcore/audio.h.

barracuda156 commented 1 month ago

@radioactiveman Sorry for a delay, will try now.

barracuda156 commented 1 month ago

This is the contents of a generated audio.h for audacious-core without any patches:

/*
 * audio.h
 * Copyright 2009-2013 John Lindgren
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions, and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions, and the following disclaimer in the documentation
 *    provided with the distribution.
 *
 * This software is provided "as is" and without any warranty, express or
 * implied. In no event shall the authors be liable for any damages arising from
 * the use of this software.
 */

#ifndef LIBAUDCORE_AUDIO_H
#define LIBAUDCORE_AUDIO_H

#define AUD_MAX_CHANNELS 10

enum {
 FMT_FLOAT,
 FMT_S8, FMT_U8,
 FMT_S16_LE, FMT_S16_BE, FMT_U16_LE, FMT_U16_BE,
 FMT_S24_LE, FMT_S24_BE, FMT_U24_LE, FMT_U24_BE, /* padded to 4 bytes */
 FMT_S32_LE, FMT_S32_BE, FMT_U32_LE, FMT_U32_BE,
 FMT_S24_3LE, FMT_S24_3BE, FMT_U24_3LE, FMT_U24_3BE }; /* packed in 3 bytes */

struct ReplayGainInfo {
    float track_gain; /* dB */
    float track_peak; /* 0-1 */
    float album_gain; /* dB */
    float album_peak; /* 0-1 */
};

struct StereoVolume {
    int left, right;
};

#ifdef WANT_AUD_BSWAP

#include <stdint.h>

#undef bswap16
#undef bswap32
#undef bswap64

/* GCC will optimize these to appropriate bswap instructions */
constexpr uint16_t bswap16 (uint16_t x)
    { return ((x & 0xff00) >> 8) | ((x & 0x00ff) << 8); }

constexpr uint32_t bswap32 (uint32_t x)
{
    return ((x & 0xff000000) >> 24) | ((x & 0x00ff0000) >> 8) |
           ((x & 0x0000ff00) << 8) | ((x & 0x000000ff) << 24);
}

constexpr uint64_t bswap64 (uint64_t x)
{
    return ((x & 0xff00000000000000) >> 56) | ((x & 0x00ff000000000000) >> 40) |
           ((x & 0x0000ff0000000000) >> 24) | ((x & 0x000000ff00000000) >> 8) |
           ((x & 0x00000000ff000000) << 8) | ((x & 0x0000000000ff0000) << 24) |
           ((x & 0x000000000000ff00) << 40) | ((x & 0x00000000000000ff) << 56);
}

#endif // WANT_AUD_BSWAP

#if 1

#define FMT_S16_NE FMT_S16_BE
#define FMT_U16_NE FMT_U16_BE
#define FMT_S24_NE FMT_S24_BE
#define FMT_U24_NE FMT_U24_BE
#define FMT_S32_NE FMT_S32_BE
#define FMT_U32_NE FMT_U32_BE
#define FMT_S24_3NE FMT_S24_3BE
#define FMT_U24_3NE FMT_U24_3BE

#ifdef WANT_AUD_BSWAP
#define FROM_BE16(x) (x)
#define FROM_BE32(x) (x)
#define FROM_BE64(x) (x)
#define FROM_LE16(x) (bswap16 (x))
#define FROM_LE32(x) (bswap32 (x))
#define FROM_LE64(x) (bswap64 (x))
#define TO_BE16(x) (x)
#define TO_BE32(x) (x)
#define TO_BE64(x) (x)
#define TO_LE16(x) (bswap16 (x))
#define TO_LE32(x) (bswap32 (x))
#define TO_LE64(x) (bswap64 (x))
#endif

#else  // ! BIGENDIAN

#define FMT_S16_NE FMT_S16_LE
#define FMT_U16_NE FMT_U16_LE
#define FMT_S24_NE FMT_S24_LE
#define FMT_U24_NE FMT_U24_LE
#define FMT_S32_NE FMT_S32_LE
#define FMT_U32_NE FMT_U32_LE
#define FMT_S24_3NE FMT_S24_3LE
#define FMT_U24_3NE FMT_U24_3LE

#ifdef WANT_AUD_BSWAP
#define FROM_BE16(x) (bswap16 (x))
#define FROM_BE32(x) (bswap32 (x))
#define FROM_BE64(x) (bswap64 (x))
#define FROM_LE16(x) (x)
#define FROM_LE32(x) (x)
#define FROM_LE64(x) (x)
#define TO_BE16(x) (bswap16 (x))
#define TO_BE32(x) (bswap32 (x))
#define TO_BE64(x) (bswap64 (x))
#define TO_LE16(x) (x)
#define TO_LE32(x) (x)
#define TO_LE64(x) (x)
#endif

#endif

#define FMT_SIZEOF(f) (((f) >= FMT_S24_3LE) ? 3 : \
                       ((f) >= FMT_S24_LE) ? 4 : \
                       ((f) >= FMT_S16_LE) ? 2 : \
                       ((f) >= FMT_S8) ? 1 : sizeof (float))

void audio_interlace (const void * const * in, int format, int channels, void * out, int frames);
void audio_deinterlace (const void * in, int format, int channels, void * const * out, int frames);
void audio_from_int (const void * in, int format, float * out, int samples);
void audio_to_int (const float * in, void * out, int format, int samples);
void audio_amplify (float * data, int channels, int frames, const float * factors);
void audio_amplify (float * data, int channels, int frames, StereoVolume volume);
void audio_soft_clip (float * data, int samples);

#endif /* LIBAUDCORE_AUDIO_H */
barracuda156 commented 1 month ago

I.e. identical with the one when patch from https://github.com/audacious-media-player/audacious-plugins/pull/166#issuecomment-2256165238 is applied, at least on my 10.6 with the compiler used (my concern was that not every compiler/OS may define identical macros), I diffed the two.

barracuda156 commented 1 month ago

@radioactiveman audacious-plugins do not have that folder, so I dunno where to look for audio.h.

barracuda156 commented 1 month ago

@radioactiveman Unfortunately, no change with your patch to audacious-plugins. BTW, upon switching to coreaudio output, I get this in the terminal:

WARNING ../audacious-plugins-4.4/src/coreaudio/coreaudio.cc:270 [set_device_samplerate]: Preparing the "Built-in Audio" for bit perfect output (this can take a moment)
ERROR ../audacious-plugins-4.4/src/coreaudio/audiodevice.mm:257 [Init]: Couldn't register property listener for selected default device: 560227702 (!dev)
2024-07-31 16:59:13.717 audacious[25269:10b] Using audio device 260 "Built-in Audio", 6 sample rates in 6 range(s); [32000,96000] (
    32000,
    44100,
    48000,
    64000,
    88200,
    96000
); current sample rate 44100Hz
WARNING ../audacious-plugins-4.4/src/coreaudio/coreaudio.cc:478 [open_audio]: Failed to open device for exclusive mode, continuing anyway... [2003332927]