2014-02-23 21:11:01 -08:00
|
|
|
#ifndef ALC_HRTF_H
|
|
|
|
#define ALC_HRTF_H
|
|
|
|
|
2019-02-07 08:38:49 -08:00
|
|
|
#include <array>
|
2019-07-28 11:28:36 -07:00
|
|
|
#include <cstddef>
|
2019-01-08 23:44:08 -08:00
|
|
|
#include <memory>
|
2018-12-25 11:09:41 -08:00
|
|
|
#include <string>
|
|
|
|
|
2018-11-22 07:54:29 -08:00
|
|
|
#include "almalloc.h"
|
2019-09-25 02:11:37 -07:00
|
|
|
#include "alspan.h"
|
2019-07-28 11:28:36 -07:00
|
|
|
#include "ambidefs.h"
|
|
|
|
#include "atomic.h"
|
2020-11-27 19:18:17 -08:00
|
|
|
#include "core/bufferline.h"
|
2020-12-04 09:42:13 -08:00
|
|
|
#include "core/filters/splitter.h"
|
2020-03-01 17:16:09 -08:00
|
|
|
#include "intrusive_ptr.h"
|
2019-07-28 11:28:36 -07:00
|
|
|
#include "vector.h"
|
|
|
|
|
2019-07-28 21:29:59 -07:00
|
|
|
|
2020-08-28 23:26:55 -07:00
|
|
|
#define HRTF_HISTORY_BITS 6
|
2018-01-11 03:53:25 -08:00
|
|
|
#define HRTF_HISTORY_LENGTH (1<<HRTF_HISTORY_BITS)
|
|
|
|
#define HRTF_HISTORY_MASK (HRTF_HISTORY_LENGTH-1)
|
|
|
|
|
2020-08-28 23:26:55 -07:00
|
|
|
#define HRIR_BITS 7
|
2019-12-11 02:24:44 -08:00
|
|
|
#define HRIR_LENGTH (1<<HRIR_BITS)
|
|
|
|
#define HRIR_MASK (HRIR_LENGTH-1)
|
|
|
|
|
2020-08-28 23:26:55 -07:00
|
|
|
#define MIN_IR_LENGTH 8
|
2018-01-11 03:53:25 -08:00
|
|
|
|
2019-11-28 09:46:16 -08:00
|
|
|
using float2 = std::array<float,2>;
|
|
|
|
using HrirArray = std::array<float2,HRIR_LENGTH>;
|
2020-11-22 17:27:22 -08:00
|
|
|
using ubyte = unsigned char;
|
|
|
|
using ubyte2 = std::array<ubyte,2>;
|
|
|
|
using ushort = unsigned short;
|
|
|
|
using uint = unsigned int;
|
2018-01-11 03:53:25 -08:00
|
|
|
|
2019-11-28 06:10:36 -08:00
|
|
|
struct HrtfStore {
|
2019-09-14 18:27:57 -07:00
|
|
|
RefCount mRef;
|
2017-04-06 13:00:29 -07:00
|
|
|
|
2020-11-22 17:27:22 -08:00
|
|
|
uint sampleRate;
|
|
|
|
uint irSize;
|
2017-10-23 13:26:35 -07:00
|
|
|
|
2019-01-28 20:31:58 -08:00
|
|
|
struct Field {
|
2020-03-30 13:43:49 -07:00
|
|
|
float distance;
|
2020-11-22 17:27:22 -08:00
|
|
|
ubyte evCount;
|
2019-01-28 20:31:58 -08:00
|
|
|
};
|
2019-02-27 23:13:40 -08:00
|
|
|
/* NOTE: Fields are stored *backwards*. field[0] is the farthest field, and
|
|
|
|
* field[fdCount-1] is the nearest.
|
|
|
|
*/
|
2020-11-22 17:27:22 -08:00
|
|
|
uint fdCount;
|
2019-05-22 10:58:18 -07:00
|
|
|
const Field *field;
|
2016-07-07 10:26:42 -07:00
|
|
|
|
2019-05-22 10:58:18 -07:00
|
|
|
struct Elevation {
|
2020-11-22 17:27:22 -08:00
|
|
|
ushort azCount;
|
|
|
|
ushort irOffset;
|
2019-05-22 10:58:18 -07:00
|
|
|
};
|
|
|
|
Elevation *elev;
|
2019-11-28 09:46:16 -08:00
|
|
|
const HrirArray *coeffs;
|
2019-12-30 21:04:10 -08:00
|
|
|
const ubyte2 *delays;
|
2019-01-24 10:05:37 -08:00
|
|
|
|
2020-03-01 17:16:09 -08:00
|
|
|
void add_ref();
|
|
|
|
void release();
|
2019-01-24 10:05:37 -08:00
|
|
|
|
|
|
|
DEF_PLACE_NEWDEL()
|
2016-07-07 10:26:42 -07:00
|
|
|
};
|
2020-03-01 17:16:09 -08:00
|
|
|
using HrtfStorePtr = al::intrusive_ptr<HrtfStore>;
|
2014-02-23 21:11:01 -08:00
|
|
|
|
2017-01-18 19:16:24 -08:00
|
|
|
|
2019-06-18 06:20:35 -07:00
|
|
|
struct HrtfFilter {
|
2019-07-31 10:46:33 -07:00
|
|
|
alignas(16) HrirArray Coeffs;
|
2020-11-22 17:27:22 -08:00
|
|
|
std::array<uint,2> Delay;
|
2019-11-29 08:33:46 -08:00
|
|
|
float Gain;
|
2018-11-22 06:59:32 -08:00
|
|
|
};
|
2018-01-11 03:53:25 -08:00
|
|
|
|
|
|
|
|
2019-12-06 23:11:26 -08:00
|
|
|
struct EvRadians { float value; };
|
|
|
|
struct AzRadians { float value; };
|
2018-02-17 22:12:54 -08:00
|
|
|
struct AngularPoint {
|
2019-12-06 23:11:26 -08:00
|
|
|
EvRadians Elev;
|
|
|
|
AzRadians Azim;
|
2018-02-17 22:12:54 -08:00
|
|
|
};
|
|
|
|
|
2020-05-21 15:25:03 -07:00
|
|
|
#define HRTF_DIRECT_DELAY 192
|
2020-05-01 10:28:16 -07:00
|
|
|
struct DirectHrtfState {
|
2020-05-19 10:27:52 -07:00
|
|
|
struct ChannelData {
|
|
|
|
std::array<float,HRTF_DIRECT_DELAY> mDelay{};
|
|
|
|
BandSplitter mSplitter;
|
|
|
|
float mHfScale{};
|
|
|
|
alignas(16) HrirArray mCoeffs{};
|
|
|
|
};
|
|
|
|
|
2020-11-28 03:38:20 -08:00
|
|
|
std::array<float,HRTF_DIRECT_DELAY+BufferLineSize> mTemp;
|
2020-05-19 10:27:52 -07:00
|
|
|
|
2020-05-01 10:28:16 -07:00
|
|
|
/* HRTF filter state for dry buffer content */
|
2020-11-22 17:27:22 -08:00
|
|
|
uint mIrSize{0};
|
2020-05-19 10:27:52 -07:00
|
|
|
al::FlexArray<ChannelData> mChannels;
|
2020-05-01 10:28:16 -07:00
|
|
|
|
2020-05-19 10:27:52 -07:00
|
|
|
DirectHrtfState(size_t numchans) : mChannels{numchans} { }
|
2020-05-01 10:28:16 -07:00
|
|
|
/**
|
|
|
|
* Produces HRTF filter coefficients for decoding B-Format, given a set of
|
|
|
|
* virtual speaker positions, a matching decoding matrix, and per-order
|
|
|
|
* high-frequency gains for the decoder. The calculated impulse responses
|
|
|
|
* are ordered and scaled according to the matrix input.
|
|
|
|
*/
|
2020-12-11 15:08:50 -08:00
|
|
|
void build(const HrtfStore *Hrtf, const uint irSize,
|
|
|
|
const al::span<const AngularPoint> AmbiPoints, const float (*AmbiMatrix)[MaxAmbiChannels],
|
2020-12-04 13:53:56 -08:00
|
|
|
const al::span<const float,MaxAmbiOrder+1> AmbiOrderHFGain);
|
2020-05-01 10:28:16 -07:00
|
|
|
|
|
|
|
static std::unique_ptr<DirectHrtfState> Create(size_t num_chans);
|
|
|
|
|
2020-05-19 10:27:52 -07:00
|
|
|
DEF_FAM_NEWDEL(DirectHrtfState, mChannels)
|
2020-05-01 10:28:16 -07:00
|
|
|
};
|
|
|
|
|
2018-01-11 03:53:25 -08:00
|
|
|
|
2019-11-28 08:24:29 -08:00
|
|
|
al::vector<std::string> EnumerateHrtf(const char *devname);
|
2020-12-11 15:08:50 -08:00
|
|
|
HrtfStorePtr GetLoadedHrtf(const std::string &name, const uint devrate);
|
2015-10-06 00:23:11 -07:00
|
|
|
|
2019-11-29 08:33:46 -08:00
|
|
|
void GetHrtfCoeffs(const HrtfStore *Hrtf, float elevation, float azimuth, float distance,
|
2020-11-22 17:27:22 -08:00
|
|
|
float spread, HrirArray &coeffs, const al::span<uint,2> delays);
|
2014-02-23 21:11:01 -08:00
|
|
|
|
|
|
|
#endif /* ALC_HRTF_H */
|