1/******************************************************************************
2 *
3 *  Copyright (C) 2014 The Android Open Source Project
4 *  Copyright 2003 - 2004 Open Interface North America, Inc. All rights
5 *                        reserved.
6 *
7 *  Licensed under the Apache License, Version 2.0 (the "License");
8 *  you may not use this file except in compliance with the License.
9 *  You may obtain a copy of the License at:
10 *
11 *  http://www.apache.org/licenses/LICENSE-2.0
12 *
13 *  Unless required by applicable law or agreed to in writing, software
14 *  distributed under the License is distributed on an "AS IS" BASIS,
15 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 *  See the License for the specific language governing permissions and
17 *  limitations under the License.
18 *
19 ******************************************************************************/
20#ifndef _OI_CODEC_SBC_PRIVATE_H
21#define _OI_CODEC_SBC_PRIVATE_H
22
23/*******************************************************************************
24  $Revision: #1 $
25 ******************************************************************************/
26
27/**
28@file
29Function prototypes and macro definitions used internally by the codec.
30
31@ingroup codec_internal
32*/
33
34/**
35@addtogroup codec_internal
36@{
37*/
38
39#ifdef USE_RESTRICT_KEYWORD
40#define RESTRICT restrict
41#else
42#define RESTRICT
43#endif
44
45#ifdef CODEC_DEBUG
46#include <stdio.h>
47#define ERROR(x)  \
48  do {            \
49    printf x;     \
50    printf("\n"); \
51  } while (0)
52#else
53#define ERROR(x)
54#endif
55
56#ifdef TRACE_EXECUTION
57#define TRACE(x)  \
58  do {            \
59    printf x;     \
60    printf("\n"); \
61  } while (0)
62#else
63#define TRACE(x)
64#endif
65
66#ifndef PRIVATE
67#define PRIVATE
68#endif
69
70#ifndef INLINE
71#define INLINE
72#endif
73
74#include "oi_assert.h"
75#include "oi_codec_sbc.h"
76
77#ifndef OI_SBC_SYNCWORD
78#define OI_SBC_SYNCWORD 0x9c
79#endif
80
81#ifndef DIVIDE
82#define DIVIDE(a, b) ((a) / (b))
83#endif
84
85typedef union {
86  uint8_t uint8[SBC_MAX_BANDS];
87  uint32_t uint32[SBC_MAX_BANDS / 4];
88} BITNEED_UNION1;
89
90typedef union {
91  uint8_t uint8[2 * SBC_MAX_BANDS];
92  uint32_t uint32[2 * SBC_MAX_BANDS / 4];
93} BITNEED_UNION2;
94
95static const uint16_t freq_values[] = {16000, 32000, 44100, 48000};
96static const uint8_t block_values[] = {4, 8, 12, 16};
97static const uint8_t channel_values[] = {1, 2, 2, 2};
98static const uint8_t band_values[] = {4, 8};
99
100#define TEST_MODE_SENTINEL "OINA"
101#define TEST_MODE_SENTINEL_LENGTH 4
102
103/** Used internally. */
104typedef struct {
105  union {
106    const uint8_t* r;
107    uint8_t* w;
108  } ptr;
109  uint32_t value;
110  OI_UINT bitPtr;
111} OI_BITSTREAM;
112
113#define VALID_INT16(x) (((x) >= OI_INT16_MIN) && ((x) <= OI_INT16_MAX))
114#define VALID_INT32(x) (((x) >= OI_INT32_MIN) && ((x) <= OI_INT32_MAX))
115
116#define DCTII_8_SHIFT_IN 0
117#define DCTII_8_SHIFT_OUT (16 - DCTII_8_SHIFT_IN)
118
119#define DCTII_8_SHIFT_0 (DCTII_8_SHIFT_OUT)
120#define DCTII_8_SHIFT_1 (DCTII_8_SHIFT_OUT)
121#define DCTII_8_SHIFT_2 (DCTII_8_SHIFT_OUT)
122#define DCTII_8_SHIFT_3 (DCTII_8_SHIFT_OUT)
123#define DCTII_8_SHIFT_4 (DCTII_8_SHIFT_OUT)
124#define DCTII_8_SHIFT_5 (DCTII_8_SHIFT_OUT)
125#define DCTII_8_SHIFT_6 (DCTII_8_SHIFT_OUT - 1)
126#define DCTII_8_SHIFT_7 (DCTII_8_SHIFT_OUT - 2)
127
128#define DCT_SHIFT 15
129
130#define DCTIII_4_SHIFT_IN 2
131#define DCTIII_4_SHIFT_OUT 15
132
133#define DCTIII_8_SHIFT_IN 3
134#define DCTIII_8_SHIFT_OUT 14
135
136OI_UINT computeBitneed(OI_CODEC_SBC_COMMON_CONTEXT* common, uint8_t* bitneeds,
137                       OI_UINT ch, OI_UINT* preferredBitpool);
138
139void oneChannelBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT* common,
140                             BITNEED_UNION1* bitneeds, OI_UINT ch,
141                             OI_UINT bitcount);
142
143OI_INT adjustToFitBitpool(const OI_UINT bitpool, uint32_t* bitneeds,
144                          const OI_UINT subbands, OI_UINT bitcount,
145                          OI_UINT* excess);
146
147INLINE OI_INT allocAdjustedBits(uint8_t* dest, OI_INT bits, OI_INT excess);
148
149INLINE OI_INT allocExcessBits(uint8_t* dest, OI_INT excess);
150
151PRIVATE uint32_t internal_CalculateBitrate(OI_CODEC_SBC_FRAME_INFO* frame);
152
153PRIVATE uint16_t internal_CalculateFramelen(OI_CODEC_SBC_FRAME_INFO* frame);
154
155void monoBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT* common);
156
157typedef void (*BIT_ALLOC)(OI_CODEC_SBC_COMMON_CONTEXT* common);
158
159PRIVATE OI_STATUS internal_DecodeRaw(OI_CODEC_SBC_DECODER_CONTEXT* context,
160                                     uint8_t bitpool, const OI_BYTE** frameData,
161                                     uint32_t* frameBytes, int16_t* pcmData,
162                                     uint32_t* pcmBytes);
163
164INLINE OI_STATUS internal_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT* context,
165                                       uint32_t* decoderData,
166                                       uint32_t decoderDataBytes,
167                                       OI_BYTE maxChannels, OI_BYTE pcmStride,
168                                       OI_BOOL enhanced);
169
170INLINE uint16_t OI_SBC_CalculateFrameAndHeaderlen(
171    OI_CODEC_SBC_FRAME_INFO* frame, OI_UINT* headerLen_);
172
173PRIVATE uint32_t OI_SBC_MaxBitpool(OI_CODEC_SBC_FRAME_INFO* frame);
174
175PRIVATE void OI_SBC_ComputeBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT* frame);
176PRIVATE uint8_t OI_SBC_CalculateChecksum(OI_CODEC_SBC_FRAME_INFO* frame,
177                                         OI_BYTE const* data);
178
179/* Transform functions */
180PRIVATE void shift_buffer(SBC_BUFFER_T* dest, SBC_BUFFER_T* src,
181                          OI_UINT wordCount);
182PRIVATE void cosineModulateSynth4(SBC_BUFFER_T* RESTRICT out,
183                                  int32_t const* RESTRICT in);
184PRIVATE void SynthWindow40_int32_int32_symmetry_with_sum(
185    int16_t* pcm, SBC_BUFFER_T buffer[80], OI_UINT strideShift);
186
187INLINE void dct3_4(int32_t* RESTRICT out, int32_t const* RESTRICT in);
188PRIVATE void analyze4_generated(SBC_BUFFER_T analysisBuffer[RESTRICT 40],
189                                int16_t* pcm, OI_UINT strideShift,
190                                int32_t subband[4]);
191
192INLINE void dct3_8(int32_t* RESTRICT out, int32_t const* RESTRICT in);
193
194PRIVATE void analyze8_generated(SBC_BUFFER_T analysisBuffer[RESTRICT 80],
195                                int16_t* pcm, OI_UINT strideShift,
196                                int32_t subband[8]);
197
198#ifdef SBC_ENHANCED
199PRIVATE void analyze8_enhanced_generated(
200    SBC_BUFFER_T analysisBuffer[RESTRICT 112], int16_t* pcm,
201    OI_UINT strideShift, int32_t subband[8]);
202#endif
203
204/* Decoder functions */
205
206INLINE void OI_SBC_ReadHeader(OI_CODEC_SBC_COMMON_CONTEXT* common,
207                              const OI_BYTE* data);
208PRIVATE void OI_SBC_ReadScalefactors(OI_CODEC_SBC_COMMON_CONTEXT* common,
209                                     const OI_BYTE* b, OI_BITSTREAM* bs);
210PRIVATE void OI_SBC_ReadSamples(OI_CODEC_SBC_DECODER_CONTEXT* common,
211                                OI_BITSTREAM* ob);
212PRIVATE void OI_SBC_ReadSamplesJoint(OI_CODEC_SBC_DECODER_CONTEXT* common,
213                                     OI_BITSTREAM* global_bs);
214PRIVATE void OI_SBC_SynthFrame(OI_CODEC_SBC_DECODER_CONTEXT* context,
215                               int16_t* pcm, OI_UINT start_block,
216                               OI_UINT nrof_blocks);
217INLINE int32_t OI_SBC_Dequant(uint32_t raw, OI_UINT scale_factor, OI_UINT bits);
218PRIVATE OI_BOOL OI_SBC_ExamineCommandPacket(
219    OI_CODEC_SBC_DECODER_CONTEXT* context, const OI_BYTE* data, uint32_t len);
220PRIVATE void OI_SBC_GenerateTestSignal(int16_t pcmData[][2],
221                                       uint32_t sampleCount);
222
223PRIVATE void OI_SBC_ExpandFrameFields(OI_CODEC_SBC_FRAME_INFO* frame);
224PRIVATE OI_STATUS OI_CODEC_SBC_Alloc(OI_CODEC_SBC_COMMON_CONTEXT* common,
225                                     uint32_t* codecDataAligned,
226                                     uint32_t codecDataBytes,
227                                     uint8_t maxChannels, uint8_t pcmStride);
228/**
229@}
230*/
231
232#endif /* _OI_CODEC_SBC_PRIVATE_H */
233