Spatial Audio: Log head tracking velocity in degrees / s
Head tracking velocity is given as the intrinsic axis * (dangle / dt).
We express this as degrees/s with d_pitch, d_roll, d_yaw.
Cleanup of the VectorRecorder index offset and add delimiters.
Test: adb shell dumpsys media.audio_policy
Bug: 270763710
Change-Id: I64a194a9b839567529c0359c2ebe3a78d89e7c61
diff --git a/services/audiopolicy/service/Spatializer.cpp b/services/audiopolicy/service/Spatializer.cpp
index 2f65f39..d868d31 100644
--- a/services/audiopolicy/service/Spatializer.cpp
+++ b/services/audiopolicy/service/Spatializer.cpp
@@ -1092,13 +1092,13 @@
if (mPoseController != nullptr) {
ss.append(mPoseController->toString(level + 1))
.append(prefixSpace)
- .append("Pose (active stage-to-head) [tx, ty, tz, pitch, roll, yaw]:\n")
+ .append("Pose (active stage-to-head) [tx, ty, tz : pitch, roll, yaw]:\n")
.append(prefixSpace)
.append(" PerMinuteHistory:\n")
- .append(mPoseDurableRecorder.toString(level + 2))
+ .append(mPoseDurableRecorder.toString(level + 3))
.append(prefixSpace)
.append(" PerSecondHistory:\n")
- .append(mPoseRecorder.toString(level + 2));
+ .append(mPoseRecorder.toString(level + 3));
} else {
ss.append(prefixSpace).append("SpatializerPoseController not exist\n");
}
diff --git a/services/audiopolicy/service/Spatializer.h b/services/audiopolicy/service/Spatializer.h
index f03d764..c677868 100644
--- a/services/audiopolicy/service/Spatializer.h
+++ b/services/audiopolicy/service/Spatializer.h
@@ -404,10 +404,10 @@
*/
// Record one log line per second (up to mMaxLocalLogLine) to capture most recent sensor data.
media::VectorRecorder mPoseRecorder GUARDED_BY(mLock) {
- 6 /* vectorSize */, std::chrono::seconds(1), mMaxLocalLogLine };
+ 6 /* vectorSize */, std::chrono::seconds(1), mMaxLocalLogLine, { 3 } /* delimiterIdx */};
// Record one log line per minute (up to mMaxLocalLogLine) to capture durable sensor data.
media::VectorRecorder mPoseDurableRecorder GUARDED_BY(mLock) {
- 6 /* vectorSize */, std::chrono::minutes(1), mMaxLocalLogLine };
+ 6 /* vectorSize */, std::chrono::minutes(1), mMaxLocalLogLine, { 3 } /* delimiterIdx */};
}; // Spatializer
}; // namespace android
diff --git a/services/audiopolicy/service/SpatializerPoseController.cpp b/services/audiopolicy/service/SpatializerPoseController.cpp
index 2ac2af7..032572e 100644
--- a/services/audiopolicy/service/SpatializerPoseController.cpp
+++ b/services/audiopolicy/service/SpatializerPoseController.cpp
@@ -290,22 +290,29 @@
const float delayMs = (elapsedRealtimeNano() - timestamp) * NANOS_TO_MILLIS; // CLOCK_BOOTTIME
if (sensor == mHeadSensor) {
- std::vector<float> pryxyzdt(8); // pitch, roll, yaw, rot_vel_x, rot_vel_y, rot_vel_z,
+ std::vector<float> pryprydt(8); // pitch, roll, yaw, d_pitch, d_roll, d_yaw,
// discontinuity, timestamp_delay
- media::quaternionToAngles(pose.rotation(), &pryxyzdt[0], &pryxyzdt[1], &pryxyzdt[2]);
+ media::quaternionToAngles(pose.rotation(), &pryprydt[0], &pryprydt[1], &pryprydt[2]);
if (twist) {
const auto rotationalVelocity = twist->rotationalVelocity();
- for (size_t i = 0; i < 3; ++i) {
- pryxyzdt[i + 3] = rotationalVelocity[i];
- }
+ // The rotational velocity is an intrinsic transform (i.e. based on the head
+ // coordinate system, not the world coordinate system). It is a 3 element vector:
+ // axis (d theta / dt).
+ //
+ // We leave rotational velocity relative to the head coordinate system,
+ // as the initial head tracking sensor's world frame is arbitrary.
+ media::quaternionToAngles(media::rotationVectorToQuaternion(rotationalVelocity),
+ &pryprydt[3], &pryprydt[4], &pryprydt[5]);
}
- pryxyzdt[6] = isNewReference;
- pryxyzdt[7] = delayMs;
- for (size_t i = 0; i < 3; ++i) { // pitch, roll, yaw only. rotational velocity in rad/s.
- pryxyzdt[i] *= RAD_TO_DEGREE;
+ pryprydt[6] = isNewReference;
+ pryprydt[7] = delayMs;
+ for (size_t i = 0; i < 6; ++i) {
+ // pitch, roll, yaw in degrees, referenced in degrees on the world frame.
+ // d_pitch, d_roll, d_yaw rotational velocity in degrees/s, based on the world frame.
+ pryprydt[i] *= RAD_TO_DEGREE;
}
- mHeadSensorRecorder.record(pryxyzdt);
- mHeadSensorDurableRecorder.record(pryxyzdt);
+ mHeadSensorRecorder.record(pryprydt);
+ mHeadSensorDurableRecorder.record(pryprydt);
mProcessor->setWorldToHeadPose(timestamp, pose,
twist.value_or(Twist3f()) / kTicksPerSecond);
@@ -346,15 +353,16 @@
if (mHeadSensor == INVALID_SENSOR) {
ss += "HeadSensor: INVALID\n";
} else {
- base::StringAppendF(&ss, "HeadSensor: 0x%08x (active world-to-head) "
- "[ pitch, roll, yaw, vx, vy, vz, disc, delay ] "
- "(degrees, rad/s, bool, ms)\n", mHeadSensor);
+ base::StringAppendF(&ss, "HeadSensor: 0x%08x "
+ "(active world-to-head : head-relative velocity) "
+ "[ pitch, roll, yaw : d_pitch, d_roll, d_yaw : disc : delay ] "
+ "(degrees, degrees/s, bool, ms)\n", mHeadSensor);
ss.append(prefixSpace)
.append(" PerMinuteHistory:\n")
- .append(mHeadSensorDurableRecorder.toString(level + 2))
+ .append(mHeadSensorDurableRecorder.toString(level + 3))
.append(prefixSpace)
.append(" PerSecondHistory:\n")
- .append(mHeadSensorRecorder.toString(level + 2));
+ .append(mHeadSensorRecorder.toString(level + 3));
}
ss += prefixSpace;
@@ -362,14 +370,14 @@
ss += "ScreenSensor: INVALID\n";
} else {
base::StringAppendF(&ss, "ScreenSensor: 0x%08x (active world-to-screen) "
- "[ pitch, roll, yaw, delay ] "
+ "[ pitch, roll, yaw : delay ] "
"(degrees, ms)\n", mScreenSensor);
ss.append(prefixSpace)
.append(" PerMinuteHistory:\n")
- .append(mScreenSensorDurableRecorder.toString(level + 2))
+ .append(mScreenSensorDurableRecorder.toString(level + 3))
.append(prefixSpace)
.append(" PerSecondHistory:\n")
- .append(mScreenSensorRecorder.toString(level + 2));
+ .append(mScreenSensorRecorder.toString(level + 3));
}
ss += prefixSpace;
diff --git a/services/audiopolicy/service/SpatializerPoseController.h b/services/audiopolicy/service/SpatializerPoseController.h
index ee2c2be..9d78188 100644
--- a/services/audiopolicy/service/SpatializerPoseController.h
+++ b/services/audiopolicy/service/SpatializerPoseController.h
@@ -133,14 +133,18 @@
bool mCalculated = false;
media::VectorRecorder mHeadSensorRecorder{
- 8 /* vectorSize */, std::chrono::seconds(1), 10 /* maxLogLine */};
+ 8 /* vectorSize */, std::chrono::seconds(1), 10 /* maxLogLine */,
+ { 3, 6, 7 } /* delimiterIdx */};
media::VectorRecorder mHeadSensorDurableRecorder{
- 8 /* vectorSize */, std::chrono::minutes(1), 10 /* maxLogLine */};
+ 8 /* vectorSize */, std::chrono::minutes(1), 10 /* maxLogLine */,
+ { 3, 6, 7 } /* delimiterIdx */};
media::VectorRecorder mScreenSensorRecorder{
- 4 /* vectorSize */, std::chrono::seconds(1), 10 /* maxLogLine */};
+ 4 /* vectorSize */, std::chrono::seconds(1), 10 /* maxLogLine */,
+ { 3 } /* delimiterIdx */};
media::VectorRecorder mScreenSensorDurableRecorder{
- 4 /* vectorSize */, std::chrono::minutes(1), 10 /* maxLogLine */};
+ 4 /* vectorSize */, std::chrono::minutes(1), 10 /* maxLogLine */,
+ { 3 } /* delimiterIdx */};
// It's important that mThread is the last variable in this class
// since we starts mThread in initializer list