10#include <private/qplatformmediaintegration_p.h>
12#include <QtCore/qjniobject.h>
16Q_DECLARE_JNI_CLASS(QtAudioDeviceManager,
17 "org/qtproject/qt/android/multimedia/QtAudioDeviceManager");
20using namespace QtJniTypes;
24QAudioFormat preferredFormatForDevice(
const QtJniTypes::AudioDeviceInfo &deviceInfo)
26 QAudioFormat preferredFormat;
29 QJniArray<jint> channelCounts = deviceInfo.callMethod<QJniArray<jint>>(
"getChannelCounts");
30 if (channelCounts.isEmpty()) {
31 preferredFormat.setChannelCount(2);
33 const auto [minIt, maxIt] = std::minmax_element(channelCounts.begin(), channelCounts.end());
34 preferredFormat.setChannelCount(std::clamp(2, *minIt, *maxIt));
38 preferredFormat.setSampleRate(
39 QtAudioDeviceManager::callStaticMethod<jint>(
"getDefaultSampleRate"));
43 preferredFormat.setSampleFormat(QAudioFormat::Float);
45 return preferredFormat;
48QList<QAudioDevice> availableDevices(QAudioDevice::Mode mode)
50 if (mode == QAudioDevice::Null)
53 QList<QAudioDevice> devices;
54 const char *getMethod =
55 mode == QAudioDevice::Input ?
"getAudioInputDevices" :
"getAudioOutputDevices";
57 QtAudioDeviceManager::callStaticMethod<QJniArray<AudioDeviceInfo>>(getMethod);
59 if (!deviceInfos.isValid())
62 for (
int i = 0; i < deviceInfos.size(); ++i) {
63 AudioDeviceInfo deviceInfo = deviceInfos.at(i);
64 int id = deviceInfo.callMethod<jint>(
"getId");
65 jint deviceType = deviceInfo.callMethod<jint>(
"getType");
66 auto description = QtAudioDeviceManager::callStaticMethod<QString>(
67 "audioDeviceTypeToString", deviceType);
68 bool isBluetoothDevice =
69 QtAudioDeviceManager::callStaticMethod<jboolean>(
"isBluetoothDevice", deviceInfo);
70 devices << QAudioDevicePrivate::createQAudioDevice(std::make_unique<QAndroidAudioDevice>(
71 QString::number(id).toUtf8(), description, mode,
72 preferredFormatForDevice(deviceInfo), isBluetoothDevice, i == 0));
80QAndroidAudioDevices::QAndroidAudioDevices() : QPlatformAudioDevices()
82 QtAudioDeviceManager::callStaticMethod<
void>(
"registerAudioHeadsetStateReceiver");
85QAndroidAudioDevices::~QAndroidAudioDevices()
90 QtAudioDeviceManager::callStaticMethod<
void>(
"unregisterAudioHeadsetStateReceiver");
93QList<QAudioDevice> QAndroidAudioDevices::findAudioInputs()
const
95 return availableDevices(QAudioDevice::Input);
98QList<QAudioDevice> QAndroidAudioDevices::findAudioOutputs()
const
100 return availableDevices(QAudioDevice::Output);
103QPlatformAudioSource *QAndroidAudioDevices::createAudioSource(
const QAudioDevice &deviceInfo,
104 const QAudioFormat &fmt,
107 return new QtAAudio::QAndroidAudioSource(deviceInfo, fmt, parent);
110QPlatformAudioSink *QAndroidAudioDevices::createAudioSink(
const QAudioDevice &deviceInfo,
111 const QAudioFormat &fmt, QObject *parent)
113 return new QtAAudio::QAndroidAudioSink(deviceInfo, fmt, parent);
118 static_cast<QAndroidAudioDevices *>(QPlatformMediaIntegration::instance()->audioDevices())
119 ->onAudioInputsChanged();
124 static_cast<QAndroidAudioDevices *>(QPlatformMediaIntegration::instance()->audioDevices())
125 ->onAudioOutputsChanged();
128Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm,
void * )
130 static bool initialized =
false;
132 return JNI_VERSION_1_6;
137 JNIEnv *nativeEnvironment;
141 UnionJNIEnvToVoid uenv;
144 if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_6) != JNI_OK)
147 const auto context = QNativeInterface::QAndroidApplication::context();
148 QtAudioDeviceManager::callStaticMethod<
void>(
"setContext", context);
150 const JNINativeMethod methods[] = {
151 {
"onAudioInputDevicesUpdated",
"()V", (
void *)onAudioInputDevicesUpdated },
152 {
"onAudioOutputDevicesUpdated",
"()V", (
void *)onAudioOutputDevicesUpdated }
155 bool registered = QJniEnvironment().registerNativeMethods(
156 "org/qtproject/qt/android/multimedia/QtAudioDeviceManager", methods,
162 return JNI_VERSION_1_6;
static void onAudioInputDevicesUpdated(JNIEnv *, jobject)
static void onAudioOutputDevicesUpdated(JNIEnv *, jobject)
Q_DECLARE_JNI_CLASS(MotionEvent, "android/view/MotionEvent")