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