Home | History | Annotate | Download | only in src
      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 
     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 
     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 
     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 
     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 
    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 
    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 
    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