feat(ncm): 网易云客户端 v1 UI+播放链路 (agent-205) — os.meow.ncm: 登录页(真实unikey二维码+轮询状态机)/我的歌单(listview)/歌单详情/播放页(封面+seek+滚动歌词+竖横屏切换)/设置(音质默认Hi-res+缓存上限默认10G); 播放线程(缓存LRU+minimp3→ALSA UAPI直开hw:0,0); 媒体会话MSG_META上报+PLAYCTL接收(首真实媒体源)
ncm 1e331964 (text 764KB); 0 warning; 宿主离屏6页截图目检+真实QR可扫+qemu-mipsel干净启动+解码446xRT 真机待联调: ALSA时序/803扫码闭环/媒体会话联动/gbk大字库渲染
This commit is contained in:
1 parent
32543ac616
commit
21519ce2e4
23 files changed
+3255
No files matched your search
@@ -0,0 +1,67 @@
|
||||
/* test/test_decode.c — 播放解码链路验证(宿主):minimp3 解码 mp3 → audio_out(FILE sink) 写 WAV。
|
||||
* 不依赖网络/登录(输入本地 mp3)。验证:解码无错、WAV 非空、时长合理、RT 因子。
|
||||
* 运行:NCM_AUDIO_SINK=file NCM_AUDIO_OUT=/tmp/ncm_decode.wav ./test_decode <path.mp3>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "../ncm_app_internal.h" /* 引 audio_out / minimp3 声明 */
|
||||
#include "minimp3_ex.h"
|
||||
|
||||
ncm_app_state_t g_st;
|
||||
ncm_play_run_t g_play = { .mu = PTHREAD_MUTEX_INITIALIZER };
|
||||
volatile int g_app_quit = 0;
|
||||
volatile int g_net_ready = 0;
|
||||
int g_host_mock = 1;
|
||||
|
||||
static double now_s(void)
|
||||
{
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return (double)ts.tv_sec + ts.tv_nsec / 1e9;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *path = (argc > 1) ? argv[1] : "vendor/minimp3/vectors/performance/MIPSTest.mp3";
|
||||
mp3dec_ex_t dec;
|
||||
memset(&dec, 0, sizeof dec);
|
||||
if (mp3dec_ex_open(&dec, path, MP3D_SEEK_TO_BYTE) != 0) { fprintf(stderr, "open failed\n"); return 1; }
|
||||
|
||||
static mp3d_sample_t pcm[8192 * 2];
|
||||
/* 读首帧确定采样率/声道(read 会填 dec.info)*/
|
||||
size_t got = mp3dec_ex_read(&dec, pcm, 8192 * 2);
|
||||
int sr = dec.info.hz;
|
||||
int ch = dec.info.channels;
|
||||
if (sr <= 0 || ch <= 0) { fprintf(stderr, "bad stream\n"); return 1; }
|
||||
printf("mp3: %s %dHz x%d detected_samples=%lld bitrate=%dkbps\n",
|
||||
path, sr, ch, (long long)dec.samples, dec.info.bitrate_kbps);
|
||||
if (audio_out_open(sr, ch, 16) != 0) { fprintf(stderr, "audio_out open failed\n"); return 1; }
|
||||
|
||||
long long frames = 0;
|
||||
double t0 = now_s();
|
||||
if (got > 0) {
|
||||
int fr = (int)(got / (size_t)ch);
|
||||
if (audio_out_write(pcm, fr) != fr) { fprintf(stderr, "write failed\n"); return 1; }
|
||||
frames += fr;
|
||||
}
|
||||
for (;;) {
|
||||
if (g_app_quit) break;
|
||||
got = mp3dec_ex_read(&dec, pcm, 8192 * 2);
|
||||
if (got == 0) break;
|
||||
int fr = (int)(got / (size_t)ch);
|
||||
if (audio_out_write(pcm, fr) != fr) { fprintf(stderr, "write failed\n"); break; }
|
||||
frames += fr;
|
||||
}
|
||||
double dt = now_s() - t0;
|
||||
audio_out_close();
|
||||
mp3dec_ex_close(&dec);
|
||||
|
||||
double secs = (double)frames / (double)sr;
|
||||
double rt = (dt > 0) ? secs / dt : 0;
|
||||
printf("decoded %lld frames = %.2f s audio (%d Hz) in %.3f s => %.1fx RT\n",
|
||||
frames, secs, sr, dt, rt);
|
||||
printf("OK: %s\n", (frames > 0) ? "decode chain works" : "EMPTY");
|
||||
return (frames > 0) ? 0 : 1;
|
||||
}
|
||||
Reference in new issue
Block a user