{"id":60,"date":"2026-05-04T11:57:32","date_gmt":"2026-05-04T11:57:32","guid":{"rendered":"http:\/\/www.fryduck99.com\/?p=60"},"modified":"2026-05-07T15:38:08","modified_gmt":"2026-05-07T15:38:08","slug":"android-audio-architecture-improvement","status":"publish","type":"post","link":"\/index.php\/2026\/05\/04\/android-audio-architecture-improvement\/","title":{"rendered":"Android \u539f\u751f\u97f3\u9891\u67b6\u6784\u4e0d\u8db3\u4e0e\u6539\u8fdb\u5b9e\u8df5"},"content":{"rendered":"<p>\u672c\u6587\u68b3\u7406\u4e86 Android \u539f\u751f\u97f3\u9891\u67b6\u6784\u7684\u6838\u5fc3\u95ee\u9898\uff0c\u5e76\u7ed9\u51fa\u5177\u4f53\u6539\u8fdb\u65b9\u6848\u548c\u5b9e\u73b0\u4ee3\u7801\u3002<\/p>\n<h2>\u4e00\u3001Android \u539f\u751f\u97f3\u9891\u67b6\u6784<\/h2>\n<h3>1.1 \u6574\u4f53\u67b6\u6784\u4e00\u89c8<\/h3>\n<p>Android \u97f3\u9891\u7cfb\u7edf\u4ece\u9876\u5c42 App \u5230\u786c\u4ef6\uff0c\u5927\u81f4\u5206\u4e3a\u56db\u5c42\uff1a<\/p>\n<pre>\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502                     \u5e94\u7528\u5c42 (App Layer)                       \u2502\n\u2502         AudioTrack \/ AudioRecord \/ MediaPlayer              \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                             \u2502 Java API (AudioTrack.write())\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25bc\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502                  \u6846\u67b6\u5c42 (Framework Layer)                   \u2502\n\u2502    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510      \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510  \u2502\n\u2502    \u2502   AudioFlinger   \u2502 \u2190\u2192   \u2502  AudioPolicyService       \u2502  \u2502\n\u2502    \u2502  (\u64ad\u653e\/\u6df7\u97f3\/\u8c03\u5ea6) \u2502      \u2502  (\u8def\u7531\/\u97f3\u9891\u7b56\u7565\/\u8bbe\u5907\u7ba1\u7406) \u2502  \u2502\n\u2502    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518      \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518  \u2502\n\u2502              \u2191                        \u2191                       \u2502\n\u2502    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510             \u2502\n\u2502    \u2502              Native Layer                \u2502             \u2502\n\u2502    \u2502  AudioTrack \/ AudioRecord \/ AudioEffect   \u2502             \u2502\n\u2502    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518             \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                             \u2502 Binder IPC\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25bc\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502                   Audio HAL Layer                            \u2502\n\u2502    (IAudioFlinger.hal \/ IAudioPolicy.hal \/ IEffect.hal)    \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                             \u2502\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25bc\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502                      \u97f3\u9891\u786c\u4ef6                                \u2502\n\u2502             DAC \/ DSP \/ I2S \/ \u626c\u58f0\u5668 \/ \u84dd\u7259 A2DP           \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n<\/pre>\n<p>\u6bcf\u4e00\u5c42\u90fd\u901a\u8fc7 HIDL\/AIDL HAL \u63a5\u53e3\u89e3\u8026\uff0c\u5382\u5546\u53ea\u9700\u5b9e\u73b0 HAL\uff0c\u65e0\u9700\u6539\u52a8\u4e0a\u5c42\u3002<\/p>\n<h3>1.2 AudioFlinger vs AudioPolicyService<\/h3>\n<p>\u5f88\u591a\u4eba\u641e\u4e0d\u6e05\u695a\u8fd9\u4e24\u4e2a\u670d\u52a1\u7684\u5173\u7cfb\uff1a<\/p>\n<pre>\nAudioFlinger\uff1a\u8d1f\u8d23\"\u600e\u4e48\u64ad\u653e\"\n  \u2192 \u7ba1\u7406 PlaybackThread \u548c RecordThread\n  \u2192 \u5b9e\u9645\u7684\u6df7\u97f3\u3001\u8c03\u5ea6\u3001\u5171\u4eab\u5185\u5b58\u7ba1\u7406\n  \u2192 \u628a\u6df7\u97f3\u540e\u7684\u6570\u636e\u5199\u5165 HAL\n\nAudioPolicyService\uff1a\u8d1f\u8d23\"\u80fd\u4e0d\u80fd\u64ad\u653e\"\u548c\"\u64ad\u5230\u54ea\u91cc\"\n  \u2192 \u8bbe\u5907\u9009\u578b\uff08speaker\/headset\/bt\uff09\n  \u2192 \u8def\u7531\u7b56\u7565\uff08\u63d2\u8033\u673a\u5207\u8f93\u51fa\u6e90\uff09\n  \u2192 Audio Focus \u7ba1\u7406\uff08\u8c01\u6253\u65ad\u8c01\uff09\n  \u2192 \u97f3\u91cf\u7ba1\u7406\uff08\u4e0d\u540c Zone \u7684\u97f3\u91cf\u66f2\u7ebf\uff09\n<\/pre>\n<h3>1.3 \u5173\u952e\u97f3\u9891\u8def\u5f84<\/h3>\n<pre>\n\u5a92\u4f53\u64ad\u653e\u8def\u5f84\uff1a\nMediaPlayer.decode()\n  \u2192 AudioTrack.write()     [44.1kHz PCM]\n    \u2192 AudioFlinger\n      \u2192 PlaybackThread\n        \u2192 \u91cd\u91c7\u6837 \u2192 [48kHz]\n        \u2192 \u6df7\u97f3\n        \u2192 Output Effects \u2192 [\u5747\u8861\u5668\/\u4f4e\u97f3\u589e\u5f3a]\n          \u2192 HAL.open_output_stream()\n            \u2192 DAC \u2192 \u626c\u58f0\u5668\n\n\u5bfc\u822a\u64ad\u62a5\u8def\u5f84\uff1a\nNavigationApp\n  \u2192 AudioTrack.write()     [\u4f4e\u5ef6\u8fdf\uff0cFLAG_AUDIBILITY_ENFORCED]\n    \u2192 AudioFlinger\n      \u2192 PlaybackThread (\u9ad8\u4f18\u5148\u7ea7)\n        \u2192 \u9ad8\u4f18\u5148\u7ea7 Track \u62a2\u5360 Mixer\n        \u2192 \u76f4\u63a5\u8f93\u51fa \u2192 [\u538b\u4f4e\u5a92\u4f53\u97f3\u91cf]\n          \u2192 HAL \u2192 \u626c\u58f0\u5668\n<\/pre>\n<h3>1.4 \u539f\u67b6\u6784\u7684\u6838\u5fc3\u95ee\u9898<\/h3>\n<p>| \u95ee\u9898 | \u63cf\u8ff0 |<br \/>\n|&#8212;&#8212;|&#8212;&#8212;|<br \/>\n| <strong>\u5355\u70b9\u74f6\u9888<\/strong> | \u6240\u6709 Track \u5171\u7528\u4e00\u4e2a MixerThread\uff0c\u9ad8\u4f18\u5148\u7ea7\u62a2\u5360\u65f6\u4f4e\u4f18\u5148\u7ea7\u88ab\u8fde\u5e26\u5f71\u54cd |<br \/>\n| <strong>Focus \u7c92\u5ea6\u7c97<\/strong> | \u53ea\u6709 4 \u79cd\u72b6\u6001\uff0c\u65e0\u6cd5\u7cbe\u7ec6\u63a7\u5236 Duck Level \u548c\u6062\u590d\u65f6\u95f4 |<br \/>\n| <strong>\u65e0 Zone \u652f\u6301<\/strong> | \u6807\u51c6 Android \u65e0\u591a\u533a\u57df\u97f3\u9891\u6982\u5ff5\uff0c\u8f66\u8f7d\u9700\u8981 CarAudioService \u5728\u4e0a\u5c42\u6a21\u62df |<br \/>\n| <strong>HAL \u788e\u7247\u5316<\/strong> | \u4e0d\u540c\u5382\u5546 HAL \u6027\u80fd\u5dee\u5f02\u5927\uff0c\u5ef6\u8fdf\u4e0d\u53ef\u9884\u671f |<br \/>\n| <strong>Effects \u5c40\u9650<\/strong> | \u7b2c\u4e09\u65b9 App \u65e0\u6cd5 attach Effect \u5230\u81ea\u5df1\u7684 Track |<\/p>\n<h2>\u4e8c\u3001\u6539\u8fdb\u540e\u7684\u97f3\u9891\u67b6\u6784<\/h2>\n<h3>2.1 \u65b0\u67b6\u6784\u5168\u666f<\/h3>\n<pre>\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502                     \u5e94\u7528\u5c42 (App Layer)                          \u2502\n\u2502         AudioTrack \/ AudioRecord \/ MediaPlayer                  \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                               \u2502 Java\/Native API\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25bc\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502                  \u6846\u67b6\u5c42 (Framework Layer)                      \u2502\n\u2502    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510      \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510  \u2502\n\u2502    \u2502   AudioFlinger  \u2502 \u2190\u2192   \u2502  AudioPolicyService          \u2502  \u2502\n\u2502    \u2502  + PriorityGroup\u2502      \u2502  + ExtendedAudioFocus        \u2502  \u2502\n\u2502    \u2502  + AudioZone     \u2502      \u2502  + ZoneManager               \u2502  \u2502\n\u2502    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518      \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518  \u2502\n\u2502             \u2502                                                      \u2502\n\u2502    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                \u2502\n\u2502    \u2502        PriorityPlaybackThread              \u2502                \u2502\n\u2502    \u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2510\u2502                \u2502\n\u2502    \u2502  \u2502CRITICAL \u2502 \u2502IMPORTANT\u2502 \u2502 NORMAL \u2502 \u2502BG  \u2502\u2502                \u2502\n\u2502    \u2502  \u2502 Group   \u2502 \u2502 Group   \u2502 \u2502 Group   \u2502 \u2502Group\u2502\u2502                \u2502\n\u2502    \u2502  \u2502(ADAS)   \u2502 \u2502(Nav)    \u2502 \u2502(Media)  \u2502 \u2502(Notif)\u2502             \u2502\n\u2502    \u2502  \u2514\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2518\u2502                \u2502\n\u2502    \u2502       \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518                \u2502\n\u2502    \u2502                   \u2193           \u2193                                \u2502\n\u2502    \u2502             \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                                    \u2502\n\u2502    \u2502             \u2502 FinalMixer \u2502 \u2190 \u5404 Group \u6c47\u603b                    \u2502\n\u2502    \u2502             \u2514\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2518                                    \u2502\n\u2502    \u2502                   \u2193                                            \u2502\n\u2502    \u2502             \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510     \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                 \u2502\n\u2502    \u2502             \u2502ZoneEffects \u2502 \u2190\u2192  \u2502TrackEffects \u2502                 \u2502\n\u2502    \u2502             \u2514\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2518     \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518                 \u2502\n\u2502    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\u2502                        \u2193\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25bc\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502                   Audio HAL Layer                                 \u2502\n\u2502    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510      \u2502\n\u2502    \u2502 StreamOut + Performance \u2502  \u2502 IStreamOutPerformanceExt   \u2502      \u2502\n\u2502    \u2502 (\u5e26 PerformanceClass)    \u2502  \u2502 (\u65b0\u589e\u6027\u80fd\u7b49\u7ea7\u67e5\u8be2\u63a5\u53e3)     \u2502      \u2502\n\u2502    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518      \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                              \u2193\n                      \u97f3\u9891\u786c\u4ef6 (\u5e26\u6027\u80fd\u7b49\u7ea7\u6807\u6ce8)\n<\/pre>\n<h3>2.2 Priority Group \u5206\u7ec4\u6df7\u97f3\u673a\u5236<\/h3>\n<pre>\n\u539f\u67b6\u6784\uff1a\u6240\u6709 Track \u2192 [\u5355 Mixer] \u2192 HAL\n       \u2193 \u95ee\u9898\uff1a\u9ad8\u4f18\u5148\u7ea7\u62a2\u5360\u65f6\u4f4e\u4f18\u5148\u7ea7\u88ab\u8fde\u5e26\u5f71\u54cd\n\n\u6539\u8fdb\u540e\uff1aTrack \u2192 [PriorityGroup \u5206\u7c7b] \u2192 [\u5404\u81ea\u72ec\u7acb Mixer] \u2192 [FinalMixer] \u2192 HAL\n       \u2193 \u4f18\u52bf\uff1a\u9ad8\u4f18\u5148\u7ea7\u72ec\u7acb\u6df7\u97f3\uff0c\u4e0d\u5f71\u54cd\u4f4e\u4f18\u5148\u7ea7\u8c03\u5ea6\n<\/pre>\n<pre>\nPriorityPlaybackThread \u5185\u90e8\u6d41\u7a0b\uff1a\n\n\u2460 \u9ad8\u4f18\u5148\u7ea7 Track \u5199\u6570\u636e\n   \u2193\n\u2461 CRITICAL Group \u72ec\u7acb\u6df7\u97f3\uff085ms buffer\uff0c\u65e0 Effects bypass\uff09\n   \u2193\n\u2462 IMPORTANT Group \u72ec\u7acb\u6df7\u97f3\uff0810ms buffer\uff09\n   \u2193\n\u2463 NORMAL Group \u6df7\u97f3\uff0820ms buffer\uff09\n   \u2193\n\u2464 BACKGROUND Group \u6df7\u97f3\uff0850ms buffer\uff0cDuck \u65f6\u964d\u5230 10%\uff09\n   \u2193\n\u2465 FinalMixer \u6c47\u603b\u6240\u6709 Group \u8f93\u51fa\n   \u2193\n\u2466 Zone Effects \u5904\u7406\n   \u2193\n\u2467 \u5199\u5165 HAL\n<\/pre>\n<h3>2.3 AudioZone \u591a\u533a\u57df\u539f\u751f\u652f\u6301<\/h3>\n<pre>\n\u539f\u67b6\u6784\uff1a\u65e0 Zone \u6982\u5ff5\uff0c\u6240\u6709\u8f93\u51fa\u5171\u4eab\u5355\u97f3\u91cf\u63a7\u5236\n\u6539\u8fdb\u540e\uff1aAudioZone \u539f\u751f\u652f\u6301\uff0c\u6bcf\u4e2a Zone \u72ec\u7acb\u8fd0\u884c\n\nAudioZoneManager \u2500\u2500\u252c\u2500\u2500 Zone[DRIVER]    { PriorityGroups + Focus }\n                    \u251c\u2500\u2500 Zone[FRONT_PASSENGER] { ... }\n                    \u251c\u2500\u2500 Zone[REAR_LEFT]  { ... }\n                    \u251c\u2500\u2500 Zone[REAR_RIGHT] { ... }\n                    \u2514\u2500\u2500 Zone[CENTER]     { \u5bfc\u822a\/ADAS \u8bed\u97f3 }\n\nZone \u95f4\u9694\u79bb\uff1a\n- \u9a7e\u9a76\u5ea7\u5bfc\u822a\u64ad\u62a5 \u2192 \u53ea\u5728 DRIVER Zone \u5185\u6253\u65ad\u5a92\u4f53\n- \u540e\u6392\u97f3\u4e50 \u2192 \u4e0d\u53d7\u9a7e\u9a76\u5ea7 Focus \u53d8\u5316\u5f71\u54cd\n- Center Zone \u7684 ADAS \u8b66\u793a\u97f3 \u2192 \u53ef\u914d\u7f6e\u662f\u5426\u538b\u4f4e\u5176\u4ed6 Zone\n<\/pre>\n<h3>2.4 \u6539\u8fdb\u540e\u7684 AudioFocus \u6d41\u7a0b<\/h3>\n<pre>\n\u539f\u6d41\u7a0b\uff1a\nApp \u8bf7\u6c42 Focus \u2192 \u8fd4\u56de GAIN\/LOSS \u2192 \u56fa\u5b9a\u884c\u4e3a\n\n\u6539\u8fdb\u540e\u6d41\u7a0b\uff1a\nApp \u8bf7\u6c42 Focus \u2192 ExtendedAudioFocus \u2192 \u8fd4\u56de\u7cbe\u7ec6\u5316 FocusInfo\n                                         \u251c\u2500\u2500 duckLevel: 0.0~1.0\n                                         \u251c\u2500\u2500 resumeDelayMs: 0~5000\n                                         \u251c\u2500\u2500 affectedUsages: [...]\n                                         \u2514\u2500\u2500 zoneId: \u9694\u79bb Zone\n\nFocus \u53d8\u5316\u56de\u8c03\uff1a\n  GAIN \u2192 \u6b63\u5e38\u64ad\u653e\n  LOSS_TRANSIENT \u2192 pause() \u7b49 resumeDelayMs \u540e\u81ea\u52a8\u6062\u590d\n  LOSS_TRANSIENT_MAY_DUCK \u2192 volume = duckLevel (\u53ef\u914d\u7f6e 30%)\n  LOSS \u2192 pause()\n<\/pre>\n<h3>2.5 HAL Performance Class \u9009\u62e9\u8def\u5f84<\/h3>\n<pre>\nAudioFlinger \u67e5\u8be2 HAL PerformanceClass\uff1a\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 PERFORMANCE_A   \u2502 \u2192 FastMixer \u76f4\u8fde\uff08< 20ms\uff09\n\u2502 (\u5ef6\u8fdf < 20ms)  \u2502   \u9002\u7528\u4e8e\uff1aADAS \u8b66\u793a\u3001\u5361\u62c9OK\u3001\u5b9e\u65f6\u76d1\u542c\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 PERFORMANCE_B   \u2502 \u2192 \u6807\u51c6\u8def\u5f84 + \u4f18\u5316\uff08< 50ms\uff09\n\u2502 (\u5ef6\u8fdf < 50ms)   \u2502   \u9002\u7528\u4e8e\uff1a\u5bfc\u822a\u64ad\u62a5\u3001\u6e38\u620f\u97f3\u6548\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 PERFORMANCE_C   \u2502 \u2192 \u5927 Buffer \u7a33\u5b9a\uff08< 100ms\uff09\n\u2502 (\u5ef6\u8fdf < 100ms)  \u2502   \u9002\u7528\u4e8e\uff1a\u540e\u53f0\u97f3\u4e50\u3001\u901a\u77e5\u97f3\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 UNSPECIFIED     \u2502 \u2192 \u6309\u6700\u574f\u60c5\u51b5\u5904\u7406\uff08\u52a0\u989d\u5916\u7f13\u51b2\uff09\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n<\/pre>\n<h2>\u4e09\u3001\u6539\u8fdb\u65b9\u6848\u4e0e\u4ee3\u7801\u5b9e\u73b0<\/h2>\n<h3>1. Priority Group \u5206\u7ec4\u6df7\u97f3<\/h3>\n<pre>\n\/\/ PriorityGroup.h\nenum audio_priority_group_t : int32_t {\n    PRIORITY_GROUP_CRITICAL = 0,   \/\/ ADAS \u8b66\u793a\u97f3\uff0cFLAG_AUDIBILITY_ENFORCED\n    PRIORITY_GROUP_IMPORTANT = 1,  \/\/ \u5bfc\u822a\u64ad\u62a5\u3001\u8bed\u97f3\u901a\u8bdd\n    PRIORITY_GROUP_NORMAL = 2,     \/\/ \u5a92\u4f53\u64ad\u653e\u3001\u6e38\u620f\u97f3\u6548\n    PRIORITY_GROUP_BACKGROUND = 3, \/\/ \u901a\u77e5\u97f3\u3001Touch Sound\n};\n\nstruct PriorityGroupConfig {\n    audio_priority_group_t groupId;\n    size_t maxTracks;\n    uint32_t bufferSizeMs;       \/\/ CRITICAL \u7528\u5c0f buffer \u4f4e\u5ef6\u8fdf\n    int32_t resamplerQuality;\n    bool effectsBypass;           \/\/ CRITICAL \u901a\u5e38 bypass Effects\n};\n\n\/\/ \u9ed8\u8ba4\u914d\u7f6e\nPriorityGroupConfig::defaultConfigs[PRIORITY_GROUP_COUNT] = {\n    { CRITICAL,   8,  5ms, HIGH,   true  },   \/\/ 5ms\uff0c\u65e0 Effects\n    { IMPORTANT, 16, 10ms, MEDIUM, false },\n    { NORMAL,    32, 20ms, MEDIUM, false },\n    { BACKGROUND,16, 50ms, LOW,   true  },   \/\/ \u5927 buffer \u7a33\u5b9a\n};\n<\/pre>\n<pre>\n\/\/ PriorityPlaybackThread.cpp \u2014 \u6838\u5fc3\u6df7\u97f3\u903b\u8f91\nbool PriorityPlaybackThread::threadLoop() {\n    \/\/ Phase 1: \u6309 Group \u72ec\u7acb\u6df7\u97f3\n    memset(mFinalMixBuffer.data(), 0, bufferBytes);\n    \n    for (int i = 0; i &lt; PRIORITY_GROUP_COUNT; i++) {\n        auto&amp; group = mPriorityGroups[i];\n        if (!group-&gt;hasActiveTracks()) continue;\n        \n        std::vector&lt;float&gt; groupBuffer(frameCount * channels);\n        group-&gt;mixTracks(mSampleRate, mChannelMask, frameCount,\n                        groupBuffer.data(), frameCount);\n        \n        for (size_t j = 0; j &lt; frameCount * channels; j++) {\n            mFinalMixBuffer[j] += groupBuffer[j];  \/\/ \u6c47\u603b\n        }\n    }\n    \n    \/\/ Phase 2: Ducking \u2014 \u9ad8\u4f18\u5148\u7ea7 Group \u6d3b\u8dc3\u65f6\u964d\u4f4e\u4f4e\u4f18\u5148\u7ea7\u97f3\u91cf\n    if (mIsDucking) {\n        mPriorityGroups[BACKGROUND]-&gt;setVolume(mDuckingLevel * 0.5f);  \/\/ 10%\n        mPriorityGroups[NORMAL]-&gt;setVolume(mDuckingLevel);               \/\/ 20%\n    }\n    \n    writeToHal(mFinalMixBuffer.data(), frameCount);\n    return true;\n}\n<\/pre>\n<h3>2. AudioZone \u539f\u751f\u652f\u6301<\/h3>\n<pre>\n\/\/ AudioZone.h \u2014 \u591a\u533a\u57df\u97f3\u9891\u6838\u5fc3\u5b9a\u4e49\nenum audio_zone_id_t : int32_t {\n    AUDIO_ZONE_ID_DEFAULT = 0,\n    AUDIO_ZONE_ID_DRIVER = 0,\n    AUDIO_ZONE_ID_FRONT_PASSENGER = 1,\n    AUDIO_ZONE_ID_REAR_LEFT = 2,\n    AUDIO_ZONE_ID_REAR_RIGHT = 3,\n    AUDIO_ZONE_ID_CENTER = 4,      \/\/ \u4e2d\u592e\u901a\u9053\uff0c\u5bfc\u822a\/ADAS\n};\n\nclass AudioZone : public RefBase {\n    audio_zone_id_t getZoneId() const { return mConfig.zoneId; }\n    \n    \/\/ Zone \u5185\u6309 PriorityGroup \u5206\u7ec4\uff0c\u5404\u81ea\u72ec\u7acb\u6df7\u97f3\n    std::vector&lt;sp&lt;PriorityGroup&gt;&gt; mPriorityGroups;\n    \n    \/\/ Zone \u7ea7\u97f3\u91cf + Focus \u9694\u79bb\n    float mVolume;\n    sp&lt;AudioFocusManager&gt; mFocusManager;\n};\n\nclass AudioZoneManager : public RefBase {\n    std::vector&lt;sp&lt;AudioZone&gt;&gt; mZones;  \/\/ \u6240\u6709 Zone\n    \n    \/\/ \u5168\u5c40\u6df7\u97f3\u5165\u53e3\n    status_t mixAllZones(void* halOutput, uint32_t halFrames);\n    \n    \/\/ Zone \u8def\u7531\u914d\u7f6e\n    status_t setZoneRoute(audio_zone_id_t zoneId, audio_io_handle_t halOutput);\n};\n<\/pre>\n<h3>3. AudioFocus \u7cbe\u7ec6\u5316\u63a7\u5236<\/h3>\n<pre>\n\/\/ AudioFocusRequest.java \u2014 \u6269\u5c55 Focus \u8bf7\u6c42\npublic static class Builder {\n    \/** Ducking Level\uff080.0 ~ 1.0\uff09\uff0c\u539f\u6765\u53ea\u80fd 0 \u6216 0.2 *\/\n    public @NonNull Builder setDuckingLevel(float level) {\n        mDuckingLevel = level;  \/\/ \u53ef\u8bbe 0.3 \u5373 30%\n        return this;\n    }\n    \n    \/** \u5ef6\u8fdf\u6062\u590d\u65f6\u95f4\uff08ms\uff09*\/\n    public @NonNull Builder setResumeDelayMs(int delayMs) {\n        mResumeDelayMs = delayMs;  \/\/ \u88ab\u6253\u65ad\u540e\u7b492\u79d2\u518d\u6062\u590d\n        return this;\n    }\n    \n    \/** \u53d7\u5f71\u54cd\u7684 Usage\uff08\u53ea\u5f71\u54cd\u6307\u5b9a\u7684\uff0c\u4e0d\u5f71\u54cd\u5176\u4ed6\uff09*\/\n    public @NonNull Builder setAffectedUsages(@NonNull AudioUsage[] usages) {\n        mAffectedUsages = Arrays.copyOf(usages, usages.length);\n        return this;\n    }\n    \n    \/** Zone \u9694\u79bb\uff08\u9a7e\u9a76\u5ea7\u7684 Focus \u4e0d\u6253\u65ad\u540e\u6392\u97f3\u4e50\uff09*\/\n    public @NonNull Builder setZoneId(int zoneId) {\n        mZoneId = zoneId;\n        return this;\n    }\n}\n\n\/\/ \u4f7f\u7528\u793a\u4f8b\nAudioFocusRequest request = new AudioFocusRequest.Builder(AUDIOFOCUS_GAIN)\n    .setDuckingLevel(0.3f)              \/\/ duck \u5230 30%\n    .setResumeDelayMs(2000)              \/\/ 2\u79d2\u540e\u6062\u590d\n    .setAffectedUsages(MEDIA, GAME)      \/\/ \u53ea\u538b\u4f4e\u5a92\u4f53\u548c\u6e38\u620f\n    .setZoneId(DRIVER_ZONE)              \/\/ \u53ea\u5728\u9a7e\u9a76 Zone \u751f\u6548\n    .build();\n<\/pre>\n<h3>4. HAL Performance Class \u6807\u51c6<\/h3>\n<pre>\n\/\/ StreamOut.h \u2014 \u5b9a\u4e49 HAL \u6027\u80fd\u7b49\u7ea7\nenum audio_hal_performance_class_t : int32_t {\n    PERFORMANCE_CLASS_A = 0,  \/\/ \u5ef6\u8fdf &lt; 20ms\uff0c\u5fc5\u987b FastMixer\n    PERFORMANCE_CLASS_B = 1,    \/\/ \u5ef6\u8fdf &lt; 50ms\n    PERFORMANCE_CLASS_C = 2,    \/\/ \u5ef6\u8fdf &lt; 100ms\n};\n\nstruct audio_hal_performance_info_t {\n    audio_hal_performance_class_t performanceClass;\n    uint32_t latencyMs;          \/\/ \u5b9e\u6d4b\u7aef\u5230\u7aef\u5ef6\u8fdf\n    uint32_t halBufferMs;         \/\/ HAL \u5185\u90e8\u7f13\u51b2\n    bool supportsFastMixer;\n    bool supportsLowLatency;\n};\n\nclass IStreamOutPerformanceExtension {\n    virtual int getPerformanceClass(audio_hal_performance_info_t* info) = 0;\n    virtual bool supportsLatency(uint32_t targetLatencyMs) = 0;\n};\n<\/pre>\n<pre>\n\/\/ AudioFlinger \u6839\u636e\u7b49\u7ea7\u9009\u62e9\u8def\u5f84\nif (performanceClass == PERFORMANCE_CLASS_A) {\n    useFastMixerPath(streamOut);        \/\/ &lt; 20ms\n} else if (performanceClass == PERFORMANCE_CLASS_B) {\n    useOptimizedMixerPath(streamOut);   \/\/ &lt; 50ms\n} else {\n    useStabilizedPath(streamOut);        \/\/ &lt; 100ms\n}\n<\/pre>\n<h3>5. Track Effects \u5f00\u653e API<\/h3>\n<pre>\n\/\/ AudioTrack.java \u2014 \u6269\u5c55 Builder\npublic static class Builder extends AudioTrack.Builder {\n    private ArrayList&lt;Integer&gt; mEffectIds = new ArrayList&lt;&gt;();\n    \n    public @NonNull Builder setAttachEffect(int effectId) {\n        mEffectIds.add(effectId);  \/\/ \u652f\u6301\u591a\u4e2a Effect \u4e32\u884c\n        return this;\n    }\n}\n\nAudioTrack track = new AudioTrack.Builder()\n    .setAudioAttributes(...)\n    .setAttachEffect(effectId1)  \/\/ \u9644\u52a0 Effect \u5230 Track\n    .setAttachEffect(effectId2)\n    .build();\n\ntrack.attachEffect(effectId3);   \/\/ \u52a8\u6001 attach\ntrack.detachEffect(effectId1);    \/\/ \u52a8\u6001 detach\n<\/pre>\n<h2>\u56db\u3001\u603b\u7ed3<\/h2>\n<p>| \u4e0d\u8db3 | \u6539\u8fdb\u65b9\u6848 | \u6838\u5fc3\u53d8\u5316 |<br \/>\n|------|----------|----------|<br \/>\n| \u5355\u70b9\u74f6\u9888 | Priority Group \u5206\u7ec4\u6df7\u97f3 | \u6309\u4f18\u5148\u7ea7\u72ec\u7acb Mixer\uff0c\u4e92\u4e0d\u5f71\u54cd |<br \/>\n| Focus \u592a\u7c97 | \u591a\u7ea7 Focus + ResumeDelay | \u7cbe\u7ec6\u5316 Duck Level + \u5ef6\u8fdf\u6062\u590d |<br \/>\n| \u591a Zone \u592a\u5f31 | AudioZone \u539f\u751f\u652f\u6301 | Zone \u95f4 Focus \u9694\u79bb |<br \/>\n| HAL \u788e\u7247\u5316 | Performance Class | \u6309\u6027\u80fd\u7b49\u7ea7\u9009\u62e9\u6700\u4f18\u8def\u5f84 |<br \/>\n| Effects \u5c40\u9650 | Track Effects \u5f00\u653e | App \u53ef attach Effect |<\/p>\n<h2>\u4e94\u3001\u540e\u7eed\u5de5\u4f5c<\/h2>\n<ol>\n<li>\u4f18\u5148\u7ea7\u5206\u7c7b\u89c4\u5219\u548c AudioPolicyService \u8054\u52a8\u5b8c\u5584<\/li>\n<li>AudioZone \u7684 HAL \u8def\u7531\u9700\u8981\u548c CarAudioHAL \u5bf9\u63a5<\/li>\n<li>Track Effects \u7684 native \u5c42\u5b9e\u73b0 binder \u901a\u4fe1<\/li>\n<li>Performance Class \u5728 HAL CTS \u6d4b\u8bd5\u4e2d\u9a8c\u8bc1<\/li>\n<li>\u5b8c\u6574\u7684\u6d4b\u8bd5\u7528\u4f8b\uff08CTS\/VTS\uff09<\/li>\n<\/ol>\n<p>\u5b8c\u6574\u7684\u5b9e\u73b0\u4ee3\u7801\u5df2\u4e0a\u4f20\u5230 GitHub\uff0c\u53ef\u4f5c\u4e3a\u5185\u90e8\u8bbe\u8ba1\u6587\u6863\u6216\u6982\u5ff5\u9a8c\u8bc1\u7684\u57fa\u7840\u3002<\/p>\n<hr>\n<p><strong>\u914d\u5957\u4ee3\u7801\u4ed3\u5e93\uff1a<\/strong><br \/>GitHub: <a href=\"https:\/\/github.com\/fryduck\/android-audio-architecture-improvement\">fryduck\/android-audio-architecture-improvement<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u672c\u6587\u68b3\u7406\u4e86 Android \u539f\u751f\u97f3\u9891\u67b6\u6784\u7684\u6838\u5fc3\u95ee\u9898\uff0c\u5e76\u7ed9\u51fa\u5177\u4f53\u6539\u8fdb\u65b9\u6848\u548c\u5b9e\u73b0\u4ee3\u7801\u3002 \u4e00\u3001Android \u539f\u751f\u97f3 &#8230; <a title=\"Android \u539f\u751f\u97f3\u9891\u67b6\u6784\u4e0d\u8db3\u4e0e\u6539\u8fdb\u5b9e\u8df5\" class=\"read-more\" href=\"\/index.php\/2026\/05\/04\/android-audio-architecture-improvement\/\" aria-label=\"\u9605\u8bfb Android \u539f\u751f\u97f3\u9891\u67b6\u6784\u4e0d\u8db3\u4e0e\u6539\u8fdb\u5b9e\u8df5\">\u9605\u8bfb\u66f4\u591a<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,3],"tags":[],"class_list":["post-60","post","type-post","status-publish","format-standard","hentry","category-tech","category-car-audio"],"_links":{"self":[{"href":"\/index.php\/wp-json\/wp\/v2\/posts\/60","targetHints":{"allow":["GET"]}}],"collection":[{"href":"\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"\/index.php\/wp-json\/wp\/v2\/comments?post=60"}],"version-history":[{"count":3,"href":"\/index.php\/wp-json\/wp\/v2\/posts\/60\/revisions"}],"predecessor-version":[{"id":68,"href":"\/index.php\/wp-json\/wp\/v2\/posts\/60\/revisions\/68"}],"wp:attachment":[{"href":"\/index.php\/wp-json\/wp\/v2\/media?parent=60"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"\/index.php\/wp-json\/wp\/v2\/categories?post=60"},{"taxonomy":"post_tag","embeddable":true,"href":"\/index.php\/wp-json\/wp\/v2\/tags?post=60"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}