上回说到,我现在已经做到用自己的gnuradio流图从音频信号做fsk解调,得到方波。然后用c程序把方波转为二进制数。又用python把二进制数转为最终的字母。
但是遗留问题是python解码,起始位如果错误,解的信息是错的。另外,也没有实现两个字符串的错位输出(这个功能是很好理解的,但是为了简化代码,我暂时没做)。
主要是python的问题,所以我把python改为比较完整的版本,并且这次我的输入数据,直接用c程序的输出,而不是人工去截取最好的一段数据,代码如下:
import numpy as np
import scipy
import scipy.signal
from scipy.io import wavfile
from navtex import ALPHABET_FIGS, ALPHABET_LTRSstring = "111111000011001111110000110011111100001100111111000011001111110000110011111100001100111111000011001111110000110011111100001100111111000010110101100110101101111100011101000101101111010001011011110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100011001111101001111000111010001100111111000011001111110000110011111100001100111111000011"bits = list(string)bits = np.array(bits)N = 7
shift = 0cur_alphabet_A = ALPHABET_LTRS
cur_alphabet_B = ALPHABET_LTRSmsg_a = ""
msg_b = ""
msgs_a = []
msgs_b = []alpha_shift = 0
i = 0
while i*N + shift < len(bits):b = bits[i*N + shift:(i+1)*N + shift]s = "".join(map(str, b))s = s[::-1]h = int(s, 2)print (s, h, shift)if s.count('1') != 4:shift += 1continue # Phasing signals, reset receiverif h == 0xf: # [alpha]alpha_shift = i % 2cur_alphabet_A = ALPHABET_LTRSif len(msg_a.replace('_', '')) > 10:msgs_a.append(msg_a)msgs_b.append(msg_b)msg_a = ""msg_b = ""msg_a = ""elif h == 0x66: # [rep]alpha_shift = (i+1) % 2cur_alphabet_B = ALPHABET_LTRSif len(msg_a.replace('_', '')) > 10:msgs_a.append(msg_a)msgs_b.append(msg_b)msg_a = ""msg_b = ""msg_b = ""# Regular symbolsif i % 2 == alpha_shift:dec = cur_alphabet_A[h]if dec == '[ltrs]':cur_alphabet_A = ALPHABET_LTRSelif dec == '[figs]':cur_alphabet_A = ALPHABET_FIGSelif not dec.startswith('['):msg_a += decelse:dec = cur_alphabet_B[h]if dec == '[ltrs]':cur_alphabet_B = ALPHABET_LTRSelif dec == '[figs]':cur_alphabet_B = ALPHABET_FIGSelif not dec.startswith('['):msg_b += deci += 1i = 0
for msg_a, msg_b in zip(msgs_a, msgs_b):i += 1msg = ""for a, b in zip(msg_a, msg_b):if a == b:msg += aelse:if a == '_' and b != '_':msg += belif a != '_' and b == '_':msg += aelse:msg += "_"print ("A: ", msg_a)print ("B: ", msg_b)print ("final: ", msg)print ("-" * 80)
输出结果如下:
('0111111', 63)
('0011111', 31)
('0001111', 15)
('1100110', 102)
('0001111', 15)
('1100110', 102)
('0001111', 15)
('1100110', 102)
('0001111', 15)
('1100110', 102)
('0001111', 15)
('1100110', 102)
('0001111', 15)
('1100110', 102)
('0001111', 15)
('1100110', 102)
('0001111', 15)
('1100110', 102)
('0001111', 15)
('1100110', 102)
('0001111', 15)
('1011010', 90)
('1100110', 102)
('1011010', 90)
('0001111', 15)
('0010111', 23)
('1011010', 90)
('0010111', 23)
('1011010', 90)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('0010111', 23)
('1100110', 102)
('0010111', 23)
('0001111', 15)
('0010111', 23)
('1100110', 102)
('0001111', 15)
('1100110', 102)
('0001111', 15)
('1100110', 102)
('0001111', 15)
('1100110', 102)
('0001111', 15)
('110', 6)
0
('A: ', 'JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ')
('B: ', 'JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ')
('final: ', 'JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ')
--------------------------------------------------------------------------------
程序先通过找连续7个位里正好有4个1的组合,如果找到就解码,找不到就移动1位。然后才开始根据解码内容找数据起始。
代码开头和结尾确实有15和102,对应0x0F和0x66,也就是[alpha]和[rep],就是通过找这两个phasing_signal,我们才能找到正确的起始位置。
另外结尾处也分别写出了A和B两列,经过比较完全一致,说明接收正确。
你还会看到90,对应0x5a,对应[ltrs]
接下来我们要做的是看懂这段python代码,把它改写为c++。还有之前的c代码也要改为c++然后合并到一起。
import numpy as np
from navtex import ALPHABET_FIGS, ALPHABET_LTRSstring = "11100001100111111000011001111110000110011111100001100111111000011001111110000110011111100001100111111000010110101100110101101111100011101000101101111010001011011110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100011001111101001111000111010001100111111000011001111110000110011111100001100111111000011"bits = list(string)bits = np.array(bits)N = 7
shift = 0cur_alphabet_A = ALPHABET_LTRS
cur_alphabet_B = ALPHABET_LTRSmsg_a = ""
msg_b = ""
msgs_a = []
msgs_b = []alpha_shift = 0
i = 0
while i*N + shift < len(bits):b = bits[i*N + shift:(i+1)*N + shift]s = "".join(map(str, b))s = s[::-1]if s.count('1') != 4:shift += 1continue h = int(s, 2)print (s, h)# Phasing signals, reset receiverif h == 0x0f: # [alpha]alpha_shift = i % 2msg = ""for a, b in zip(msg_a, msg_b):if a == b:msg += aif (len(msg)>0):print ("final : ", msg)print ("-" * 80)msg_a = ""msg_b = ""elif h == 0x66: # [rep]alpha_shift = (i+1) % 2msg = ""for a, b in zip(msg_a, msg_b):if a == b:msg += aif (len(msg)>0):print ("final : ", msg)print ("-" * 80)msg_a = ""msg_b = ""# Regular symbolsif i % 2 == alpha_shift:dec = cur_alphabet_A[h]if dec == '[ltrs]':cur_alphabet_A = ALPHABET_LTRSelif dec == '[figs]':cur_alphabet_A = ALPHABET_FIGSelif not dec.startswith('['):msg_a += decelse:dec = cur_alphabet_B[h]if dec == '[ltrs]':cur_alphabet_B = ALPHABET_LTRSelif dec == '[figs]':cur_alphabet_B = ALPHABET_FIGSelif not dec.startswith('['):msg_b += deci += 1
进一步简化会变成这样:
import numpy as np
from navtex import ALPHABET_FIGS, ALPHABET_LTRSstring = "11100001100111111000011001111110000110011111100001100111111000011001111110000110011111100001100111111000010110101100110101101111100011101000101101111010001011011110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100011001111101001111000111010001100111111000011001111110000110011111100001100111111000011"bits = list(string)
bits = np.array(bits)N = 7
shift = 0i = 0
while i*N + shift < len(bits):b = bits[i*N + shift:(i+1)*N + shift]s = "".join(map(str, b))s = s[::-1]if s.count('1') != 4:shift += 1continue h = int(s, 2)print (s, h, ALPHABET_LTRS[h])i += 1
('1100110', 102, '[rep]')
('0001111', 15, '[alpha]')
('1100110', 102, '[rep]')
('0001111', 15, '[alpha]')
('1100110', 102, '[rep]')
('0001111', 15, '[alpha]')
('1100110', 102, '[rep]')
('0001111', 15, '[alpha]')
('1100110', 102, '[rep]')
('0001111', 15, '[alpha]')
('1100110', 102, '[rep]')
('0001111', 15, '[alpha]')
('1100110', 102, '[rep]')
('0001111', 15, '[alpha]')
('1011010', 90, '[ltrs]')
('1100110', 102, '[rep]')
('1011010', 90, '[ltrs]')
('0001111', 15, '[alpha]')
('0010111', 23, 'J')
('1011010', 90, '[ltrs]')
('0010111', 23, 'J')
('1011010', 90, '[ltrs]')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('0010111', 23, 'J')
('1100110', 102, '[rep]')
('0010111', 23, 'J')
('0001111', 15, '[alpha]')
('0010111', 23, 'J')
('1100110', 102, '[rep]')
('0001111', 15, '[alpha]')
('1100110', 102, '[rep]')
('0001111', 15, '[alpha]')
('1100110', 102, '[rep]')
('0001111', 15, '[alpha]')
('1100110', 102, '[rep]')
('0001111', 15, '[alpha]')
用下面的c++程序,可实现类似的效果,会用shift找合适的二进制串,也能转为10进制,但还不能转为字符
#include <stdio.h>
#include <string>
#include <math.h>
#include <iostream>using namespace std;std::string str_temp = "11100001100111111000011001111110000110011111100001100111111000011001111110000110011111100001100111111000010110101100110101101111100011101000101101111010001011011110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100011001111101001111000111010001100111111000011001111110000110011111100001100111111000011";
//std::string str_temp = "1010101101010110101011010101101010110101011010101";
char *char_temp = const_cast<char *>(str_temp.c_str()) ;int main (int argc, char**argv){int N = 7;int shift = 0;int i = 0;cout << str_temp.length() << endl;while (i*N + shift < str_temp.length()){int result_6 = char_temp[i*N+shift+0] - '0';int result_5 = char_temp[i*N+shift+1] - '0';int result_4 = char_temp[i*N+shift+2] - '0';int result_3 = char_temp[i*N+shift+3] - '0';int result_2 = char_temp[i*N+shift+4] - '0';int result_1 = char_temp[i*N+shift+5] - '0';int result_0 = char_temp[i*N+shift+6] - '0';int sum = result_0 + result_1 + result_2 + result_3 + result_4 + result_5 + result_6;if (sum != 4){shift += 1;continue;}cout << result_0 << result_1 << result_2 << result_3 << result_4 << result_5 << result_6 << endl;int result = result_0 * 64 + result_1 * 32 + result_2 * 16 + result_3 * 8 + result_4 * 4 + result_5 * 2 + result_6 * 1;cout << result << endl;i+=1; }return 0;
}
接下来,我在c++版本的解码程序中,把字符转换也加好了,还加入了一部分的控制逻辑,比如字母和数字切换,以及AB列分开等。代码如下:
#include <stdio.h>
#include <string>
#include <math.h>
#include <iostream>using namespace std;std::string str_temp ="111111000011001111110000110011111100001100111111000011001111110000110011111100001100111111000011001111110000110011111100001100111111000010110101100110101101111100010101010101101100011101011011010101101010110001111000111101010110101011000111100011110101011010101100011110001111010101101010110001111000111101010110101011000111100011110101011010101100011110001111010101101010110001111000111101010110101011000111100011110101011010101100011110001111010101101010110001111000111101010110101011000111100011110101011010101100011110001111010101101010110001111000111101010110101011000111100011110101011010101100011110001111010101101010110001111000111101010110101011000111100011110101011010101011001110001111111000101010101100111111000011001111110000110011111100001100111111000011";
//std::string str_temp = "11100001100111111000011001111110000110011111100001100111111000011001111110000110011111100001100111111000010110101100110101101111100011101000101101111010001011011110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100011001111101001111000111010001100111111000011001111110000110011111100001100111111000011";
//std::string str_temp = "1010101101010110101011010101101010110101011010101";std::string msg_a;
std::string msg_b;
char *char_temp = const_cast<char *>(str_temp.c_str()) ;
bool letters = false;
int alpha_shift = 0;std::string final_decode_letters(int input)
{std::string decode_result;if (input == 15) decode_result = "[alpha]";if (input == 23) decode_result = "J";if (input == 27) decode_result = "F";if (input == 29) decode_result = "C";if (input == 30) decode_result = "K";if (input == 39) decode_result = "W";if (input == 43) decode_result = "Y";if (input == 45) decode_result = "P";if (input == 46) decode_result = "Q";if (input == 51) decode_result = "[beta]";if (input == 53) decode_result = "G";if (input == 54) decode_result = "[figs]";if (input == 57) decode_result = "M";if (input == 58) decode_result = "X";if (input == 60) decode_result = "V";if (input == 71) decode_result = "A";if (input == 75) decode_result = "S";if (input == 77) decode_result = "I";if (input == 78) decode_result = "U";if (input == 83) decode_result = "D";if (input == 85) decode_result = "R";if (input == 86) decode_result = "E";if (input == 89) decode_result = "N";if (input == 90) decode_result = "[ltrs]";if (input == 92) decode_result = " ";if (input == 99) decode_result = "Z";if (input == 101) decode_result = "L";if (input == 102) decode_result = "[rep]";if (input == 105) decode_result = "H";if (input == 106) decode_result = "[]";if (input == 108) decode_result = "\n";if (input == 113) decode_result = "O";if (input == 114) decode_result = "B";if (input == 116) decode_result = "T";if (input == 120) decode_result = "[cr]";return decode_result;}std::string final_decode_figures(int input)
{std::string decode_result;if (input == 15) decode_result = "[alpha]";if (input == 23) decode_result = "'";if (input == 27) decode_result = "!";if (input == 29) decode_result = ":";if (input == 30) decode_result = "(";if (input == 39) decode_result = "2";if (input == 43) decode_result = "6";if (input == 45) decode_result = "0";if (input == 46) decode_result = "1";if (input == 51) decode_result = "[beta]";if (input == 53) decode_result = "&";if (input == 54) decode_result = "[figs]";if (input == 57) decode_result = ".";if (input == 58) decode_result = "/";if (input == 60) decode_result = ";";if (input == 71) decode_result = "-";if (input == 75) decode_result = "[bell]";if (input == 77) decode_result = "8";if (input == 78) decode_result = "7";if (input == 83) decode_result = "$";if (input == 85) decode_result = "4";if (input == 86) decode_result = "3";if (input == 89) decode_result = ",";if (input == 90) decode_result = "[ltrs]";if (input == 92) decode_result = " ";if (input == 99) decode_result = "\\";if (input == 101) decode_result = ")";if (input == 102) decode_result = "[rep]";if (input == 105) decode_result = "#";if (input == 106) decode_result = "[]";if (input == 108) decode_result = "\n";if (input == 113) decode_result = "9";if (input == 114) decode_result = "?";if (input == 116) decode_result = "5";if (input == 120) decode_result = "[cr]";return decode_result;}int main (int argc, char**argv){int N = 7;int shift = 0;int i = 0;cout << "length: " << str_temp.length() << endl;while (i*N + shift < str_temp.length()){int result_6 = char_temp[i*N+shift+0] - '0';int result_5 = char_temp[i*N+shift+1] - '0';int result_4 = char_temp[i*N+shift+2] - '0';int result_3 = char_temp[i*N+shift+3] - '0';int result_2 = char_temp[i*N+shift+4] - '0';int result_1 = char_temp[i*N+shift+5] - '0';int result_0 = char_temp[i*N+shift+6] - '0';int sum = result_0 + result_1 + result_2 + result_3 + result_4 + result_5 + result_6;if (sum != 4){shift += 1;continue;}//cout << result_0 << result_1 << result_2 << result_3 << result_4 << result_5 << result_6 << endl;int input = result_0 * 64 + result_1 * 32 + result_2 * 16 + result_3 * 8 + result_4 * 4 + result_5 * 2 + result_6 * 1;//cout << input << " ";if (input == 15){alpha_shift = i % 2;if (msg_a.length() > 0 && msg_b.length() > 0 ){cout << "A: " << msg_a << endl;cout << "B: " << msg_b << endl;}msg_a = "";msg_b = "";}if (input == 102){alpha_shift = (i+1) % 2;if (msg_a.length() > 0 && msg_b.length() > 0 ){cout << "A: " << msg_a << endl;cout << "B: " << msg_b << endl;}msg_a = "";msg_b = "";}if (input == 90){letters = true;}if (input == 54){letters = false;}if (alpha_shift == i % 2){std::string output;if (letters == true){output = final_decode_letters(input);}else{output = final_decode_figures(input);}if (output[0] != '['){ msg_a = msg_a + output;}}else{std::string output;if (letters == true){output = final_decode_letters(input);}else{output = final_decode_figures(input);}if (output[0] != '['){ msg_b = msg_b + output;}}i+=1; }return 0;
}
效果如下:
length: 768
A: ROROROROROROROROROROROROROROROROROR
B: ROROROROROROROROROROROROROROROROROROR
接下来,另外一部分从gnuradio接收到方波波型,转为二进制数的c语言程序也合并到一起就行,那部分程序需要先转为c++,但这两种语言很接近,几乎不需要怎么改动就行:
#include <stdio.h>
#include <string.h>
#include <math.h>int main (int argc, char**argv){int16_t cursamp = 0;int result = 0, last_result = 0;int16_t counter = 0;int real_counter = 0;int buffer[10];while(!feof(stdin) ) {cursamp = (int16_t) ( fgetc(stdin) | fgetc(stdin)<<8);counter++;if (cursamp >= 0 ){result = 1;}else{result = 0;}if (last_result != result){real_counter = (int)(counter / 440);for (int i = 0; i < real_counter; i++){buffer[i] = last_result;}for (int i = 0; i < real_counter; i++){printf("%d", buffer[i]);}counter = 0;last_result = result;}//printf("%d", result);}return 0;
}