• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (C) 2022 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  *
18  *  All declarations relevant for the SyncInserter class. This class exposes a
19  *  public interface that lets a client supply two aptX encoder objects (left
20  *  and right stereo channel) and have the current quantised codes adjusted to
21  *  bury an autosync bit.
22  *
23  *----------------------------------------------------------------------------*/
24 
25 #ifndef SYNCINSERTER_H
26 #define SYNCINSERTER_H
27 #ifdef _GCC
28 #pragma GCC visibility push(hidden)
29 #endif
30 
31 #include "AptxParameters.h"
32 
33 /* Function to insert sync information into one of the 8 quantised codes
34  * spread across 2 aptX codewords (1 codeword per channel) */
xbtEncinsertSync(Encoder_data * leftChannelEncoder,Encoder_data * rightChannelEncoder,uint32_t * syncWordPhase)35 XBT_INLINE_ void xbtEncinsertSync(Encoder_data* leftChannelEncoder,
36                                   Encoder_data* rightChannelEncoder, uint32_t* syncWordPhase) {
37   /* Currently using 0x1 as the 8-bit sync pattern */
38   static const uint32_t syncWord = 0x1;
39   uint32_t tmp_var;
40 
41   uint32_t i;
42 
43   /* Variable to hold the XOR of all the quantised code lsbs */
44   uint32_t xorCodeLsbs;
45 
46   /* Variable to point to the quantiser with the minimum calculated distance
47    * penalty. */
48   Quantiser_data* minPenaltyQuantiser;
49 
50   /* Get the vector of quantiser pointers from the left and right encoders */
51   Quantiser_data* leftQuant[4];
52   Quantiser_data* rightQuant[4];
53   leftQuant[0] = &leftChannelEncoder->m_qdata[0];
54   leftQuant[1] = &leftChannelEncoder->m_qdata[1];
55   leftQuant[2] = &leftChannelEncoder->m_qdata[2];
56   leftQuant[3] = &leftChannelEncoder->m_qdata[3];
57   rightQuant[0] = &rightChannelEncoder->m_qdata[0];
58   rightQuant[1] = &rightChannelEncoder->m_qdata[1];
59   rightQuant[2] = &rightChannelEncoder->m_qdata[2];
60   rightQuant[3] = &rightChannelEncoder->m_qdata[3];
61 
62   /* Starting quantiser traversal with the LL quantiser from the left channel.
63    * Initialise the pointer to the minimum penalty quantiser with the details
64    * of the left LL quantiser. Initialise the code lsbs XOR variable with the
65    * left LL quantised code lsbs and also XOR in the left and right random
66    * dither bit generated by the 2 encoders. */
67   xorCodeLsbs = ((rightQuant[LL]->qCode) & 0x1) ^ leftChannelEncoder->m_dithSyncRandBit ^
68                 rightChannelEncoder->m_dithSyncRandBit;
69   minPenaltyQuantiser = rightQuant[LH];
70 
71   /* Traverse across the LH, HL and HH quantisers from the right channel */
72   for (i = LH; i <= HH; i++) {
73     /* XOR in the lsb of the quantised code currently examined */
74     xorCodeLsbs ^= (rightQuant[i]->qCode) & 0x1;
75   }
76 
77   /* If the distance penalty associated with a quantiser is less than the
78    * current minimum, then make that quantiser the minimum penalty
79    * quantiser. */
80   if (rightQuant[HL]->distPenalty < minPenaltyQuantiser->distPenalty) {
81     minPenaltyQuantiser = rightQuant[HL];
82   }
83   if (rightQuant[LL]->distPenalty < minPenaltyQuantiser->distPenalty) {
84     minPenaltyQuantiser = rightQuant[LL];
85   }
86   if (rightQuant[HH]->distPenalty < minPenaltyQuantiser->distPenalty) {
87     minPenaltyQuantiser = rightQuant[HH];
88   }
89 
90   /* Traverse across all quantisers from the left channel */
91   for (i = LL; i <= HH; i++) {
92     /* XOR in the lsb of the quantised code currently examined */
93     xorCodeLsbs ^= (leftQuant[i]->qCode) & 0x1;
94   }
95 
96   /* If the distance penalty associated with a quantiser is less than the
97    * current minimum, then make that quantiser the minimum penalty
98    * quantiser. */
99   if (leftQuant[LH]->distPenalty < minPenaltyQuantiser->distPenalty) {
100     minPenaltyQuantiser = leftQuant[LH];
101   }
102   if (leftQuant[HL]->distPenalty < minPenaltyQuantiser->distPenalty) {
103     minPenaltyQuantiser = leftQuant[HL];
104   }
105   if (leftQuant[LL]->distPenalty < minPenaltyQuantiser->distPenalty) {
106     minPenaltyQuantiser = leftQuant[LL];
107   }
108   if (leftQuant[HH]->distPenalty < minPenaltyQuantiser->distPenalty) {
109     minPenaltyQuantiser = leftQuant[HH];
110   }
111 
112   /* If the lsbs of all 8 quantised codes don't happen to equal the desired
113    * sync bit to embed, then force them to be by replacing the optimum code
114    * with the alternate code in the minimum penalty quantiser (changes the lsb
115    * of the code in this quantiser) */
116   if (xorCodeLsbs != ((syncWord >> (*syncWordPhase)) & 0x1)) {
117     minPenaltyQuantiser->qCode = minPenaltyQuantiser->altQcode;
118   }
119 
120   /* Decrement the selected sync word bit modulo 8 for the next pass. */
121   tmp_var = --(*syncWordPhase);
122   (*syncWordPhase) = tmp_var & 0x7;
123 }
124 
xbtEncinsertSyncDualMono(Encoder_data * leftChannelEncoder,Encoder_data * rightChannelEncoder,uint32_t * syncWordPhase)125 XBT_INLINE_ void xbtEncinsertSyncDualMono(Encoder_data* leftChannelEncoder,
126                                           Encoder_data* rightChannelEncoder,
127                                           uint32_t* syncWordPhase) {
128   /* Currently using 0x1 as the 8-bit sync pattern */
129   static const uint32_t syncWord = 0x1;
130   uint32_t tmp_var;
131 
132   uint32_t i;
133 
134   /* Variable to hold the XOR of all the quantised code lsbs */
135   uint32_t xorCodeLsbs;
136 
137   /* Variable to point to the quantiser with the minimum calculated distance
138    * penalty. */
139   Quantiser_data* minPenaltyQuantiser;
140 
141   /* Get the vector of quantiser pointers from the left and right encoders */
142   Quantiser_data* leftQuant[4];
143   Quantiser_data* rightQuant[4];
144   leftQuant[0] = &leftChannelEncoder->m_qdata[0];
145   leftQuant[1] = &leftChannelEncoder->m_qdata[1];
146   leftQuant[2] = &leftChannelEncoder->m_qdata[2];
147   leftQuant[3] = &leftChannelEncoder->m_qdata[3];
148   rightQuant[0] = &rightChannelEncoder->m_qdata[0];
149   rightQuant[1] = &rightChannelEncoder->m_qdata[1];
150   rightQuant[2] = &rightChannelEncoder->m_qdata[2];
151   rightQuant[3] = &rightChannelEncoder->m_qdata[3];
152 
153   /* Starting quantiser traversal with the LL quantiser from the left channel.
154    * Initialise the pointer to the minimum penalty quantiser with the details
155    * of the left LL quantiser. Initialise the code lsbs XOR variable with the
156    * left LL quantised code lsbs */
157   xorCodeLsbs = leftChannelEncoder->m_dithSyncRandBit;
158 
159   minPenaltyQuantiser = leftQuant[LH];
160 
161   /* Traverse across all the quantisers from the left channel */
162   for (i = LL; i <= HH; i++) {
163     /* XOR in the lsb of the quantised code currently examined */
164     xorCodeLsbs ^= (leftQuant[i]->qCode) & 0x1;
165   }
166 
167   /* If the distance penalty associated with a quantiser is less than the
168    * current minimum, then make that quantiser the minimum penalty
169    * quantiser. */
170   if (leftQuant[LH]->distPenalty < minPenaltyQuantiser->distPenalty) {
171     minPenaltyQuantiser = leftQuant[LH];
172   }
173   if (leftQuant[HL]->distPenalty < minPenaltyQuantiser->distPenalty) {
174     minPenaltyQuantiser = leftQuant[HL];
175   }
176   if (leftQuant[LL]->distPenalty < minPenaltyQuantiser->distPenalty) {
177     minPenaltyQuantiser = leftQuant[LL];
178   }
179   if (leftQuant[HH]->distPenalty < minPenaltyQuantiser->distPenalty) {
180     minPenaltyQuantiser = leftQuant[HH];
181   }
182 
183   /* If the lsbs of all 4 quantised codes don't happen to equal the desired
184    * sync bit to embed, then force them to be by replacing the optimum code
185    * with the alternate code in the minimum penalty quantiser (changes the lsb
186    * of the code in this quantiser) */
187   if (xorCodeLsbs != ((syncWord >> (*syncWordPhase)) & 0x1)) {
188     minPenaltyQuantiser->qCode = minPenaltyQuantiser->altQcode;
189   }
190 
191   /****  Insert sync on the Right channel  ****/
192   xorCodeLsbs = rightChannelEncoder->m_dithSyncRandBit;
193 
194   minPenaltyQuantiser = rightQuant[LH];
195 
196   /* Traverse across all quantisers from the right channel */
197   for (i = LL; i <= HH; i++) {
198     /* XOR in the lsb of the quantised code currently examined */
199     xorCodeLsbs ^= (rightQuant[i]->qCode) & 0x1;
200   }
201 
202   /* If the distance penalty associated with a quantiser is less than the
203    * current minimum, then make that quantiser the minimum penalty
204    * quantiser. */
205   if (rightQuant[LH]->distPenalty < minPenaltyQuantiser->distPenalty) {
206     minPenaltyQuantiser = rightQuant[LH];
207   }
208   if (rightQuant[HL]->distPenalty < minPenaltyQuantiser->distPenalty) {
209     minPenaltyQuantiser = rightQuant[HL];
210   }
211   if (rightQuant[LL]->distPenalty < minPenaltyQuantiser->distPenalty) {
212     minPenaltyQuantiser = rightQuant[LL];
213   }
214   if (rightQuant[HH]->distPenalty < minPenaltyQuantiser->distPenalty) {
215     minPenaltyQuantiser = rightQuant[HH];
216   }
217 
218   /* If the lsbs of all 4 quantised codes don't happen to equal the desired
219    * sync bit to embed, then force them to be by replacing the optimum code
220    * with the alternate code in the minimum penalty quantiser (changes the lsb
221    * of the code in this quantiser) */
222   if (xorCodeLsbs != ((syncWord >> (*syncWordPhase)) & 0x1)) {
223     minPenaltyQuantiser->qCode = minPenaltyQuantiser->altQcode;
224   }
225 
226   /*  End of Right channel autosync insert*/
227   /* Decrement the selected sync word bit modulo 8 for the next pass. */
228   tmp_var = --(*syncWordPhase);
229   (*syncWordPhase) = tmp_var & 0x7;
230 }
231 
232 #ifdef _GCC
233 #pragma GCC visibility pop
234 #endif
235 #endif  // SYNCINSERTER_H
236