/* * Copyright (C) 2025 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. */ #pragma once #include namespace aidl::android::hardware::audio::core { // Simplified APE (Monkey Audio) header definition sufficient to figure out // the basic parameters of the encoded file. Only supports the "current" // versions of the header (>= 3980). #pragma pack(push, 4) // Only the beginning of the descriptor is needed to find the header which // follows the descriptor. struct ApeDescriptor { uint32_t signature; // 'MAC ' or 'MACF' uint16_t version; uint16_t padding; uint32_t descriptorSizeBytes; uint32_t headerSizeBytes; }; struct ApeHeader { uint16_t compressionLevel; uint16_t flags; uint32_t blocksPerFrame; // "frames" are encoder frames, while "blocks" are audio frames uint32_t lastFrameBlocks; // number of "blocks" in the last encoder "frame" uint32_t totalFrames; // total number of encoder "frames" uint16_t bitsPerSample; uint16_t channelCount; uint32_t sampleRate; }; #pragma pack(pop) // Tries to find APE descriptor and header in the buffer. Returns the position // after the header or nullptr if it was not found. void* findApeHeader(void* buffer, size_t bufferSizeBytes, ApeHeader** header); // Clip duration in audio frames ("blocks" in the APE terminology). inline int64_t getApeClipDurationFrames(const ApeHeader* header) { return header->totalFrames != 0 ? (header->totalFrames - 1) * header->blocksPerFrame + header->lastFrameBlocks : 0; } } // namespace aidl::android::hardware::audio::core