|
51 | 51 | * separated with audio tracks in between, or from being the first tracks |
52 | 52 | * followed by the audio tracks. It's not known if this is intended to be |
53 | 53 | * allowed, but it's not supported. Object position tracks must be last. |
54 | | - * |
55 | | - * Some remaining issues: |
56 | | - * |
57 | | - * - Positions are specified in left-handed coordinates, despite the LAF |
58 | | - * documentation saying it's right-handed. Might be an encoding error with |
59 | | - * the files tested, or might be a misunderstanding about which is which. How |
60 | | - * to proceed may depend on how wide-spread this issue ends up being, but for |
61 | | - * now, they're treated as left-handed here. |
62 | | - * |
63 | | - * - The LAF documentation doesn't specify the range or direction for the |
64 | | - * channels' X and Y axis rotation in Channels mode. Presumably X rotation |
65 | | - * (elevation) goes from -pi/2...+pi/2 and Y rotation (azimuth) goes from |
66 | | - * either -pi...+pi or 0...pi*2, but the direction of movement isn't |
67 | | - * specified. Currently positive azimuth moves from center rightward and |
68 | | - * positive elevation moves from head-level upward. |
69 | 54 | */ |
70 | 55 |
|
71 | 56 | #include <algorithm> |
|
77 | 62 | #include <iostream> |
78 | 63 | #include <iterator> |
79 | 64 | #include <memory> |
| 65 | +#include <numbers> |
80 | 66 | #include <numeric> |
81 | 67 | #include <ranges> |
82 | 68 | #include <source_location> |
@@ -769,12 +755,31 @@ try { |
769 | 755 | alSourcef(channel.mSource, AL_ROLLOFF_FACTOR, 0.0f); |
770 | 756 | alSourcei(channel.mSource, AL_SOURCE_RELATIVE, AL_TRUE); |
771 | 757 |
|
772 | | - /* FIXME: Is the Y rotation/azimuth clockwise or counter-clockwise? |
773 | | - * Does +azimuth move a front sound right or left? |
774 | | - */ |
775 | | - const auto x = std::sin(channel.mAzimuth) * std::cos(channel.mElevation); |
776 | | - const auto y = std::sin(channel.mElevation); |
777 | | - const auto z = -std::cos(channel.mAzimuth) * std::cos(channel.mElevation); |
| 758 | + /* Convert degrees to radians, wrapping between -pi...+pi. */ |
| 759 | + auto azi = channel.mAzimuth / 180.0f; |
| 760 | + /* At this magnitude, the result is always 0. */ |
| 761 | + if(!(std::abs(azi) < 16777216.0f)) |
| 762 | + azi = 0.0f; |
| 763 | + else |
| 764 | + { |
| 765 | + const auto tmp = gsl::narrow_cast<int>(azi); |
| 766 | + azi -= gsl::narrow_cast<float>(tmp + (tmp%2)); |
| 767 | + azi *= std::numbers::pi_v<float>; |
| 768 | + } |
| 769 | + |
| 770 | + auto elev = channel.mElevation / 180.0f; |
| 771 | + if(!(std::abs(elev) < 16777216.0f)) |
| 772 | + elev = 0.0f; |
| 773 | + else |
| 774 | + { |
| 775 | + const auto tmp = gsl::narrow_cast<int>(elev); |
| 776 | + elev -= gsl::narrow_cast<float>(tmp + (tmp%2)); |
| 777 | + elev *= std::numbers::pi_v<float>; |
| 778 | + } |
| 779 | + |
| 780 | + const auto x = std::sin(azi) * std::cos(elev); |
| 781 | + const auto y = std::sin(elev); |
| 782 | + const auto z = -std::cos(azi) * std::cos(elev); |
778 | 783 | alSource3f(channel.mSource, AL_POSITION, x, y, z); |
779 | 784 |
|
780 | 785 | if(channel.mIsLfe) |
@@ -999,9 +1004,7 @@ try { |
999 | 1004 | const auto y = laf->mPosTracks[trackidx][posoffset*3 + 1]; |
1000 | 1005 | const auto z = laf->mPosTracks[trackidx][posoffset*3 + 2]; |
1001 | 1006 |
|
1002 | | - /* Contrary to the docs, the position is left-handed and |
1003 | | - * needs to be converted to right-handed. |
1004 | | - */ |
| 1007 | + /* Convert left-handed coords to right-handed. */ |
1005 | 1008 | alSource3f(laf->mChannels[i].mSource, AL_POSITION, x, y, -z); |
1006 | 1009 | } |
1007 | 1010 | alcProcessContext(alcGetCurrentContext()); |
|
0 commit comments