feat(bt): 蓝牙P2 source实装 — audiod OUT_BT输出目标(libasound直连pcm.bluealsa,BT独立目标不动DAC独占/FPGA/音量反转)+音量AVRCP隔离(不下发DAC反转)+codec生效+MSG_AUDIO_OUTPUT/CLI;宿主67pass/0warning;sink标记P2.5;遗留mipsel静态dlopen不支持libasound(硬集成项)
This commit is contained in:
1 parent
1f6d390e1c
commit
71b2dafecc
5 files changed
+587
-42
No files matched your search
@@ -153,6 +153,22 @@ static int start_audiod(void)
|
||||
return start_audiod_ex("file", NULL, NULL);
|
||||
}
|
||||
|
||||
/* 带自定义 settings.conf 的启动(P2 蓝牙:测 audio.output_bt / bt.codec 读取生效) */
|
||||
static int start_audiod_settings(const char *sink, const char *settings_path)
|
||||
{
|
||||
pid_t pid = fork();
|
||||
if (pid == 0) {
|
||||
setenv("MEOW_AUDIO_SINK", sink, 1);
|
||||
setenv("MEOW_AUDIO_OUT", TWAV, 1);
|
||||
setenv("MEOW_AUDIO_SOCK", TSOCK, 1);
|
||||
setenv("MEOW_AUDIO_FORCE", "1", 1);
|
||||
if (settings_path) setenv("MEOW_AUDIO_SETTINGS", settings_path, 1);
|
||||
execl("./meow_audiod_host", "meow_audiod_host", (char *)0);
|
||||
_exit(127);
|
||||
}
|
||||
return pid;
|
||||
}
|
||||
|
||||
/* 直接客户端 open */
|
||||
static int do_open(struct cli *c, int rate, int ch, int fmt, m_audio_open_ack_t *ack)
|
||||
{
|
||||
@@ -690,6 +706,78 @@ int main(void)
|
||||
check(eok, "fresh OPEN after overflow (table recycled, no exhaustion/wedge)");
|
||||
check(stop_audiod_tmo(5000) != 0, "audiod not wedged by overflow (SIGTERM clean exit)");
|
||||
|
||||
/* ---- T11:P2 蓝牙 输出目标(OUT_BT)+ 音量 AVRCP 隔离 + 格式归一 + codec。
|
||||
* 宿主以 FILE sink 跑(真 bluealsa 传输留给真机),验证目标选择/音量隔离/格式逻辑:
|
||||
* - settings.conf `audio.output_bt=1` + `bt.codec=SBC` → target=bt / codec=SBC / volctl=avrcp / grant fmt=S16;
|
||||
* - BT 下 MSG_AUDIO_VOLUME 设置:**不下发 DAC 音量反转**——g_vol_pct 不变、不持久化 audio.volume、
|
||||
* volctl 仍 avrcp(隔离成立);
|
||||
* - MSG_AUDIO_OUTPUT 切回 DAC:target=dac / volctl=dac;此后音量设置写 DAC + 持久化 audio.volume。
|
||||
* 断言:BT 路径绝不动 DAC 音量(plan §三/§五「两套隔离」);BT 格式归一=S16;codec 读到生效。 ---- */
|
||||
printf("[T11 BT output target + AVRCP vol isolation]\n");
|
||||
unlink(TSOCK); unlink(TWAV);
|
||||
const char *tconf = "/tmp/meow_test_settings.conf";
|
||||
FILE *tf = fopen(tconf, "w");
|
||||
if (tf) { fprintf(tf, "# meow-settings 1\naudio.volume = 60\naudio.output_bt = 1\nbt.codec = SBC\n"); fclose(tf); }
|
||||
g_audiod_pid = start_audiod_settings("file", tconf);
|
||||
usleep(400000);
|
||||
struct cli b11;
|
||||
check(cli_connect(&b11) == 0, "connect B11");
|
||||
m_audio_open_ack_t ack11;
|
||||
check(do_open(&b11, 44100, 2, AUDIO_FMT_S16, &ack11) == 0 && ack11.err == MEOW_OK, "open B11 (bt)");
|
||||
char q11[1024];
|
||||
check(do_query(&b11, q11, sizeof q11) == 0 && strstr(q11, "target=bt"),
|
||||
"settings output_bt=1 -> target=bt");
|
||||
check(strstr(q11, "codec=SBC") != NULL, "settings bt.codec=SBC -> codec=SBC");
|
||||
check(strstr(q11, "volctl=avrcp") != NULL, "bt -> volctl=avrcp (AVRCP vol control)");
|
||||
check(strstr(q11, "fmt=S16") != NULL, "bt grant fmt=S16 (format normalize)");
|
||||
/* BT/file sink 写一段流(应正常落盘到 WAV) */
|
||||
do_write(&b11, pcm, (uint32_t)gen_sine(pcm, sizeof pcm, (int)(ack11.grant_fmt ? ack11.grant_fmt : AUDIO_FMT_S16), 600, 440, 44100));
|
||||
usleep(150000);
|
||||
/* 音量设置 while BT:不下发 DAC——g_vol_pct 不变(60)、不持久化 audio.volume=40、volctl 仍 avrcp */
|
||||
{
|
||||
int32_t pct = 40;
|
||||
if (sf(b11.fd, MSG_AUDIO_VOLUME, 8, &pct, sizeof pct) == 0) {
|
||||
uint8_t ab[64]; uint16_t at; rf(b11.fd, &at, ab, sizeof ab); /* 消费 ACK */
|
||||
}
|
||||
usleep(100000);
|
||||
}
|
||||
check(do_query(&b11, q11, sizeof q11) == 0 && strstr(q11, "volctl=avrcp"),
|
||||
"vol set while bt -> volctl still avrcp (isolation)");
|
||||
check(strstr(q11, "vol=60") != NULL, "vol set while bt -> DAC vol unchanged (60)");
|
||||
{
|
||||
FILE *chk = fopen(tconf, "r"); int has40 = 0; char l[128];
|
||||
if (chk) { while (fgets(l, sizeof l, chk)) if (strstr(l, "audio.volume = 40")) has40 = 1; fclose(chk); }
|
||||
check(!has40, "bt vol set does NOT persist audio.volume=40");
|
||||
}
|
||||
/* MSG_AUDIO_OUTPUT 切回 DAC */
|
||||
{
|
||||
m_audio_output_t oo; oo.target = AUDIO_OUT_DAC;
|
||||
if (sf(b11.fd, MSG_AUDIO_OUTPUT, 9, &oo, sizeof oo) == 0) {
|
||||
uint8_t ab[64]; uint16_t at; rf(b11.fd, &at, ab, sizeof ab);
|
||||
}
|
||||
usleep(150000);
|
||||
}
|
||||
check(do_query(&b11, q11, sizeof q11) == 0 && strstr(q11, "target=dac"),
|
||||
"MSG_AUDIO_OUTPUT -> target=dac");
|
||||
check(strstr(q11, "volctl=dac") != NULL, "dac -> volctl=dac");
|
||||
/* 现在音量设置应写 DAC + 持久化 */
|
||||
{
|
||||
int32_t pct = 40;
|
||||
if (sf(b11.fd, MSG_AUDIO_VOLUME, 10, &pct, sizeof pct) == 0) {
|
||||
uint8_t ab[64]; uint16_t at; rf(b11.fd, &at, ab, sizeof ab);
|
||||
}
|
||||
usleep(150000);
|
||||
}
|
||||
check(do_query(&b11, q11, sizeof q11) == 0 && strstr(q11, "vol=40"), "dac vol set -> g_vol_pct=40");
|
||||
{
|
||||
FILE *chk = fopen(tconf, "r"); int has40 = 0; char l[128];
|
||||
if (chk) { while (fgets(l, sizeof l, chk)) if (strstr(l, "audio.volume = 40")) has40 = 1; fclose(chk); }
|
||||
check(has40, "dac vol set persists audio.volume=40");
|
||||
}
|
||||
do_ctrl(&b11, MSG_AUDIO_STOP, ack11.stream_id);
|
||||
close(b11.fd);
|
||||
stop_audiod();
|
||||
|
||||
printf("=== SUMMARY: pass=%d fail=%d ===\n", g_pass, g_fail);
|
||||
return g_fail ? 1 : 0;
|
||||
}
|
||||
Reference in new issue
Block a user