Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qandroidaudiosource.cpp
Go to the documentation of this file.
1
// Copyright (C) 2021 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4
#
include
<
QtMultimedia
/
private
/
qandroidaudiosource_p
.
h
>
5
6
#
include
<
QtCore
/
qcoreapplication
.
h
>
7
#
include
<
QtCore
/
qpermissions
.
h
>
8
9
#
include
<
QtMultimedia
/
private
/
qandroidaudiojnitypes_p
.
h
>
10
#
include
<
QtMultimedia
/
private
/
qandroidaudioutil_p
.
h
>
11
12
QT_BEGIN_NAMESPACE
13
14
namespace
QtAAudio
{
15
16
Q_STATIC_LOGGING_CATEGORY(
qLcAndroidAudioSource
,
"qt.multimedia.android.audiosource"
)
17
18
QAndroidAudioSourceStream
::
QAndroidAudioSourceStream
(
QAudioDevice
device
,
19
const
QAudioFormat
&
format
,
20
std
::
optional
<
int
>
ringbufferSize
,
21
QAndroidAudioSource
*
parent
,
float
volume
,
22
std
::
optional
<
int32_t
>
hardwareBufferFrames
)
23
:
QtMultimediaPrivate
::
QPlatformAudioSourceStream
(
std
::
move
(
device
),
format
,
ringbufferSize
,
24
hardwareBufferFrames
,
volume
),
25
m_parent
(
parent
)
26
{
27
QtAAudio
::
StreamBuilder
builder
(
format
);
28
29
qCDebug
(
qLcAndroidAudioSource
) <<
"Creating source for device id:"
<<
m_audioDevice
.
id
()
30
<<
", description:"
<<
m_audioDevice
.
description
();
31
32
builder
.
deviceId
=
m_audioDevice
.
id
().
toInt
();
33
34
// Set buffer parameters
35
builder
.
bufferCapacity
=
m_hardwareBufferFrames
? *
m_hardwareBufferFrames
: 1024;
36
37
// NOTE: AAudio doesn't support UINT8, so convert to INT16 if that's requested
38
if
(
format
.
sampleFormat
() ==
QAudioFormat
::
UInt8
)
39
m_nativeSampleFormat
=
NativeSampleFormat
::
int16_t
;
40
41
// Set builder parameters for audio source
42
builder
.
params
.
sharingMode
=
AAUDIO_SHARING_MODE_SHARED
;
43
builder
.
params
.
direction
=
AAUDIO_DIRECTION_INPUT
;
44
45
// TODO: Set input preset based on device
46
47
builder
.
userData
=
this
;
48
builder
.
callback
= [](
AAudioStream
*,
void
*
userData
,
void
*
audioData
,
49
int32_t
numFrames
) ->
int
{
50
auto
*
stream
=
reinterpret_cast
<
QAndroidAudioSourceStream
*>(
userData
);
51
Q_ASSERT
(
stream
);
52
return
stream
->
process
(
audioData
,
numFrames
);
53
};
54
builder
.
errorCallback
= [](
AAudioStream
*,
void
*
userData
,
aaudio_result_t
error
) ->
void
{
55
auto
*
stream
=
reinterpret_cast
<
QAndroidAudioSourceStream
*>(
userData
);
56
Q_ASSERT
(
stream
);
57
stream
->
handleError
(
error
);
58
};
59
60
builder
.
setupBuilder
();
61
62
if
(!
QtJniTypes
::
QtAudioDeviceManager
::
callStaticMethod
<
jboolean
>(
"prepareAudioInput"
,
63
m_audioDevice
.
id
().
toInt
()))
64
qCWarning
(
qLcAndroidAudioSource
) <<
"Preparation failed for device:"
<<
m_audioDevice
.
id
().
toInt
();
65
66
m_stream
=
std
::
make_unique
<
QtAAudio
::
Stream
>(
builder
);
67
}
68
69
QAndroidAudioSourceStream
::~
QAndroidAudioSourceStream
()
70
{
71
QtJniTypes
::
QtAudioDeviceManager
::
callStaticMethod
<
void
>(
"releaseAudioDevice"
,
72
m_audioDevice
.
id
().
toInt
());
73
}
74
75
bool
QAndroidAudioSourceStream
::
open
()
76
{
77
QMicrophonePermission
permission
;
78
79
const
bool
permitted
=
qApp
->
checkPermission
(
permission
) ==
Qt
::
PermissionStatus
::
Granted
;
80
if
(!
permitted
) {
81
qWarning
(
"Missing microphone permission!"
);
82
requestStop
();
83
return
false
;
84
}
85
86
if
(!
m_stream
->
isOpen
()) {
87
qCWarning
(
qLcAndroidAudioSource
) <<
"Stream null"
;
88
requestStop
();
89
return
false
;
90
}
91
92
if
(!
m_stream
->
areStreamParametersRespected
())
93
qCWarning
(
qLcAndroidAudioSource
) <<
"Stream parameters not correct"
;
94
95
return
true
;
96
}
97
98
bool
QAndroidAudioSourceStream
::
start
(
QIODevice
*
device
)
99
{
100
Q_ASSERT
(
thread
()->
isCurrentThread
());
101
setQIODevice
(
device
);
102
createQIODeviceConnections
(
device
);
103
104
if
(!
m_stream
->
start
()) {
105
requestStop
();
106
return
false
;
107
}
108
109
return
true
;
110
}
111
112
QIODevice
*
QAndroidAudioSourceStream
::
start
()
113
{
114
auto
*
device
=
createRingbufferReaderDevice
();
115
return
start
(
device
) ?
device
:
nullptr
;
116
}
117
118
void
QAndroidAudioSourceStream
::
suspend
()
119
{
120
Q_ASSERT
(
thread
()->
isCurrentThread
());
121
m_stream
->
stop
();
122
}
123
124
void
QAndroidAudioSourceStream
::
resume
()
125
{
126
Q_ASSERT
(
thread
()->
isCurrentThread
());
127
m_stream
->
start
();
128
}
129
130
void
QAndroidAudioSourceStream
::
stop
(
ShutdownPolicy
policy
)
131
{
132
Q_ASSERT
(
thread
()->
isCurrentThread
());
133
requestStop
();
134
135
m_stream
->
stop
();
136
137
disconnectQIODeviceConnections
();
138
finalizeQIODevice
(
policy
);
139
140
if
(
policy
==
ShutdownPolicy
::
DiscardRingbuffer
)
141
emptyRingbuffer
();
142
}
143
144
void
QAndroidAudioSourceStream
::
updateStreamIdle
(
bool
idle
)
145
{
146
if
(
m_parent
)
147
m_parent
->
updateStreamIdle
(
idle
);
148
}
149
150
aaudio_data_callback_result_t
151
QAndroidAudioSourceStream
::
process
(
void
*
audioData
,
int
numFrames
)
noexcept
QT_MM_NONBLOCKING
152
{
153
qsizetype
bytesForFrames
=
m_nativeSampleFormat
154
? (
QAudioHelperInternal
::
bytesPerSample
(*
m_nativeSampleFormat
) *
m_format
.
channelCount
()
155
*
numFrames
)
156
:
m_format
.
bytesForFrames
(
numFrames
);
157
QSpan
<
std
::
byte
>
audioSpan
{
reinterpret_cast
<
std
::
byte
*>(
audioData
),
bytesForFrames
};
158
159
auto
framesWritten
=
160
QPlatformAudioSourceStream
::
process
(
audioSpan
,
numFrames
,
m_nativeSampleFormat
);
161
162
if
(
framesWritten
!=
static_cast
<
uint64_t
>(
numFrames
) &&
isStopRequested
())
163
return
AAUDIO_CALLBACK_RESULT_STOP
;
164
165
return
AAUDIO_CALLBACK_RESULT_CONTINUE
;
166
}
167
168
void
QAndroidAudioSourceStream
::
handleError
(
aaudio_result_t
)
169
{
170
// Handle as IO error which closes the stream
171
requestStop
();
172
invokeOnAppThread
([
this
] {
173
// clang-format off
174
handleIOError
(
m_parent
);
175
// clang-format on
176
});
177
}
178
179
QAndroidAudioSource
::
QAndroidAudioSource
(
QAudioDevice
device
,
const
QAudioFormat
&
format
,
180
QObject
*
parent
)
181
:
BaseClass
(
std
::
move
(
device
),
format
,
parent
)
182
{
183
}
184
185
}
// namespace QtAAudio
186
187
QT_END_NAMESPACE
QtAAudio
Definition
qaaudiostream.cpp:58
qtmultimedia
src
multimedia
android
qandroidaudiosource.cpp
Generated on
for Qt by
1.14.0