Mach1 Spatial SDK
Loading...
Searching...
No Matches
Mach1Encode.h
1// Mach1 Spatial SDK
2// Copyright © 2017 Mach1. All rights reserved.
3
4#ifndef MACH1SPATIALSDK_MACH1ENCODE_H
5#define MACH1SPATIALSDK_MACH1ENCODE_H
6
7#include <Mach1Point3D.h>
8#include <cstring>
9#include <string>
10#include <vector>
11
12#include "Mach1EncodeCAPI.h"
13
14#ifdef M1ENCODE_INLINE_DECODE
15# include "Mach1DecodeCAPI.h"
16#endif
17
18template <typename PCM>
20 public:
22 Mach1Encode(const Mach1Encode &other);
23 Mach1Encode &operator=(const Mach1Encode &other);
24 Mach1Encode(Mach1Encode&& other) noexcept;
25 Mach1Encode& operator=(Mach1Encode&& other) noexcept;
27
38 std::vector<Mach1Point3D> getPoints();
39
50 std::vector<std::vector<PCM> > getGains();
51
55 std::vector<std::string> getPointsNames();
56
63 std::vector<float> getGainsForInputChannelNamed(const std::string &pointName);
64
70
74 int getPointsCount();
75
79 Mach1EncodeInputMode getInputMode();
80
84 void setInputMode(Mach1EncodeInputMode inputMode);
85
89 Mach1EncodeOutputMode getOutputMode();
90
94 void setOutputMode(Mach1EncodeOutputMode outputMode);
95
104 Mach1EncodePannerMode getPannerMode();
105
125 void setPannerMode(enum Mach1EncodePannerMode pannerMode);
126
131 bool getAutoOrbit();
132
138
144
149 void setAzimuth(float azimuthFromMinus1To1);
150
155 void setAzimuthDegrees(float azimuthDegrees);
156
161 void setAzimuthRadians(float azimuthRadians);
162
167 void setElevation(float elevationFromMinus1to1);
168
173 void setElevationDegrees(float elevationFromMinus90to90);
174
179 void setElevationRadians(float elevationFromMinusHalfPItoHalfPI);
180
187 void setFrontSurroundPerspective(bool frontSurroundPerspective);
188
194 float getOutputGain(bool isDecibel);
195
201 void setOutputGain(float outputGainMultipler, bool isDecibel);
202
207 float getGainCompensation(bool isDecibel);
208
213
224 void setGainCompensationActive(bool active);
225
230 void setOrbitRotation(float orbitRotationFromMinusOnetoOne);
231
236 void setOrbitRotationDegrees(float orbitRotationDegrees);
237
242 void setOrbitRotationRadians(float orbitRotationRadians);
243
248 void setDiverge(float divergeFromMinus1To1);
249
254 void setStereoSpread(float sSpreadFrom0to1);
255
261 void setAutoOrbit(bool autoOrbit);
262
268 inline void encodeBuffer(std::vector<std::vector<PCM> > &in, std::vector<std::vector<PCM> > &out, int size);
269
276 inline void encodeBufferRebuffer(std::vector<std::vector<PCM> > &in, std::vector<std::vector<PCM> > &out, int size);
277
283 inline void encodeBufferInPlaceRebuffer(std::vector<std::vector<PCM> > &buffer, size_t buffer_size);
284
290 inline void encodeBufferInPlace(std::vector<std::vector<PCM> > &buffer, size_t buffer_size);
291
292#ifdef M1ENCODE_INLINE_DECODE
300 std::vector<float> getResultingCoeffsDecoded(Mach1DecodeMode decodeMode, std::vector<float> &decodeResult);
301#endif
302
303 private:
304 void *M1obj;
305
306 std::vector<std::vector<PCM> > last_gains;
307 std::vector<std::vector<PCM> > intermediary_buffer;
308
309 int ib_channel_count{};
310 size_t ib_buffer_size{};
311};
312
313#endif // MACH1SPATIALSDK_MACH1ENCODE_H
314
315// Implementation of Mach1Encode<PCM>
316#ifndef MACH1SPATIALSDK_MACH1ENCODE_TPP
317#define MACH1SPATIALSDK_MACH1ENCODE_TPP
318
319template <typename PCM>
321 M1obj = Mach1EncodeCAPI_create();
322}
323
324template <typename PCM>
326 Mach1EncodeCAPI_delete(M1obj);
327}
328
329template <typename PCM>
331 M1obj = Mach1EncodeCAPI_create();
332 Mach1EncodeCAPI_copy(other.M1obj, M1obj);
333}
334
335template <typename PCM>
337 if (this != &other) {
338 // Delete current M1obj if it's not nullptr
339 if (M1obj != nullptr) {
340 Mach1EncodeCAPI_delete(M1obj);
341 M1obj = nullptr;
342 }
343
344 // Create a new M1obj
345 M1obj = Mach1EncodeCAPI_create();
346
347 // Copy from other.M1obj into M1obj
348 Mach1EncodeCAPI_copy(other.M1obj, M1obj);
349 }
350 return *this;
351}
352
353template <typename PCM>
355 M1obj = other.M1obj;
356 other.M1obj = nullptr;
357}
358
359template <typename PCM>
361 if (this != &other) {
362 // Delete current M1obj
363 if (M1obj != nullptr) {
364 Mach1EncodeCAPI_delete(M1obj);
365 }
366
367 // Transfer ownership
368 M1obj = other.M1obj;
369 other.M1obj = nullptr;
370 }
371 return *this;
372}
373
374template <typename PCM>
375std::vector<Mach1Point3D> Mach1Encode<PCM>::getPoints() {
376 std::vector<Mach1Point3D> vec(Mach1EncodeCAPI_getPointsCount(M1obj));
377
378 auto *arr = (Mach1Point3D *)Mach1EncodeCAPI_getPoints(M1obj);
379 for (int i = 0; i < vec.size(); i++)
380 vec[i] = arr[i];
381
382 return vec;
383}
384
385template <typename PCM>
386std::vector<std::vector<PCM> > Mach1Encode<PCM>::getGains() {
387 std::vector<std::vector<float> > vec(Mach1EncodeCAPI_getPointsCount(M1obj));
388
389 auto **arr = (float **)Mach1EncodeCAPI_getGains(M1obj);
390
391 for (int i = 0; i < vec.size(); i++) {
392 vec[i].resize(Mach1EncodeCAPI_getOutputChannelsCount(M1obj));
393
394 for (int j = 0; j < vec[i].size(); j++) {
395 vec[i][j] = arr[i][j];
396 }
397 }
398
399 return vec;
400}
401
402template <typename PCM>
403std::vector<std::string> Mach1Encode<PCM>::getPointsNames() {
404 std::vector<std::string> vec(Mach1EncodeCAPI_getPointsCount(M1obj));
405
406 auto **arr = (char **)Mach1EncodeCAPI_getPointsNames(M1obj);
407
408 for (int i = 0; i < vec.size(); i++) {
409 vec[i] = arr[i];
410 }
411
412 return vec;
413}
414
415template <typename PCM>
416std::vector<float> Mach1Encode<PCM>::getGainsForInputChannelNamed(const std::string &pointName) {
417 std::vector<float> vec(Mach1EncodeCAPI_getOutputChannelsCount(M1obj));
418
419 auto *arr = (float *)Mach1EncodeCAPI_getGainsForInputChannelNamed(M1obj, (char *)pointName.c_str());
420
421 for (int i = 0; i < vec.size(); i++) {
422 vec[i] = arr[i];
423 }
424
425 return vec;
426}
427
428template <typename PCM>
430 Mach1EncodeCAPI_generatePointResults(M1obj);
431}
432
433template <typename PCM>
435 return Mach1EncodeCAPI_getPointsCount(M1obj);
436}
437
438template <typename PCM>
439Mach1EncodeInputMode Mach1Encode<PCM>::getInputMode() {
440 return Mach1EncodeCAPI_getInputMode(M1obj);
441}
442
443template <typename PCM>
444Mach1EncodeOutputMode Mach1Encode<PCM>::getOutputMode() {
445 return Mach1EncodeCAPI_getOutputMode(M1obj);
446}
447
448template <typename PCM>
449Mach1EncodePannerMode Mach1Encode<PCM>::getPannerMode() {
450 return Mach1EncodeCAPI_getPannerMode(M1obj);
451}
452
453template <typename PCM>
455 return Mach1EncodeCAPI_getAutoOrbit(M1obj);
456}
457
458template <typename PCM>
460 return Mach1EncodeCAPI_getInputChannelsCount(M1obj);
461}
462
463template <typename PCM>
465 return Mach1EncodeCAPI_getOutputChannelsCount(M1obj);
466}
467
468template <typename PCM>
469void Mach1Encode<PCM>::setInputMode(Mach1EncodeInputMode inputMode) {
470 Mach1EncodeCAPI_setInputMode(M1obj, inputMode);
471}
472
473template <typename PCM>
474void Mach1Encode<PCM>::setOutputMode(Mach1EncodeOutputMode outputMode) {
475 Mach1EncodeCAPI_setOutputMode(M1obj, outputMode);
476}
477
478template <typename PCM>
479void Mach1Encode<PCM>::setAzimuth(float azimuthFromMinus1To1) {
480 Mach1EncodeCAPI_setAzimuth(M1obj, azimuthFromMinus1To1);
481}
482
483template <typename PCM>
484void Mach1Encode<PCM>::setAzimuthDegrees(float azimuthDegrees) {
485 Mach1EncodeCAPI_setAzimuthDegrees(M1obj, azimuthDegrees);
486}
487
488template <typename PCM>
489void Mach1Encode<PCM>::setAzimuthRadians(float azimuthRadians) {
490 Mach1EncodeCAPI_setAzimuthRadians(M1obj, azimuthRadians);
491}
492
493template <typename PCM>
494void Mach1Encode<PCM>::setDiverge(float divergeFromMinus1To1) {
495 Mach1EncodeCAPI_setDiverge(M1obj, divergeFromMinus1To1);
496}
497
498template <typename PCM>
499void Mach1Encode<PCM>::setElevation(float elevationFromMinus1to1) {
500 Mach1EncodeCAPI_setElevation(M1obj, elevationFromMinus1to1);
501}
502
503template <typename PCM>
504void Mach1Encode<PCM>::setElevationDegrees(float elevationFromMinus90to90) {
505 Mach1EncodeCAPI_setElevationDegrees(M1obj, elevationFromMinus90to90);
506}
507
508template <typename PCM>
509void Mach1Encode<PCM>::setElevationRadians(float elevationFromMinusHalfPItoHalfPI) {
510 Mach1EncodeCAPI_setElevationRadians(M1obj, elevationFromMinusHalfPItoHalfPI);
511}
512
513template <typename PCM>
514void Mach1Encode<PCM>::setPannerMode(Mach1EncodePannerMode pannerMode) {
515 Mach1EncodeCAPI_setPannerMode(M1obj, pannerMode);
516}
517
518template <typename PCM>
519void Mach1Encode<PCM>::setFrontSurroundPerspective(bool frontSurroundPerspective) {
520 Mach1EncodeCAPI_setFrontSurroundPerspective(M1obj, frontSurroundPerspective);
521}
522
523template <typename PCM>
524float Mach1Encode<PCM>::getOutputGain(bool isDecibel) {
525 Mach1EncodeCAPI_getOutputGain(M1obj, isDecibel);
526}
527
528template <typename PCM>
529void Mach1Encode<PCM>::setOutputGain(float outputGainMultipler, bool isDecibel) {
530 Mach1EncodeCAPI_setOutputGain(M1obj, outputGainMultipler, isDecibel);
531}
532
533template <typename PCM>
535 return Mach1EncodeCAPI_getGainCompensation(M1obj, isDecibel);
536}
537
538template <typename PCM>
540 return Mach1EncodeCAPI_getGainCompensationActive(M1obj);
541}
542
543template <typename PCM>
545 Mach1EncodeCAPI_setGainCompensationActive(M1obj, active);
546}
547
548template <typename PCM>
549void Mach1Encode<PCM>::setOrbitRotation(float orbitRotationFromMinusOnetoOne) {
550 Mach1EncodeCAPI_setOrbitRotation(M1obj, orbitRotationFromMinusOnetoOne);
551}
552
553template <typename PCM>
554void Mach1Encode<PCM>::setOrbitRotationDegrees(float orbitRotationDegrees) {
555 Mach1EncodeCAPI_setOrbitRotationDegrees(M1obj, orbitRotationDegrees);
556}
557
558template <typename PCM>
559void Mach1Encode<PCM>::setOrbitRotationRadians(float orbitRotationRadians) {
560 Mach1EncodeCAPI_setOrbitRotationRadians(M1obj, orbitRotationRadians);
561}
562
563template <typename PCM>
564void Mach1Encode<PCM>::setStereoSpread(float sSpreadFrom0to1) {
565 Mach1EncodeCAPI_setStereoSpread(M1obj, sSpreadFrom0to1);
566}
567
568template <typename PCM>
569void Mach1Encode<PCM>::setAutoOrbit(bool autoOrbit) {
570 Mach1EncodeCAPI_setAutoOrbit(M1obj, autoOrbit);
571}
572
573#ifdef M1ENCODE_INLINE_DECODE
574template <typename PCM>
575std::vector<float> Mach1Encode<PCM>::getResultingCoeffsDecoded(Mach1DecodeMode decodeMode, std::vector<float> &decodeResult) {
576 std::vector<float> vec(Mach1EncodeCAPI_getPointsCount(M1obj) * 2);
577
578 float *arr = (float *)Mach1EncodeCAPI_getResultingCoeffsDecoded(M1obj, decodeMode, decodeResult.data());
579
580 for (int i = 0; i < vec.size(); i++) {
581 vec[i] = arr[i];
582 }
583
584 return vec;
585}
586#endif
587
588template <typename PCM>
589inline void
590Mach1Encode<PCM>::encodeBuffer(std::vector<std::vector<PCM> > &in, std::vector<std::vector<PCM> > &out, int size) {
591 auto encode_gains = getGains();
592
593 if (last_gains.size() != encode_gains.size()) {
594 last_gains = encode_gains;
595 }
596
597 float size_reciprocal = 1.0f / (float)size;
598
599 // process the samples manually
600 for (int point_idx = 0; point_idx < getPointsCount(); point_idx++) {
601 for (int output_idx = 0; output_idx < getOutputChannelsCount(); output_idx++) {
602 auto encode_gain = encode_gains[point_idx][output_idx];
603 auto last_encode_gain = last_gains[point_idx][output_idx];
604
605 for (int sample_idx = 0; sample_idx < size; sample_idx++) {
606 auto prc = (float)sample_idx * size_reciprocal;
607 auto gain = encode_gain * (1.0f - prc) + last_encode_gain * prc;
608
609 auto val = in[output_idx][sample_idx];
610 out[output_idx][sample_idx] = gain * val;
611 }
612 }
613 }
614}
615
616template <typename PCM>
617inline void Mach1Encode<PCM>::encodeBufferInPlace(std::vector<std::vector<PCM> > &buffer, size_t buffer_size) {
618 encodeBuffer(buffer, buffer, buffer_size);
619}
620
621template <typename PCM>
622inline void
623Mach1Encode<PCM>::encodeBufferRebuffer(std::vector<std::vector<PCM> > &in, std::vector<std::vector<PCM> > &out,
624 int size) {
625 auto encode_gains = getGains();
626 auto output_channel_count = getOutputChannelsCount();
627
628 if (last_gains.size() != encode_gains.size()) {
629 last_gains = encode_gains;
630 }
631
632 // restructure intermediary buffer
633 if (ib_channel_count != output_channel_count || ib_buffer_size != size) {
634 intermediary_buffer.resize(output_channel_count);
635
636 for (int i = 0; i < output_channel_count; i++) {
637 intermediary_buffer[i].resize(size);
638 }
639
640 ib_channel_count = output_channel_count;
641 ib_buffer_size = size;
642
643 for (int i = 0; i < ib_channel_count; i++) {
644 memset(intermediary_buffer[i].data(), 0, sizeof(float) * ib_buffer_size);
645 }
646 }
647
648 // clear intermediary buffer
649 for (int i = 0; i < ib_channel_count; i++) {
650 memset(intermediary_buffer[i].data(), 0, sizeof(float) * ib_buffer_size);
651 }
652
653 float size_reciprocal = 1.0f / (float)size;
654
655 // process the samples manually
656 for (int point_idx = 0; point_idx < getPointsCount(); point_idx++) {
657 for (int output_idx = 0; output_idx < output_channel_count; output_idx++) {
658 auto encode_gain = encode_gains[point_idx][output_idx];
659 auto last_encode_gain = last_gains[point_idx][output_idx];
660
661 for (int sample_idx = 0; sample_idx < size; sample_idx++) {
662 auto prc = (float)sample_idx * size_reciprocal;
663 auto gain = encode_gain * (1.0f - prc) + last_encode_gain * prc;
664 auto val = in[output_idx][sample_idx];
665 intermediary_buffer[output_idx][sample_idx] += gain * val;
666 }
667 }
668 }
669
670 // copy over values in intermediary buffer to output buffer
671 for (int output_idx = 0; output_idx < output_channel_count; output_idx++) {
672 memcpy(out[output_idx].data(), intermediary_buffer[output_idx].data(), sizeof(float) * size);
673 }
674
675 last_gains = encode_gains;
676}
677
678template <typename PCM>
679inline void Mach1Encode<PCM>::encodeBufferInPlaceRebuffer(std::vector<std::vector<PCM> > &buffer, size_t buffer_size) {
680 encodeBufferRebuffer(buffer, buffer, buffer_size);
681}
682
683#endif // MACH1SPATIALSDK_MACH1ENCODE_TPP
Definition Mach1Encode.h:19
std::vector< float > getGainsForInputChannelNamed(const std::string &pointName)
Given the name of an input channel/point, return array of gain coefficients.
Definition Mach1Encode.h:416
Mach1EncodeInputMode getInputMode()
Get the format in which this Mach1Encode expects to receive audio for encoding.
Definition Mach1Encode.h:439
void setOutputMode(Mach1EncodeOutputMode outputMode)
Set the format in which this Mach1Encode will output encoded audio.
Definition Mach1Encode.h:474
std::vector< Mach1Point3D > getPoints()
Returns the control center reference point's normalized coordinate location (XYZ) within the vector p...
Definition Mach1Encode.h:375
bool getAutoOrbit()
Get whether auto-orbit mode is enabled. If true, then orbit rotation is extrapolated from the current...
Definition Mach1Encode.h:454
void encodeBufferRebuffer(std::vector< std::vector< PCM > > &in, std::vector< std::vector< PCM > > &out, int size)
Definition Mach1Encode.h:623
bool getGainCompensationActive()
Gets whether gain compensation is active.
Definition Mach1Encode.h:539
void setOrbitRotationDegrees(float orbitRotationDegrees)
Sets the two stereo points around the axis of the center point between them.
Definition Mach1Encode.h:554
void setPannerMode(enum Mach1EncodePannerMode pannerMode)
Sets the style and mode of panner input calculation.
Definition Mach1Encode.h:514
std::vector< std::vector< PCM > > getGains()
Returns an array per input channel, resulting in an array of array results each internal array (per i...
Definition Mach1Encode.h:386
void setElevationDegrees(float elevationFromMinus90to90)
Sets the point(s) up/down the vector space.
Definition Mach1Encode.h:504
std::vector< std::string > getPointsNames()
Return the string name for each input channel/point.
Definition Mach1Encode.h:403
void setAzimuthRadians(float azimuthRadians)
Sets the point(s) azimuth rotation of the vector space.
Definition Mach1Encode.h:489
void setAzimuth(float azimuthFromMinus1To1)
Sets the point(s) azimuth rotation of the vector space.
Definition Mach1Encode.h:479
int getOutputChannelsCount()
Get the number of output channels that this Mach1Encode expects to receive for encoding,...
Definition Mach1Encode.h:464
void setElevation(float elevationFromMinus1to1)
Sets the point(s) up/down the vector space.
Definition Mach1Encode.h:499
void setOrbitRotation(float orbitRotationFromMinusOnetoOne)
Sets the two stereo points around the axis of the center point between them.
Definition Mach1Encode.h:549
void generatePointResults()
Recalculate and update the encoder with the currently set spatial configuration.
Definition Mach1Encode.h:429
Mach1EncodePannerMode getPannerMode()
Get the calculation strategy by which the points in this Mach1Encode are calculated.
Definition Mach1Encode.h:449
void setAutoOrbit(bool autoOrbit)
Sets whether encoding behavior acts evenly with distribution across all azimuth/rotation angles and a...
Definition Mach1Encode.h:569
void encodeBufferInPlace(std::vector< std::vector< PCM > > &buffer, size_t buffer_size)
Definition Mach1Encode.h:617
void setDiverge(float divergeFromMinus1To1)
Sets the point(s) to/from center origin of the vector space.
Definition Mach1Encode.h:494
float getOutputGain(bool isDecibel)
Definition Mach1Encode.h:524
void setOutputGain(float outputGainMultipler, bool isDecibel)
Definition Mach1Encode.h:529
void setOrbitRotationRadians(float orbitRotationRadians)
Sets the two stereo points around the axis of the center point between them.
Definition Mach1Encode.h:559
void setElevationRadians(float elevationFromMinusHalfPItoHalfPI)
Sets the point(s) up/down the vector space.
Definition Mach1Encode.h:509
void setFrontSurroundPerspective(bool frontSurroundPerspective)
Definition Mach1Encode.h:519
void encodeBuffer(std::vector< std::vector< PCM > > &in, std::vector< std::vector< PCM > > &out, int size)
Definition Mach1Encode.h:590
void setStereoSpread(float sSpreadFrom0to1)
Sets the space between the two stereo points.
Definition Mach1Encode.h:564
float getGainCompensation(bool isDecibel)
Gets the current gain compensation value.
Definition Mach1Encode.h:534
void encodeBufferInPlaceRebuffer(std::vector< std::vector< PCM > > &buffer, size_t buffer_size)
Definition Mach1Encode.h:679
int getPointsCount()
Get the number of point results that have been generated after a call to generatePointResults.
Definition Mach1Encode.h:434
void setGainCompensationActive(bool active)
Sets whether gain compensation is active.
Definition Mach1Encode.h:544
Mach1EncodeOutputMode getOutputMode()
Get the format in which this Mach1Encode will output encoded audio.
Definition Mach1Encode.h:444
void setInputMode(Mach1EncodeInputMode inputMode)
Definition Mach1Encode.h:469
void setAzimuthDegrees(float azimuthDegrees)
Sets the point(s) azimuth rotation of the vector space.
Definition Mach1Encode.h:484
int getInputChannelsCount()
Get the number of input channels that this Mach1Encode expects to receive for encoding,...
Definition Mach1Encode.h:459
Definition Mach1Point3D.h:17