ardour
mix.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2000-2005 Paul Davis
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 #include <cmath>
21 #include "ardour/types.h"
22 #include "ardour/utils.h"
23 #include "ardour/mix.h"
25 #include <stdint.h>
26 
27 using std::min;
28 using std::max;
29 using namespace ARDOUR;
30 
31 #if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS)
32 // Debug wrappers
33 
34 float
35 debug_compute_peak (const ARDOUR::Sample *buf, pframes_t nsamples, float current)
36 {
37  if ( ((intptr_t)buf % 16) != 0) {
38  std::cerr << "compute_peak(): buffer unaligned!" << std::endl;
39  }
40 
41  return x86_sse_compute_peak(buf, nsamples, current);
42 }
43 
44 void
45 debug_apply_gain_to_buffer (ARDOUR::Sample *buf, pframes_t nframes, float gain)
46 {
47  if ( ((intptr_t)buf % 16) != 0) {
48  std::cerr << "apply_gain_to_buffer(): buffer unaligned!" << std::endl;
49  }
50 
51  x86_sse_apply_gain_to_buffer(buf, nframes, gain);
52 }
53 
54 void
55 debug_mix_buffers_with_gain (ARDOUR::Sample *dst, const ARDOUR::Sample *src, pframes_t nframes, float gain)
56 {
57  if ( ((intptr_t)dst & 15) != 0) {
58  std::cerr << "mix_buffers_with_gain(): dst unaligned!" << std::endl;
59  }
60 
61  if ( ((intptr_t)dst & 15) != ((intptr_t)src & 15) ) {
62  std::cerr << "mix_buffers_with_gain(): dst & src don't have the same alignment!" << std::endl;
63  mix_buffers_with_gain(dst, src, nframes, gain);
64  } else {
65  x86_sse_mix_buffers_with_gain(dst, src, nframes, gain);
66  }
67 }
68 
69 void
70 debug_mix_buffers_no_gain (ARDOUR::Sample *dst, const ARDOUR::Sample *src, pframes_t nframes)
71 {
72  if ( ((intptr_t)dst & 15) != 0) {
73  std::cerr << "mix_buffers_no_gain(): dst unaligned!" << std::endl;
74  }
75 
76  if ( ((intptr_t)dst & 15) != ((intptr_t)src & 15) ) {
77  std::cerr << "mix_buffers_no_gain(): dst & src don't have the same alignment!" << std::endl;
78  mix_buffers_no_gain(dst, src, nframes);
79  } else {
80  x86_sse_mix_buffers_no_gain(dst, src, nframes);
81  }
82 }
83 
84 #endif
85 
86 
87 float
88 default_compute_peak (const ARDOUR::Sample * buf, pframes_t nsamples, float current)
89 {
90  for (pframes_t i = 0; i < nsamples; ++i) {
91  current = f_max (current, fabsf (buf[i]));
92  }
93 
94  return current;
95 }
96 
97 void
98 default_find_peaks (const ARDOUR::Sample * buf, pframes_t nframes, float *minf, float *maxf)
99 {
100  pframes_t i;
101  float a, b;
102 
103  a = *maxf;
104  b = *minf;
105 
106  for (i = 0; i < nframes; i++)
107  {
108  a = max (buf[i], a);
109  b = min (buf[i], b);
110  }
111 
112  *maxf = a;
113  *minf = b;
114 }
115 
116 void
118 {
119  for (pframes_t i=0; i<nframes; i++)
120  buf[i] *= gain;
121 }
122 
123 void
124 default_mix_buffers_with_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, pframes_t nframes, float gain)
125 {
126  for (pframes_t i = 0; i < nframes; i++) {
127  dst[i] += src[i] * gain;
128  }
129 }
130 
131 void
133 {
134  for (pframes_t i=0; i < nframes; i++) {
135  dst[i] += src[i];
136  }
137 }
138 
139 #if defined (__APPLE__) && defined (BUILD_VECLIB_OPTIMIZATIONS)
140 #include <Accelerate/Accelerate.h>
141 
142 float
143 veclib_compute_peak (const ARDOUR::Sample * buf, pframes_t nsamples, float current)
144 {
145  float tmpmax = 0.0f;
146  vDSP_maxmgv(buf, 1, &tmpmax, nsamples);
147  return f_max(current, tmpmax);
148 }
149 
150 void
151 veclib_find_peaks (const ARDOUR::Sample * buf, pframes_t nframes, float *min, float *max)
152 {
153  vDSP_maxv (const_cast<ARDOUR::Sample*>(buf), 1, max, nframes);
154  vDSP_minv (const_cast<ARDOUR::Sample*>(buf), 1, min, nframes);
155 }
156 
157 void
158 veclib_apply_gain_to_buffer (ARDOUR::Sample * buf, pframes_t nframes, float gain)
159 {
160  vDSP_vsmul(buf, 1, &gain, buf, 1, nframes);
161 }
162 
163 void
164 veclib_mix_buffers_with_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, pframes_t nframes, float gain)
165 {
166  vDSP_vsma(src, 1, &gain, dst, 1, dst, 1, nframes);
167 }
168 
169 void
170 veclib_mix_buffers_no_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, pframes_t nframes)
171 {
172  // It seems that a vector mult only operation does not exist...
173  float gain = 1.0f;
174  vDSP_vsma(src, 1, &gain, dst, 1, dst, 1, nframes);
175 }
176 
177 #endif
178 
179 
void default_find_peaks(const ARDOUR::Sample *buf, pframes_t nframes, float *minf, float *maxf)
Definition: mix.cc:98
uint32_t pframes_t
Definition: types.h:61
LIBARDOUR_API PBD::PropertyDescriptor< bool > gain
Definition: route_group.cc:44
void default_apply_gain_to_buffer(ARDOUR::Sample *buf, pframes_t nframes, float gain)
Definition: mix.cc:117
LIBARDOUR_API mix_buffers_with_gain_t mix_buffers_with_gain
Definition: globals.cc:132
float Sample
Definition: types.h:54
void default_mix_buffers_no_gain(ARDOUR::Sample *dst, const ARDOUR::Sample *src, pframes_t nframes)
Definition: mix.cc:132
Definition: amp.h:29
int intptr_t
Definition: types.h:46
float default_compute_peak(const ARDOUR::Sample *buf, pframes_t nsamples, float current)
Definition: mix.cc:88
LIBARDOUR_API mix_buffers_no_gain_t mix_buffers_no_gain
Definition: globals.cc:133
void default_mix_buffers_with_gain(ARDOUR::Sample *dst, const ARDOUR::Sample *src, pframes_t nframes, float gain)
Definition: mix.cc:124
static float f_max(float x, float a)
Definition: utils.h:51