1 /*
2  * Copyright 2023 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 #include "btif/include/btif_avrcp_audio_track.h"
18 
19 #ifndef __INTRODUCED_IN
20 #define __INTRODUCED_IN(x)
21 #endif
22 
23 #include <aaudio/AAudio.h>
24 #include <aaudio/AAudioTesting.h>
25 #include <gtest/gtest.h>
26 
27 #include <memory>
28 
29 // Define the incomplete audio stream struct type.
30 struct AAudioStreamStruct {
31   // The ID of the stream.
32   int32_t streamId;
33 };
34 
35 // Expected audio track.
36 typedef struct {
37   AAudioStream* stream;
38   int bitsPerSample;
39   int channelCount;
40   float* buffer;
41   size_t bufferLength;
42   float gain;
43 } BtifAvrcpAudioTrack;
44 
45 class BtifAvrcpAudioTrackTest : public ::testing::Test {};
46 
TEST_F(BtifAvrcpAudioTrackTest,setAudioTrackGain_maxGainSet)47 TEST_F(BtifAvrcpAudioTrackTest, setAudioTrackGain_maxGainSet) {
48   void* track_handle = BtifAvrcpAudioTrackCreate(10, 16, 3);
49   BtifAvrcpSetAudioTrackGain(track_handle, 1.0f);
50   BtifAvrcpAudioTrack* trackHolder =
51       static_cast<BtifAvrcpAudioTrack*>(track_handle);
52   EXPECT_EQ(trackHolder->gain, 1.0f);
53   BtifAvrcpAudioTrackDelete(track_handle);
54 }
55 
TEST_F(BtifAvrcpAudioTrackTest,setAudioTrackGain_minimumGainSet)56 TEST_F(BtifAvrcpAudioTrackTest, setAudioTrackGain_minimumGainSet) {
57   void* track_handle = BtifAvrcpAudioTrackCreate(10, 16, 3);
58   BtifAvrcpSetAudioTrackGain(track_handle, 0.0f);
59   BtifAvrcpAudioTrack* trackHolder =
60       static_cast<BtifAvrcpAudioTrack*>(track_handle);
61   EXPECT_EQ(trackHolder->gain, 0.0f);
62   BtifAvrcpAudioTrackDelete(track_handle);
63 }
64 
TEST_F(BtifAvrcpAudioTrackTest,setAudioTrackGain_maxGainOutOfBounds_setsCappedGain)65 TEST_F(BtifAvrcpAudioTrackTest,
66        setAudioTrackGain_maxGainOutOfBounds_setsCappedGain) {
67   void* track_handle = BtifAvrcpAudioTrackCreate(10, 16, 3);
68   BtifAvrcpAudioTrack* trackHolder =
69       static_cast<BtifAvrcpAudioTrack*>(track_handle);
70   BtifAvrcpSetAudioTrackGain(track_handle, 2.0f);
71   EXPECT_EQ(trackHolder->gain, 1.0f);
72   BtifAvrcpAudioTrackDelete(track_handle);
73 }
74 
TEST_F(BtifAvrcpAudioTrackTest,setAudioTrackGain_minGainOutOfBounds_setsCappedGain)75 TEST_F(BtifAvrcpAudioTrackTest,
76        setAudioTrackGain_minGainOutOfBounds_setsCappedGain) {
77   void* track_handle = BtifAvrcpAudioTrackCreate(10, 16, 3);
78   BtifAvrcpAudioTrack* trackHolder =
79       static_cast<BtifAvrcpAudioTrack*>(track_handle);
80   BtifAvrcpSetAudioTrackGain(track_handle, -2.0f);
81   EXPECT_EQ(trackHolder->gain, 0.0f);
82   BtifAvrcpAudioTrackDelete(track_handle);
83 }
84 
TEST_F(BtifAvrcpAudioTrackTest,setMaxAudioTrackGain_minGain_bufferStreamDucked)85 TEST_F(BtifAvrcpAudioTrackTest,
86        setMaxAudioTrackGain_minGain_bufferStreamDucked) {
87   constexpr float scaleQ15ToFloat = 1.0f / 32768.0f;
88   constexpr size_t bufferLength = 100;
89   constexpr int bitsPerSample = 16;
90   constexpr size_t sampleSize = bitsPerSample / 8;
91   constexpr auto gainValue = 0.5f;
92   void* track_handle = BtifAvrcpAudioTrackCreate(10, bitsPerSample, 3);
93   BtifAvrcpAudioTrack* trackHolder =
94       static_cast<BtifAvrcpAudioTrack*>(track_handle);
95   std::unique_ptr<AAudioStream> stream(new AAudioStream);
96   // Set the values to track holder as mock audio lib APIs are a no-op.
97   trackHolder->stream = stream.get();
98   trackHolder->bufferLength = bufferLength;
99   trackHolder->buffer = new float[trackHolder->bufferLength]();
100 
101   BtifAvrcpSetAudioTrackGain(trackHolder, gainValue);
102   // Create a fake buffer.
103   uint8_t data[bufferLength];
104   for (size_t index = 0; index < bufferLength; ++index) {
105     data[index] = index;
106   }
107   BtifAvrcpAudioTrackWriteData(trackHolder, data, bufferLength);
108   const int16_t* dataInt = (int16_t*)data;
109   for (size_t index = 0; index < bufferLength / sampleSize; ++index) {
110     const float expected = dataInt[index] * scaleQ15ToFloat * gainValue;
111     EXPECT_NEAR(expected, trackHolder->buffer[index], 0.01f);
112   }
113   BtifAvrcpAudioTrackDelete(trackHolder);
114 }
115