4#ifndef MACH1SPATIALSDK_MACH1DECODE_H
5#define MACH1SPATIALSDK_MACH1DECODE_H
7#include "Mach1DecodeCAPI.h"
12template <
typename PCM>
131 std::vector<PCM>
decode(
float Yaw,
float Pitch,
float Roll,
int bufferSize = 0,
int sampleIndex = 0);
149 std::vector<PCM>
decodeCoeffs(
int bufferSize = 0,
int sampleIndex = 0);
168 std::vector<PCM>
decodePannedCoeffs(
int bufferSize = 0,
int sampleIndex = 0,
bool applyPanLaw =
true);
170 std::vector<PCM> decodeCoeffsUsingTranscodeMatrix(std::vector<std::vector<float> > matrix,
int channels,
int bufferSize = 0,
int sampleIndex = 0);
172 inline void decodeBuffer(std::vector<std::vector<PCM> > &in, std::vector<std::vector<PCM> > &out,
int size);
174 inline void decodeBufferInPlace(std::vector<std::vector<PCM> > &buffer,
int size);
176 inline void decodeBufferRebuffer(std::vector<std::vector<PCM> > &in, std::vector<std::vector<PCM> > &out,
int size);
178 inline void decodeBufferInPlaceRebuffer(std::vector<std::vector<PCM> > &buffer,
int size);
180#ifndef __EMSCRIPTEN__
181 void decode(
float Yaw,
float Pitch,
float Roll,
float *result,
int bufferSize = 0,
int sampleIndex = 0);
182 void decodeCoeffs(
float *result,
int bufferSize = 0,
int sampleIndex = 0);
183 void decodePannedCoeffs(
float *result,
int bufferSize = 0,
int sampleIndex = 0,
bool applyPanLaw =
true);
199 std::vector<float> old_decode_gains;
200 std::vector<std::vector<float> > intermediary_buffer;
201 int ib_channel_count;
202 size_t ib_buffer_size;
208#ifndef MACH1SPATIALSDK_MACH1DECODE_TPP
209#define MACH1SPATIALSDK_MACH1DECODE_TPP
211template <
typename PCM>
213 M1obj = Mach1DecodeCAPI_create();
216template <
typename PCM>
218 Mach1DecodeCAPI_delete(M1obj);
221template <
typename PCM>
223 Mach1DecodeCAPI_setPlatformType(M1obj, type);
226template <
typename PCM>
228 Mach1DecodeCAPI_setDecodeMode(M1obj, mode);
231template <
typename PCM>
233 return Mach1DecodeCAPI_getPlatformType(M1obj);
236template <
typename PCM>
238 return Mach1DecodeCAPI_getDecodeMode(M1obj);
241#ifndef __EMSCRIPTEN__
242template <
typename PCM>
244 Mach1DecodeCAPI_decode(M1obj, Yaw, Pitch, Roll, result, bufferSize, sampleIndex);
247template <
typename PCM>
249 Mach1DecodeCAPI_decodeCoeffs(M1obj, result, bufferSize, sampleIndex);
252template <
typename PCM>
254 Mach1DecodeCAPI_decodePannedCoeffs(M1obj, result, bufferSize, sampleIndex, applyPanLaw);
258template <
typename PCM>
260 std::vector<PCM> vec(getFormatCoeffCount());
262 Mach1DecodeCAPI_decode(M1obj, Yaw, Pitch, Roll, vec.data(), bufferSize, sampleIndex);
267template <
typename PCM>
269 std::vector<PCM> vec(getFormatCoeffCount());
271 Mach1DecodeCAPI_decodeCoeffs(M1obj, vec.data(), bufferSize, sampleIndex);
276template <
typename PCM>
278 std::vector<PCM> vec(getFormatCoeffCount());
280 Mach1DecodeCAPI_decodePannedCoeffs(M1obj, vec.data(), bufferSize, sampleIndex, applyPanLaw);
285template <
typename PCM>
287 std::vector<PCM> vec(2 * channels);
289 int inChans = channels;
290 int outChans = getFormatChannelCount();
292 float *m =
new float[inChans * outChans];
293 for (
int i = 0; i < outChans; i++) {
294 for (
int j = 0; j < inChans; j++) {
295 m[i * inChans + j] = matrix[i][j];
299 Mach1DecodeCAPI_decodeCoeffsUsingTranscodeMatrix(M1obj, m, channels, vec.data(), bufferSize, sampleIndex);
305template <
typename PCM>
307 return Mach1DecodeCAPI_getFormatChannelCount(M1obj);
310template <
typename PCM>
312 return Mach1DecodeCAPI_getFormatCoeffCount(M1obj);
315template <
typename PCM>
317 Mach1DecodeCAPI_setRotation(M1obj, newRotationFromMinusOnetoOne);
320template <
typename PCM>
322 Mach1DecodeCAPI_setRotationDegrees(M1obj, newRotationDegrees);
325template <
typename PCM>
327 Mach1DecodeCAPI_setRotationRadians(M1obj, newRotationRadians);
330template <
typename PCM>
332 Mach1DecodeCAPI_setRotationQuat(M1obj, newRotationQuat);
335template <
typename PCM>
337 Mach1DecodeCAPI_setFilterSpeed(M1obj, filterSpeed);
340template <
typename PCM>
342 return Mach1DecodeCAPI_getCurrentTime(M1obj);
345#ifndef __EMSCRIPTEN__
346template <
typename PCM>
348 return Mach1DecodeCAPI_getLog(M1obj);
351template <
typename PCM>
353 return std::string(Mach1DecodeCAPI_getLog(M1obj));
358template <
typename PCM>
360 return Mach1DecodeCAPI_getCurrentAngle(M1obj);
363template <
typename PCM>
366 auto decode_gains = decodeCoeffs();
368 if (old_decode_gains.size() != decode_gains.size()) {
369 old_decode_gains = decode_gains;
372 float size_reciprocal = 1.0f / (float)size;
375 for (
int decode_idx = 0, output_idx = 0; decode_idx < decode_gains.size(); decode_idx += 2, output_idx += 1) {
376 auto left_gain = decode_gains[decode_idx + 0];
377 auto right_gain = decode_gains[decode_idx + 1];
378 auto old_left_gain = old_decode_gains[decode_idx + 0];
379 auto old_right_gain = old_decode_gains[decode_idx + 1];
381 for (
int sample_idx = 0; sample_idx < size; sample_idx++) {
382 auto prc = (float)sample_idx * size_reciprocal;
383 auto left = left_gain * (1.0f - prc) + old_left_gain * prc;
384 auto right = right_gain * (1.0f - prc) + old_right_gain * prc;
387 float sample = in[output_idx][sample_idx];
390 out[output_idx][sample_idx] = 0;
391 out[0][sample_idx] += sample * left;
392 out[1][sample_idx] += sample * right;
396 old_decode_gains = decode_gains;
399template <
typename PCM>
401 decodeBuffer(buffer, buffer, size);
404template <
typename PCM>
406 auto channel_count = 2;
409 if (ib_channel_count != channel_count || ib_buffer_size != size) {
410 intermediary_buffer.resize(channel_count);
412 for (
int i = 0; i < channel_count; i++) {
413 intermediary_buffer[i].resize(size);
416 ib_channel_count = channel_count;
417 ib_buffer_size = size;
421 for (
int i = 0; i < ib_channel_count; i++) {
422 memset(intermediary_buffer[i].data(), 0,
sizeof(
float) * ib_buffer_size);
426 auto decode_gains = decodeCoeffs();
428 if (old_decode_gains.size() != decode_gains.size()) {
429 old_decode_gains = decode_gains;
432 float size_reciprocal = 1.0f / (float)size;
435 for (
int decode_idx = 0, output_idx = 0; decode_idx < decode_gains.size(); decode_idx += 2, output_idx += 1) {
436 auto left_gain = decode_gains[decode_idx + 0];
437 auto right_gain = decode_gains[decode_idx + 1];
438 auto old_left_gain = old_decode_gains[decode_idx + 0];
439 auto old_right_gain = old_decode_gains[decode_idx + 1];
441 for (
int sample_idx = 0; sample_idx < size; sample_idx++) {
442 auto prc = (float)sample_idx * size_reciprocal;
443 auto left = left_gain * (1.0f - prc) + old_left_gain * prc;
444 auto right = right_gain * (1.0f - prc) + old_right_gain * prc;
447 float sample = in[output_idx][sample_idx];
449 intermediary_buffer[0][sample_idx] += sample * left;
450 intermediary_buffer[1][sample_idx] += sample * right;
455 for (
int output_idx = 0; output_idx < channel_count; output_idx++) {
456 memcpy(out[output_idx].data(), intermediary_buffer[output_idx].data(),
sizeof(
float) * size);
459 old_decode_gains = decode_gains;
462template <
typename PCM>
464 decodeBufferRebuffer(buffer, buffer, size);
Definition Mach1Decode.h:13
void setRotation(Mach1Point3D newRotationFromMinusOnetoOne)
Set current buffer/sample intended decoding orientation YPR.
Definition Mach1Decode.h:316
std::vector< PCM > decode(float Yaw, float Pitch, float Roll, int bufferSize=0, int sampleIndex=0)
Definition Mach1Decode.h:259
int getFormatChannelCount()
Get the get amount of channels that this Mach1Decode expects to decode, based on the currently active...
Definition Mach1Decode.h:306
std::vector< PCM > decodePannedCoeffs(int bufferSize=0, int sampleIndex=0, bool applyPanLaw=true)
Definition Mach1Decode.h:277
int getFormatCoeffCount()
Get the get amount of decoding coefficients this Mach1Decode will generate, based on the currently ac...
Definition Mach1Decode.h:311
void setRotationRadians(Mach1Point3D newRotationRadians)
Set current buffer/sample intended decoding orientation YPR.
Definition Mach1Decode.h:326
std::vector< PCM > decodeCoeffs(int bufferSize=0, int sampleIndex=0)
Definition Mach1Decode.h:268
void setFilterSpeed(float filterSpeed)
Set the amount of angle smoothing applied to the orientation angles used for this Mach1Decode.
Definition Mach1Decode.h:336
void setRotationQuat(Mach1Point4D newRotationQuat)
Set current buffer/sample intended decoding orientation YPR.
Definition Mach1Decode.h:331
void setPlatformType(Mach1PlatformType type)
Set the device's angle order and convention if applicable.
Definition Mach1Decode.h:222
char * getLog()
Get the internal log that has been accumulated into this Mach1Decode.
Definition Mach1Decode.h:347
Mach1DecodeMode getDecodeMode()
Get the decoding mode.
Definition Mach1Decode.h:237
void setDecodeMode(Mach1DecodeMode mode)
Set the decoding mode.
Definition Mach1Decode.h:227
Mach1Point3D getCurrentAngle()
Get this Mach1Decode's current 3D angle for feedback design.
Definition Mach1Decode.h:359
void setRotationDegrees(Mach1Point3D newRotationDegrees)
Set current buffer/sample intended decoding orientation YPR.
Definition Mach1Decode.h:321
long getCurrentTime()
Get the current elapsed time in milliseconds (ms) this Mach1Decode has been constructed.
Definition Mach1Decode.h:341
Mach1PlatformType getPlatformType()
Get the device's angle order and convention if applicable.
Definition Mach1Decode.h:232
Definition Mach1Point3D.h:17
Definition Mach1Point4D.h:15