mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-01 20:18:15 +01:00
An Android 11 TV played nothing over a Bluetooth headset since the switch to Oboe, while its speakers worked. Testing on it showed AAudio with MMAP is silent there and AAudio without MMAP works, as does OpenSL ES (also when the headset is connected mid-game), whatever the stream usage. MMAP should never be used for a Bluetooth route, so it's a firmware bug. Audio settings get an Audio API choice and a Low-latency audio (MMAP) checkbox, with hints, so other devices with the same kind of bug can be worked around. The API defaults to OpenSL ES on TVs and before Android 8.1, where the choice isn't offered, and AAudio elsewhere. Changing them reopens the streams right away. System Information shows the output stream that got opened (API, MMAP or not, rate, buffers, device) and any audio error. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
52 lines
2.0 KiB
C++
52 lines
2.0 KiB
C++
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <mutex>
|
|
|
|
typedef void (*AndroidAudioCallback)(short *buffer, int numSamples, int sampleRateHz, void *userdata);
|
|
|
|
class AudioContext {
|
|
public:
|
|
AudioContext(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleRate);
|
|
virtual bool Init() { return false; }
|
|
virtual bool AudioRecord_Start(int sampleRate) { return false; };
|
|
virtual bool AudioRecord_Stop() { return false; };
|
|
|
|
int SampleRate() const { return sampleRate; }
|
|
|
|
virtual ~AudioContext() {}
|
|
|
|
protected:
|
|
static void SetErrorString(const std::string &error);
|
|
static void SetInfoString(const std::string &info);
|
|
AndroidAudioCallback audioCallback;
|
|
|
|
int framesPerBuffer;
|
|
int sampleRate;
|
|
std::mutex errorMutex_;
|
|
};
|
|
|
|
struct AndroidAudioState;
|
|
|
|
// TODO: Get rid of this unnecessary wrapper layer from the old .so days
|
|
|
|
// It's okay for optimalFramesPerBuffer and optimalSampleRate to be 0. Defaults will be used.
|
|
AndroidAudioState *AndroidAudio_Init(AndroidAudioCallback cb, int optimalFramesPerBuffer, int optimalSampleRate);
|
|
bool AndroidAudio_Recording_SetSampleRate(AndroidAudioState *state, int sampleRate);
|
|
bool AndroidAudio_Recording_Start(AndroidAudioState *state);
|
|
bool AndroidAudio_Recording_Stop(AndroidAudioState *state);
|
|
// Microphone input is buffered: the input stream pushes it, and AndroidAudio_Recording_Poll hands it
|
|
// over to Microphone::addAudioData. Poll and Clear are for the CPU thread.
|
|
void AndroidAudio_Recording_Push(const int16_t *samples, int count);
|
|
void AndroidAudio_Recording_Poll();
|
|
void AndroidAudio_Recording_Clear();
|
|
bool AndroidAudio_Pause(AndroidAudioState *state);
|
|
bool AndroidAudio_Resume(AndroidAudioState *state);
|
|
// Closes the streams and opens them again, to apply changed settings.
|
|
bool AndroidAudio_Restart(AndroidAudioState *state);
|
|
bool AndroidAudio_Shutdown(AndroidAudioState *state);
|
|
const std::string AndroidAudio_GetErrorString(AndroidAudioState *state);
|
|
// Describes the output stream that's open.
|
|
const std::string AndroidAudio_GetInfoString(AndroidAudioState *state);
|