File: AmbisonicProcessor.h

package info (click to toggle)
libspatialaudio 0.3.0%2Bgit20180730%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, buster
  • size: 464 kB
  • sloc: cpp: 2,293; ansic: 1,247; makefile: 5
file content (197 lines) | stat: -rw-r--r-- 6,228 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/*############################################################################*/
/*#                                                                          #*/
/*#  Ambisonic C++ Library                                                   #*/
/*#  CAmbisonicProcessor - Ambisonic Processor                               #*/
/*#  Copyright © 2007 Aristotel Digenis                                      #*/
/*#  Copyright © 2017 Videolabs                                              #*/
/*#                                                                          #*/
/*#  Filename:      AmbisonicProcessor.h                                     #*/
/*#  Version:       0.2                                                      #*/
/*#  Date:          19/05/2007                                               #*/
/*#  Author(s):     Aristotel Digenis, Peter Stitt                           #*/
/*#  Licence:       LGPL (+ Proprietary)                                     #*/
/*#                                                                          #*/
/*############################################################################*/


#ifndef _AMBISONIC_PROCESSOR_H
#define    _AMBISONIC_PROCESSOR_H

#include "AmbisonicBase.h"
#include "BFormat.h"
#include "kiss_fftr.h"
#include "AmbisonicPsychoacousticFilters.h"
#include "AmbisonicZoomer.h"

enum ProcessorDOR
{
    kYaw, kRoll, kPitch, kNumProcessorDOR //(Degrees of Rotation)
};

enum ProcessorModes
{
    kYawRollPitch, kYawPitchRoll,
    kRollYawPitch, kRollPitchYaw,
    kPitchYawRoll, kPitchRollYaw,
    kNumProcessorModes
};


class CAmbisonicProcessor;


/// Struct for soundfield rotation.
class Orientation
{
public:
    Orientation(float fYaw, float fPitch, float fRoll)
        : fYaw(fYaw), fPitch(fPitch), fRoll(fRoll)
    {
        float fCosYaw = cosf(fYaw);
        float fSinYaw = sinf(fYaw);
        float fCosRoll = cosf(fRoll);
        float fSinRoll = sinf(fRoll);
        float fCosPitch = cosf(fPitch);
        float fSinPitch = sinf(fPitch);

        /* Conversion from yaw, pitch, roll (ZYX) to ZYZ convention to match rotation matrices
        This method reduces the complexity of the rotation matrices since the Z0 and Z1 rotations are the same form */
        float r33 = fCosPitch * fCosRoll;
        if (r33 == 1.f)
        {
            fBeta = 0.f;
            fGamma = 0.f;
            fAlpha = atan2(fSinYaw, fCosYaw);
        }
        else
        {
            if (r33 == -1.f)
            {
                fBeta = M_PI;
                fGamma = 0.f;
                fAlpha = atan2(-fSinYaw, fCosYaw);
            }
            else
            {

                float r32 = -fCosYaw * fSinRoll + fCosRoll * fSinPitch * fSinYaw ;
                float r31 = fCosRoll * fCosYaw * fSinPitch + fSinRoll * fSinYaw ;
                fAlpha = atan2( r32 , r31 );

                fBeta = acos( r33 );

                float r23 = fCosPitch * fSinRoll;
                float r13 = -fSinPitch;
                fGamma = atan2( r23 , -r13 );
            }
        }
    }

    friend class CAmbisonicProcessor;

private:
    /** rotation around the Z axis (yaw) */
    float fYaw;
    /** rotation around the Y axis (pitch) */
    float fPitch;
    /** rotation around the X axis (roll) */
    float fRoll;

    /** These angles are obtained from Yaw, Pitch and Roll (ZYX convention)**/
    /** They follow the ZYZ convention to match the rotation equations **/
    /** rotation around the Z axis */
    float fAlpha;
    /** rotation around the X axis */
    float fBeta;
    /** rotation around the new Z axis */
    float fGamma;
};


/// Ambisonic processor.

/** This object is used to rotate the BFormat signal around all three axes.
    Orientation structs are used to define the the soundfield's orientation. */

class CAmbisonicProcessor : public CAmbisonicBase
{
public:
    CAmbisonicProcessor();
    ~CAmbisonicProcessor();
    /**
        Re-create the object for the given configuration. Previous data is
        lost. The last argument is not used, it is just there to match with 
        the base class's form. Returns true if successful.
    */
    bool Configure(unsigned nOrder, bool b3D, unsigned nBlockSize, unsigned nMisc);
    /**
        Not implemented.
    */
    void Reset();
    /**
        Recalculate coefficients.
    */
    void Refresh();
    /**
        Set yaw, roll, and pitch settings.
    */
    void SetOrientation(Orientation orientation);
    /**
        Get yaw, roll, and pitch settings.
    */
    Orientation GetOrientation();
    /**
        Rotate B-Format stream.
    */
    void Process(CBFormat* pBFSrcDst, unsigned nSamples);

private:
    void ProcessOrder1_3D(CBFormat* pBFSrcDst, unsigned nSamples);
    void ProcessOrder2_3D(CBFormat* pBFSrcDst, unsigned nSamples);
    void ProcessOrder3_3D(CBFormat* pBFSrcDst, unsigned nSamples);
    void ProcessOrder1_2D(CBFormat* pBFSrcDst, unsigned nSamples);
    void ProcessOrder2_2D(CBFormat* pBFSrcDst, unsigned nSamples);
    void ProcessOrder3_2D(CBFormat* pBFSrcDst, unsigned nSamples);

    void ShelfFilterOrder(CBFormat* pBFSrcDst, unsigned nSamples);

protected:
    Orientation m_orientation;
    float* m_pfTempSample;

    kiss_fftr_cfg m_pFFT_psych_cfg;
    kiss_fftr_cfg m_pIFFT_psych_cfg;

    float* m_pfScratchBufferA;
    float** m_pfOverlap;
    unsigned m_nFFTSize;
    unsigned m_nBlockSize;
    unsigned m_nTaps;
    unsigned m_nOverlapLength;
    unsigned m_nFFTBins;
    float m_fFFTScaler;

    kiss_fft_cpx** m_ppcpPsychFilters;
    kiss_fft_cpx* m_pcpScratch;

    float m_fCosAlpha;
    float m_fSinAlpha;
    float m_fCosBeta;
    float m_fSinBeta;
    float m_fCosGamma;
    float m_fSinGamma;
    float m_fCos2Alpha;
    float m_fSin2Alpha;
    float m_fCos2Beta;
    float m_fSin2Beta;
    float m_fCos2Gamma;
    float m_fSin2Gamma;
    float m_fCos3Alpha;
    float m_fSin3Alpha;
    float m_fCos3Beta;
    float m_fSin3Beta;
    float m_fCos3Gamma;
    float m_fSin3Gamma;
};

#endif // _AMBISONIC_PROCESSOR_H