시연 동영상 링크

https://youtu.be/lI-I8FzTY5U

주제

Send Unicode via MFSK

주요 목표

송수신 기능 완성

#1 송신

  • send_data 함수는 사용자가 입력한 텍스트를 소리로 바꾸어 재생한다.
  • MFSK 인코딩을 해야하므로,
    1. text → hex
    2. start 주파수 전송 (2 unit)
    3. 데이터 주파수 전송 (1 unit씩)
    4. end 주파수 전송 (2 unit)
    5. pyaudio로 재생

#2 수신

  1. 오디오 스트림 열기
  2. 녹음에 필요한 여러 상수 정의
  3. 오디오 데이터 수신
  4. Noise Threshold 처리 (RMS 사용)
  5. 데이터 안에 포함된 주파수 성분 분석 위해 FFT(푸리에 변환) 적용
  6. 정리 후 결과 출력
  • main은 강의자료의 코드를 그대로 사용했다.


세부 목표

목표1) 소음에 대한 처리

[ 데이터 도착할 때부터 연산: Current Data 출력 ] (#2 수신 - 4,5번 참고)

  • START Signal 받기 전에도 소음이 들어온다. 그러나 이것까지 FFT돌리고 주파수를 찾는 것은 의미 없는 낭비가 되므로, RMS값을 이용하여 noise threshold처리를 해줬다. THRESHOLD보다 작은 rms값은 noise로 판단하고 별다른 처리를 하지 않는다.
  • 코드 실행 환경에 따라 THRESHOLD를 다르게 설정해야했는데, 이에 소음에 대한 rms값이 현재 어떤지 확인하며 실시간으로 디버깅해야했다.
  • 이때 강의자료에서는 기준으로 표준편차를 사용했으나, 디버깅 시 변화량을 보는 것이 직관적이지 않아 나는 RMS(Root Mean Square)를 이용했다. 이는 에너지의 크기 측정하는 방법인데, 수식을 보면 표준편차와 거의 linear관계이고 사인파의 평균값이 0 근처이므로 대체 가능했다.
  • 이 if문 다음에 푸리에 연산이 오는데, THRESHOLD보다 작은 값(데이터가 아닌 노이즈)이면 다른 연산 없이 다시 while문의 처음으로 돌아가므로 데이터가 도착할 때부터 연산을 시작할 수 있다.
  • 또한 Current Data는 5번의 해당 코드를 통해 출력된다. (Detected: data, data는 주파수에 매핑된 데이터). START / END / HEX(0~F) / “” 값을 갖는다.
print(f"[{status}] | [RMS: {rms:.2f}] | Detected: {data} | Freq: {top_freq:.1f} Hz | Text Hex: {text_hex}")

목표2) 데이터가 언제 시작하는지 알아내기 (동기화)

[ START Signal 처리 방법 ] (#2 수신 - 5번 참고)

  • 앞서 START 주파수를 rules 딕셔너리에 정의해둔 바 있다. padding에 의해 512±5Hz의 값이 들어오면 딕셔너리 매핑을 통해 판단, 데이터 수신을 시작한다. is_receiving 변수로 받아야 할 데이터의 시작 전후 상태를 구분한다.
  • is_receiving은 ’NONE(필요없는 데이터)’과 ‘DATA(변환해야 할 데이터)’ 상태 구분을 위해 도입한 변수이다.
  • 이때 과제의 출력조건을 만족시키기 위해, 로그에 [START]가 찍히도록 들어갈 status를 문자열로 정의해준다.
  • 노이즈로 인해 end_count가 변했을 수도 있어, 이후 정확히 END조건을 판단할 수 있게 0으로 초기화해준다.
  • 처리가 끝나면 continue로 while의 처음으로 돌아와 다음 데이터를 받고, 이제 .

목표3) 데이터가 언제 끝나는지 알아내기 (동기화)

[ END Signal 처리 방법 ] (#2 수신 - 5번 참고)

  • 앞서 END 주파수를 rules 딕셔너리에 정의해둔 바 있다. padding에 의해 2944±5Hz의 값이 들어오면 딕셔너리 매핑을 통해 판단, 데이터 수신을 종료한다. (2944 = 512 + 128 + 128 * 16 + 128 * 2)
  • 이때 주파수가 수신되더라도 end_count를 세며 이게 2 이상일 때만 종료하는데, 노이즈에 의해 순간 END주파수가 들어오는 상황을 처리하기 위함이다.

Leave a comment