3 This software is being provided to you, the licensee, by Ville Pulkki,
4 under the following license. By obtaining, using and/or copying this
5 software, you agree that you have read, understood, and will comply
6 with these terms and conditions: Permission to use, copy, modify and
7 distribute, including the right to grant others rights to distribute
8 at any tier, this software and its documentation for any purpose and
9 without fee or royalty is hereby granted, provided that you agree to
10 comply with the following copyright notice and statements, including
11 the disclaimer, and that the same appear on ALL copies of the software
12 and documentation, including modifications that you make for internal
13 use or for distribution:
15 Copyright 1998 by Ville Pulkki, Helsinki University of Technology. All
18 The software may be used, distributed, and included to commercial
19 products without any charges. When included to a commercial product,
20 the method "Vector Base Amplitude Panning" and its developer Ville
21 Pulkki must be referred to in documentation.
23 This software is provided "as is", and Ville Pulkki or Helsinki
24 University of Technology make no representations or warranties,
25 expressed or implied. By way of example, but not limitation, Helsinki
26 University of Technology or Ville Pulkki make no representations or
27 warranties of merchantability or fitness for any particular purpose or
28 that the use of the licensed software or documentation will not
29 infringe any third party patents, copyrights, trademarks or other
30 rights. The name of Ville Pulkki or Helsinki University of Technology
31 may not be used in advertising or publicity pertaining to distribution
43 #include "pbd/cartesian.h"
45 #include "ardour/speakers.h"
46 #include "ardour/vbap.h"
47 #include "ardour/vbap_speakers.h"
48 #include "ardour/audio_buffer.h"
49 #include "ardour/buffer_set.h"
52 using namespace ARDOUR;
55 string VBAPanner::name = X_("VBAP");
57 VBAPanner::VBAPanner (Panner& parent, Evoral::Parameter param, Speakers& s)
58 : StreamPanner (parent, param)
60 , _speakers (VBAPSpeakers::instance (s))
64 VBAPanner::~VBAPanner ()
71 /* force 2D for now */
79 VBAPanner::compute_gains (double gains[3], int speaker_ids[3], int azi, int ele)
81 /* calculates gain factors using loudspeaker setup and given direction */
86 double big_sm_g, gtmp[3];
88 azi_ele_to_cart (azi,ele, cartdir[0], cartdir[1], cartdir[2]);
91 gains[0] = gains[1] = gains[2] = 0;
92 speaker_ids[0] = speaker_ids[1] = speaker_ids[2] = 0;
94 for (i = 0; i < _speakers.n_tuples(); i++) {
98 for (j = 0; j < _speakers.dimension(); j++) {
102 for (k = 0; k < _speakers.dimension(); k++) {
103 gtmp[j] += cartdir[k] * _speakers.matrix(i)[j*_speakers.dimension()+k];
106 if (gtmp[j] < small_g) {
111 if (small_g > big_sm_g) {
118 speaker_ids[0] = _speakers.speaker_for_tuple (i, 0);
119 speaker_ids[1] = _speakers.speaker_for_tuple (i, 1);
121 if (_speakers.dimension() == 3) {
123 speaker_ids[2] = _speakers.speaker_for_tuple (i, 2);
131 power = sqrt (gains[0]*gains[0] + gains[1]*gains[1] + gains[2]*gains[2]);
143 VBAPanner::do_distribute (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gain_coefficient, pframes_t nframes)
149 Sample* const src = srcbuf.data();
152 uint32_t n_audio = obufs.count().n_audio();
155 if ((was_dirty = _dirty)) {
156 compute_gains (desired_gains, desired_outputs, _angles.azi, _angles.ele);
157 cerr << " @ " << _angles.azi << " /= " << _angles.ele
159 << desired_outputs[0] + 1 << ' '
160 << desired_outputs[1] + 1 << ' '
162 << desired_gains[0] << ' '
163 << desired_gains[1] << ' '
169 for (uint32_t o = 0; o < n_audio; ++o) {
174 /* VBAP may distribute the signal across up to 3 speakers depending on
175 the configuration of the speakers.
178 for (int o = 0; o < 3; ++o) {
179 if (desired_outputs[o] != -1) {
183 /* XXX TODO: interpolate across changes in gain and/or outputs
186 dst = obufs.get_audio(desired_outputs[o]).data();
188 pan = gain_coefficient * desired_gains[o];
189 mix_buffers_with_gain (dst+n,src+n,nframes-n,pan);
195 for (uint32_t o = 0; o < n_audio; ++o) {
197 /* VBAP decided not to deliver any audio to this output, so we write silence */
198 dst = obufs.get_audio(o).data();
199 memset (dst, 0, sizeof (Sample) * nframes);
204 memcpy (gains, desired_gains, sizeof (gains));
205 memcpy (outputs, desired_outputs, sizeof (outputs));
210 VBAPanner::do_distribute_automated (AudioBuffer& src, BufferSet& obufs,
211 framepos_t start, framepos_t end, pframes_t nframes, pan_t** buffers)
216 VBAPanner::get_state ()
222 VBAPanner::state (bool full_state)
224 XMLNode& node (StreamPanner::get_state());
225 node.add_property (X_("type"), VBAPanner::name);
230 VBAPanner::set_state (const XMLNode& node, int /*version*/)
236 VBAPanner::factory (Panner& parent, Evoral::Parameter param, Speakers& s)
238 return new VBAPanner (parent, param, s);