1 /* ----------------------------------------------------------------------
2  * Project:      CMSIS DSP Library
3  * Title:        arm_f64_to_q31.c
4  * Description:  Converts the elements of the 64 bit floating-point vector to Q31 vector
5  *
6  * $Date:        18 August 2022
7  * $Revision:    V1.0.0
8  *
9  * Target Processor: Cortex-M and Cortex-A cores
10  * -------------------------------------------------------------------- */
11 /*
12  * Copyright (C) 2010-2022 ARM Limited or its affiliates. All rights reserved.
13  *
14  * SPDX-License-Identifier: Apache-2.0
15  *
16  * Licensed under the Apache License, Version 2.0 (the License); you may
17  * not use this file except in compliance with the License.
18  * You may obtain a copy of the License at
19  *
20  * www.apache.org/licenses/LICENSE-2.0
21  *
22  * Unless required by applicable law or agreed to in writing, software
23  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
24  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25  * See the License for the specific language governing permissions and
26  * limitations under the License.
27  */
28 
29 #include "dsp/support_functions.h"
30 
31 /**
32   @ingroup groupSupport
33  */
34 
35 
36 /**
37   @addtogroup f64_to_x
38   @{
39  */
40 
41 /**
42   @brief         Converts the elements of the 64 bit floating-point vector to Q31 vector.
43   @param[in]     pSrc       points to the 64 bit floating-point input vector
44   @param[out]    pDst       points to the Q31 output vector
45   @param[in]     blockSize  number of samples in each vector
46 
47   @par           Details
48                    The equation used for the conversion process is:
49   <pre>
50       pDst[n] = (q31_t)(pSrc[n] * 2147483648);   0 <= n < blockSize.
51   </pre>
52 
53   @par           Scaling and Overflow Behavior
54                    The function uses saturating arithmetic.
55                    Results outside of the allowable Q31 range[0x80000000 0x7FFFFFFF] are saturated.
56 
57   @note
58                    In order to apply rounding, the library should be rebuilt with the ROUNDING macro
59                    defined in the preprocessor section of project options.
60  */
61 
62 
arm_f64_to_q31(const float64_t * pSrc,q31_t * pDst,uint32_t blockSize)63 void arm_f64_to_q31(
64   const float64_t * pSrc,
65         q31_t * pDst,
66         uint32_t blockSize)
67 {
68         uint32_t blkCnt;                               /* Loop counter */
69   const float64_t *pIn = pSrc;                         /* Source pointer */
70 
71 #ifdef ARM_MATH_ROUNDING
72         float64_t in;
73 #endif /* #ifdef ARM_MATH_ROUNDING */
74 
75 #if defined (ARM_MATH_LOOPUNROLL)
76 
77   /* Loop unrolling: Compute 4 outputs at a time */
78   blkCnt = blockSize >> 2U;
79 
80   while (blkCnt > 0U)
81   {
82     /* C = A * 2147483648 */
83 
84     /* convert from float to Q31 and store result in destination buffer */
85 #ifdef ARM_MATH_ROUNDING
86 
87     in = (*pIn++ * 2147483648.0);
88     in += in > 0.0 ? 0.5 : -0.5;
89     *pDst++ = clip_q63_to_q31((q63_t) (in));
90 
91     in = (*pIn++ * 2147483648.0);
92     in += in > 0.0 ? 0.5 : -0.5;
93     *pDst++ = clip_q63_to_q31((q63_t) (in));
94 
95     in = (*pIn++ * 2147483648.0);
96     in += in > 0.0 ? 0.5 : -0.5;
97     *pDst++ = clip_q63_to_q31((q63_t) (in));
98 
99     in = (*pIn++ * 2147483648.0);
100     in += in > 0.0 ? 0.5 : -0.5;
101     *pDst++ = clip_q63_to_q31((q63_t) (in));
102 
103 #else
104 
105     /* C = A * 2147483648 */
106     /* Convert from float to Q31 and then store the results in the destination buffer */
107     *pDst++ = clip_q63_to_q31((q63_t) (*pIn++ * 2147483648.0));
108     *pDst++ = clip_q63_to_q31((q63_t) (*pIn++ * 2147483648.0));
109     *pDst++ = clip_q63_to_q31((q63_t) (*pIn++ * 2147483648.0));
110     *pDst++ = clip_q63_to_q31((q63_t) (*pIn++ * 2147483648.0));
111 
112 #endif /* #ifdef ARM_MATH_ROUNDING */
113 
114     /* Decrement loop counter */
115     blkCnt--;
116   }
117 
118   /* Loop unrolling: Compute remaining outputs */
119   blkCnt = blockSize % 0x4U;
120 
121 #else
122 
123   /* Initialize blkCnt with number of samples */
124   blkCnt = blockSize;
125 
126 #endif /* #if defined (ARM_MATH_LOOPUNROLL) */
127 
128   while (blkCnt > 0U)
129   {
130     /* C = A * 2147483648 */
131 
132     /* convert from float to Q31 and store result in destination buffer */
133 #ifdef ARM_MATH_ROUNDING
134 
135     in = (*pIn++ * 2147483648.0);
136     in += in > 0.0 ? 0.5 : -0.5;
137     *pDst++ = clip_q63_to_q31((q63_t) (in));
138 
139 #else
140 
141     /* C = A * 2147483648 */
142     /* Convert from float to Q31 and then store the results in the destination buffer */
143     *pDst++ = clip_q63_to_q31((q63_t) (*pIn++ * 2147483648.0));
144 
145 #endif /* #ifdef ARM_MATH_ROUNDING */
146 
147     /* Decrement loop counter */
148     blkCnt--;
149   }
150 
151 }
152 
153 
154 /**
155   @} end of f64_to_x group
156  */
157