• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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 #pragma once
18 
19 #include <cstdint>
20 
21 namespace aidl::android::hardware::audio::core {
22 
23 // Simplified APE (Monkey Audio) header definition sufficient to figure out
24 // the basic parameters of the encoded file. Only supports the "current"
25 // versions of the header (>= 3980).
26 
27 #pragma pack(push, 4)
28 
29 // Only the beginning of the descriptor is needed to find the header which
30 // follows the descriptor.
31 struct ApeDescriptor {
32     uint32_t signature;  // 'MAC ' or 'MACF'
33     uint16_t version;
34     uint16_t padding;
35     uint32_t descriptorSizeBytes;
36     uint32_t headerSizeBytes;
37 };
38 
39 struct ApeHeader {
40     uint16_t compressionLevel;
41     uint16_t flags;
42     uint32_t blocksPerFrame;   // "frames" are encoder frames, while "blocks" are audio frames
43     uint32_t lastFrameBlocks;  // number of "blocks" in the last encoder "frame"
44     uint32_t totalFrames;      // total number of encoder "frames"
45     uint16_t bitsPerSample;
46     uint16_t channelCount;
47     uint32_t sampleRate;
48 };
49 
50 #pragma pack(pop)
51 
52 // Tries to find APE descriptor and header in the buffer. Returns the position
53 // after the header or nullptr if it was not found.
54 void* findApeHeader(void* buffer, size_t bufferSizeBytes, ApeHeader** header);
55 
56 // Clip duration in audio frames ("blocks" in the APE terminology).
getApeClipDurationFrames(const ApeHeader * header)57 inline int64_t getApeClipDurationFrames(const ApeHeader* header) {
58     return header->totalFrames != 0
59                    ? (header->totalFrames - 1) * header->blocksPerFrame + header->lastFrameBlocks
60                    : 0;
61 }
62 
63 }  // namespace aidl::android::hardware::audio::core
64