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