4#include <QtMultimedia/private/qandroidaudiodevices_p.h>
6#include <QtMultimedia/private/qandroidaudiodevice_p.h>
7#include <QtMultimedia/private/qandroidaudiojnitypes_p.h>
8#include <QtMultimedia/private/qandroidaudiosink_p.h>
9#include <QtMultimedia/private/qandroidaudiosource_p.h>
11#include <QtMultimedia/private/qplatformmediaintegration_p.h>
13#include <QtCore/qjniobject.h>
17using namespace QtJniTypes;
21QAudioFormat preferredFormatForDevice(
const QtJniTypes::AudioDeviceInfo &deviceInfo)
23 QAudioFormat preferredFormat;
26 QJniArray<jint> channelCounts = deviceInfo.callMethod<QJniArray<jint>>(
"getChannelCounts");
27 if (channelCounts.isEmpty()) {
28 preferredFormat.setChannelCount(2);
30 const auto [minIt, maxIt] = std::minmax_element(channelCounts.begin(), channelCounts.end());
31 preferredFormat.setChannelCount(std::clamp(2, *minIt, *maxIt));
35 preferredFormat.setSampleRate(
36 QtAudioDeviceManager::callStaticMethod<jint>(
"getDefaultSampleRate"));
40 preferredFormat.setSampleFormat(QAudioFormat::Float);
42 return preferredFormat;
45QList<QAudioDevice> availableDevices(QAudioDevice::Mode mode)
47 if (mode == QAudioDevice::Null)
50 QList<QAudioDevice> devices;
51 const char *getMethod =
52 mode == QAudioDevice::Input ?
"getAudioInputDevices" :
"getAudioOutputDevices";
54 QtAudioDeviceManager::callStaticMethod<QJniArray<AudioDeviceInfo>>(getMethod);
56 if (!deviceInfos.isValid())
59 for (
int i = 0; i < deviceInfos.size(); ++i) {
60 AudioDeviceInfo deviceInfo = deviceInfos.at(i);
61 int id = deviceInfo.callMethod<jint>(
"getId");
62 jint deviceType = deviceInfo.callMethod<jint>(
"getType");
63 auto description = QtAudioDeviceManager::callStaticMethod<QString>(
64 "audioDeviceTypeToString", deviceType);
65 bool isBluetoothDevice =
66 QtAudioDeviceManager::callStaticMethod<jboolean>(
"isBluetoothDevice", deviceInfo);
67 devices << QAudioDevicePrivate::createQAudioDevice(std::make_unique<QAndroidAudioDevice>(
68 QString::number(id).toUtf8(), description, mode,
69 preferredFormatForDevice(deviceInfo), isBluetoothDevice, i == 0));
77QAndroidAudioDevices::QAndroidAudioDevices() : QPlatformAudioDevices()
79 QtAudioDeviceManager::callStaticMethod<
void>(
"registerAudioHeadsetStateReceiver");
82QAndroidAudioDevices::~QAndroidAudioDevices()
87 QtAudioDeviceManager::callStaticMethod<
void>(
"unregisterAudioHeadsetStateReceiver");
90QList<QAudioDevice> QAndroidAudioDevices::findAudioInputs()
const
92 return availableDevices(QAudioDevice::Input);
95QList<QAudioDevice> QAndroidAudioDevices::findAudioOutputs()
const
97 return availableDevices(QAudioDevice::Output);
100QPlatformAudioSource *QAndroidAudioDevices::createAudioSource(
const QAudioDevice &deviceInfo,
101 const QAudioFormat &fmt,
104 return new QtAAudio::QAndroidAudioSource(deviceInfo, fmt, parent);
107QPlatformAudioSink *QAndroidAudioDevices::createAudioSink(
const QAudioDevice &deviceInfo,
108 const QAudioFormat &fmt, QObject *parent)
110 return new QtAAudio::QAndroidAudioSink(deviceInfo, fmt, parent);
115 static_cast<QAndroidAudioDevices *>(QPlatformMediaIntegration::instance()->audioDevices())
116 ->onAudioInputsChanged();
121 static_cast<QAndroidAudioDevices *>(QPlatformMediaIntegration::instance()->audioDevices())
122 ->onAudioOutputsChanged();
125Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm,
void * )
127 static bool initialized =
false;
129 return JNI_VERSION_1_6;
134 JNIEnv *nativeEnvironment;
138 UnionJNIEnvToVoid uenv;
141 if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_6) != JNI_OK)
144 const auto context = QNativeInterface::QAndroidApplication::context();
145 QtAudioDeviceManager::callStaticMethod<
void>(
"setContext", context);
147 const JNINativeMethod methods[] = {
148 {
"onAudioInputDevicesUpdated",
"()V", (
void *)onAudioInputDevicesUpdated },
149 {
"onAudioOutputDevicesUpdated",
"()V", (
void *)onAudioOutputDevicesUpdated }
152 bool registered = QJniEnvironment().registerNativeMethods(
153 "org/qtproject/qt/android/multimedia/QtAudioDeviceManager", methods,
159 return JNI_VERSION_1_6;
static void onAudioInputDevicesUpdated(JNIEnv *, jobject)
static void onAudioOutputDevicesUpdated(JNIEnv *, jobject)