1 #ifndef INCLUDE_AL_AMBISONICS_HPP
2 #define INCLUDE_AL_AMBISONICS_HPP
56 #include "al/math/al_Vec.hpp"
57 #include "al/sound/al_Spatializer.hpp"
58 #include "al/sound/al_Speaker.hpp"
59 #include "al/spatial/al_DistAtten.hpp"
60 #include "al/spatial/al_Pose.hpp"
123 int dim()
const {
return mDim; }
126 int order()
const {
return mOrder; }
129 const float *
weights()
const {
return mWeights; }
143 static int channelsToUniformOrder(
int channels);
148 float azimuth,
float elevation);
161 static int orderToChannels(
int dim,
int order);
162 static int orderToChannelsH(
int orderH);
163 static int orderToChannelsV(
int orderV);
165 static int channelsToOrder(
int channels);
166 static int channelsToDimensions(
int channels);
174 template <
typename T>
static void resize(T *&a,
int n);
195 virtual void decode(
float *dec,
const float *enc,
int numDecFrames)
const;
197 float decodeWeight(
int speaker,
int channel)
const {
198 return mWeights[channel] * mDecodeMatrix[
speaker *
channels() + channel];
207 void print(std::ostream &stream)
const;
215 void setSpeakerRadians(
int index,
int deviceChannel,
float azimuth,
216 float elevation,
float amp = 1.f);
218 void setSpeaker(
int index,
int deviceChannel,
float azimuth,
219 float elevation = 0,
float amp = 1.f);
240 float *mDecodeMatrix;
248 void updateChanWeights();
249 void resizeArrays(
int numChannels,
int numSpeakers);
251 float decode(
float *encFrame,
int encNumChannels,
254 static float flavorWeights[4][5][5];
278 void encode(
float *ambiChans,
int numFrames,
int timeIndex,
279 float timeSample)
const;
286 void encode(
float *ambiChans,
const float *input,
int numFrames);
296 void encode(
float *ambiChans,
const XYZ *dir,
const float *input,
308 void direction(
float x,
float y,
float z);
310 void print(std::ostream &stream);
324 void configure(
int dim,
int order,
int flavor);
326 float *ambiChans(
unsigned channel = 0);
334 void setSpeakerLayout(
const Speakers &speakers);
339 const float *samples,
344 const unsigned int &frameIndex)
override;
348 virtual void print(std::ostream &stream = std::cout)
override;
353 std::vector<float> mAmbiDomainChannels;
360 inline int AmbiBase::orderToChannels(
int dim,
int order) {
361 int chans = orderToChannelsH(
order);
362 return dim == 2 ? chans : chans + orderToChannelsV(
order);
365 inline int AmbiBase::orderToChannelsH(
int orderH) {
return (orderH << 1) + 1; }
366 inline int AmbiBase::orderToChannelsV(
int orderV) {
return orderV * orderV; }
368 inline int AmbiBase::channelsToOrder(
int channels) {
387 inline int AmbiBase::channelsToDimensions(
int channels) {
404 template <
typename T>
void AmbiBase::resize(T *&a,
int n) {
407 memset(a, 0, n *
sizeof(T));
415 float *dec = mDecodeMatrix + speakerNum *
channels();
416 float *wc = mWeights;
417 for (
int i = 0; i < encNumChannels; ++i)
418 smp += *dec++ * *wc++ * *encFrame++;
455 float timeSample)
const {
458 #define CS(chanindex) \
460 ambiChans[chanindex * numFrames + timeIndex] += \
461 weights()[chanindex] * timeSample;
468 CS(11) CS(10) CS(9) CS(8) CS(7) CS(6) CS(5) CS(4) CS(3) CS(2) CS(1)
476 float *pAmbi = ambiChans;
479 for (
int c = 0; c <
channels(); ++c) {
480 const float *pInput = input;
482 for (
int i = 0; i < numFrames; ++i) {
483 *pAmbi++ += weight * *pInput++;
510 for (
int i = 0; i < numFrames; ++i) {
511 direction(dir[i][0], dir[i][1], dir[i][2]);
512 encode(ambiChans, numFrames, i, input[i]);
519 inline float *AmbisonicsSpatializer::ambiChans(
unsigned channel) {
520 assert(mNumFrames != 0 &&
"number of frames not set.");
521 return &mAmbiDomainChannels[channel * mNumFrames];
static void encodeWeightsFuMa(float *ws, int dim, int order, float x, float y, float z)
void dim(int dim)
Set the number of dimensions.
static void encodeWeightsFuMa(float *weights, int dim, int order, float azimuth, float elevation)
static void encodeWeightsFuMa16(float *ws, float x, float y, float z)
(x,y,z unit vector in the listener's coordinate frame)
void order(int order)
Set the order.
int channels() const
Returns total number of Ambisonic domain (B-format) channels.
AmbiBase(int dim, int order)
const float * weights() const
Get Ambisonic channel weights.
int dim() const
Get number dimensions.
static void encodeWeightsFuMa16(float *weights, float azimuth, float elevation)
Brute force 3rd order. Weights must be of size 16.
virtual void onChannelsChange()
Called whenever the number of Ambisonic channels changes.
int order() const
Get order.
void numSpeakers(int num)
Set number of speakers. Positions are zeroed upon resize.
AmbiDecode(int dim, int order, int numSpeakers, int flavor=1)
int numSpeakers() const
Returns number of speakers.
int flavor() const
Returns decode flavor.
Speaker & speaker(int num)
Get speaker.
virtual void onChannelsChange()
Called whenever the number of Ambisonic channels changes.
void flavor(int type)
Set decoding algorithm.
virtual void decode(float *dec, const float *enc, int numDecFrames) const
AmbiEncode(int dim, int order)
void encode(float *ambiChans, int numFrames, int timeIndex, float timeSample) const
Encode a single time sample.
void direction(float az, float el)
Set spherical direction of source to be encoded.
virtual void print(std::ostream &stream=std::cout) override
Print out information about spatializer.
virtual void renderSample(AudioIOData &io, const Pose &listeningPose, const float &sample, const unsigned int &frameIndex) override
Render audio sample in position.
virtual void compile() override
virtual void numFrames(unsigned int v) override
Set number of frames.
virtual void finalize(AudioIOData &io) override
virtual void renderBuffer(AudioIOData &io, const Pose &listeningPose, const float *samples, const unsigned int &numFrames) override
Render audio buffer in position.
virtual void prepare(AudioIOData &io) override
A local coordinate frame.
int numSpeakers() const
Get number of speakers.
std::vector< Speaker > Speakers
A set of speakers.