ardour
pcm_utils.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2006 Paul Davis , portions Erik de Castro Lopo
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 
18 */
19 
20 #ifdef COMPILER_MSVC
21 #include <ardourext/float_cast.h>
22 #endif
23 #include "ardour/pcm_utils.h"
24 #include <cmath>
25 
26 using namespace std;
27 
28 // TODO: check CPU_CLIPS_POSITIVE and CPU_CLIPS_NEGATIVE with scons
29 #define CPU_CLIPS_NEGATIVE 0
30 #define CPU_CLIPS_POSITIVE 0
31 
32 /* these routines deal with 24 bit int handling (tribytes)
33  * originally from libsndfile, but modified. XXX - Copyright Erik de Castro Lopo
34  */
35 
36 void
37 pcm_let2f_array (tribyte *src, int count, float *dest)
38 {
39  /* Special normfactor because tribyte value is read into an int. */
40  static const float normfact = 1.0 / ((float) 0x80000000);
41 
42  unsigned char *ucptr ;
43  int value ;
44 
45  ucptr = ((unsigned char*) src) + 3 * count ;
46  while (--count >= 0)
47  { ucptr -= 3 ;
48  value = LET2H_INT_PTR (ucptr) ;
49  dest [count] = ((float) value) * normfact ;
50  } ;
51 } /* let2f_array */
52 
53 void
54 pcm_bet2f_array (tribyte *src, int count, float *dest)
55 {
56  /* Special normfactor because tribyte value is read into an int. */
57  static const float normfact = 1.0 / ((float) 0x80000000);
58 
59  unsigned char *ucptr ;
60  int value ;
61 
62 
63  ucptr = ((unsigned char*) src) + 3 * count ;
64  while (--count >= 0)
65  { ucptr -= 3 ;
66  value = BET2H_INT_PTR (ucptr) ;
67  dest [count] = ((float) value) * normfact ;
68  } ;
69 } /* bet2f_array */
70 
71 void
72 pcm_f2let_array (float *src, tribyte *dest, int count)
73 {
74  static const float normfact = (1.0 * 0x7FFFFF);
75 
76  unsigned char *ucptr ;
77  int value ;
78 
79  ucptr = ((unsigned char*) dest) + 3 * count ;
80 
81  while (count)
82  { count -- ;
83  ucptr -= 3 ;
84  value = lrintf (src [count] * normfact) ;
85  ucptr [0] = value ;
86  ucptr [1] = value >> 8 ;
87  ucptr [2] = value >> 16 ;
88  } ;
89 } /* f2let_array */
90 
91 void
92 pcm_f2let_clip_array (float *src, tribyte *dest, int count)
93 {
94  static const float normfact = (8.0 * 0x10000000);
95 
96  unsigned char *ucptr ;
97  float scaled_value ;
98  int value ;
99 
100  ucptr = ((unsigned char*) dest) + 3 * count ;
101 
102  while (count)
103  { count -- ;
104  ucptr -= 3 ;
105  scaled_value = src [count] * normfact ;
106  if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
107  { ucptr [0] = 0xFF ;
108  ucptr [1] = 0xFF ;
109  ucptr [2] = 0x7F ;
110  continue ;
111  } ;
112  if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
113  { ucptr [0] = 0x00 ;
114  ucptr [1] = 0x00 ;
115  ucptr [2] = 0x80 ;
116  continue ;
117  } ;
118 
119  value = lrintf (scaled_value) ;
120  ucptr [0] = value >> 8 ;
121  ucptr [1] = value >> 16 ;
122  ucptr [2] = value >> 24 ;
123  } ;
124 } /* f2let_clip_array */
125 
126 void
127 pcm_f2bet_array (const float *src, tribyte *dest, int count)
128 {
129  static const float normfact = (1.0 * 0x7FFFFF);
130 
131  unsigned char *ucptr ;
132  int value ;
133 
134  ucptr = ((unsigned char*) dest) + 3 * count ;
135 
136  while (--count >= 0)
137  { ucptr -= 3 ;
138  value = lrintf (src [count] * normfact) ;
139  ucptr [0] = value >> 16 ;
140  ucptr [1] = value >> 8 ;
141  ucptr [2] = value ;
142  } ;
143 } /* f2bet_array */
144 
145 void
146 pcm_f2bet_clip_array (const float *src, tribyte *dest, int count)
147 {
148  static const float normfact = (8.0 * 0x10000000);
149 
150  unsigned char *ucptr ;
151  float scaled_value ;
152  int value ;
153 
154  ucptr = ((unsigned char*) dest) + 3 * count ;
155 
156  while (--count >= 0)
157  { ucptr -= 3 ;
158  scaled_value = src [count] * normfact ;
159  if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
160  { ucptr [0] = 0x7F ;
161  ucptr [1] = 0xFF ;
162  ucptr [2] = 0xFF ;
163  continue ;
164  } ;
165  if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
166  { ucptr [0] = 0x80 ;
167  ucptr [1] = 0x00 ;
168  ucptr [2] = 0x00 ;
169  continue ;
170  } ;
171 
172  value = lrint (scaled_value) ;
173  ucptr [0] = value >> 24 ;
174  ucptr [1] = value >> 16 ;
175  ucptr [2] = value >> 8 ;
176  } ;
177 } /* f2bet_clip_array */
178 
179 //@@@@@@@
#define CPU_CLIPS_NEGATIVE
Definition: pcm_utils.cc:29
void pcm_bet2f_array(tribyte *src, int count, float *dest)
Definition: pcm_utils.cc:54
void pcm_f2bet_clip_array(const float *src, tribyte *dest, int count)
Definition: pcm_utils.cc:146
Definition: Beats.hpp:239
void tribyte
Definition: pcm_utils.h:23
void pcm_f2let_array(float *src, tribyte *dest, int count)
Definition: pcm_utils.cc:72
#define CPU_CLIPS_POSITIVE
Definition: pcm_utils.cc:30
#define LET2H_INT_PTR(x)
Definition: pcm_utils.h:28
#define BET2H_INT_PTR(x)
Definition: pcm_utils.h:27
void pcm_f2bet_array(const float *src, tribyte *dest, int count)
Definition: pcm_utils.cc:127
void pcm_f2let_clip_array(float *src, tribyte *dest, int count)
Definition: pcm_utils.cc:92
void pcm_let2f_array(tribyte *src, int count, float *dest)
Definition: pcm_utils.cc:37