122 lines
4.9 KiB
C
122 lines
4.9 KiB
C
/*
|
||
* meow_ui_vol.c — SDK 状态栏音量换算纯函数 + settings.conf 读取(A-0 核心数源)。
|
||
*
|
||
* 单独成 TU 的目的:
|
||
* 1. 纯函数(clamp / 键读取)不依赖 meow_ui 其它子系统,宿主 gcc 直接可测
|
||
* (test_meow_ui_vol.c),无需链整库/stub。
|
||
* 2. 把「音量从 settings 读数并 clamp 到 volume_max」这一语义钉死在单点,
|
||
* 与 launcher 的 vol_clamp(audio.c)口径对齐,杜绝两端音量漂移。
|
||
*
|
||
* 数据源:/usr/data/meow/settings.conf 扁平 key=value。launcher meow_settings.c
|
||
* 落盘为 "key = value"(带空格),本解析兼容无空格/多空格,与 launcher 读循环
|
||
* 及 sdk meow_ui_theme.c 的 get_setting_str 同款解析。
|
||
*/
|
||
#include "meow_ui_vol.h"
|
||
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
|
||
int meow_ui_vol_clamp(int vol, int vol_max)
|
||
{
|
||
if (vol < 0) vol = 0;
|
||
if (vol > MEOW_UI_VOL_MAX) vol = MEOW_UI_VOL_MAX;
|
||
if (vol_max < 0) vol_max = 0; /* 异常上限兜底:不进负值 */
|
||
if (vol > vol_max) vol = vol_max;
|
||
return vol;
|
||
}
|
||
|
||
int meow_ui_vol_read(const char *path, const char *key, int def)
|
||
{
|
||
if (!path || !key) return def;
|
||
FILE *f = fopen(path, "r");
|
||
if (!f) return def;
|
||
int kl = (int)strlen(key);
|
||
char line[160];
|
||
char *found = NULL;
|
||
while (fgets(line, sizeof line, f)) {
|
||
char *eq = strchr(line, '=');
|
||
if (!eq) continue; /* 非 key=value 行(注释/空行)跳过 */
|
||
char *k = line;
|
||
while (*k == ' ' || *k == '\t') k++; /* key 左去空白 */
|
||
int n = (int)(eq - k);
|
||
while (n > 0 && (k[n-1] == ' ' || k[n-1] == '\t')) n--; /* key 右去空白 */
|
||
if (n != kl || strncmp(k, key, (size_t)kl) != 0) continue; /* key 不精确匹配 */
|
||
found = eq + 1; /* 命中所求键 */
|
||
break;
|
||
}
|
||
fclose(f);
|
||
if (!found) return def;
|
||
while (*found == ' ' || *found == '\t') found++; /* value 左去空白;atoi 天然停于非数字 */
|
||
return atoi(found);
|
||
}
|
||
|
||
/* 改 settings.conf 一个 int 键:流式拷贝原文件到 <path>.tmp,命中键行改写为
|
||
* "key = value"(launcher 落盘格式,带空格),键缺失则末尾追加;rename 原子替换。
|
||
* 保留其余行(注释/其它设置)——绝不 O_TRUNC 整文件。 */
|
||
int meow_ui_vol_set(const char *path, const char *key, int val)
|
||
{
|
||
if (!path || !path[0] || !key || !key[0]) return -1;
|
||
FILE *in = fopen(path, "r");
|
||
char tmp[512];
|
||
int kl = (int)strlen(key);
|
||
snprintf(tmp, sizeof tmp, "%s.tmp", path);
|
||
FILE *out = fopen(tmp, "w");
|
||
if (!out) { if (in) fclose(in); return -1; }
|
||
|
||
int found = 0;
|
||
char line[256];
|
||
while (in && fgets(line, sizeof line, in)) {
|
||
char *eq = strchr(line, '=');
|
||
char *k = line;
|
||
while (*k == ' ' || *k == '\t') k++;
|
||
int n = eq ? (int)(eq - k) : 0;
|
||
while (n > 0 && (k[n-1] == ' ' || k[n-1] == '\t')) n--;
|
||
if (eq && n == kl && strncmp(k, key, (size_t)kl) == 0) {
|
||
fprintf(out, "%s = %d\n", key, val); /* 命中:改写为规范格式 */
|
||
found = 1;
|
||
} else {
|
||
fputs(line, out); /* 其它行原样保留 */
|
||
}
|
||
}
|
||
if (in) fclose(in);
|
||
if (!found) fprintf(out, "%s = %d\n", key, val);
|
||
fclose(out);
|
||
|
||
if (rename(tmp, path) != 0) { remove(tmp); return -1; }
|
||
return 0;
|
||
}
|
||
|
||
/* 音量步进(系统语义,与 launcher 设置页/watchdog 同源:volume_step/volume_max 约束)。
|
||
* 只做 settings 逻辑 + 持久化;DAC 写入由调用方(meow_ui_vol_dac_write)负责。 */
|
||
int meow_ui_vol_step(const char *path, int dir)
|
||
{
|
||
int vol = meow_ui_vol_read(path, "audio.volume", MEOW_UI_VOL_DEFAULT);
|
||
int vol_max= meow_ui_vol_read(path, "audio.volume_max", MEOW_UI_VOL_MAX_DEF);
|
||
int step = meow_ui_vol_read(path, "audio.volume_step", 1);
|
||
if (step < 1) step = 1;
|
||
if (step > 5) step = 5; /* 与 watchdog 读取口径一致(1..5) */
|
||
if (dir < 0) dir = -1;
|
||
else if (dir > 0) dir = 1;
|
||
else return vol;
|
||
|
||
int v = meow_ui_vol_clamp(vol + dir * step, vol_max);
|
||
if (v == vol) return vol; /* 已在上下限:无进展,不写 */
|
||
meow_ui_vol_set(path, "audio.volume", v);
|
||
return v;
|
||
}
|
||
|
||
/* 真实 DAC 音量(CS43198, numid 1/2, 0-255),pct→255 映射直写两声道。
|
||
* 与 launcher meow_dac_vol_write / watchdog wd_vol_write 完全同路径(语义同源)。 */
|
||
void meow_ui_vol_dac_write(int pct)
|
||
{
|
||
int dac = 255 - pct * 255 / 100; /* CS43198 寄存器=衰减量(0=最响 255=静音),用户 pct 越大越响 → 反转映射 */
|
||
if (dac < 0) dac = 0;
|
||
if (dac > 255) dac = 255;
|
||
char cmd[160];
|
||
snprintf(cmd, sizeof cmd,
|
||
"amixer -c 0 cset numid=1 %d >/dev/null 2>&1; amixer -c 0 cset numid=2 %d >/dev/null 2>&1",
|
||
dac, dac);
|
||
system(cmd);
|
||
}
|