새싹 해커톤 : 생성 AI 활용

아이디어 | 생성형 AI | 생성 | 정성평가

마감

 

김동영 멘토님 리액트 프로젝트에서 음성 녹음 기술 관련 여쭤볼 것이 있습니다.

2024.08.01 20:01 1,081 조회

안녕하세요, 멘토님.

현재 프로젝트에서 음성 품질 문제로 인해 어려움을 겪고 있습니다. 기능에 대한 배경과 요약된 코드를 아래와 같이 정리하여 문제점에 대해 말씀드리겠습니다.

  • 프론트엔드 음성 녹음 및 처리
  • 녹음: 사용자의 음성을 MediaRecorder API를 통해 녹음합니다. 이와 함께 AudioContextAudioWorklet을 사용하여 오디오 품질을 개선하려고 합니다.
  • 음성 변환: 녹음된 음성을 WAV 형식으로 변환하여 백엔드로 전송합니다. 이 과정에서 AudioContext를 사용하여 WAV 파일 헤더를 작성하고, DataView를 통해 PCM 샘플을 기록합니다.
  • 백엔드 처리
  • 음성 인식: 백엔드에서는 음성 데이터를 텍스트로 변환하는 Speech-to-Text 서비스를 사용하고 있습니다.

프론트엔드에서 녹음된 음성의 품질이 낮아 백엔드에서 텍스트 변환의 정확도가 떨어지고 있습니다.

MediaRecorder API를 사용하여 음성을 녹음하고 있으며, AudioContextAudioWorklet을 통해 오디오 품질을 개선하도록 구현했습니다.

노이즈 감소 및 오디오 필터링을 최적화할 수 있는 방법에 대해 조언을 부탁드립니다. AudioContextAudioWorklet에서 음성 품질을 개선하기 위한 설정이나 기법이 있는지 알려주시면 좋겠습니다.

녹음된 음성을 WAV 파일로 변환할 때, AudioContext를 사용하여 오디오 데이터를 PCM 형식으로 변환하고, WAV 헤더를 직접 작성합니다. 이 과정에서 DataView를 사용하여 WAV 파일의 헤더를 작성하고 PCM 데이터를 기록합니다.

WAV 파일을 백엔드로 전송할 때 품질을 최대한 유지할 수 있는 방법에 대해 조언을 부탁드립니다. 파일 변환 과정에서 품질 손실이 발생할 수 있는지, 이를 최소화할 수 있는 방법이 있는지 확인하고 싶습니다.


  • 음성 녹음:
const mediaRecorder = new MediaRecorder(stream);
mediaRecorder.start();

MediaRecorder API를 사용하여 사용자의 음성을 녹음합니다.

  • WAV 파일 변환:
const convertBlobToWav = async (blob) => {
  const audioContext = new (window.AudioContext || window.webkitAudioContext)({
    sampleRate: 16000,
  });
  const arrayBuffer = await blob.arrayBuffer();
  const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
  const numberOfChannels = audioBuffer.numberOfChannels;
  const length = audioBuffer.length * numberOfChannels * 2 + 44;
  const buffer = new ArrayBuffer(length);
  const view = new DataView(buffer);
  
  // WAV 파일 헤더 작성
  writeString(view, 0, 'RIFF');
  view.setUint32(4, 36 + audioBuffer.length * numberOfChannels * 2, true);
  writeString(view, 8, 'WAVE');
  writeString(view, 12, 'fmt ');
  view.setUint32(16, 16, true);
  view.setUint16(20, 1, true);
  view.setUint16(22, numberOfChannels, true);
  view.setUint32(24, 16000, true);
  view.setUint32(28, 16000 * 2 * numberOfChannels, true);
  view.setUint16(32, numberOfChannels * 2, true);
  view.setUint16(34, 16, true);
  writeString(view, 36, 'data');
  view.setUint32(40, audioBuffer.length * numberOfChannels * 2, true);
  
  // PCM 샘플 작성
  const offset = 44;
  for (let i = 0; i < audioBuffer.length; i++) {
    for (let channel = 0; channel < numberOfChannels; channel++) {
      const sample = audioBuffer.getChannelData(channel)[i];
      const intSample = sample < 0 ? sample * 32768 : sample * 32767;
      view.setInt16(offset + (i * numberOfChannels + channel) * 2, intSample, true);
    }
  }
  return new Blob([buffer], { type: 'audio/wav' });
};

AudioContextDataView를 사용하여 WAV 파일 헤더를 작성하고 PCM 데이터를 기록합니다.

  • 음성 전송:
const formData = new FormData();
formData.append('audio', sound);
const audioResponse = await getAudioFeedback(formData);

FormData를 사용하여 WAV 파일을 백엔드로 전송합니다


로그인이 필요합니다
0 / 1000
새싹해커톤_멘토_김동영
2024.08.01 20:21

음성 처리는 제 주 분야가 아니라서 얼마나 도움이 될지는 모르겠지만, 제가 알고 있는 정도 내에서 답변을 남겨보겠습니다.
노이즈 감소 같은 기능이 구현하기 쉬운 영역의 기술은 아니어서 딥하게 들어가고자 하면 끝이 없기 때문에, 해커톤 기간 중에 목표로 하는 품질까지 도달하는데 어려움이 있을 수 있습니다. WAV 파일을 생성하고 전송하는 과정 자체는 문제가 없어 보이네요.
프로젝트 목표가 무엇이냐에 따라 다르겠지만, 음성 데이터를 텍스트로 변환하는 게 목적이라면 해커톤에서는 클라우드 서비스에서 제공하는 STT 기술을 활용해보심이 어떨까 싶습니다.

새싹해커톤_멘토_김동영
2024.08.01 20:26

그래도 직접 노이즈 필터링 등의 기능을 적용하려고 한다면 해당 기능은 프론트엔드보다는 백엔드 영역에서 구현하는 게 https://github.com/timsainb/noisereduce 같은 라이브러리를 사용할 수 있어서 구현하기 더 나으실 겁니다.

이예나
2024.08.01 20:35

알려주신거 참고해서 기능을 구현해보겠습니다. 감사합니다!

이전 글
새싹톤 수상 내역 증빙자료 관련 문의 드립니다.
대회 - 새싹 해커톤 : 생성 AI 활용
좋아요 5
조회 818
댓글 1
10달 전
현재 글
김동영 멘토님 리액트 프로젝트에서 음성 녹음 기술 관련 여쭤볼 것이 있습니다.
대회 - 새싹 해커톤 : 생성 AI 활용
좋아요 4
조회 1,081
댓글 3
10달 전
다음 글
Socket Exception
대회 - 새싹 해커톤 : 생성 AI 활용
좋아요 4
조회 743
댓글 3
10달 전