1 /*
2  * Copyright (C) 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 <base/logging.h>
23 #include <media/AudioTrack.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 { android::sp<android::AudioTrack> track; } BtifAvrcpAudioTrack;
32 
33 #if (DUMP_PCM_DATA == TRUE)
34 FILE* outputPcmSampleFile;
35 char outputFilename[50] = "/data/misc/bluedroid/output_sample.pcm";
36 #endif
37 
BtifAvrcpAudioTrackCreate(int trackFreq,int channelType)38 void* BtifAvrcpAudioTrackCreate(int trackFreq, int channelType) {
39   LOG_VERBOSE(LOG_TAG, "%s Track.cpp: btCreateTrack freq %d  channel %d ",
40               __func__, trackFreq, channelType);
41   sp<android::AudioTrack> track = new android::AudioTrack(
42       AUDIO_STREAM_MUSIC, trackFreq, AUDIO_FORMAT_PCM_16_BIT, channelType,
43       (size_t)0 /*frameCount*/, (audio_output_flags_t)AUDIO_OUTPUT_FLAG_FAST,
44       NULL /*callback_t*/, NULL /*void* user*/, 0 /*notificationFrames*/,
45       AUDIO_SESSION_ALLOCATE, android::AudioTrack::TRANSFER_SYNC);
46   CHECK(track != NULL);
47 
48   BtifAvrcpAudioTrack* trackHolder = new BtifAvrcpAudioTrack;
49   CHECK(trackHolder != NULL);
50   trackHolder->track = track;
51 
52   if (trackHolder->track->initCheck() != 0) {
53     return nullptr;
54   }
55 
56 #if (DUMP_PCM_DATA == TRUE)
57   outputPcmSampleFile = fopen(outputFilename, "ab");
58 #endif
59   trackHolder->track->setVolume(1, 1);
60   return (void*)trackHolder;
61 }
62 
BtifAvrcpAudioTrackStart(void * handle)63 void BtifAvrcpAudioTrackStart(void* handle) {
64   if (handle == NULL) {
65     LOG_ERROR(LOG_TAG, "%s: handle is null!", __func__);
66     return;
67   }
68   BtifAvrcpAudioTrack* trackHolder = static_cast<BtifAvrcpAudioTrack*>(handle);
69   CHECK(trackHolder != NULL);
70   CHECK(trackHolder->track != NULL);
71   LOG_VERBOSE(LOG_TAG, "%s Track.cpp: btStartTrack", __func__);
72   trackHolder->track->start();
73 }
74 
BtifAvrcpAudioTrackStop(void * handle)75 void BtifAvrcpAudioTrackStop(void* handle) {
76   if (handle == NULL) {
77     LOG_DEBUG(LOG_TAG, "%s handle is null.", __func__);
78     return;
79   }
80   BtifAvrcpAudioTrack* trackHolder = static_cast<BtifAvrcpAudioTrack*>(handle);
81   if (trackHolder != NULL && trackHolder->track != NULL) {
82     LOG_VERBOSE(LOG_TAG, "%s Track.cpp: btStartTrack", __func__);
83     trackHolder->track->stop();
84   }
85 }
86 
BtifAvrcpAudioTrackDelete(void * handle)87 void BtifAvrcpAudioTrackDelete(void* handle) {
88   if (handle == NULL) {
89     LOG_DEBUG(LOG_TAG, "%s handle is null.", __func__);
90     return;
91   }
92   BtifAvrcpAudioTrack* trackHolder = static_cast<BtifAvrcpAudioTrack*>(handle);
93   if (trackHolder != NULL && trackHolder->track != NULL) {
94     LOG_VERBOSE(LOG_TAG, "%s Track.cpp: btStartTrack", __func__);
95     delete trackHolder;
96   }
97 
98 #if (DUMP_PCM_DATA == TRUE)
99   if (outputPcmSampleFile) {
100     fclose(outputPcmSampleFile);
101   }
102   outputPcmSampleFile = NULL;
103 #endif
104 }
105 
BtifAvrcpAudioTrackPause(void * handle)106 void BtifAvrcpAudioTrackPause(void* handle) {
107   if (handle == NULL) {
108     LOG_DEBUG(LOG_TAG, "%s handle is null.", __func__);
109     return;
110   }
111   BtifAvrcpAudioTrack* trackHolder = static_cast<BtifAvrcpAudioTrack*>(handle);
112   if (trackHolder != NULL && trackHolder->track != NULL) {
113     LOG_VERBOSE(LOG_TAG, "%s Track.cpp: btStartTrack", __func__);
114     trackHolder->track->pause();
115     trackHolder->track->flush();
116   }
117 }
118 
BtifAvrcpSetAudioTrackGain(void * handle,float gain)119 void BtifAvrcpSetAudioTrackGain(void* handle, float gain) {
120   if (handle == NULL) {
121     LOG_DEBUG(LOG_TAG, "%s handle is null.", __func__);
122     return;
123   }
124   BtifAvrcpAudioTrack* trackHolder = static_cast<BtifAvrcpAudioTrack*>(handle);
125   if (trackHolder != NULL && trackHolder->track != NULL) {
126     LOG_VERBOSE(LOG_TAG, "%s set gain %f", __func__, gain);
127     trackHolder->track->setVolume(gain);
128   }
129 }
130 
BtifAvrcpAudioTrackWriteData(void * handle,void * audioBuffer,int bufferlen)131 int BtifAvrcpAudioTrackWriteData(void* handle, void* audioBuffer,
132                                  int bufferlen) {
133   BtifAvrcpAudioTrack* trackHolder = static_cast<BtifAvrcpAudioTrack*>(handle);
134   CHECK(trackHolder != NULL);
135   CHECK(trackHolder->track != NULL);
136   int retval = -1;
137 #if (DUMP_PCM_DATA == TRUE)
138   if (outputPcmSampleFile) {
139     fwrite((audioBuffer), 1, (size_t)bufferlen, outputPcmSampleFile);
140   }
141 #endif
142   retval = trackHolder->track->write(audioBuffer, (size_t)bufferlen);
143   LOG_VERBOSE(LOG_TAG, "%s Track.cpp: btWriteData len = %d ret = %d", __func__,
144               bufferlen, retval);
145   return retval;
146 }
147