Petitcom 3 QPSK Modulator

8KB以内の任意のファイルを、音声信号に変換して、プチコン3号のマイク入力経由で復号させる。

※2回に1回程度の成功率です。過度な期待はしないでください。あしからず。
※音量に注意!! 人間が聞くと非常に不快な音が発生します。
※Chrome 39, ニンテンドー3DS(CTR-001), プチコン3号(ver 3.00) で動作確認してますが、何が起きても無保証です。

Version 0.2.1 (November 27, 2014)
Powered by md5.js base64.js


この ツール の しようほうほう

  1. どうにかして、PCの音声を3DS本体のマイクで拾えるようにする。
  2. プチコン3号側で、プログラム "QPSK_DEM" を実行する。
  3. 下にあるファイル選択用ボタンをクリックし、転送したいファイルを選択する。
  4. プチコン3号側でAボタンを押し、その直後に、下にあるプレイヤーの再生ボタンをクリックする。
  5. 音がピーガー鳴っている間、静かに待つ。
  6. 音が鳴りやんだら、プチコン3号側でBボタンを押す。(32秒経ったら自動的に先に進む)
  7. プチコン3号の画面に、受信したデータの内容が黄色い文字で出力されるのを眺める。
  8. 最後に、受信バイト数と、簡易チェックサムが表示されるので、一致しているか確認する。


ふくごう よう プログラム "QPSK_DEM"

公開キー: 28EN3HE   version 0.2 (November 26, 2014)
'
'   TXT:QPSK_DEM     Programmed by OBONO   
'
_TH=20 ' Threshold
_CE=1  ' Coefficient (1 or -1)

' INITIALIZE
DIM _W%[261760]
DIM _VF[4],_VP[6,4],_MR[3],_MC[7]
READ _HS$
FOR _I=0 TO 5:FOR _J=0 TO 3
 READ _VP[_I,_J]
NEXT:NEXT
FOR _I=0 TO 2:READ _MR[_I]:NEXT
FOR _I=0 TO 6:READ _MC[_I]:NEXT
DEF _GETW(_I):RETURN (_W%[_I]-&H80)*_CE:END

' RECORD FROM MIC
? "<<< QPSK Demodulater ver 0.2 >>>"
? "Push  to start recording."
XON MIC:REPEAT:VSYNC 1:UNTIL BUTTON(1)==16
MICSTART 0,0,32:? "Recording... ( to stop)"
REPEAT:UNTIL BUTTON(1)==32 || MICPOS==261759
MICSTOP:_WS=MICPOS+1:MICSAVE 0,_WS,_W%
XOFF MIC:? "Got ";_WS;" samples."
'LOAD"DAT:WAVE",_W%:_WS=261760

' DEMODULATION 

_WP=0:_VL=0:_VE=0:_CK=0:_TV=_TH/2
GOSUB @PRE

' SYNCHRONIZE
@SYNC
_HL=0:_HS=0:_HC=0
REPEAT
 _W=_GETW(_WP)
 _HP=_HS*3+(_W>=_TH)-(_W<=-_TH)+1
 _HS=ASC(MID$(_HS$,_HP,1))-65
 _HC=(_HC+1)*(_HS>=10)
 _HS=_HS MOD 10:_HL=_HL+1:_WP=_WP+1
 IF _VL && _HL>=1024 || _WP>=_WS THEN @BAIL
UNTIL !_HS && _HC>=256
_VB=0:_VC=0:_VU=0

' OBTAIN DATA
REPEAT
 GOSUB @GETV
 IF _VR>=_TV THEN
  GOSUB @MATCH
  IF _VM<4 THEN
   _VB=_VB OR _VM<<(12-_VC*2)
   _VC=(_VC+1) MOD 7:_VU=1
   IF !_VC THEN
    GOSUB @DEC:GOSUB @BYTE
    _CK=_CK+(Z XOR _VL*23 AND &HFF)
    _VL=_VL+1:_VB=0
    IF _VL MOD 512==0 THEN @SYNC
   ENDIF
  ENDIF
 ENDIF
 _WP=_WP+4
UNTIL _WP>=_WS-4 || _VR<_TV

' FINISH
@BAIL
GOSUB @POST
IF _VL>0 THEN
 PRINT "Demodulated ";_VL;" bytes."
 PRINT "(Corrected ";_VE;" bits)"
 PRINT "Checksum: ";_CK
ENDIF
END

' SUB ROUTINES 

' GET A SIGNAL
@GETV
_VR=0:FOR _I=0 TO 3
 _VF[_I]=_GETW(_WP+_I):_VR=_VR+POW(_VF[_I],2)
NEXT:_VR=SQR(_VR)
IF _VR>0 THEN
 FOR _I=0 TO 3:_VF[_I]=_VF[_I]*2/_VR:NEXT
ENDIF:RETURN

' JUDGE PHASE
@MATCH
FOR _I=0 TO 5-_VU*2:_D=0:FOR _J=0 TO 3
  _D=_D+POW(_VF[_J]-_VP[_I,_J],2)
 NEXT:IF !_I || _VD>_D THEN _VM=_I:_VD=_D
NEXT:RETURN

' DECODE A BYTE
@DEC
FOR _I=0 TO 1
 _N=0
 FOR _J=0 TO 2
  _B=0:_R=_VB>>_I*7 AND _MR[_J]
  FOR _K=0 TO 6:_B=_B XOR _R>>_K AND 1:NEXT
  _N=_N OR _B<<_J
 NEXT
 IF _N THEN
  _VB=_VB XOR 1<<_MC[_N-1]+_I*7:_VE=_VE+1
 ENDIF
NEXT
Z=(_VB>>6 AND &HF0) OR (_VB>>3 AND &H0F)
RETURN

' DATA
DATA "AALAAMAANAOPQABQEFRAASAAKKA"
DATA -1,-1, 1, 1,  1,-1,-1, 1, -1, 1, 1,-1
DATA  1, 1,-1,-1,  1, 1, 1, 1, -1,-1,-1,-1
DATA &H39,&H6A,&H5C,0,1,5,2,4,6,3

' PROCEDURE 

@PRE
COLOR 7:RETURN

@BYTE
IF Z>=&H20 && Z<&H7F THEN PRINT CHR$(Z);
IF Z==&HA THEN PRINT
RETURN

@POST
PRINT:COLOR 15:RETURN

' EOF

かいせつ

おんせいへんかん

変換したいデータのバイト列に対し、各バイトについて4ビットずつ分割し、4ビット毎に(7,4)ハミング符号化を適用します。

こうして得られたビット列に対して、QPSK変調を行います。
つまり、2ビット毎に、対応する波形をどんどん連結していくわけです。

仕上げに、512バイト相当のデータ毎に、同期をとるための信号を挿入して完了です。

ふくごう

まず同期信号を検出するために、配列に格納された音声データを1サンプルずつチェックしていきます。
H → H → H → (H or N) → L → L → L → (L or N) → … という繰り返しが一定期間継続したら、同期完了と判断します。

同期が完了したら、それ以降は4サンプルずつチェックし、一番近い信号の波形に対応する値を受信データとして採用します。

受信データが14ビット分溜まったら、上位7ビット、下位7ビットで分割し、それぞれで誤り訂正と復号化を行います。
512バイト分受信したら、また同期信号の検出処理を行います。
信号レベルが、ある閾値を下回ったら、信号が終了したと判断し、復号処理を終了します。

さんこうしりょう


OBONO's Storage に戻る