FSK, Wave, Packet 그리고 ASK 짧은? 요약 #115
Replies: 6 comments 9 replies
-
어려운 내용 알기 쉽게 정리해주셔서 감사합니다 ㅎㅎ |
Beta Was this translation helpful? Give feedback.
-
꼼꼼히 읽어봐야겠네요! 감사합니다 👍 |
Beta Was this translation helpful? Give feedback.
-
와 정말 상세하게 설명해주셨네요! ASK에서 주파수는 그냥 기본값으로 처리해야 할 것 같았는데 역시나군요!
요 마지막 부분을 읽으면서 제가 어떻게 구현해야 할지 고민한 것들이 싹 내려갔습니다.. 멋진 해결책 감사드립니다!! 👍👍 |
Beta Was this translation helpful? Give feedback.
-
감사합니다!! 그럼 Amplitude도 0~f, S 까지 해서 16개로 적절하게 나눠서 setting 하는 과정이 필요하겠네요 |
Beta Was this translation helpful? Give feedback.
-
아래는 euphony.js 에서의 ASK 구현체입니다. 참고하시면 구현에 도움이 될 것 같습니다. 그리고 ASK에서는 하나의 frequency만 사용하시면 되고 (예를 들어 FSK에서의 0에 해당하는 frequency?) |
Beta Was this translation helpful? Give feedback.
-
자세한 설명 감사드립니다!!!🔥🔥 |
Beta Was this translation helpful? Give feedback.
-
FSK.cpp 분석
코드를 다 적으면 너무너무 길어져서 가독성을 해치기 때문에 설명 위주로 적은 부분 양해 부탁드립니다 ㅠㅠ 😢
전체 흐름을 먼저 이해하시고 코드랑 같이 보시면 도움이 될 거라고 생각합니다. (되었으면 좋겠네요 ㅠ)
잘못된 부분 있으면 언제든지 댓글로 알려주세요 @designe 👍
FSK 사용법
크게 두 가지 mod와 demod 메소드를 사용합니다.
메소드의 파라미터와 리턴을 정리하면 다음과 같습니다.
modulate
string -> wave의 벡터
packet -> wave의 벡터
demodulate
wave의 벡터 -> packet
float, 길이, 버퍼크기 -> packet
packet과 wave의 벡터는 mod에도 demod에도 있으니 두 클래스가 중요해보이네요.
Packet
Packet은 음파 통신의 데이터 패킷을 나타내는 클래스입니다. 통신에서 사용하는 그 패킷 개념이 맞습니다.
PacketBuilder 클래스를 사용하여 Packet을 생성할 때 인자를 직접 넣는 대신 메소드를 호출하여 각 인자를 설정하고 마지막에 build()하여 Packet을 얻습니다.
생성자를 봅시다
HexVector를 받아서 Base2나 Base16 데이터로 변환하여 payload에 저장합니다.
Wave
Wave는 디지털 데이터를 아날로그(음파)로 변환한 sin 파형이 저장된 자료구조입니다.
마찬가지로 WaveBuilder를 사용하여 생성합니다.
생성자를 보죠
주파수와 버퍼 크기를 받거나 float과 버퍼 크기를 받습니다.
주파수와 버퍼 크기를 받은 경우, 멤버 변수를 세팅하고 oscillate를 호출합니다.
oscillate는 뭘하냐? sin 함수를 샘플링해서 버퍼에 채웁니다.
러프하게 설명하자면 0부터 2pi까지 버퍼 크기만큼 등분을 해서 등분한 x 좌표에 대한 sin(x) 값을 저장한다는 것입니다.
물론 주파수에 따라 phase 증가량이 바뀌기 때문에 0부터 2pi까지라는 보장은 없습니다.
그리고 crossfade를 적용하는데 아마도 갑작스럽게 주파수가 바뀔 때 발생하는 잡음을 줄이기 위한 것으로 보입니다.
FSK
다시 FSK로 돌아와서 modulate를 보겠습니다.
packet을 문자열로 다시 돌려서 modulate를 합니다.
packet을 문자열로 돌리면
"S" + payload의 문자열 + checksum의 문자열 + parityCode의 문자열
이 됩니다.즉 "a"를 Packet으로 만들어서 다시 문자열로 돌린 것이 S + 61 + 9 + 7 인 겁니다. 참고로 a는 0x61입니다.
그럼 이 패킷의 문자열을 modulate에 넣으면 어떻게 될까요.
이런 식으로 잘 분쇄해서 한 글자씩 Wave로 만들어 벡터에 담아서 return합니다.
다시말해서 FSK가 하는 일은 문자열를 받아서 각 문자마다 정해진 주파수의 wave로 만들어서 돌려주는 것입니다.
그런데 저희가 개발할 ASK는 주파수를 건드리지 않습니다. 그냥 아무 주파수나 사람 귀에 잘 안 들리는 주파수 고정이면 됩니다.
변할 것은 amplitude입니다.
각 문자마다 amplitude를 정해서 wave의 버퍼에 곱해주면 될 것 같습니다. 문제는 버퍼가 private여서 직접 곱할 수는 없습니다.
WaveBuilder에 amplitude를 설정할 수 있는 메소드도 없습니다.
위에서 혜성님이 말씀하신 것처럼 EuPIOscillator 클래스에 amplitude가 존재는 하지만 이 클래스는 Euphony Programming Interface의 Oscillator 역할을 하는 클래스라 사용하기 어려울 것 같습니다.
제 생각에는 wave와 builder에 amplitude를 설정하는 메소드를 추가하면 쉽게 modulate를 구현할 수 있을 것 같습니다.
그리고 demodulate의 경우 미리 고정해둔 주파수대역의 amplitude를 확인하고 처리해서 HexVector에 차곡차곡 넣은 후에 Packet으로 만들어 return하면 될 것 같습니다.
또는 멘토님 말씀처럼 amplitude를 0과 1로만 구분하는 방법도 있을 것 같습니다.
#85 (reply in thread)
FSK에서는 현재 소리에서 가장 많이 포함된 주파수를 찾고 이를 데이터로 읽지만
ASK에서는 현재 소리의 특정한 주파수의 세기를 구간으로 나눠서 데이터로 읽기 때문에 노이즈에 많이 취약합니다.
그래서 소리의 세기를 잘게 나누면 인식이 잘 안될 것 같습니다.
특정 세기 이하는 0 이상은 1 이런 식으로 BASE2로 전송하면 속도는 많이 느리지만 노이즈에 강해질 것 같네요.
Beta Was this translation helpful? Give feedback.
All reactions