138 lines
4.5 KiB
Python
138 lines
4.5 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
"""Drive K1 via RTT while recording laptop mic; compare I/II vs III+ pitch."""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import os
|
||
|
|
import sys
|
||
|
|
import time
|
||
|
|
from datetime import datetime
|
||
|
|
|
||
|
|
# Reuse helpers from sibling tools
|
||
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||
|
|
|
||
|
|
from mic_pitch_analyze import ( # noqa: E402
|
||
|
|
analyze_audio,
|
||
|
|
compare_summaries,
|
||
|
|
print_summary,
|
||
|
|
record,
|
||
|
|
save_wav,
|
||
|
|
summarize,
|
||
|
|
write_frame_log,
|
||
|
|
)
|
||
|
|
from rtt_pitch_reg_test import ( # noqa: E402
|
||
|
|
RttSession,
|
||
|
|
connect_jlink,
|
||
|
|
find_rtt_control_block,
|
||
|
|
import_deps,
|
||
|
|
wait_rtt_ready,
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
def main() -> int:
|
||
|
|
if hasattr(sys.stdout, "reconfigure"):
|
||
|
|
try:
|
||
|
|
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
|
||
|
|
except Exception:
|
||
|
|
pass
|
||
|
|
|
||
|
|
stamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||
|
|
out_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
|
||
|
|
hold = 8.0
|
||
|
|
sr = 16000
|
||
|
|
device = None # default mic
|
||
|
|
|
||
|
|
import_deps()
|
||
|
|
jlink = connect_jlink("AT32F403AC")
|
||
|
|
try:
|
||
|
|
cb = find_rtt_control_block(jlink)
|
||
|
|
if cb is None:
|
||
|
|
raise SystemExit("RTT CB not found")
|
||
|
|
print(f"RTT CB @ 0x{cb:08X}", flush=True)
|
||
|
|
jlink.rtt_start(cb)
|
||
|
|
wait_rtt_ready(jlink)
|
||
|
|
sess = RttSession(jlink)
|
||
|
|
sess.pump(0.3)
|
||
|
|
|
||
|
|
sess.cmd("log clear", 0.2)
|
||
|
|
sess.cmd("tone local", 1.0)
|
||
|
|
sess.set_xpose(2)
|
||
|
|
sess.cmd("tone pick", 0.8)
|
||
|
|
|
||
|
|
# ---- Take A: I/II ----
|
||
|
|
print("\n=== TAKE A: I/II (key2) — put guitar near mic ===", flush=True)
|
||
|
|
sess.set_key(0)
|
||
|
|
sess.set_key(2)
|
||
|
|
sess.pump(0.8)
|
||
|
|
print("MIC record A starting...", flush=True)
|
||
|
|
audio_a = record(hold, sr, device)
|
||
|
|
wav_a = os.path.join(out_dir, f"mic_A_I_{stamp}.wav")
|
||
|
|
save_wav(wav_a, audio_a, sr)
|
||
|
|
frames_a = analyze_audio(audio_a, sr, fmin=40, fmax=500)
|
||
|
|
sum_a = summarize(frames_a, label="A:I/II")
|
||
|
|
print_summary(sum_a)
|
||
|
|
write_frame_log(os.path.join(out_dir, f"mic_A_I_{stamp}.csv"), frames_a, sum_a)
|
||
|
|
|
||
|
|
# ---- Take B: III ----
|
||
|
|
print("\n=== TAKE B: III (key8) ===", flush=True)
|
||
|
|
sess.set_key(0)
|
||
|
|
sess.set_key(8)
|
||
|
|
sess.pump(0.8)
|
||
|
|
print("MIC record B starting...", flush=True)
|
||
|
|
audio_b = record(hold, sr, device)
|
||
|
|
wav_b = os.path.join(out_dir, f"mic_B_III_{stamp}.wav")
|
||
|
|
save_wav(wav_b, audio_b, sr)
|
||
|
|
frames_b = analyze_audio(audio_b, sr, fmin=40, fmax=500)
|
||
|
|
sum_b = summarize(frames_b, label="B:III")
|
||
|
|
print_summary(sum_b)
|
||
|
|
write_frame_log(os.path.join(out_dir, f"mic_B_III_{stamp}.csv"), frames_b, sum_b)
|
||
|
|
|
||
|
|
# ---- Take C: VII + xpose #F (extra -12) ----
|
||
|
|
print("\n=== TAKE C: VII key20 + xpose=#F ===", flush=True)
|
||
|
|
sess.set_xpose(6)
|
||
|
|
sess.set_key(0)
|
||
|
|
sess.set_key(20)
|
||
|
|
sess.pump(0.8)
|
||
|
|
print("MIC record C starting...", flush=True)
|
||
|
|
audio_c = record(hold, sr, device)
|
||
|
|
wav_c = os.path.join(out_dir, f"mic_C_VII_xf_{stamp}.wav")
|
||
|
|
save_wav(wav_c, audio_c, sr)
|
||
|
|
frames_c = analyze_audio(audio_c, sr, fmin=40, fmax=500)
|
||
|
|
sum_c = summarize(frames_c, label="C:VII+#F")
|
||
|
|
print_summary(sum_c)
|
||
|
|
write_frame_log(os.path.join(out_dir, f"mic_C_VII_xf_{stamp}.csv"), frames_c, sum_c)
|
||
|
|
|
||
|
|
# Also bass-biased analysis (prefer low F0)
|
||
|
|
print("\n=== Bass-biased (fmax=180Hz) ===", flush=True)
|
||
|
|
for label, audio in (("A", audio_a), ("B", audio_b), ("C", audio_c)):
|
||
|
|
fr = analyze_audio(audio, sr, fmin=40, fmax=180)
|
||
|
|
print_summary(summarize(fr, label=f"{label}-bassband"))
|
||
|
|
|
||
|
|
print("\n=== A vs B (I/II vs III) ===", flush=True)
|
||
|
|
compare_summaries(sum_a, sum_b)
|
||
|
|
print("\n=== A vs C (I/II vs VII+#F) ===", flush=True)
|
||
|
|
compare_summaries(sum_a, sum_c)
|
||
|
|
|
||
|
|
print("\n=== stop ===", flush=True)
|
||
|
|
sess.stop_band()
|
||
|
|
|
||
|
|
# Save RTT lines
|
||
|
|
rtt_path = os.path.join(out_dir, f"mic_rtt_{stamp}.log")
|
||
|
|
with open(rtt_path, "w", encoding="utf-8", newline="\n") as f:
|
||
|
|
f.write(f"# rtt+mic test {datetime.now().isoformat(timespec='seconds')}\n")
|
||
|
|
for line in sess.lines:
|
||
|
|
f.write(line + "\n")
|
||
|
|
print(f"RTT log: {rtt_path}", flush=True)
|
||
|
|
print(f"WAV A/B/C: {wav_a}\n {wav_b}\n {wav_c}", flush=True)
|
||
|
|
return 0
|
||
|
|
finally:
|
||
|
|
try:
|
||
|
|
jlink.rtt_stop()
|
||
|
|
except Exception:
|
||
|
|
pass
|
||
|
|
jlink.close()
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
raise SystemExit(main())
|