255 lines
8.0 KiB
Markdown
255 lines
8.0 KiB
Markdown
|
|
# 음성 인식 민감도 향상 개발 문서
|
||
|
|
|
||
|
|
## 개요
|
||
|
|
음성 녹음 기능에서 작은 소리도 텍스트로 변환되도록 음성 인식 민감도를 향상시키는 개선 작업을 수행했습니다.
|
||
|
|
|
||
|
|
**개선 일자**: 2024년
|
||
|
|
**대상 파일**: `voice_ai_cnslt/index.php`
|
||
|
|
|
||
|
|
## 문제점
|
||
|
|
기존에는 마이크에 가까이서 말해야만 텍스트로 변환되는 문제가 있었습니다. 작은 소리나 멀리서 말한 경우 인식이 제대로 되지 않았습니다.
|
||
|
|
|
||
|
|
## 개선 내용
|
||
|
|
|
||
|
|
### 1. 오디오 증폭 (Audio Amplification)
|
||
|
|
|
||
|
|
#### 1.1 GainNode를 이용한 오디오 증폭
|
||
|
|
- **위치**: `startAudioStream()` 함수
|
||
|
|
- **기술**: Web Audio API의 `GainNode` 사용
|
||
|
|
- **증폭 배수**: 3.0배 (기본값)
|
||
|
|
- **목적**: 작은 소리도 인식할 수 있도록 오디오 신호 증폭
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
// GainNode 생성 및 증폭 설정
|
||
|
|
gainNode = audioContext.createGain();
|
||
|
|
gainNode.gain.value = 3.0; // 3배 증폭
|
||
|
|
|
||
|
|
// 오디오 체인: Source -> Gain -> Analyser
|
||
|
|
audioSource.connect(gainNode);
|
||
|
|
analyser = audioContext.createAnalyser();
|
||
|
|
gainNode.connect(analyser);
|
||
|
|
```
|
||
|
|
|
||
|
|
#### 1.2 변수 추가
|
||
|
|
- `gainNode`: 오디오 증폭을 위한 GainNode 객체
|
||
|
|
- `audioSource`: 오디오 소스 객체
|
||
|
|
|
||
|
|
### 2. 마이크 제약 조건 최적화
|
||
|
|
|
||
|
|
#### 2.1 오디오 제약 조건 설정
|
||
|
|
- **위치**: `startAudioStream()` 함수 내 `getUserMedia()` 호출
|
||
|
|
- **목적**: 작은 소리 감지 향상을 위한 마이크 설정 최적화
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
const audioConstraints = {
|
||
|
|
audio: {
|
||
|
|
echoCancellation: false, // 에코 캔슬 비활성화
|
||
|
|
noiseSuppression: false, // 노이즈 억제 비활성화
|
||
|
|
autoGainControl: true, // 자동 게인 제어 활성화
|
||
|
|
sampleRate: 48000, // 높은 샘플레이트
|
||
|
|
channelCount: 1 // 모노 채널
|
||
|
|
}
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
#### 2.2 설정 상세 설명
|
||
|
|
|
||
|
|
| 설정 | 값 | 설명 |
|
||
|
|
|------|-----|------|
|
||
|
|
| `echoCancellation` | `false` | 에코 캔슬을 비활성화하여 작은 소리도 감지하도록 함 |
|
||
|
|
| `noiseSuppression` | `false` | 노이즈 억제를 비활성화하여 작은 소리도 감지하도록 함 |
|
||
|
|
| `autoGainControl` | `true` | 자동 게인 제어를 활성화하여 입력 신호를 자동으로 조정 |
|
||
|
|
| `sampleRate` | `48000` | 높은 샘플레이트로 더 정확한 오디오 캡처 |
|
||
|
|
| `channelCount` | `1` | 모노 채널 사용 |
|
||
|
|
|
||
|
|
**주의사항**:
|
||
|
|
- `echoCancellation: false`와 `noiseSuppression: false`는 작은 소리 감지에는 도움이 되지만, 주변 소음이 많은 환경에서는 노이즈가 증가할 수 있습니다.
|
||
|
|
- 필요에 따라 환경에 맞게 조정이 필요할 수 있습니다.
|
||
|
|
|
||
|
|
### 3. Web Speech API 설정 최적화
|
||
|
|
|
||
|
|
#### 3.1 maxAlternatives 설정
|
||
|
|
- **위치**: `initSpeechRecognition()` 함수
|
||
|
|
- **목적**: 더 많은 대안 결과를 허용하여 인식 정확도 향상
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
recognition.maxAlternatives = 3; // 더 많은 대안 결과 허용
|
||
|
|
```
|
||
|
|
|
||
|
|
#### 3.2 기존 설정 유지
|
||
|
|
- `lang: 'ko-KR'`: 한국어 인식
|
||
|
|
- `continuous: true`: 연속 인식 모드
|
||
|
|
- `interimResults: true`: 중간 결과 표시
|
||
|
|
|
||
|
|
### 4. 에러 처리 개선
|
||
|
|
|
||
|
|
#### 4.1 자동 재시작 로직 추가
|
||
|
|
- **위치**: `setupRecognitionHandlers()` 함수 내 `recognition.onerror` 핸들러
|
||
|
|
- **목적**: 일시적인 오류 발생 시 자동으로 재시작하여 인식 지속성 향상
|
||
|
|
|
||
|
|
#### 4.2 처리하는 오류 유형
|
||
|
|
|
||
|
|
**1. `no-speech` 오류**
|
||
|
|
```javascript
|
||
|
|
if (event.error === 'no-speech') {
|
||
|
|
// 음성이 감지되지 않음 - 자동 재시작 (작은 소리도 감지하도록 지속 시도)
|
||
|
|
if (isRecording) {
|
||
|
|
setTimeout(() => {
|
||
|
|
try {
|
||
|
|
if (isRecording && !isRecognitionActive) {
|
||
|
|
recognition.start();
|
||
|
|
}
|
||
|
|
} catch (e) {
|
||
|
|
console.log('Recognition restart after no-speech:', e);
|
||
|
|
}
|
||
|
|
}, 500);
|
||
|
|
}
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**2. `network` 오류**
|
||
|
|
```javascript
|
||
|
|
if (event.error === 'network') {
|
||
|
|
// 네트워크 오류 시 자동 재시도
|
||
|
|
if (isRecording) {
|
||
|
|
setTimeout(() => {
|
||
|
|
try {
|
||
|
|
if (isRecording && !isRecognitionActive) {
|
||
|
|
recognition.start();
|
||
|
|
}
|
||
|
|
} catch (e) {
|
||
|
|
console.log('Recognition restart after network error:', e);
|
||
|
|
}
|
||
|
|
}, 1000);
|
||
|
|
}
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 5. 리소스 정리 개선
|
||
|
|
|
||
|
|
#### 5.1 오디오 노드 연결 해제
|
||
|
|
- **위치**: `stopAudioStream()` 함수
|
||
|
|
- **목적**: 메모리 누수 방지 및 리소스 정리
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
// 오디오 노드 연결 해제
|
||
|
|
if (audioSource) {
|
||
|
|
try {
|
||
|
|
audioSource.disconnect();
|
||
|
|
} catch (e) {
|
||
|
|
console.log('Audio source disconnect:', e);
|
||
|
|
}
|
||
|
|
audioSource = null;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (gainNode) {
|
||
|
|
try {
|
||
|
|
gainNode.disconnect();
|
||
|
|
} catch (e) {
|
||
|
|
console.log('Gain node disconnect:', e);
|
||
|
|
}
|
||
|
|
gainNode = null;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (analyser) {
|
||
|
|
try {
|
||
|
|
analyser.disconnect();
|
||
|
|
} catch (e) {
|
||
|
|
console.log('Analyser disconnect:', e);
|
||
|
|
}
|
||
|
|
analyser = null;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## 기술 스택
|
||
|
|
|
||
|
|
- **Web Audio API**: 오디오 증폭 및 처리
|
||
|
|
- **Web Speech API**: 음성 인식
|
||
|
|
- **MediaRecorder API**: 오디오 녹음
|
||
|
|
- **getUserMedia API**: 마이크 접근
|
||
|
|
|
||
|
|
## 테스트 방법
|
||
|
|
|
||
|
|
1. **기본 테스트**
|
||
|
|
- 마이크에서 약 30cm 이상 떨어진 거리에서 말하기
|
||
|
|
- 작은 목소리로 말하기
|
||
|
|
- 정상적으로 텍스트로 변환되는지 확인
|
||
|
|
|
||
|
|
2. **민감도 조정 테스트**
|
||
|
|
- 증폭 배수를 조정하여 테스트
|
||
|
|
- `gainNode.gain.value` 값을 변경 (3.0 → 5.0 또는 7.0)
|
||
|
|
- 너무 높은 값은 오디오 왜곡을 유발할 수 있으므로 주의
|
||
|
|
|
||
|
|
3. **환경별 테스트**
|
||
|
|
- 조용한 환경에서 테스트
|
||
|
|
- 소음이 있는 환경에서 테스트
|
||
|
|
- 필요시 `echoCancellation`과 `noiseSuppression` 설정 조정
|
||
|
|
|
||
|
|
## 민감도 조정 가이드
|
||
|
|
|
||
|
|
### 증폭 배수 조정
|
||
|
|
```javascript
|
||
|
|
// 현재 설정 (3.0배)
|
||
|
|
gainNode.gain.value = 3.0;
|
||
|
|
|
||
|
|
// 더 높은 민감도가 필요한 경우
|
||
|
|
gainNode.gain.value = 5.0; // 5배 증폭
|
||
|
|
gainNode.gain.value = 7.0; // 7배 증폭 (최대 권장값)
|
||
|
|
|
||
|
|
// 주의: 10 이상의 값은 오디오 왜곡을 유발할 수 있음
|
||
|
|
```
|
||
|
|
|
||
|
|
### 마이크 제약 조건 조정
|
||
|
|
```javascript
|
||
|
|
// 조용한 환경에서 소음이 많은 경우
|
||
|
|
audio: {
|
||
|
|
echoCancellation: true, // 에코 캔슬 활성화
|
||
|
|
noiseSuppression: true, // 노이즈 억제 활성화
|
||
|
|
autoGainControl: true,
|
||
|
|
sampleRate: 48000,
|
||
|
|
channelCount: 1
|
||
|
|
}
|
||
|
|
|
||
|
|
// 작은 소리 감지가 최우선인 경우 (현재 설정)
|
||
|
|
audio: {
|
||
|
|
echoCancellation: false, // 에코 캔슬 비활성화
|
||
|
|
noiseSuppression: false, // 노이즈 억제 비활성화
|
||
|
|
autoGainControl: true,
|
||
|
|
sampleRate: 48000,
|
||
|
|
channelCount: 1
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## 주의사항
|
||
|
|
|
||
|
|
1. **오디오 왜곡**: 증폭 배수가 너무 높으면 오디오가 왜곡될 수 있습니다. 권장 범위는 3.0 ~ 7.0입니다.
|
||
|
|
|
||
|
|
2. **노이즈 증가**: `echoCancellation`과 `noiseSuppression`을 비활성화하면 주변 소음이 증가할 수 있습니다. 환경에 따라 조정이 필요합니다.
|
||
|
|
|
||
|
|
3. **브라우저 호환성**:
|
||
|
|
- Chrome 브라우저에서 최적의 성능을 보입니다
|
||
|
|
- 다른 브라우저에서는 일부 기능이 제한될 수 있습니다
|
||
|
|
|
||
|
|
4. **마이크 권한**: 사용자가 마이크 권한을 허용해야 합니다.
|
||
|
|
|
||
|
|
## 향후 개선 방향
|
||
|
|
|
||
|
|
1. **동적 민감도 조정**: 사용자가 UI에서 민감도를 조정할 수 있는 슬라이더 추가
|
||
|
|
2. **환경 감지**: 주변 소음 레벨을 감지하여 자동으로 설정 조정
|
||
|
|
3. **다양한 마이크 타입 지원**: 다양한 마이크 타입에 최적화된 설정 제공
|
||
|
|
|
||
|
|
## 참고 자료
|
||
|
|
|
||
|
|
- [Web Audio API - MDN](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API)
|
||
|
|
- [Web Speech API - MDN](https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API)
|
||
|
|
- [MediaDevices.getUserMedia() - MDN](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia)
|
||
|
|
|
||
|
|
## 변경 이력
|
||
|
|
|
||
|
|
| 날짜 | 버전 | 변경 내용 |
|
||
|
|
|------|------|----------|
|
||
|
|
| 2024 | 1.0 | 음성 인식 민감도 향상 기능 추가 |
|
||
|
|
|