feat(audiod): A3+DSD — ①24/32bit高清byte-exact(偏好S32) ②独立AUDIO_FMT_DOP DoP DSD透传+失败报错关流(拒BT) ③音量收编v2双组写PCM+DSD_VOLUME平方锥度audiod权威 ④/api/audio/monitor监控+前端音频页监控卡;宿主100/0,0warning;SDK meow_ui_audio ABI变大M6.34需重编meow_ui.a+重链四App
This commit is contained in:
1 parent
2dc4cad454
commit
effce6d0db
6 files changed
+533
-56
No files matched your search
@@ -27,6 +27,7 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#define TSOCK "/tmp/meow_audio_test.sock"
|
||||
#define TWAV "/tmp/meow_audio_test.wav"
|
||||
@@ -169,12 +170,29 @@ static int start_audiod_settings(const char *sink, const char *settings_path)
|
||||
return pid;
|
||||
}
|
||||
|
||||
/* 直接客户端 open */
|
||||
static int do_open(struct cli *c, int rate, int ch, int fmt, m_audio_open_ack_t *ack)
|
||||
/* 带 amixer 追踪的启动(A3/DSD:断言「音量双组写」PCM+DSD_VOLUME 成对下发)。settings_path 可空。 */
|
||||
static int start_audiod_trace(const char *sink, const char *settings_path, const char *trace_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);
|
||||
if (trace_path) setenv("MEOW_AUDIO_AMIXER_TRACE", trace_path, 1);
|
||||
execl("./meow_audiod_host", "meow_audiod_host", (char *)0);
|
||||
_exit(127);
|
||||
}
|
||||
return pid;
|
||||
}
|
||||
|
||||
/* 直接客户端 open(带 flags:AUDIO_FLAG_DSD 用于 DoP) */
|
||||
static int do_open_f(struct cli *c, int rate, int ch, int fmt, uint32_t flags, m_audio_open_ack_t *ack)
|
||||
{
|
||||
m_audio_open_t o; memset(&o, 0, sizeof o);
|
||||
snprintf(o.app_id, sizeof o.app_id, "test");
|
||||
o.rate = (uint32_t)rate; o.ch = (uint16_t)ch; o.fmt = (uint16_t)fmt; o.flags = 0;
|
||||
o.rate = (uint32_t)rate; o.ch = (uint16_t)ch; o.fmt = (uint16_t)fmt; o.flags = flags;
|
||||
if (sf(c->fd, MSG_AUDIO_OPEN, 1, &o, sizeof o)) return -1;
|
||||
uint8_t rbuf[256]; uint16_t rt;
|
||||
if (rf(c->fd, &rt, rbuf, sizeof rbuf) < 0) return -1;
|
||||
@@ -182,6 +200,11 @@ static int do_open(struct cli *c, int rate, int ch, int fmt, m_audio_open_ack_t
|
||||
memcpy(ack, rbuf, sizeof *ack);
|
||||
return 0;
|
||||
}
|
||||
/* 直接客户端 open */
|
||||
static int do_open(struct cli *c, int rate, int ch, int fmt, m_audio_open_ack_t *ack)
|
||||
{
|
||||
return do_open_f(c, rate, ch, fmt, 0, ack);
|
||||
}
|
||||
|
||||
static int do_write(struct cli *c, const void *pcm, uint32_t len)
|
||||
{
|
||||
@@ -266,6 +289,45 @@ static int verify_wav(const char *path, int rate_expect, int ch_expect, int bits
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 字节保真校验(A3 高清 / DoP 透传):WAV 头 rate/ch/bits 精确匹配 + data 段与 payload 逐字节一致。
|
||||
* 返回 0=合法且逐字节等同;-1=文件/头非法;-2=data_len 或内容不匹配。 */
|
||||
static int wav_byte_exact(const char *path, int rate_expect, int ch_expect, int bits_expect,
|
||||
const uint8_t *payload, size_t plen)
|
||||
{
|
||||
FILE *f = fopen(path, "rb");
|
||||
if (!f) return -1;
|
||||
unsigned char h[44];
|
||||
if (fread(h, 1, 44, f) != 44) { fclose(f); return -1; }
|
||||
if (memcmp(h, "RIFF", 4) || memcmp(h + 8, "WAVE", 4) || memcmp(h + 12, "fmt ", 4)) { fclose(f); return -1; }
|
||||
uint16_t ch, bits; uint32_t rate, data_len, byterate;
|
||||
memcpy(&ch, h + 22, 2); memcpy(&rate, h + 24, 4); memcpy(&byterate, h + 28, 4); memcpy(&bits, h + 34, 2);
|
||||
memcpy(&data_len, h + 40, 4);
|
||||
if (ch != (uint16_t)ch_expect || rate != (uint32_t)rate_expect || bits != (uint16_t)bits_expect) { fclose(f); return -1; }
|
||||
if (byterate != rate * ch * bits / 8) { fclose(f); return -1; }
|
||||
if (data_len != (uint32_t)plen) { fclose(f); return -2; }
|
||||
uint8_t *body = malloc(plen ? plen : 1);
|
||||
if (!body) { fclose(f); return -1; }
|
||||
size_t rd = fread(body, 1, plen, f);
|
||||
fclose(f);
|
||||
int ok = (rd == plen) && (memcmp(body, payload, plen) == 0);
|
||||
free(body);
|
||||
return ok ? 0 : -2;
|
||||
}
|
||||
|
||||
/* 等 WAV 头出现(设备已 dev_open 写入 44B 头):**STOP 前调用**——修复 OPEN→write→STOP 过快时
|
||||
* 播放线程尚未来得及 reconfigure(设备未打开,STOP 的 session_end 清 reconfig → 空 WAV)的竞态。
|
||||
* 返回 0=头已出现;-1=超时。 */
|
||||
static int wait_wav_open(const char *path, int tmo_ms)
|
||||
{
|
||||
for (int i = 0; i < tmo_ms / 50; i++) {
|
||||
struct stat st;
|
||||
if (stat(path, &st) < 0) { usleep(50000); continue; }
|
||||
if (st.st_size >= 44) return 0;
|
||||
usleep(50000);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
unlink(TSOCK); unlink(TWAV);
|
||||
@@ -778,6 +840,246 @@ int main(void)
|
||||
close(b11.fd);
|
||||
stop_audiod();
|
||||
|
||||
/* ---- T12:24/32bit 高清流 byte-exact(A3 高清实测;FILE sink 按请求保真,S32 升位不降位)。
|
||||
* ① S32@192000:open 应 grant S32(FILE/NULL sink 按 native 高保真透传);写已知 32-bit 交织帧,
|
||||
* 验证 WAV 为 32-bit 且 data 段与 payload 逐字节相等(无降位/无重排)。
|
||||
* ② S24@88200(32-in-32):grant S24,WAV 32-bit 逐字节等同。鉴真机 DAC 高清率由 hw_probe 决定。 */
|
||||
printf("[T12 24/32bit hi-res byte-exact]\n");
|
||||
unlink(TSOCK); unlink(TWAV);
|
||||
g_audiod_pid = start_audiod(); /* file sink */
|
||||
usleep(400000);
|
||||
{
|
||||
struct cli h12;
|
||||
check(cli_connect(&h12) == 0, "connect H12");
|
||||
m_audio_open_ack_t ack12;
|
||||
check(do_open_f(&h12, 192000, 2, AUDIO_FMT_S32, 0, &ack12) == 0 && ack12.err == MEOW_OK,
|
||||
"open S32@192000");
|
||||
check(ack12.grant_fmt == AUDIO_FMT_S32, "grant S32 for S32 request (FILE byte-exact)");
|
||||
check(ack12.grant_rate == 192000, "grant_rate=192000 (no SRC)");
|
||||
uint8_t pl[4096];
|
||||
size_t fs12 = 2 * 4; /* stereo S32 */
|
||||
size_t nframes = sizeof pl / fs12;
|
||||
uint8_t *op = pl;
|
||||
for (size_t i = 0; i < nframes; i++) {
|
||||
uint32_t l = (uint32_t)(((i * 7u) & 0xFFFFu) << 16);
|
||||
uint32_t r = (uint32_t)((0x10000u - ((i * 7u) & 0xFFFFu)) << 16);
|
||||
memcpy(op, &l, 4); op += 4; memcpy(op, &r, 4); op += 4;
|
||||
}
|
||||
do_write(&h12, pl, (uint32_t)sizeof pl);
|
||||
char q12[1024];
|
||||
do_query(&h12, q12, sizeof q12); /* 活动态快照 + 给播放线程时间重配设备 */
|
||||
check(strstr(q12, "fmt=S32") != NULL, "query fmt=S32 (hi-res format exposed)");
|
||||
wait_wav_open(TWAV, 3000); /* 等设备开(WAV 头已在),再 STOP */
|
||||
do_ctrl(&h12, MSG_AUDIO_STOP, ack12.stream_id);
|
||||
for (int i = 0; i < 300; i++) { /* ≤30s 等排空 + WAV 头回填 */
|
||||
usleep(100000);
|
||||
if (wav_byte_exact(TWAV, 192000, 2, 32, pl, sizeof pl) == 0) break;
|
||||
}
|
||||
check(wav_byte_exact(TWAV, 192000, 2, 32, pl, sizeof pl) == 0,
|
||||
"S32@192000 WAV byte-exact (32-bit, no downshift)");
|
||||
/* ② S24@88200(32-in-32) */
|
||||
unlink(TWAV);
|
||||
struct cli h12b;
|
||||
check(cli_connect(&h12b) == 0, "connect H12b");
|
||||
m_audio_open_ack_t ack12b;
|
||||
check(do_open_f(&h12b, 88200, 2, AUDIO_FMT_S24, 0, &ack12b) == 0 && ack12b.err == MEOW_OK,
|
||||
"open S24@88200");
|
||||
check(ack12b.grant_fmt == AUDIO_FMT_S24, "grant S24 for S24 request (32-in-32)");
|
||||
uint8_t pl2[4096];
|
||||
size_t fs24 = 2 * 4;
|
||||
size_t n2 = sizeof pl2 / fs24;
|
||||
uint8_t *op2 = pl2;
|
||||
for (size_t i = 0; i < n2; i++) {
|
||||
uint32_t l = (uint32_t)((i * 11u) << 8); /* 24-bit 区在 [31:8] */
|
||||
uint32_t r = (uint32_t)(0x1000000u - ((i * 11u) << 8));
|
||||
memcpy(op2, &l, 4); op2 += 4; memcpy(op2, &r, 4); op2 += 4;
|
||||
}
|
||||
do_write(&h12b, pl2, (uint32_t)sizeof pl2);
|
||||
char q12b[1024];
|
||||
do_query(&h12b, q12b, sizeof q12b); /* 活动态快照:fmt 未清 */
|
||||
check(strstr(q12b, "fmt=S24") != NULL, "query fmt=S24 (hi-res format exposed)");
|
||||
wait_wav_open(TWAV, 3000); /* 等设备开(WAV 头已在),再 STOP */
|
||||
do_ctrl(&h12b, MSG_AUDIO_STOP, ack12b.stream_id);
|
||||
for (int i = 0; i < 300; i++) {
|
||||
usleep(100000);
|
||||
if (wav_byte_exact(TWAV, 88200, 2, 32, pl2, sizeof pl2) == 0) break;
|
||||
}
|
||||
check(wav_byte_exact(TWAV, 88200, 2, 32, pl2, sizeof pl2) == 0,
|
||||
"S24@88200 WAV byte-exact (32-in-32)");
|
||||
close(h12.fd); close(h12b.fd);
|
||||
}
|
||||
stop_audiod();
|
||||
|
||||
/* ---- T13:DoP DSD 透传(A3+DSD:fmt=DOP+flags=DSD,audiod 只透传;不做 dsd2pcm)。
|
||||
* 写已知 DoP 帧(32-bit:bits[31:16]=16bit DSD,bits[15:8]=标记 0xFA(L)/0x05(R)),
|
||||
* 验证 grant=DOP、WAV 32-bit 逐字节等同(透传保真)、query fmt=DoP dsd=1。 */
|
||||
printf("[T13 DoP DSD passthrough]\n");
|
||||
unlink(TSOCK); unlink(TWAV);
|
||||
g_audiod_pid = start_audiod();
|
||||
usleep(400000);
|
||||
{
|
||||
struct cli d13;
|
||||
check(cli_connect(&d13) == 0, "connect D13");
|
||||
m_audio_open_ack_t ack13;
|
||||
check(do_open_f(&d13, 176400, 2, AUDIO_FMT_DOP, AUDIO_FLAG_DSD, &ack13) == 0 && ack13.err == MEOW_OK,
|
||||
"open DoP@176400 (DSD64)");
|
||||
check(ack13.grant_fmt == AUDIO_FMT_DOP, "grant=DoP (DOP passthrough)");
|
||||
check(ack13.grant_rate == 176400, "grant_rate=176400 (container rate, no SRC)");
|
||||
/* DoP 帧:16bit DSD 数据(左/右不同)+ 标记字节 */
|
||||
uint8_t dop[4096];
|
||||
size_t fsd = 2 * 4;
|
||||
size_t nd = sizeof dop / fsd;
|
||||
uint8_t *od = dop;
|
||||
for (size_t i = 0; i < nd; i++) {
|
||||
uint32_t wl = ((uint32_t)(i & 0xFFFFu) << 16) | (0xFAu << 8); /* 标记 0xFA=左 */
|
||||
uint32_t wr = ((uint32_t)(~i & 0xFFFFu) << 16) | (0x05u << 8); /* 标记 0x05=右 */
|
||||
memcpy(od, &wl, 4); od += 4; memcpy(od, &wr, 4); od += 4;
|
||||
}
|
||||
do_write(&d13, dop, (uint32_t)sizeof dop);
|
||||
char q13[1024];
|
||||
do_query(&d13, q13, sizeof q13); /* 活动态快照:fmt=DoP/dsd=1 */
|
||||
check(strstr(q13, "fmt=DoP") != NULL, "query fmt=DoP");
|
||||
check(strstr(q13, "dsd=1") != NULL, "query dsd=1 (DoP stream active)");
|
||||
wait_wav_open(TWAV, 3000); /* 等设备开(WAV 头已在),再 STOP */
|
||||
do_ctrl(&d13, MSG_AUDIO_STOP, ack13.stream_id);
|
||||
for (int i = 0; i < 300; i++) {
|
||||
usleep(100000);
|
||||
if (wav_byte_exact(TWAV, 176400, 2, 32, dop, sizeof dop) == 0) break;
|
||||
}
|
||||
check(wav_byte_exact(TWAV, 176400, 2, 32, dop, sizeof dop) == 0,
|
||||
"DoP WAV byte-exact (32-bit container, marker preserved)");
|
||||
/* 无 DSD 标志的 DOP 请求 → 拒(INVAL):DoP 必须带 AUDIO_FLAG_DSD */
|
||||
struct cli d13b;
|
||||
check(cli_connect(&d13b) == 0, "connect D13b");
|
||||
m_audio_open_ack_t ack13b;
|
||||
check(do_open_f(&d13b, 176400, 2, AUDIO_FMT_DOP, 0, &ack13b) == 0 && ack13b.err == MEOW_ERR_INVAL,
|
||||
"DoP without AUDIO_FLAG_DSD rejected (INVAL)");
|
||||
close(d13.fd); close(d13b.fd);
|
||||
}
|
||||
stop_audiod();
|
||||
|
||||
/* ---- T14:DSD 失败回退 = 报错关流(案 A;不引 dsd2pcm、不静默退化)。
|
||||
* output_bt=1(BT 目标)下 DoP open → MEOW_ERR_NODEV(BT/A2DP 不能承载 DoP);
|
||||
* 此后普通 PCM(S16)open 仍正常(BT 目标不变),证明失败只关该 DSD 流、不殃及目标。 */
|
||||
printf("[T14 DSD fallback (BT) = error/close]\n");
|
||||
unlink(TSOCK); unlink(TWAV);
|
||||
const char *tconf14 = "/tmp/meow_test_settings14.conf";
|
||||
FILE *tf14 = fopen(tconf14, "w");
|
||||
if (tf14) { fprintf(tf14, "# meow-settings 1\naudio.volume = 60\naudio.output_bt = 1\n"); fclose(tf14); }
|
||||
g_audiod_pid = start_audiod_settings("file", tconf14);
|
||||
usleep(400000);
|
||||
{
|
||||
struct cli d14;
|
||||
check(cli_connect(&d14) == 0, "connect D14");
|
||||
m_audio_open_ack_t ack14;
|
||||
check(do_open_f(&d14, 176400, 2, AUDIO_FMT_DOP, AUDIO_FLAG_DSD, &ack14) == 0 &&
|
||||
ack14.err == MEOW_ERR_NODEV, "DoP on BT target rejected (NODEV)");
|
||||
/* 失败后 state 归干净(无流基线);同目标普通 PCM 正常开 */
|
||||
struct cli d14b;
|
||||
check(cli_connect(&d14b) == 0, "connect D14b");
|
||||
m_audio_open_ack_t ack14b;
|
||||
check(do_open(&d14b, 44100, 2, AUDIO_FMT_S16, &ack14b) == 0 && ack14b.err == MEOW_OK,
|
||||
"PCM open still ok on BT after DSD reject");
|
||||
do_ctrl(&d14b, MSG_AUDIO_STOP, ack14b.stream_id);
|
||||
close(d14.fd); close(d14b.fd);
|
||||
}
|
||||
stop_audiod();
|
||||
|
||||
/* ---- T15:音量收编 v2 双组写 + 权威(A3:audiod 唯一音量权威;泛化双组写 PCM+DSD_VOLUME;
|
||||
* 维持平方锥度;audio.volume 由 audiod 读写权威)。amixer 轨迹断言:一次 vol set 同发 numid=1/2(DSD)。
|
||||
* 全部经 MSG_AUDIO_VOLUME —— 权威路径;host FILE sink 无真实 amixer(popen 失败仍记 trace)。 */
|
||||
printf("[T15 volume v2 dual-group write + authority]\n");
|
||||
unlink(TSOCK); unlink(TWAV);
|
||||
const char *tconf15 = "/tmp/meow_test_settings15.conf";
|
||||
FILE *tf15 = fopen(tconf15, "w");
|
||||
if (tf15) { fprintf(tf15, "# meow-settings 1\naudio.volume = 60\n"); fclose(tf15); }
|
||||
const char *trace15 = "/tmp/meow_amixer_trace15.txt";
|
||||
unlink(trace15);
|
||||
g_audiod_pid = start_audiod_trace("file", tconf15, trace15);
|
||||
usleep(400000);
|
||||
{
|
||||
struct cli v15;
|
||||
check(cli_connect(&v15) == 0, "connect V15");
|
||||
m_audio_open_ack_t ack15;
|
||||
check(do_open(&v15, 44100, 2, AUDIO_FMT_S16, &ack15) == 0 && ack15.err == MEOW_OK, "open V15");
|
||||
/* 权威写音量(非 BT→DAC):设置 40 */
|
||||
{
|
||||
int32_t pct = 40;
|
||||
if (sf(v15.fd, MSG_AUDIO_VOLUME, 15, &pct, sizeof pct) == 0) {
|
||||
uint8_t ab[64]; uint16_t at; rf(v15.fd, &at, ab, sizeof ab);
|
||||
}
|
||||
}
|
||||
usleep(150000);
|
||||
char q15[1024];
|
||||
check(do_query(&v15, q15, sizeof q15) == 0 && strstr(q15, "vol=40"),
|
||||
"authority vol set -> g_vol_pct=40 (audiod authoritative)");
|
||||
/* 持久化 audio.volume(audiod 读写权威,与 launcher/watchdog 同源同键) */
|
||||
{
|
||||
FILE *chk = fopen(tconf15, "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, "audio.volume persisted = 40 (audiod authority)");
|
||||
}
|
||||
/* 双组写断言:trace 含 numid=1、numid=2、且 DSD_VOLUME(11) 同值(40→锥度≈40×40×192/10000≈30) */
|
||||
{
|
||||
char trb[4096]; int trl = 0;
|
||||
int fd = open(trace15, O_RDONLY);
|
||||
if (fd >= 0) { trl = (int)read(fd, trb, sizeof trb - 1); close(fd); if (trl > 0) trb[trl] = 0; }
|
||||
check(trl > 0 && strstr(trb, "cset numid=1 ") && strstr(trb, "cset numid=2 ") &&
|
||||
strstr(trb, "cset numid=11 "), "dual-group write: PCM numid=1/2 + DSD_VOLUME numid=11");
|
||||
/* 平方锥度:pct=40 → dac = (100-40)^2*192/10000 = 69.12 → 69(±1 容差) */
|
||||
int dac40 = (100 - 40) * (100 - 40) * 192 / 10000;
|
||||
/* 从 trace 找 numid=2 的值,应与 dac40 一致 */
|
||||
const char *p2 = strstr(trb, "cset numid=2 ");
|
||||
int got2 = p2 ? atoi(p2 + strlen("cset numid=2 ")) : -1;
|
||||
check(got2 == dac40, "square taper kept (numid=2 == (100-40)^2*192/10000)");
|
||||
}
|
||||
do_ctrl(&v15, MSG_AUDIO_STOP, ack15.stream_id);
|
||||
close(v15.fd);
|
||||
}
|
||||
stop_audiod();
|
||||
|
||||
/* ---- T16:监控日志记录高清/DoP 实际率 + 格式(A3:monitor 记录实际率;DSD 标记)。
|
||||
* 生命周期同 T8:流活跃期写 /tmp/audio_monitor_<bootts>.log,行含 %uHz/%uch/DoP 与 hwrate/vol。 */
|
||||
printf("[T16 monitor logs hi-res/DoP rate+fmt]\n");
|
||||
unlink(TSOCK); unlink(TWAV);
|
||||
g_audiod_pid = start_audiod();
|
||||
usleep(400000);
|
||||
{
|
||||
struct cli m16;
|
||||
check(cli_connect(&m16) == 0, "connect M16");
|
||||
/* 先清空 monitor 文件(复用同一 bootts 名;先前测试 T8-T15 已写入大量旧行),
|
||||
* 保证下面的检查只针对本 DoP 流新写行(append 模式将在文件尾追加)。 */
|
||||
char bootts16[64] = "";
|
||||
{ int fd = open("/tmp/meow_bootts", O_RDONLY); if (fd >= 0) { ssize_t r = read(fd, bootts16, 63); close(fd); if (r > 0) bootts16[r] = 0; } }
|
||||
char mp16[160]; snprintf(mp16, sizeof mp16, "/tmp/audio_monitor_%s.log", bootts16);
|
||||
unlink(mp16);
|
||||
m_audio_open_ack_t ack16;
|
||||
check(do_open_f(&m16, 176400, 2, AUDIO_FMT_DOP, AUDIO_FLAG_DSD, &ack16) == 0 && ack16.err == MEOW_OK,
|
||||
"open DoP@176400 for monitor");
|
||||
uint8_t dop16[4096];
|
||||
size_t fs16 = 2 * 4;
|
||||
size_t nd16 = sizeof dop16 / fs16;
|
||||
uint8_t *od16 = dop16;
|
||||
for (size_t i = 0; i < nd16; i++) {
|
||||
uint32_t wl = ((uint32_t)(i & 0xFFFFu) << 16) | (0xFAu << 8);
|
||||
uint32_t wr = ((uint32_t)(~i & 0xFFFFu) << 16) | (0x05u << 8);
|
||||
memcpy(od16, &wl, 4); od16 += 4; memcpy(od16, &wr, 4); od16 += 4;
|
||||
}
|
||||
for (int i = 0; i < 12; i++) do_write(&m16, dop16, (uint32_t)sizeof dop16);
|
||||
char mb16[4096]; int ml16 = 0;
|
||||
for (int i = 0; i < 30; i++) {
|
||||
usleep(200000); /* 等 ≥2 个 1s 节拍写 monitor 行 */
|
||||
int fd = open(mp16, O_RDONLY);
|
||||
if (fd >= 0) { ml16 = (int)read(fd, mb16, sizeof mb16 - 1); close(fd); if (ml16 > 0) mb16[ml16] = 0; }
|
||||
if (ml16 > 0 && strstr(mb16, "176400Hz/2ch/DoP") && strstr(mb16, "dsd=1")) break;
|
||||
}
|
||||
check(ml16 > 0 && strstr(mb16, "176400Hz/2ch/DoP") && strstr(mb16, "dsd=1"),
|
||||
"monitor log records container rate 176400 + fmt DoP + dsd=1");
|
||||
do_ctrl(&m16, MSG_AUDIO_STOP, ack16.stream_id);
|
||||
close(m16.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