1 /*
2  * Copyright (C) 2017 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 <fcntl.h>
18 #include <stdio.h>
19 #include <string.h>
20 #include <unistd.h>
21 
22 #include <android/content/AttributionSourceState.h>
23 #include <binder/MemoryBase.h>
24 #include <binder/MemoryDealer.h>
25 #include <binder/MemoryHeapBase.h>
26 #include <media/AudioTrack.h>
27 
28 #include "test_create_utils.h"
29 
30 #define NUM_ARGUMENTS 10
31 #define VERSION_VALUE "1.0"
32 
33 namespace android {
34 
testTrack(FILE * inputFile,int outputFileFd)35 int testTrack(FILE* inputFile, int outputFileFd) {
36     char line[MAX_INPUT_FILE_LINE_LENGTH];
37     uint32_t testCount = 0;
38     Vector<String16> args;
39     int ret = 0;
40 
41     if (inputFile == nullptr) {
42         sp<AudioTrack> track = new AudioTrack(AUDIO_STREAM_DEFAULT, 0 /* sampleRate */,
43                                               AUDIO_FORMAT_DEFAULT, AUDIO_CHANNEL_OUT_STEREO);
44         if (track == 0 || track->initCheck() != NO_ERROR) {
45             write(outputFileFd, "Error creating AudioTrack\n",
46                   sizeof("Error creating AudioTrack\n"));
47         } else {
48             track->dump(outputFileFd, args);
49         }
50         return 0;
51     }
52 
53     // check version
54     if (!checkVersion(inputFile, VERSION_VALUE)) {
55         return 1;
56     }
57 
58     while (readLine(inputFile, line, MAX_INPUT_FILE_LINE_LENGTH) == 0) {
59         uint32_t sampleRate;
60         audio_format_t format;
61         audio_channel_mask_t channelMask;
62         size_t frameCount;
63         int32_t notificationFrames;
64         uint32_t useSharedBuffer;
65         audio_output_flags_t flags;
66         audio_session_t sessionId;
67         audio_usage_t usage;
68         audio_content_type_t contentType;
69         audio_attributes_t attributes;
70         sp<IMemory> sharedBuffer;
71         sp<MemoryDealer> heap;
72         audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER;
73         status_t status;
74         char statusStr[MAX_OUTPUT_FILE_LINE_LENGTH];
75         bool offload = false;
76         bool fast = false;
77 
78         if (sscanf(line, " %u %x %x %zu %d %u %x %u %u %u", &sampleRate, &format, &channelMask,
79                    &frameCount, &notificationFrames, &useSharedBuffer, &flags, &sessionId, &usage,
80                    &contentType) != NUM_ARGUMENTS) {
81             fprintf(stderr, "Malformed line for test #%u in input file\n", testCount + 1);
82             ret = 1;
83             continue;
84         }
85         testCount++;
86 
87         if (useSharedBuffer != 0) {
88             size_t heapSize = audio_channel_count_from_out_mask(channelMask) *
89                               audio_bytes_per_sample(format) * frameCount;
90             heap = new MemoryDealer(heapSize, "AudioTrack Heap Base");
91             sharedBuffer = heap->allocate(heapSize);
92             frameCount = 0;
93             notificationFrames = 0;
94         }
95         if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
96             offloadInfo.sample_rate = sampleRate;
97             offloadInfo.channel_mask = channelMask;
98             offloadInfo.format = format;
99             offload = true;
100         }
101         if ((flags & AUDIO_OUTPUT_FLAG_FAST) != 0) {
102             fast = true;
103         }
104 
105         memset(&attributes, 0, sizeof(attributes));
106         attributes.content_type = contentType;
107         attributes.usage = usage;
108         sp<AudioTrack> track = new AudioTrack();
109         const auto emptyCallback = sp<AudioTrack::IAudioTrackCallback>::make();
110         track->set(AUDIO_STREAM_DEFAULT, sampleRate, format, channelMask, frameCount, flags,
111                    (fast || offload) ? emptyCallback : nullptr, notificationFrames, sharedBuffer,
112                    false, sessionId,
113                    ((fast && sharedBuffer == 0) || offload) ? AudioTrack::TRANSFER_CALLBACK
114                                                             : AudioTrack::TRANSFER_DEFAULT,
115                    offload ? &offloadInfo : nullptr, AttributionSourceState(), &attributes, false,
116                    1.0f, AUDIO_PORT_HANDLE_NONE);
117         status = track->initCheck();
118         sprintf(statusStr, "\n#### Test %u status %d\n", testCount, status);
119         write(outputFileFd, statusStr, strlen(statusStr));
120         if (status != NO_ERROR) {
121             continue;
122         }
123         track->dump(outputFileFd, args);
124     }
125     return ret;
126 }
127 
128 };  // namespace android
129 
main(int argc,char ** argv)130 int main(int argc, char** argv) {
131     return android::main(argc, argv, android::testTrack);
132 }
133