Loading system/btif/Android.bp +2 −2 Original line number Diff line number Diff line Loading @@ -96,7 +96,7 @@ cc_library_static { "libmedia_headers", ], shared_libs: [ "libaudioclient", "libaaudio", "libcutils", "libfmq", "liblog", Loading Loading @@ -139,7 +139,7 @@ cc_test { ], header_libs: ["libbluetooth_headers"], shared_libs: [ "libaudioclient", "libaaudio", "android.hardware.bluetooth.a2dp@1.0", "android.hardware.bluetooth.audio@2.0", "libfmq", Loading system/btif/include/btif_avrcp_audio_track.h +3 −3 Original line number Diff line number Diff line Loading @@ -35,8 +35,8 @@ * should eventually be * deleted using BtifAvrcpAudioTrackDelete (see below). */ void* BtifAvrcpAudioTrackCreate(int trackFreq, int bits_per_sample, int channelType); void* BtifAvrcpAudioTrackCreate(int trackFreq, int bitsPerSample, int channelCount); /** * Starts the audio track. Loading Loading @@ -66,4 +66,4 @@ void BtifAvrcpAudioTrackDelete(void* handle); * Used only for debugging. */ int BtifAvrcpAudioTrackWriteData(void* handle, void* audioBuffer, int bufferlen); int bufferLength); system/btif/src/btif_a2dp_sink.cc +1 −1 Original line number Diff line number Diff line Loading @@ -595,7 +595,7 @@ static void btif_a2dp_sink_decoder_update_event( APPL_TRACE_DEBUG("%s: create audio track", __func__); btif_a2dp_sink_cb.audio_track = #ifndef OS_GENERIC BtifAvrcpAudioTrackCreate(sample_rate, bits_per_sample, channel_type); BtifAvrcpAudioTrackCreate(sample_rate, bits_per_sample, channel_count); #else NULL; #endif Loading system/btif/src/btif_avrcp_audio_track.cc +118 −53 Original line number Diff line number Diff line Loading @@ -19,8 +19,8 @@ #include "btif_avrcp_audio_track.h" #include <aaudio/AAudio.h> #include <base/logging.h> #include <media/AudioTrack.h> #include <utils/StrongPointer.h> #include "bt_target.h" Loading @@ -28,50 +28,49 @@ using namespace android; typedef struct { android::sp<android::AudioTrack> track; } BtifAvrcpAudioTrack; typedef struct { AAudioStream* stream; int bitsPerSample; int channelCount; float* buffer; size_t bufferLength; } BtifAvrcpAudioTrack; #if (DUMP_PCM_DATA == TRUE) FILE* outputPcmSampleFile; char outputFilename[50] = "/data/misc/bluedroid/output_sample.pcm"; #endif void* BtifAvrcpAudioTrackCreate(int trackFreq, int bits_per_sample, int channelType) { audio_format_t format; switch (bits_per_sample) { default: case 16: format = AUDIO_FORMAT_PCM_16_BIT; break; case 24: format = AUDIO_FORMAT_PCM_24_BIT_PACKED; break; case 32: format = AUDIO_FORMAT_PCM_32_BIT; break; } LOG_VERBOSE(LOG_TAG, "%s Track.cpp: btCreateTrack freq %d format 0x%x channel %d ", __func__, trackFreq, format, channelType); sp<android::AudioTrack> track = new android::AudioTrack( AUDIO_STREAM_MUSIC, trackFreq, format, channelType, (size_t)0 /*frameCount*/, (audio_output_flags_t)AUDIO_OUTPUT_FLAG_FAST, NULL /*callback_t*/, NULL /*void* user*/, 0 /*notificationFrames*/, AUDIO_SESSION_ALLOCATE, android::AudioTrack::TRANSFER_SYNC); CHECK(track != NULL); void* BtifAvrcpAudioTrackCreate(int trackFreq, int bitsPerSample, int channelCount) { LOG_VERBOSE(LOG_TAG, "%s Track.cpp: btCreateTrack freq %d bps %d channel %d ", __func__, trackFreq, bitsPerSample, channelCount); AAudioStreamBuilder* builder; AAudioStream* stream; aaudio_result_t result = AAudio_createStreamBuilder(&builder); AAudioStreamBuilder_setSampleRate(builder, trackFreq); AAudioStreamBuilder_setFormat(builder, AAUDIO_FORMAT_PCM_FLOAT); AAudioStreamBuilder_setChannelCount(builder, channelCount); AAudioStreamBuilder_setSessionId(builder, AAUDIO_SESSION_ID_ALLOCATE); AAudioStreamBuilder_setPerformanceMode(builder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY); result = AAudioStreamBuilder_openStream(builder, &stream); CHECK(result == AAUDIO_OK); AAudioStreamBuilder_delete(builder); BtifAvrcpAudioTrack* trackHolder = new BtifAvrcpAudioTrack; CHECK(trackHolder != NULL); trackHolder->track = track; if (trackHolder->track->initCheck() != 0) { return nullptr; } trackHolder->stream = stream; trackHolder->bitsPerSample = bitsPerSample; trackHolder->channelCount = channelCount; trackHolder->bufferLength = trackHolder->channelCount * AAudioStream_getBufferSizeInFrames(stream); trackHolder->buffer = new float[trackHolder->bufferLength](); #if (DUMP_PCM_DATA == TRUE) outputPcmSampleFile = fopen(outputFilename, "ab"); #endif trackHolder->track->setVolume(1, 1); return (void*)trackHolder; } Loading @@ -82,9 +81,9 @@ void BtifAvrcpAudioTrackStart(void* handle) { } BtifAvrcpAudioTrack* trackHolder = static_cast<BtifAvrcpAudioTrack*>(handle); CHECK(trackHolder != NULL); CHECK(trackHolder->track != NULL); CHECK(trackHolder->stream != NULL); LOG_VERBOSE(LOG_TAG, "%s Track.cpp: btStartTrack", __func__); trackHolder->track->start(); AAudioStream_requestStart(trackHolder->stream); } void BtifAvrcpAudioTrackStop(void* handle) { Loading @@ -93,9 +92,9 @@ void BtifAvrcpAudioTrackStop(void* handle) { return; } BtifAvrcpAudioTrack* trackHolder = static_cast<BtifAvrcpAudioTrack*>(handle); if (trackHolder != NULL && trackHolder->track != NULL) { if (trackHolder != NULL && trackHolder->stream != NULL) { LOG_VERBOSE(LOG_TAG, "%s Track.cpp: btStartTrack", __func__); trackHolder->track->stop(); AAudioStream_requestStop(trackHolder->stream); } } Loading @@ -105,8 +104,10 @@ void BtifAvrcpAudioTrackDelete(void* handle) { return; } BtifAvrcpAudioTrack* trackHolder = static_cast<BtifAvrcpAudioTrack*>(handle); if (trackHolder != NULL && trackHolder->track != NULL) { if (trackHolder != NULL && trackHolder->stream != NULL) { LOG_VERBOSE(LOG_TAG, "%s Track.cpp: btStartTrack", __func__); AAudioStream_close(trackHolder->stream); delete trackHolder->buffer; delete trackHolder; } Loading @@ -124,10 +125,10 @@ void BtifAvrcpAudioTrackPause(void* handle) { return; } BtifAvrcpAudioTrack* trackHolder = static_cast<BtifAvrcpAudioTrack*>(handle); if (trackHolder != NULL && trackHolder->track != NULL) { LOG_VERBOSE(LOG_TAG, "%s Track.cpp: btStartTrack", __func__); trackHolder->track->pause(); trackHolder->track->flush(); if (trackHolder != NULL && trackHolder->stream != NULL) { LOG_VERBOSE(LOG_TAG, "%s Track.cpp: btPauseTrack", __func__); AAudioStream_requestPause(trackHolder->stream); AAudioStream_requestFlush(trackHolder->stream); } } Loading @@ -136,26 +137,90 @@ void BtifAvrcpSetAudioTrackGain(void* handle, float gain) { LOG_DEBUG(LOG_TAG, "%s handle is null.", __func__); return; } BtifAvrcpAudioTrack* trackHolder = static_cast<BtifAvrcpAudioTrack*>(handle); if (trackHolder != NULL && trackHolder->track != NULL) { LOG_VERBOSE(LOG_TAG, "%s set gain %f", __func__, gain); trackHolder->track->setVolume(gain); // Does nothing right now } constexpr float kScaleQ15ToFloat = 1.0f / 32768.0f; constexpr float kScaleQ23ToFloat = 1.0f / 8388608.0f; constexpr float kScaleQ31ToFloat = 1.0f / 2147483648.0f; static size_t sampleSizeFor(BtifAvrcpAudioTrack* trackHolder) { return trackHolder->bitsPerSample / 8; } static size_t transcodeQ15ToFloat(uint8_t* buffer, size_t length, BtifAvrcpAudioTrack* trackHolder) { size_t sampleSize = sampleSizeFor(trackHolder); size_t i = 0; for (; i <= length / sampleSize; i++) { trackHolder->buffer[i] = ((int16_t*)buffer)[i] * kScaleQ15ToFloat; } return i * sampleSize; } static size_t transcodeQ23ToFloat(uint8_t* buffer, size_t length, BtifAvrcpAudioTrack* trackHolder) { size_t sampleSize = sampleSizeFor(trackHolder); size_t i = 0; for (; i <= length / sampleSize; i++) { size_t offset = i * sampleSize; int32_t sample = *((int32_t*)(buffer + offset - 1)) & 0x00FFFFFF; trackHolder->buffer[i] = sample * kScaleQ23ToFloat; } return i * sampleSize; } static size_t transcodeQ31ToFloat(uint8_t* buffer, size_t length, BtifAvrcpAudioTrack* trackHolder) { size_t sampleSize = sampleSizeFor(trackHolder); size_t i = 0; for (; i <= length / sampleSize; i++) { trackHolder->buffer[i] = ((int32_t*)buffer)[i] * kScaleQ31ToFloat; } return i * sampleSize; } static size_t transcodeToPcmFloat(uint8_t* buffer, size_t length, BtifAvrcpAudioTrack* trackHolder) { switch (trackHolder->bitsPerSample) { case 16: return transcodeQ15ToFloat(buffer, length, trackHolder); case 24: return transcodeQ23ToFloat(buffer, length, trackHolder); case 32: return transcodeQ31ToFloat(buffer, length, trackHolder); } return -1; } constexpr int64_t kTimeoutNanos = 100 * 1000 * 1000; // 100 ms int BtifAvrcpAudioTrackWriteData(void* handle, void* audioBuffer, int bufferlen) { int bufferLength) { BtifAvrcpAudioTrack* trackHolder = static_cast<BtifAvrcpAudioTrack*>(handle); CHECK(trackHolder != NULL); CHECK(trackHolder->track != NULL); int retval = -1; CHECK(trackHolder->stream != NULL); aaudio_result_t retval = -1; #if (DUMP_PCM_DATA == TRUE) if (outputPcmSampleFile) { fwrite((audioBuffer), 1, (size_t)bufferlen, outputPcmSampleFile); fwrite((audioBuffer), 1, (size_t)bufferLength, outputPcmSampleFile); } #endif retval = trackHolder->track->write(audioBuffer, (size_t)bufferlen); LOG_VERBOSE(LOG_TAG, "%s Track.cpp: btWriteData len = %d ret = %d", __func__, bufferlen, retval); return retval; size_t sampleSize = sampleSizeFor(trackHolder); int transcodedCount = 0; do { transcodedCount += transcodeToPcmFloat(((uint8_t*)audioBuffer) + transcodedCount, bufferLength - transcodedCount, trackHolder); retval = AAudioStream_write( trackHolder->stream, trackHolder->buffer, transcodedCount / (sampleSize * trackHolder->channelCount), kTimeoutNanos); LOG_VERBOSE(LOG_TAG, "%s Track.cpp: btWriteData len = %d ret = %d", __func__, bufferLength, retval); } while (transcodedCount < bufferLength); return transcodedCount; } system/main/Android.bp +1 −1 Original line number Diff line number Diff line Loading @@ -57,7 +57,7 @@ cc_library_shared { "android.hardware.bluetooth@1.1", "android.hardware.bluetooth.a2dp@1.0", "android.hardware.bluetooth.audio@2.0", "libaudioclient", "libaaudio", "libcutils", "libdl", "libfmq", Loading Loading
system/btif/Android.bp +2 −2 Original line number Diff line number Diff line Loading @@ -96,7 +96,7 @@ cc_library_static { "libmedia_headers", ], shared_libs: [ "libaudioclient", "libaaudio", "libcutils", "libfmq", "liblog", Loading Loading @@ -139,7 +139,7 @@ cc_test { ], header_libs: ["libbluetooth_headers"], shared_libs: [ "libaudioclient", "libaaudio", "android.hardware.bluetooth.a2dp@1.0", "android.hardware.bluetooth.audio@2.0", "libfmq", Loading
system/btif/include/btif_avrcp_audio_track.h +3 −3 Original line number Diff line number Diff line Loading @@ -35,8 +35,8 @@ * should eventually be * deleted using BtifAvrcpAudioTrackDelete (see below). */ void* BtifAvrcpAudioTrackCreate(int trackFreq, int bits_per_sample, int channelType); void* BtifAvrcpAudioTrackCreate(int trackFreq, int bitsPerSample, int channelCount); /** * Starts the audio track. Loading Loading @@ -66,4 +66,4 @@ void BtifAvrcpAudioTrackDelete(void* handle); * Used only for debugging. */ int BtifAvrcpAudioTrackWriteData(void* handle, void* audioBuffer, int bufferlen); int bufferLength);
system/btif/src/btif_a2dp_sink.cc +1 −1 Original line number Diff line number Diff line Loading @@ -595,7 +595,7 @@ static void btif_a2dp_sink_decoder_update_event( APPL_TRACE_DEBUG("%s: create audio track", __func__); btif_a2dp_sink_cb.audio_track = #ifndef OS_GENERIC BtifAvrcpAudioTrackCreate(sample_rate, bits_per_sample, channel_type); BtifAvrcpAudioTrackCreate(sample_rate, bits_per_sample, channel_count); #else NULL; #endif Loading
system/btif/src/btif_avrcp_audio_track.cc +118 −53 Original line number Diff line number Diff line Loading @@ -19,8 +19,8 @@ #include "btif_avrcp_audio_track.h" #include <aaudio/AAudio.h> #include <base/logging.h> #include <media/AudioTrack.h> #include <utils/StrongPointer.h> #include "bt_target.h" Loading @@ -28,50 +28,49 @@ using namespace android; typedef struct { android::sp<android::AudioTrack> track; } BtifAvrcpAudioTrack; typedef struct { AAudioStream* stream; int bitsPerSample; int channelCount; float* buffer; size_t bufferLength; } BtifAvrcpAudioTrack; #if (DUMP_PCM_DATA == TRUE) FILE* outputPcmSampleFile; char outputFilename[50] = "/data/misc/bluedroid/output_sample.pcm"; #endif void* BtifAvrcpAudioTrackCreate(int trackFreq, int bits_per_sample, int channelType) { audio_format_t format; switch (bits_per_sample) { default: case 16: format = AUDIO_FORMAT_PCM_16_BIT; break; case 24: format = AUDIO_FORMAT_PCM_24_BIT_PACKED; break; case 32: format = AUDIO_FORMAT_PCM_32_BIT; break; } LOG_VERBOSE(LOG_TAG, "%s Track.cpp: btCreateTrack freq %d format 0x%x channel %d ", __func__, trackFreq, format, channelType); sp<android::AudioTrack> track = new android::AudioTrack( AUDIO_STREAM_MUSIC, trackFreq, format, channelType, (size_t)0 /*frameCount*/, (audio_output_flags_t)AUDIO_OUTPUT_FLAG_FAST, NULL /*callback_t*/, NULL /*void* user*/, 0 /*notificationFrames*/, AUDIO_SESSION_ALLOCATE, android::AudioTrack::TRANSFER_SYNC); CHECK(track != NULL); void* BtifAvrcpAudioTrackCreate(int trackFreq, int bitsPerSample, int channelCount) { LOG_VERBOSE(LOG_TAG, "%s Track.cpp: btCreateTrack freq %d bps %d channel %d ", __func__, trackFreq, bitsPerSample, channelCount); AAudioStreamBuilder* builder; AAudioStream* stream; aaudio_result_t result = AAudio_createStreamBuilder(&builder); AAudioStreamBuilder_setSampleRate(builder, trackFreq); AAudioStreamBuilder_setFormat(builder, AAUDIO_FORMAT_PCM_FLOAT); AAudioStreamBuilder_setChannelCount(builder, channelCount); AAudioStreamBuilder_setSessionId(builder, AAUDIO_SESSION_ID_ALLOCATE); AAudioStreamBuilder_setPerformanceMode(builder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY); result = AAudioStreamBuilder_openStream(builder, &stream); CHECK(result == AAUDIO_OK); AAudioStreamBuilder_delete(builder); BtifAvrcpAudioTrack* trackHolder = new BtifAvrcpAudioTrack; CHECK(trackHolder != NULL); trackHolder->track = track; if (trackHolder->track->initCheck() != 0) { return nullptr; } trackHolder->stream = stream; trackHolder->bitsPerSample = bitsPerSample; trackHolder->channelCount = channelCount; trackHolder->bufferLength = trackHolder->channelCount * AAudioStream_getBufferSizeInFrames(stream); trackHolder->buffer = new float[trackHolder->bufferLength](); #if (DUMP_PCM_DATA == TRUE) outputPcmSampleFile = fopen(outputFilename, "ab"); #endif trackHolder->track->setVolume(1, 1); return (void*)trackHolder; } Loading @@ -82,9 +81,9 @@ void BtifAvrcpAudioTrackStart(void* handle) { } BtifAvrcpAudioTrack* trackHolder = static_cast<BtifAvrcpAudioTrack*>(handle); CHECK(trackHolder != NULL); CHECK(trackHolder->track != NULL); CHECK(trackHolder->stream != NULL); LOG_VERBOSE(LOG_TAG, "%s Track.cpp: btStartTrack", __func__); trackHolder->track->start(); AAudioStream_requestStart(trackHolder->stream); } void BtifAvrcpAudioTrackStop(void* handle) { Loading @@ -93,9 +92,9 @@ void BtifAvrcpAudioTrackStop(void* handle) { return; } BtifAvrcpAudioTrack* trackHolder = static_cast<BtifAvrcpAudioTrack*>(handle); if (trackHolder != NULL && trackHolder->track != NULL) { if (trackHolder != NULL && trackHolder->stream != NULL) { LOG_VERBOSE(LOG_TAG, "%s Track.cpp: btStartTrack", __func__); trackHolder->track->stop(); AAudioStream_requestStop(trackHolder->stream); } } Loading @@ -105,8 +104,10 @@ void BtifAvrcpAudioTrackDelete(void* handle) { return; } BtifAvrcpAudioTrack* trackHolder = static_cast<BtifAvrcpAudioTrack*>(handle); if (trackHolder != NULL && trackHolder->track != NULL) { if (trackHolder != NULL && trackHolder->stream != NULL) { LOG_VERBOSE(LOG_TAG, "%s Track.cpp: btStartTrack", __func__); AAudioStream_close(trackHolder->stream); delete trackHolder->buffer; delete trackHolder; } Loading @@ -124,10 +125,10 @@ void BtifAvrcpAudioTrackPause(void* handle) { return; } BtifAvrcpAudioTrack* trackHolder = static_cast<BtifAvrcpAudioTrack*>(handle); if (trackHolder != NULL && trackHolder->track != NULL) { LOG_VERBOSE(LOG_TAG, "%s Track.cpp: btStartTrack", __func__); trackHolder->track->pause(); trackHolder->track->flush(); if (trackHolder != NULL && trackHolder->stream != NULL) { LOG_VERBOSE(LOG_TAG, "%s Track.cpp: btPauseTrack", __func__); AAudioStream_requestPause(trackHolder->stream); AAudioStream_requestFlush(trackHolder->stream); } } Loading @@ -136,26 +137,90 @@ void BtifAvrcpSetAudioTrackGain(void* handle, float gain) { LOG_DEBUG(LOG_TAG, "%s handle is null.", __func__); return; } BtifAvrcpAudioTrack* trackHolder = static_cast<BtifAvrcpAudioTrack*>(handle); if (trackHolder != NULL && trackHolder->track != NULL) { LOG_VERBOSE(LOG_TAG, "%s set gain %f", __func__, gain); trackHolder->track->setVolume(gain); // Does nothing right now } constexpr float kScaleQ15ToFloat = 1.0f / 32768.0f; constexpr float kScaleQ23ToFloat = 1.0f / 8388608.0f; constexpr float kScaleQ31ToFloat = 1.0f / 2147483648.0f; static size_t sampleSizeFor(BtifAvrcpAudioTrack* trackHolder) { return trackHolder->bitsPerSample / 8; } static size_t transcodeQ15ToFloat(uint8_t* buffer, size_t length, BtifAvrcpAudioTrack* trackHolder) { size_t sampleSize = sampleSizeFor(trackHolder); size_t i = 0; for (; i <= length / sampleSize; i++) { trackHolder->buffer[i] = ((int16_t*)buffer)[i] * kScaleQ15ToFloat; } return i * sampleSize; } static size_t transcodeQ23ToFloat(uint8_t* buffer, size_t length, BtifAvrcpAudioTrack* trackHolder) { size_t sampleSize = sampleSizeFor(trackHolder); size_t i = 0; for (; i <= length / sampleSize; i++) { size_t offset = i * sampleSize; int32_t sample = *((int32_t*)(buffer + offset - 1)) & 0x00FFFFFF; trackHolder->buffer[i] = sample * kScaleQ23ToFloat; } return i * sampleSize; } static size_t transcodeQ31ToFloat(uint8_t* buffer, size_t length, BtifAvrcpAudioTrack* trackHolder) { size_t sampleSize = sampleSizeFor(trackHolder); size_t i = 0; for (; i <= length / sampleSize; i++) { trackHolder->buffer[i] = ((int32_t*)buffer)[i] * kScaleQ31ToFloat; } return i * sampleSize; } static size_t transcodeToPcmFloat(uint8_t* buffer, size_t length, BtifAvrcpAudioTrack* trackHolder) { switch (trackHolder->bitsPerSample) { case 16: return transcodeQ15ToFloat(buffer, length, trackHolder); case 24: return transcodeQ23ToFloat(buffer, length, trackHolder); case 32: return transcodeQ31ToFloat(buffer, length, trackHolder); } return -1; } constexpr int64_t kTimeoutNanos = 100 * 1000 * 1000; // 100 ms int BtifAvrcpAudioTrackWriteData(void* handle, void* audioBuffer, int bufferlen) { int bufferLength) { BtifAvrcpAudioTrack* trackHolder = static_cast<BtifAvrcpAudioTrack*>(handle); CHECK(trackHolder != NULL); CHECK(trackHolder->track != NULL); int retval = -1; CHECK(trackHolder->stream != NULL); aaudio_result_t retval = -1; #if (DUMP_PCM_DATA == TRUE) if (outputPcmSampleFile) { fwrite((audioBuffer), 1, (size_t)bufferlen, outputPcmSampleFile); fwrite((audioBuffer), 1, (size_t)bufferLength, outputPcmSampleFile); } #endif retval = trackHolder->track->write(audioBuffer, (size_t)bufferlen); LOG_VERBOSE(LOG_TAG, "%s Track.cpp: btWriteData len = %d ret = %d", __func__, bufferlen, retval); return retval; size_t sampleSize = sampleSizeFor(trackHolder); int transcodedCount = 0; do { transcodedCount += transcodeToPcmFloat(((uint8_t*)audioBuffer) + transcodedCount, bufferLength - transcodedCount, trackHolder); retval = AAudioStream_write( trackHolder->stream, trackHolder->buffer, transcodedCount / (sampleSize * trackHolder->channelCount), kTimeoutNanos); LOG_VERBOSE(LOG_TAG, "%s Track.cpp: btWriteData len = %d ret = %d", __func__, bufferLength, retval); } while (transcodedCount < bufferLength); return transcodedCount; }
system/main/Android.bp +1 −1 Original line number Diff line number Diff line Loading @@ -57,7 +57,7 @@ cc_library_shared { "android.hardware.bluetooth@1.1", "android.hardware.bluetooth.a2dp@1.0", "android.hardware.bluetooth.audio@2.0", "libaudioclient", "libaaudio", "libcutils", "libdl", "libfmq", Loading