| /* |
| * Copyright (C) 2017 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <fcntl.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include <unistd.h> |
| |
| #include <android/content/AttributionSourceState.h> |
| #include <binder/MemoryBase.h> |
| #include <binder/MemoryDealer.h> |
| #include <binder/MemoryHeapBase.h> |
| #include <media/AudioTrack.h> |
| |
| #include "test_create_utils.h" |
| |
| #define NUM_ARGUMENTS 10 |
| #define VERSION_VALUE "1.0" |
| |
| namespace android { |
| |
| int testTrack(FILE* inputFile, int outputFileFd) { |
| char line[MAX_INPUT_FILE_LINE_LENGTH]; |
| uint32_t testCount = 0; |
| Vector<String16> args; |
| int ret = 0; |
| |
| if (inputFile == nullptr) { |
| sp<AudioTrack> track = new AudioTrack(AUDIO_STREAM_DEFAULT, 0 /* sampleRate */, |
| AUDIO_FORMAT_DEFAULT, AUDIO_CHANNEL_OUT_STEREO); |
| if (track == 0 || track->initCheck() != NO_ERROR) { |
| write(outputFileFd, "Error creating AudioTrack\n", |
| sizeof("Error creating AudioTrack\n")); |
| } else { |
| track->dump(outputFileFd, args); |
| } |
| return 0; |
| } |
| |
| // check version |
| if (!checkVersion(inputFile, VERSION_VALUE)) { |
| return 1; |
| } |
| |
| while (readLine(inputFile, line, MAX_INPUT_FILE_LINE_LENGTH) == 0) { |
| uint32_t sampleRate; |
| audio_format_t format; |
| audio_channel_mask_t channelMask; |
| size_t frameCount; |
| int32_t notificationFrames; |
| uint32_t useSharedBuffer; |
| audio_output_flags_t flags; |
| audio_session_t sessionId; |
| audio_usage_t usage; |
| audio_content_type_t contentType; |
| audio_attributes_t attributes; |
| sp<IMemory> sharedBuffer; |
| sp<MemoryDealer> heap; |
| audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER; |
| status_t status; |
| char statusStr[MAX_OUTPUT_FILE_LINE_LENGTH]; |
| bool offload = false; |
| bool fast = false; |
| |
| if (sscanf(line, " %u %x %x %zu %d %u %x %u %u %u", &sampleRate, &format, &channelMask, |
| &frameCount, ¬ificationFrames, &useSharedBuffer, &flags, &sessionId, &usage, |
| &contentType) != NUM_ARGUMENTS) { |
| fprintf(stderr, "Malformed line for test #%u in input file\n", testCount + 1); |
| ret = 1; |
| continue; |
| } |
| testCount++; |
| |
| if (useSharedBuffer != 0) { |
| size_t heapSize = audio_channel_count_from_out_mask(channelMask) * |
| audio_bytes_per_sample(format) * frameCount; |
| heap = new MemoryDealer(heapSize, "AudioTrack Heap Base"); |
| sharedBuffer = heap->allocate(heapSize); |
| frameCount = 0; |
| notificationFrames = 0; |
| } |
| if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { |
| offloadInfo.sample_rate = sampleRate; |
| offloadInfo.channel_mask = channelMask; |
| offloadInfo.format = format; |
| offload = true; |
| } |
| if ((flags & AUDIO_OUTPUT_FLAG_FAST) != 0) { |
| fast = true; |
| } |
| |
| memset(&attributes, 0, sizeof(attributes)); |
| attributes.content_type = contentType; |
| attributes.usage = usage; |
| sp<AudioTrack> track = new AudioTrack(); |
| const auto emptyCallback = sp<AudioTrack::IAudioTrackCallback>::make(); |
| track->set(AUDIO_STREAM_DEFAULT, sampleRate, format, channelMask, frameCount, flags, |
| (fast || offload) ? emptyCallback : nullptr, notificationFrames, sharedBuffer, |
| false, sessionId, |
| ((fast && sharedBuffer == 0) || offload) ? AudioTrack::TRANSFER_CALLBACK |
| : AudioTrack::TRANSFER_DEFAULT, |
| offload ? &offloadInfo : nullptr, AttributionSourceState(), &attributes, false, |
| 1.0f, AUDIO_PORT_HANDLE_NONE); |
| status = track->initCheck(); |
| sprintf(statusStr, "\n#### Test %u status %d\n", testCount, status); |
| write(outputFileFd, statusStr, strlen(statusStr)); |
| if (status != NO_ERROR) { |
| continue; |
| } |
| track->dump(outputFileFd, args); |
| } |
| return ret; |
| } |
| |
| }; // namespace android |
| |
| int main(int argc, char** argv) { |
| return android::main(argc, argv, android::testTrack); |
| } |