1 /*
2 * Copyright 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "bt_btif_avrcp_audio_track"
19
20 #include "btif_avrcp_audio_track.h"
21
22 #include <aaudio/AAudio.h>
23 #include <base/logging.h>
24 #include <utils/StrongPointer.h>
25
26 #include "bt_target.h"
27 #include "osi/include/log.h"
28
29 using namespace android;
30
31 typedef struct {
32 AAudioStream* stream;
33 int bitsPerSample;
34 int channelCount;
35 float* buffer;
36 size_t bufferLength;
37 } BtifAvrcpAudioTrack;
38
39 #if (DUMP_PCM_DATA == TRUE)
40 FILE* outputPcmSampleFile;
41 char outputFilename[50] = "/data/misc/bluedroid/output_sample.pcm";
42 #endif
43
BtifAvrcpAudioTrackCreate(int trackFreq,int bitsPerSample,int channelCount)44 void* BtifAvrcpAudioTrackCreate(int trackFreq, int bitsPerSample,
45 int channelCount) {
46 LOG_VERBOSE("%s Track.cpp: btCreateTrack freq %d bps %d channel %d ",
47 __func__, trackFreq, bitsPerSample, channelCount);
48
49 AAudioStreamBuilder* builder;
50 AAudioStream* stream;
51 aaudio_result_t result = AAudio_createStreamBuilder(&builder);
52 AAudioStreamBuilder_setSampleRate(builder, trackFreq);
53 AAudioStreamBuilder_setFormat(builder, AAUDIO_FORMAT_PCM_FLOAT);
54 AAudioStreamBuilder_setChannelCount(builder, channelCount);
55 AAudioStreamBuilder_setSessionId(builder, AAUDIO_SESSION_ID_ALLOCATE);
56 AAudioStreamBuilder_setPerformanceMode(builder,
57 AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
58 result = AAudioStreamBuilder_openStream(builder, &stream);
59 CHECK(result == AAUDIO_OK);
60 AAudioStreamBuilder_delete(builder);
61
62 BtifAvrcpAudioTrack* trackHolder = new BtifAvrcpAudioTrack;
63 CHECK(trackHolder != NULL);
64 trackHolder->stream = stream;
65 trackHolder->bitsPerSample = bitsPerSample;
66 trackHolder->channelCount = channelCount;
67 trackHolder->bufferLength =
68 trackHolder->channelCount * AAudioStream_getBufferSizeInFrames(stream);
69 trackHolder->buffer = new float[trackHolder->bufferLength]();
70
71 #if (DUMP_PCM_DATA == TRUE)
72 outputPcmSampleFile = fopen(outputFilename, "ab");
73 #endif
74 return (void*)trackHolder;
75 }
76
BtifAvrcpAudioTrackStart(void * handle)77 void BtifAvrcpAudioTrackStart(void* handle) {
78 if (handle == NULL) {
79 LOG_ERROR("%s: handle is null!", __func__);
80 return;
81 }
82 BtifAvrcpAudioTrack* trackHolder = static_cast<BtifAvrcpAudioTrack*>(handle);
83 CHECK(trackHolder != NULL);
84 CHECK(trackHolder->stream != NULL);
85 LOG_VERBOSE("%s Track.cpp: btStartTrack", __func__);
86 AAudioStream_requestStart(trackHolder->stream);
87 }
88
BtifAvrcpAudioTrackStop(void * handle)89 void BtifAvrcpAudioTrackStop(void* handle) {
90 if (handle == NULL) {
91 LOG_DEBUG("%s handle is null.", __func__);
92 return;
93 }
94 BtifAvrcpAudioTrack* trackHolder = static_cast<BtifAvrcpAudioTrack*>(handle);
95 if (trackHolder != NULL && trackHolder->stream != NULL) {
96 LOG_VERBOSE("%s Track.cpp: btStartTrack", __func__);
97 AAudioStream_requestStop(trackHolder->stream);
98 }
99 }
100
BtifAvrcpAudioTrackDelete(void * handle)101 void BtifAvrcpAudioTrackDelete(void* handle) {
102 if (handle == NULL) {
103 LOG_DEBUG("%s handle is null.", __func__);
104 return;
105 }
106 BtifAvrcpAudioTrack* trackHolder = static_cast<BtifAvrcpAudioTrack*>(handle);
107 if (trackHolder != NULL && trackHolder->stream != NULL) {
108 LOG_VERBOSE("%s Track.cpp: btStartTrack", __func__);
109 AAudioStream_close(trackHolder->stream);
110 delete trackHolder->buffer;
111 delete trackHolder;
112 }
113
114 #if (DUMP_PCM_DATA == TRUE)
115 if (outputPcmSampleFile) {
116 fclose(outputPcmSampleFile);
117 }
118 outputPcmSampleFile = NULL;
119 #endif
120 }
121
BtifAvrcpAudioTrackPause(void * handle)122 void BtifAvrcpAudioTrackPause(void* handle) {
123 if (handle == NULL) {
124 LOG_DEBUG("%s handle is null.", __func__);
125 return;
126 }
127 BtifAvrcpAudioTrack* trackHolder = static_cast<BtifAvrcpAudioTrack*>(handle);
128 if (trackHolder != NULL && trackHolder->stream != NULL) {
129 LOG_VERBOSE("%s Track.cpp: btPauseTrack", __func__);
130 AAudioStream_requestPause(trackHolder->stream);
131 AAudioStream_requestFlush(trackHolder->stream);
132 }
133 }
134
BtifAvrcpSetAudioTrackGain(void * handle,float gain)135 void BtifAvrcpSetAudioTrackGain(void* handle, float gain) {
136 if (handle == NULL) {
137 LOG_DEBUG("%s handle is null.", __func__);
138 return;
139 }
140 // Does nothing right now
141 }
142
143 constexpr float kScaleQ15ToFloat = 1.0f / 32768.0f;
144 constexpr float kScaleQ23ToFloat = 1.0f / 8388608.0f;
145 constexpr float kScaleQ31ToFloat = 1.0f / 2147483648.0f;
146
sampleSizeFor(BtifAvrcpAudioTrack * trackHolder)147 static size_t sampleSizeFor(BtifAvrcpAudioTrack* trackHolder) {
148 return trackHolder->bitsPerSample / 8;
149 }
150
transcodeQ15ToFloat(uint8_t * buffer,size_t length,BtifAvrcpAudioTrack * trackHolder)151 static size_t transcodeQ15ToFloat(uint8_t* buffer, size_t length,
152 BtifAvrcpAudioTrack* trackHolder) {
153 size_t sampleSize = sampleSizeFor(trackHolder);
154 size_t i = 0;
155 for (; i <= length / sampleSize; i++) {
156 trackHolder->buffer[i] = ((int16_t*)buffer)[i] * kScaleQ15ToFloat;
157 }
158 return i * sampleSize;
159 }
160
transcodeQ23ToFloat(uint8_t * buffer,size_t length,BtifAvrcpAudioTrack * trackHolder)161 static size_t transcodeQ23ToFloat(uint8_t* buffer, size_t length,
162 BtifAvrcpAudioTrack* trackHolder) {
163 size_t sampleSize = sampleSizeFor(trackHolder);
164 size_t i = 0;
165 for (; i <= length / sampleSize; i++) {
166 size_t offset = i * sampleSize;
167 int32_t sample = *((int32_t*)(buffer + offset - 1)) & 0x00FFFFFF;
168 trackHolder->buffer[i] = sample * kScaleQ23ToFloat;
169 }
170 return i * sampleSize;
171 }
172
transcodeQ31ToFloat(uint8_t * buffer,size_t length,BtifAvrcpAudioTrack * trackHolder)173 static size_t transcodeQ31ToFloat(uint8_t* buffer, size_t length,
174 BtifAvrcpAudioTrack* trackHolder) {
175 size_t sampleSize = sampleSizeFor(trackHolder);
176 size_t i = 0;
177 for (; i <= length / sampleSize; i++) {
178 trackHolder->buffer[i] = ((int32_t*)buffer)[i] * kScaleQ31ToFloat;
179 }
180 return i * sampleSize;
181 }
182
transcodeToPcmFloat(uint8_t * buffer,size_t length,BtifAvrcpAudioTrack * trackHolder)183 static size_t transcodeToPcmFloat(uint8_t* buffer, size_t length,
184 BtifAvrcpAudioTrack* trackHolder) {
185 switch (trackHolder->bitsPerSample) {
186 case 16:
187 return transcodeQ15ToFloat(buffer, length, trackHolder);
188 case 24:
189 return transcodeQ23ToFloat(buffer, length, trackHolder);
190 case 32:
191 return transcodeQ31ToFloat(buffer, length, trackHolder);
192 }
193 return -1;
194 }
195
196 constexpr int64_t kTimeoutNanos = 100 * 1000 * 1000; // 100 ms
197
BtifAvrcpAudioTrackWriteData(void * handle,void * audioBuffer,int bufferLength)198 int BtifAvrcpAudioTrackWriteData(void* handle, void* audioBuffer,
199 int bufferLength) {
200 BtifAvrcpAudioTrack* trackHolder = static_cast<BtifAvrcpAudioTrack*>(handle);
201 CHECK(trackHolder != NULL);
202 CHECK(trackHolder->stream != NULL);
203 aaudio_result_t retval = -1;
204 #if (DUMP_PCM_DATA == TRUE)
205 if (outputPcmSampleFile) {
206 fwrite((audioBuffer), 1, (size_t)bufferLength, outputPcmSampleFile);
207 }
208 #endif
209
210 size_t sampleSize = sampleSizeFor(trackHolder);
211 int transcodedCount = 0;
212 do {
213 transcodedCount +=
214 transcodeToPcmFloat(((uint8_t*)audioBuffer) + transcodedCount,
215 bufferLength - transcodedCount, trackHolder);
216
217 retval = AAudioStream_write(
218 trackHolder->stream, trackHolder->buffer,
219 transcodedCount / (sampleSize * trackHolder->channelCount),
220 kTimeoutNanos);
221 LOG_VERBOSE("%s Track.cpp: btWriteData len = %d ret = %d", __func__,
222 bufferLength, retval);
223 } while (transcodedCount < bufferLength);
224
225 return transcodedCount;
226 }
227