feat: release Find-Word v0.2.3
This commit is contained in:
+33
-16
@@ -1,8 +1,8 @@
|
||||
# Find-Word v0.1.1 설계
|
||||
# Find-Word v0.2.3 설계
|
||||
|
||||
## 데이터와 출제
|
||||
|
||||
`src/content.ts`는 패턴, 질문, 단어, 오답 규칙, 배경 프리셋, 상대 dB를 서로 다른
|
||||
`src/content.ts`는 패턴, 질문, 단어, 오답 규칙, 현장음 URL, 상대 dB를 서로 다른
|
||||
배열로 보관한다. `renderSentence`가 각 패턴의 `{word}`를 정답으로,
|
||||
`{distractor1}`·`{distractor2}`를 해당 보기의 오답으로 채운다. 같은 함수를
|
||||
음성 생성기도 사용하며 런타임 문장과 WAV의 대응은 manifest 테스트가 검증한다.
|
||||
@@ -29,8 +29,9 @@
|
||||
목표 반복 횟수, 취소·조건·방향 단서와 질문 의도를 검증한다.
|
||||
|
||||
`src/game.ts`의 `createQuestions`는 seed 기반 PRNG와 Fisher–Yates로
|
||||
유형·단어·정답 위치를 섞는다. 한 세션에서 유형과 정답 단어는 각각 한 번씩
|
||||
나온다. 100개 문장 조합에 응답 방식·환경·난이도를 독립적으로 결합한다.
|
||||
유형·단어·정답 위치를 섞는다. 한 라운드는 3문항이며 유형과 정답 단어가 중복되지 않는다. 시작 단계는 1~5로
|
||||
정규화하며 세 문항에 같은 level/db를 적용한다. 혼합 모드는 선택/입력/선택이다.
|
||||
환경 순환은 seed로 여덟 곳을 섞어 세 곳을 선택한다. 100개 문장 조합에 응답 방식·환경·난이도를 독립적으로 결합한다.
|
||||
|
||||
오답의 `rule`은 `RULE_DIFFICULTY`에 연결된다. 음절 교체 1, 초성 교체 2,
|
||||
모음 교체 3, 받침 교체 4는 편집상 예상 혼동 순서이며 검증된 청각 척도가
|
||||
@@ -49,9 +50,23 @@ stateDiagram-v2
|
||||
answer --> loading: 다시 듣기
|
||||
answer --> feedback: ANSWER
|
||||
feedback --> ready: NEXT (다음 문제)
|
||||
feedback --> results: NEXT (마지막 문제)
|
||||
feedback --> results: NEXT (세 번째 문제)
|
||||
ready --> results: EXIT
|
||||
loading --> results: EXIT
|
||||
playing --> results: EXIT
|
||||
answer --> results: EXIT
|
||||
feedback --> results: EXIT
|
||||
```
|
||||
|
||||
정상 결과는 다음 단계(최대 5)의 새 라운드로 연결되며 중도 종료는 응답 수·정답 수를
|
||||
표시한 뒤 홈으로 연결된다. 무응답 정답률은 `— / 응답 없음`, 응답하지 않은 단계는 `미진행`으로 표시한다.
|
||||
중도 종료 제목과 현재 단계 완료 제목을 구분한다. 진행 막대는 답변 수가 아닌 현재 문항의 1/3, 2/3, 3/3이다.
|
||||
결과 단계는 모든 지연 이벤트를 무시한다.
|
||||
SNR은 −12~+12 dB 정수로 제한하고 NaN/Infinity는 단계 기본값으로 복구한다.
|
||||
수동 SNR은 재생 도중 현재 gain을 바꾸지 않고 현재 재청취/남은 문항/다음 라운드에
|
||||
적용한다. `heardDb`는 실제 재생 시작값을 보존해 결과를 정확히 기록한다. 홈은
|
||||
수동 SNR·답·입력·IME·토큰을 초기화하고 시작 단계·모드·환경·전체 음량은 유지한다.
|
||||
|
||||
허용되지 않은 이벤트는 동일 상태를 반환한다. 재생 전/중에는 채점할 수 없고,
|
||||
피드백 이후의 중복 답변·다음 클릭도 한 번만 반영된다. UI에서도 버튼 비활성화와
|
||||
동기 ref 잠금을 함께 사용한다. 세션 토큰으로 처음 화면 복귀·unmount 뒤 완료된
|
||||
@@ -63,7 +78,7 @@ Promise를 무시한다. 질문과 보기는 재생 완료 후 DOM에 생성되
|
||||
입력을 HTML로 해석하지 않는다.
|
||||
|
||||
점수는 정답 시 `100 × 단계 + 10 × min(연속 정답 - 1, 4)`이다. 오답은 0점,
|
||||
현재 연속 정답을 초기화한다. 최고 연속 정답과 난이도별 정답 수는 유지한다.
|
||||
현재 연속 정답을 초기화한다. 기존 공식의 cap은 40점이며 세 문항 라운드에서는 문항별 최대 20점, 라운드 합계 최대 30점(0 + 10 + 20)이다. 1단계 세 정답은 330점이다. 최고 연속 정답과 난이도별 정답 수는 유지한다.
|
||||
|
||||
## 오디오
|
||||
|
||||
@@ -73,26 +88,28 @@ Promise를 무시한다. 질문과 보기는 재생 완료 후 DOM에 생성되
|
||||
[AUDIO_PROVENANCE](AUDIO_PROVENANCE.md)에 있으며 앱은 provider에 연결하지 않는다.
|
||||
|
||||
`src/audio/dsp.ts`는 순수 수치 함수이며 장치가 없어도 테스트할 수 있다.
|
||||
정수 seed 잡음에 저역 통과 필터, 사인파, 진폭 변조를 조합하고 양 끝을 페이드한다.
|
||||
8개 프리셋은 실제 현장 녹음이 아니라 환경을 추상적으로 표현한 합성 신호다.
|
||||
8개 현장 녹음 WAV를 디코드해 재생한다. 각 12초, 24kHz mono PCM16이며 양끝
|
||||
50ms fade로 루프 접합 클릭을 줄인다. 절차적 잡음 합성 코드는 제거했다.
|
||||
|
||||
`src/audio/engine.ts`는 클릭 이벤트에서 AudioContext 생성·resume을 호출한 뒤
|
||||
같은 출처의 WAV를 로드한다. mono PCM을 decode하고 음성과 배경의 전체 버퍼
|
||||
RMS를 0.03으로 정규화한다. `gain = 10^(dB/20)`으로 목표 gain을 지정한다.
|
||||
RMS를 0.03으로 정규화한다. `gain = 10^(dB/20)`으로 목표/배경 비율을 지정한다. 정규화한 세 신호의 최대
|
||||
피크 합을 계산해 모든 경로를 공통 감쇠하므로 합계 peak ≤ 0.8이고 SNR이 유지된다.
|
||||
시간별·주파수별 청감이나 물리적 dB SPL을 보장하는 수치는 아니다.
|
||||
|
||||
`src/audio/assets.ts`는 음성 자산 버전과 URL 생성을 한 곳에서 관리한다.
|
||||
intro와 목표 100개 모두 `?v=0.1.1`을 붙여 동일 파일명에 남은 이전 캐시를
|
||||
intro·목표 100개·현장음 8개 모두 `?v=0.2.3`을 붙여 동일 파일명에 남은 이전 캐시를
|
||||
피한다. 파일을 다시 생성하면 제품 버전 유지 여부와 관계없이 자산 버전을
|
||||
갱신한다. 버전 확인을 위한 외부 요청이나 런타임 manifest 요청은 없다.
|
||||
|
||||
```text
|
||||
배경 BufferSource → 배경 Gain (1, 시작/끝 fade) ─┐
|
||||
목표 BufferSource → 음성 Gain (10^(dB/20)) ─────┼→ master Gain → destination
|
||||
안내 BufferSource → 안내 Gain (1.8 → 0.12) ─────┘
|
||||
배경 BufferSource → 배경 Gain (공통 감쇠, 시작/끝 fade) ─┐
|
||||
목표 BufferSource → 음성 Gain (공통 감쇠 × 10^(dB/20)) ─────┼→ master Gain → destination
|
||||
안내 BufferSource → 안내 Gain (공통 감쇠 × 1.8 → 0.12) ─────┘
|
||||
```
|
||||
|
||||
첫 문제에서는 웃음과 안내 음성을 낮추어 배경에 묻히게 한 후 목표 문장을
|
||||
배경 소스는 `loop=true`이며 목표 ended에서 즉시 stop/disconnect한다.
|
||||
각 라운드의 첫 문제에서는 웃음과 안내 음성을 낮추어 배경에 묻히게 한 후 목표 문장을
|
||||
재생한다. 이후에는 목표만 재생한다. 안내 도중 실패했으면 재시도 시 안내도
|
||||
다시 재생한다. 기본 master는 35%이며 음량 조절은 두 신호의 비율을 유지한다.
|
||||
|
||||
@@ -116,7 +133,7 @@ reduced motion에서는 파형이 움직이지 않는다. 오류는 role=alert
|
||||
## 검증 경계
|
||||
|
||||
Vitest는 실제 RED/GREEN으로 데이터·채점·상태·오디오 그래프·화면을 검증한다.
|
||||
Playwright는 production build와 실제 Chrome AudioContext로 두 크기의 10문제
|
||||
완주·재청취·오류 복구·axe 검사를 수행한다. 테스트 자동화는 한국어 발음의
|
||||
Playwright는 production build와 실제 Chrome AudioContext로 두 크기의 3문항
|
||||
완주·다음 단계·SNR·중도 종료·재청취·오류 복구·axe 검사를 수행한다. 테스트 자동화는 한국어 발음의
|
||||
자연스러움, 실제 사용자의 청각 난이도, 모바일 Safari의 장치별 정책까지
|
||||
증명하지 않으므로 인수 시 직접 청취를 추가한다.
|
||||
|
||||
Reference in New Issue
Block a user