From 1961c9b2932425ea3009ff44acc2930cb2df6840 Mon Sep 17 00:00:00 2001 From: Elliott Zhang <898016731@qq.com> Date: Fri, 9 Dec 2022 19:26:45 +0800 Subject: [PATCH 01/12] Implement 74-Hamming encoding --- .idea/gradle.xml | 4 +- .idea/misc.xml | 2 +- .idea/modules.xml | 7 +- .idea/runConfigurations.xml | 12 --- app/src/main/java/xwh/sound/CodeBook.java | 59 +++++++++- app/src/main/java/xwh/sound/Decoder.java | 101 +++++++++++++++++- app/src/main/java/xwh/sound/Encoder.java | 35 ++++++ app/src/main/java/xwh/sound/MainActivity.java | 19 +++- app/src/main/java/xwh/sound/PCMPlayer.java | 2 +- app/src/main/java/xwh/sound/Record.java | 5 +- build.gradle | 14 ++- gradle/wrapper/gradle-wrapper.properties | 6 +- 12 files changed, 228 insertions(+), 38 deletions(-) delete mode 100644 .idea/runConfigurations.xml diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 7ac24c7..a0de2a1 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -1,17 +1,19 @@ + diff --git a/.idea/misc.xml b/.idea/misc.xml index e0d5b93..4912fd3 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -29,7 +29,7 @@ - + diff --git a/.idea/modules.xml b/.idea/modules.xml index 80afbb3..125e41d 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,8 +2,11 @@ - - + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml deleted file mode 100644 index 7f68460..0000000 --- a/.idea/runConfigurations.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/java/xwh/sound/CodeBook.java b/app/src/main/java/xwh/sound/CodeBook.java index 8eefcaa..77042e5 100644 --- a/app/src/main/java/xwh/sound/CodeBook.java +++ b/app/src/main/java/xwh/sound/CodeBook.java @@ -19,19 +19,23 @@ public class CodeBook { public static final int START_INDEX = DUPLICATE_INDEX_2 + 1; // 开始标记 public static final int END_INDEX = START_INDEX + 1; // 结束标记 + public static int freqDistance = 50; // 两个频率之间的间距 + public static final int START_INDEX_HAMMING = 4; + public static final int END_INDEX_HAMMING = 5; + public static final int BASE_FREQ = 10000; + public static final int START_FREQ = BASE_FREQ + freqDistance * 16; + public static final int END_FREQ = BASE_FREQ + freqDistance * 20; + /** * 两个book字典码来组成下面每个字符的编码 */ public final static String CONTENT_CODE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; // Base64编码 - public static int[] freqsWave = new int[12]; // 将声音频率划分成12段,每一段表示一个字典码。 - public static int freqDistance = 500; // 两个频率之间的间距 - static { for(int i=0; i= 0; i--) { + res += (((value >> i) & 0x1) ^ ((value >> (i + 1)) & 0x1)) << i; + } + return res; + } + + private static int _inv_gray(int value, int bitNum) { + value = value & ((1<= 0; i--) { + res += (((value >> i) & 0x1) ^ ((res >> (i + 1)) & 0x1)) << i; + } + return res; + } /** * 从码库里面找到一个最相近的 @@ -64,4 +96,23 @@ public static int decode(int fre) { } return index; } + + public static int decode_codeword(int fre) { + + int index = decode(fre); + if (index == 11) { + if (Math.abs(fre - START_FREQ) < Math.abs(fre - freqsWave[11])) { + if (Math.abs(fre - START_FREQ) < Math.abs(fre - END_FREQ)) { + return START_INDEX_HAMMING; + } else { + return END_INDEX_HAMMING; + } + } + } + if (index != -1) { + index = index / 3; + index = _gray(index, 2); + } + return index; + } } diff --git a/app/src/main/java/xwh/sound/Decoder.java b/app/src/main/java/xwh/sound/Decoder.java index 1488f82..57646cb 100644 --- a/app/src/main/java/xwh/sound/Decoder.java +++ b/app/src/main/java/xwh/sound/Decoder.java @@ -5,8 +5,11 @@ import android.util.Base64; import android.util.Log; +import java.io.UnsupportedEncodingException; import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; +import java.util.Queue; import xwh.sound.utils.FFT; @@ -27,6 +30,7 @@ public class Decoder { private int countEndCode = 0; private boolean startDecode; private ArrayList codeIndexs; + private Queue codeQueue; private Handler mHandler; @@ -40,6 +44,7 @@ public class Decoder { public Decoder(Handler handler) { this.mHandler = handler; codeIndexs = new ArrayList<>(); + codeQueue = new LinkedList(); } public void countFreq(short[] datas, int sampleStep) { @@ -62,7 +67,7 @@ public void countFreq(short[] datas, int sampleStep) { /** * 对一个录音Buffer进行频率统计 */ - public int countFreq1(short[] datas, int sampleStep) { + public int countFreq1(short[] datas, int sampleStep) throws UnsupportedEncodingException { int itemStep = datas.length / COUNT_STEP_SIZE; int waveState = -1; @@ -98,7 +103,7 @@ public int countFreq1(short[] datas, int sampleStep) { bufferFreqCount += waveCount; currentFreq = waveCount * COUNT_STEP_SIZE * sampleStep / 2; // 这里根据每小段得出频率(一秒内波形次数) - decodeFre(currentFreq); + decodeFre_74hamming(currentFreq); stepCount = 0; waveCount = 0; @@ -199,6 +204,67 @@ public void decodeFre(int fre) { } } + public void decodeFre_74hamming(int fre) throws UnsupportedEncodingException { + + int codeIndex = CodeBook.decode_codeword(fre); + + if (codeIndex == -1) { + return; + } else if (codeIndex == CodeBook.START_INDEX_HAMMING) { + countEndCode = 0; + startDecode = true; + codeIndexs.clear(); + lastStartTime = System.currentTimeMillis(); + } else if (startDecode) { + countStartCode = 0; + + if (System.currentTimeMillis() - lastStartTime > TIMEOUT) { + startDecode = false; + return; + } + + if (codeIndex == CodeBook.END_INDEX_HAMMING) { + countEndCode++; + if (countEndCode >= 2) { + countEndCode = 0; + startDecode = false; + List cleanIndexs = dummyCodeIndexs(codeIndexs); + + Log.i("Record", "clearCodeIndexs:" + cleanIndexs); + + if (cleanIndexs.size() > 0) { + showResult_74hamming(cleanIndexs); + } + } + } else { + countEndCode = 0; + codeQueue.add(codeIndex); + if (codeQueue.size() >= 7) { + int c = 0; + int s = 0; + for (int i = 0; i < 7; ++i) { + s += (codeQueue.poll() << (2 * i)); + } + int [] code = new int [7]; + for (int i = 0; i < 2; ++i) { + int curr7bit = (s >> (i * 7)) & 0x7f; + for (int j = 0; j < 7; ++j) { + code[j] = (curr7bit >> j) & 0x1; + } + int errorBit = code[0] + code[1] << 1 + code[3] << 2; + code[errorBit] = ~code[errorBit]; + int curr4bit = code[2] + code[4] << 1 + code[5] << 2 + code[6] << 3; + c += (curr4bit << (4 * i)); + } + codeIndexs.add(c); + } + } + } else { + countEndCode = 0; + countStartCode = 0; + } + } + /** * 去重 * 将频率串转为编码串,出现多个连续的频率转为一个码值 @@ -232,6 +298,11 @@ private List cleanCodeIndexs(ArrayList codeIndexs) { return list; } + private List dummyCodeIndexs(ArrayList codeIndexs) { + List list = new ArrayList<>(codeIndexs); + return list; + } + private String showResult(List indexs) { @@ -285,4 +356,30 @@ private String showResult(List indexs) { } + private String showResult_74hamming(List codeIndexs) throws UnsupportedEncodingException { + byte [] bytes = new byte[codeIndexs.size()]; + for (int i = 0; i < codeIndexs.size(); ++i) { + bytes[i] = codeIndexs.get(i).byteValue(); + } + String re = new String(bytes, "UTF-8"); + String text = null; + try { + text = new String(Base64.decode(re, Base64.NO_WRAP | Base64.NO_PADDING)); + } catch (Exception e) { + e.printStackTrace(); + } + + if (mHandler != null) { + Message msg = mHandler.obtainMessage(); + msg.what = MainActivity.MSG_RESULT; + msg.obj = codeIndexs.toString() + "\n" + text; + mHandler.sendMessage(msg); + } + + Log.d(TAG, "showResult:" + "____" + re +"____"+ text); + + return text; + + } + } diff --git a/app/src/main/java/xwh/sound/Encoder.java b/app/src/main/java/xwh/sound/Encoder.java index 613d525..6ee69d5 100644 --- a/app/src/main/java/xwh/sound/Encoder.java +++ b/app/src/main/java/xwh/sound/Encoder.java @@ -3,6 +3,7 @@ import android.text.TextUtils; import android.util.Log; +import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; @@ -52,4 +53,38 @@ public static List convertTextToCodes(String text) { return mCodes; } + + public static List convertTextToCode_74hamming(String text) throws UnsupportedEncodingException { + byte[] bytes = text.getBytes("UTF-8"); + List mCodes = new ArrayList<>(); + mCodes.add(4); + mCodes.add(4); + int[] temp = new int[14]; + StringBuilder binaryString = new StringBuilder(); + // little endian + for (byte b: bytes) { + for (int i = 0; i < 2; ++i) { + int curr = (b >> (i * 4)) & 0xf; + int d1 = curr & 1; + int d2 = (curr >> 1) & 1; + int d3 = (curr >> 2) & 1; + int d4 = (curr >> 3) & 1; + temp[2 + i * 7] = d1; + temp[4 + i * 7] = d2; + temp[5 + i * 7] = d3; + temp[6 + i * 7] = d4; + //chk bits + temp[0 + i * 7] = (d1 ^ d2 ^ d4); + temp[1 + i * 7] = (d1 ^ d3 ^ d4); + temp[3 + i * 7] = (d2 ^ d3 ^ d4); + } + for (int i = 0; i < 7; ++i) { + int code = temp[i] + (temp[i+1] << 1); + mCodes.add(code); + } + } + mCodes.add(5); + mCodes.add(5); + return mCodes; + } } diff --git a/app/src/main/java/xwh/sound/MainActivity.java b/app/src/main/java/xwh/sound/MainActivity.java index 327a6b3..c11d69c 100644 --- a/app/src/main/java/xwh/sound/MainActivity.java +++ b/app/src/main/java/xwh/sound/MainActivity.java @@ -14,6 +14,7 @@ import android.widget.TextView; import android.widget.Toast; +import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; @@ -82,7 +83,11 @@ public void run() { //PCMPlayer.start(CodeBook.freqsWave[0], 2000); - testBase64(); + try { + testBase64(); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } //testCodes(); @@ -113,7 +118,11 @@ public void onClick(View v) { new Thread(new Runnable() { @Override public void run() { - record.start(); + try { + record.start(); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } } }).start(); } @@ -131,7 +140,7 @@ public void onClick(View v) { public void run() { try { int hz = Integer.parseInt(inputHz.getText().toString()); - PCMPlayer.getInstance().start(hz, 2000); + PCMPlayer.getInstance().start(hz, 5000); PCMPlayer.getInstance().stop(); } catch (NumberFormatException e) { @@ -146,10 +155,10 @@ public void run() { } - private void testBase64() { + private void testBase64() throws UnsupportedEncodingException { String test = inputHz.getText().toString(); String str = Base64.encodeToString(test.getBytes(), Base64.NO_WRAP | Base64.NO_PADDING); - List codes = Encoder.convertTextToCodes(str); + List codes = Encoder.convertTextToCode_74hamming(str); Log.d("Encode", "encodeArray:" + codes); PCMPlayer.getInstance().start(codes, 50); diff --git a/app/src/main/java/xwh/sound/PCMPlayer.java b/app/src/main/java/xwh/sound/PCMPlayer.java index 756aec4..8ea7f9a 100644 --- a/app/src/main/java/xwh/sound/PCMPlayer.java +++ b/app/src/main/java/xwh/sound/PCMPlayer.java @@ -115,7 +115,7 @@ public void start(List codeIndexs, int during){ byte[] waveAll = new byte[lengthItem * codeIndexs.size()]; for(int i=0; i Date: Sat, 10 Dec 2022 11:11:56 +0800 Subject: [PATCH 02/12] Fix errorbit problem in decoder.java --- app/src/main/java/xwh/sound/Decoder.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/xwh/sound/Decoder.java b/app/src/main/java/xwh/sound/Decoder.java index 57646cb..32c9f9d 100644 --- a/app/src/main/java/xwh/sound/Decoder.java +++ b/app/src/main/java/xwh/sound/Decoder.java @@ -242,7 +242,7 @@ public void decodeFre_74hamming(int fre) throws UnsupportedEncodingException { if (codeQueue.size() >= 7) { int c = 0; int s = 0; - for (int i = 0; i < 7; ++i) { + for (int i = 0; i < 7 && !codeQueue.isEmpty(); ++i) { s += (codeQueue.poll() << (2 * i)); } int [] code = new int [7]; @@ -251,9 +251,11 @@ public void decodeFre_74hamming(int fre) throws UnsupportedEncodingException { for (int j = 0; j < 7; ++j) { code[j] = (curr7bit >> j) & 0x1; } - int errorBit = code[0] + code[1] << 1 + code[3] << 2; - code[errorBit] = ~code[errorBit]; - int curr4bit = code[2] + code[4] << 1 + code[5] << 2 + code[6] << 3; + int errorBit = code[0] + (code[1] << 1) + (code[3] << 2); + if (errorBit != 0) { + code[errorBit-1] = ~code[errorBit-1]; + } + int curr4bit = code[2] + (code[4] << 1) + (code[5] << 2) + (code[6] << 3); c += (curr4bit << (4 * i)); } codeIndexs.add(c); From 1048fc8a06902d682bbabecdd4eeb5b7143bd5cf Mon Sep 17 00:00:00 2001 From: Elliott Zhang <898016731@qq.com> Date: Sat, 10 Dec 2022 17:25:10 +0800 Subject: [PATCH 03/12] Fix duplicate problem --- app/src/main/java/xwh/sound/CodeBook.java | 41 ++++++------- app/src/main/java/xwh/sound/Decoder.java | 67 +++++++++------------- app/src/main/java/xwh/sound/Encoder.java | 31 +++++----- app/src/main/java/xwh/sound/PCMPlayer.java | 17 +----- app/src/main/java/xwh/sound/Record.java | 26 +-------- 5 files changed, 70 insertions(+), 112 deletions(-) diff --git a/app/src/main/java/xwh/sound/CodeBook.java b/app/src/main/java/xwh/sound/CodeBook.java index 77042e5..cb41de1 100644 --- a/app/src/main/java/xwh/sound/CodeBook.java +++ b/app/src/main/java/xwh/sound/CodeBook.java @@ -1,5 +1,5 @@ package xwh.sound; - +import android.util.Log; /** * 编码字典表 * 用声音频率来表达不同的字符,理想的做法是每个字符对应一段指定频率的声音。但是声音容易被干扰,只能采用划分大的频率段的方式进行编码。 @@ -22,9 +22,13 @@ public class CodeBook { public static int freqDistance = 50; // 两个频率之间的间距 public static final int START_INDEX_HAMMING = 4; public static final int END_INDEX_HAMMING = 5; + public static final int DUPLICATE_INDEX_1_HAMMING = 6; + public static final int DUPLICATE_INDEX_2_HAMMING = 7; public static final int BASE_FREQ = 10000; - public static final int START_FREQ = BASE_FREQ + freqDistance * 16; - public static final int END_FREQ = BASE_FREQ + freqDistance * 20; + public static final int START_FREQ_HAMMING = BASE_FREQ + freqDistance * START_INDEX_HAMMING; + public static final int END_FREQ_HAMMING = BASE_FREQ + freqDistance * END_INDEX_HAMMING; + public static final int DUP1_FREQ_HAMMING = BASE_FREQ + freqDistance * DUPLICATE_INDEX_1_HAMMING; + public static final int DUP2_FREQ_HAMMING = BASE_FREQ + freqDistance * DUPLICATE_INDEX_2_HAMMING; /** * 两个book字典码来组成下面每个字符的编码 @@ -49,13 +53,19 @@ public static int encode(int index) { public static int encode_74hamming(int index) { if (index == START_INDEX_HAMMING) { - return START_FREQ; + return START_FREQ_HAMMING; } if (index == END_INDEX_HAMMING) { - return END_FREQ; + return END_FREQ_HAMMING; + } + if (index == DUP1_FREQ_HAMMING) { + return DUP1_FREQ_HAMMING; + } + if (index == DUP2_FREQ_HAMMING) { + return DUP2_FREQ_HAMMING; } int freq_idx = _inv_gray(index, 2); - return freqsWave[freq_idx * 3 + 1]; + return freqsWave[freq_idx]; } private static int _gray(int value, int bitNum) { @@ -73,6 +83,7 @@ private static int _inv_gray(int value, int bitNum) { for (int i = bitNum - 2; i >= 0; i--) { res += (((value >> i) & 0x1) ^ ((res >> (i + 1)) & 0x1)) << i; } + //Log.i("_inv_gray", "before: " + value + " after: " + res); return res; } @@ -97,22 +108,12 @@ public static int decode(int fre) { return index; } - public static int decode_codeword(int fre) { - + public static int decode_hamming(int fre) { int index = decode(fre); - if (index == 11) { - if (Math.abs(fre - START_FREQ) < Math.abs(fre - freqsWave[11])) { - if (Math.abs(fre - START_FREQ) < Math.abs(fre - END_FREQ)) { - return START_INDEX_HAMMING; - } else { - return END_INDEX_HAMMING; - } - } - } - if (index != -1) { - index = index / 3; - index = _gray(index, 2); + if (index == -1 || index >= START_INDEX_HAMMING) { + return index; } + index = _gray(index, 2); return index; } } diff --git a/app/src/main/java/xwh/sound/Decoder.java b/app/src/main/java/xwh/sound/Decoder.java index 32c9f9d..369a3f0 100644 --- a/app/src/main/java/xwh/sound/Decoder.java +++ b/app/src/main/java/xwh/sound/Decoder.java @@ -7,6 +7,7 @@ import java.io.UnsupportedEncodingException; import java.util.ArrayList; +import java.util.Deque; import java.util.LinkedList; import java.util.List; import java.util.Queue; @@ -30,7 +31,8 @@ public class Decoder { private int countEndCode = 0; private boolean startDecode; private ArrayList codeIndexs; - private Queue codeQueue; + private Deque codeQueue; + private int queueTop; private Handler mHandler; @@ -45,6 +47,7 @@ public Decoder(Handler handler) { this.mHandler = handler; codeIndexs = new ArrayList<>(); codeQueue = new LinkedList(); + queueTop = -1; } public void countFreq(short[] datas, int sampleStep) { @@ -69,17 +72,14 @@ public void countFreq(short[] datas, int sampleStep) { */ public int countFreq1(short[] datas, int sampleStep) throws UnsupportedEncodingException { int itemStep = datas.length / COUNT_STEP_SIZE; - int waveState = -1; int stepCount = 0; int bufferFreqCount = 0; int currentFreq = 0; for(short sample : datas) { - if (waveState == -1) { waveState = sample > 0 ? UP : DOWN; } - // 根据波形上下计算频率 if (waveState == UP) { if (sample < -10) { @@ -92,8 +92,6 @@ public int countFreq1(short[] datas, int sampleStep) throws UnsupportedEncodingE waveCount++; } } - - /** * 并不是每个buffer取一次频率,而是在一段buffer中获取小段,每个小段进行解码 */ @@ -102,43 +100,19 @@ public int countFreq1(short[] datas, int sampleStep) throws UnsupportedEncodingE //waveCount = waveCount / 2; // 一上一下表示一个波形,所以要除以2 bufferFreqCount += waveCount; currentFreq = waveCount * COUNT_STEP_SIZE * sampleStep / 2; // 这里根据每小段得出频率(一秒内波形次数) - decodeFre_74hamming(currentFreq); - stepCount = 0; waveCount = 0; } - } - - if (mHandler != null) { - - /*if (listBufferFreq.size() >= sampleStep) { - listBufferFreq.remove(0); - } - listBufferFreq.add(bufferFreqCount); - - int allCount = 0; - for(int bCount : listBufferFreq) { // 累计最近1s采样得到频率 - allCount += bCount; - } - - int freq = allCount / 2; // 一上一下表示一个波形,所以要除以2*/ - - //int freq = currentFreq; int freq = bufferFreqCount * sampleStep / 2; // 一上一下表示一个波形,所以要除以2 - Message msg = mHandler.obtainMessage(); msg.what = MainActivity.MSG_CURRENT_FREQ; msg.obj = freq + ""; mHandler.sendMessage(msg); - - Log.i("Record", "fre:" + freq); - } - return currentFreq; } @@ -206,23 +180,26 @@ public void decodeFre(int fre) { public void decodeFre_74hamming(int fre) throws UnsupportedEncodingException { - int codeIndex = CodeBook.decode_codeword(fre); - + int codeIndex = CodeBook.decode_hamming(fre); if (codeIndex == -1) { return; } else if (codeIndex == CodeBook.START_INDEX_HAMMING) { - countEndCode = 0; - startDecode = true; - codeIndexs.clear(); - lastStartTime = System.currentTimeMillis(); + if (startDecode) { + return; + } + countStartCode++; + if (countStartCode >= 2) { + countEndCode = 0; + startDecode = true; + codeIndexs.clear(); + lastStartTime = System.currentTimeMillis(); + } } else if (startDecode) { countStartCode = 0; - if (System.currentTimeMillis() - lastStartTime > TIMEOUT) { startDecode = false; return; } - if (codeIndex == CodeBook.END_INDEX_HAMMING) { countEndCode++; if (countEndCode >= 2) { @@ -238,12 +215,22 @@ public void decodeFre_74hamming(int fre) throws UnsupportedEncodingException { } } else { countEndCode = 0; - codeQueue.add(codeIndex); + if (queueTop != -1 && codeIndex == queueTop) { + return; + } else { + queueTop = codeIndex; + if (codeIndex == CodeBook.DUPLICATE_INDEX_2_HAMMING || codeIndex == CodeBook.DUPLICATE_INDEX_1_HAMMING) { + int value = codeQueue.getLast(); + codeQueue.add(value); + } else { + codeQueue.add(codeIndex); + } + } if (codeQueue.size() >= 7) { int c = 0; int s = 0; for (int i = 0; i < 7 && !codeQueue.isEmpty(); ++i) { - s += (codeQueue.poll() << (2 * i)); + s += (codeQueue.pollFirst() << (2 * i)); } int [] code = new int [7]; for (int i = 0; i < 2; ++i) { diff --git a/app/src/main/java/xwh/sound/Encoder.java b/app/src/main/java/xwh/sound/Encoder.java index 6ee69d5..c054faf 100644 --- a/app/src/main/java/xwh/sound/Encoder.java +++ b/app/src/main/java/xwh/sound/Encoder.java @@ -17,48 +17,40 @@ public class Encoder { public static List convertTextToCodes(String text) { List mCodes = new ArrayList<>(); if (!TextUtils.isEmpty(text)) { - mCodes.add(CodeBook.START_INDEX); //开始 mCodes.add(CodeBook.START_INDEX); //开始(防止丢失,重复添加两组) int len = text.length(); for (int i = 0; i < len; ++i) { // 内容 char ch = text.charAt(i); - int[] indexs = Utils.char2Indexs(ch); if (indexs != null) { mCodes.add(indexs[0]); mCodes.add(indexs[1]); } else { - //ret = false; Log.d(TAG, "invalidate char:" + ch); - // break; } } // 对内容进行crc校验 int[] crc = Utils.crc(mCodes, 2, mCodes.size()-1); mCodes.add(crc[0]); mCodes.add(crc[1]); - mCodes.add(CodeBook.END_INDEX); //结束 mCodes.add(CodeBook.END_INDEX); //结束(防止丢失,重复添加两组) - // 替换内容相邻相同字符 for (int i=mCodes.size()-3; i>2; i--) { if (mCodes.get(i) == mCodes.get(i-1)) { mCodes.set(i, i%2 == 0 ? CodeBook.DUPLICATE_INDEX_1 : CodeBook.DUPLICATE_INDEX_2); } } - } - return mCodes; } public static List convertTextToCode_74hamming(String text) throws UnsupportedEncodingException { byte[] bytes = text.getBytes("UTF-8"); List mCodes = new ArrayList<>(); - mCodes.add(4); - mCodes.add(4); + mCodes.add(CodeBook.START_INDEX_HAMMING); + mCodes.add(CodeBook.START_INDEX_HAMMING); int[] temp = new int[14]; StringBuilder binaryString = new StringBuilder(); // little endian @@ -78,13 +70,26 @@ public static List convertTextToCode_74hamming(String text) throws Unsu temp[1 + i * 7] = (d1 ^ d3 ^ d4); temp[3 + i * 7] = (d2 ^ d3 ^ d4); } + int last_code = -1; + boolean odd = true; for (int i = 0; i < 7; ++i) { int code = temp[i] + (temp[i+1] << 1); - mCodes.add(code); + if (code != last_code) { + odd = true; + mCodes.add(code); + last_code = code; + } else if (odd) { + mCodes.add(CodeBook.DUPLICATE_INDEX_1_HAMMING); + odd = false; + } else { + mCodes.add(CodeBook.DUPLICATE_INDEX_2_HAMMING); + odd = true; + } } } - mCodes.add(5); - mCodes.add(5); + mCodes.add(CodeBook.END_INDEX_HAMMING); + mCodes.add(CodeBook.END_INDEX_HAMMING); + //Log.i("mCodes", "before: " + text + " after: " + mCodes); return mCodes; } } diff --git a/app/src/main/java/xwh/sound/PCMPlayer.java b/app/src/main/java/xwh/sound/PCMPlayer.java index 8ea7f9a..28dbafb 100644 --- a/app/src/main/java/xwh/sound/PCMPlayer.java +++ b/app/src/main/java/xwh/sound/PCMPlayer.java @@ -3,6 +3,7 @@ import android.media.AudioFormat; import android.media.AudioManager; import android.media.AudioTrack; +import android.util.Log; import java.util.List; @@ -16,8 +17,8 @@ public class PCMPlayer { public final static int DEFAULT_SAMPLE_RATE = 44100; private AudioTrack mAudioTrack; - private static PCMPlayer instance; + public static PCMPlayer getInstance() { if (instance == null) { instance = new PCMPlayer(); @@ -29,7 +30,6 @@ private void init() { int minBufSize = AudioTrack.getMinBufferSize(DEFAULT_SAMPLE_RATE, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT); - mAudioTrack=new AudioTrack(AudioManager.STREAM_MUSIC, DEFAULT_SAMPLE_RATE, AudioFormat.CHANNEL_OUT_MONO, // CHANNEL_CONFIGURATION_MONO, @@ -50,7 +50,6 @@ public byte[] sin(byte[] wave, int start, int freq, int length) { if(freq % 2 == 1) { // 偶数(奇数会有噪音,暂时没找到原因) freq += 1; } - for (int i = 0; i < length; i+=2) { int index = i+start; if (freq == 0) { @@ -74,23 +73,18 @@ public void start(int hz, int during){ if (isPlaying()) { return; } - int length = DEFAULT_SAMPLE_RATE * during / 1000 * 2; - //生成正弦波 byte[] wave = new byte[length]; - if(hz>0){ if (mAudioTrack == null) { init(); } mAudioTrack.play(); - sin(wave, 0, hz, length); }else{ sin(wave, 0, 0, length); } - mAudioTrack.write(wave, 0, length); } @@ -104,30 +98,23 @@ public void start(List codeIndexs, int during){ if (isPlaying()) { return; } - if (mAudioTrack == null) { init(); } mAudioTrack.play(); - int lengthItem = DEFAULT_SAMPLE_RATE * during / 1000 * 2; - byte[] waveAll = new byte[lengthItem * codeIndexs.size()]; - for(int i=0; i minBufferSize) { - buffer = new byte[mBufferSize]; - mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, DEFAULT_SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, mBufferSize); - mAudioRecord.startRecording(); - short[] waveDatas = new short[mBufferSize/2]; - while (isRecording()) { readSize = mAudioRecord.read(buffer, 0, mBufferSize); if (AudioRecord.ERROR_INVALID_OPERATION != readSize) { short sh; - for (int i = 0; i < mBufferSize; i+=2) { - short sh1 = buffer[i]; sh1 &= 0xff; short sh2 = buffer[i+1]; sh2 <<= 8; sh = (short) ((sh1) | (sh2)); // 16Bit,两个字节一个采样值。 - waveDatas[i/2] = sh; - } - mDecoder.countFreq1(waveDatas, SAMPLE_STEP); - } - } } - } - - public void stopRecord() { if (mAudioRecord != null) { mAudioRecord.stop(); From 2f532320115298bec1d23bf1b92b821589224e25 Mon Sep 17 00:00:00 2001 From: Elliott Zhang <898016731@qq.com> Date: Tue, 13 Dec 2022 11:50:14 +0800 Subject: [PATCH 04/12] Fix bugs in encoder --- app/src/main/java/xwh/sound/CodeBook.java | 2 +- app/src/main/java/xwh/sound/Decoder.java | 22 ++++++++++++++++------ app/src/main/java/xwh/sound/Encoder.java | 9 +++++++-- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/xwh/sound/CodeBook.java b/app/src/main/java/xwh/sound/CodeBook.java index cb41de1..e813a2b 100644 --- a/app/src/main/java/xwh/sound/CodeBook.java +++ b/app/src/main/java/xwh/sound/CodeBook.java @@ -19,7 +19,7 @@ public class CodeBook { public static final int START_INDEX = DUPLICATE_INDEX_2 + 1; // 开始标记 public static final int END_INDEX = START_INDEX + 1; // 结束标记 - public static int freqDistance = 50; // 两个频率之间的间距 + public static int freqDistance = 500; // 两个频率之间的间距 public static final int START_INDEX_HAMMING = 4; public static final int END_INDEX_HAMMING = 5; public static final int DUPLICATE_INDEX_1_HAMMING = 6; diff --git a/app/src/main/java/xwh/sound/Decoder.java b/app/src/main/java/xwh/sound/Decoder.java index 369a3f0..d3002e6 100644 --- a/app/src/main/java/xwh/sound/Decoder.java +++ b/app/src/main/java/xwh/sound/Decoder.java @@ -32,6 +32,7 @@ public class Decoder { private boolean startDecode; private ArrayList codeIndexs; private Deque codeQueue; + private Deque debugQueue; private int queueTop; private Handler mHandler; @@ -39,7 +40,7 @@ public class Decoder { private long lastStartTime; private static final int TIMEOUT = 10000; - private static final int COUNT_STEP_SIZE = 10; + private static final int COUNT_STEP_SIZE = 5; private FFT fft = new FFT(); @@ -47,6 +48,7 @@ public Decoder(Handler handler) { this.mHandler = handler; codeIndexs = new ArrayList<>(); codeQueue = new LinkedList(); + debugQueue = new LinkedList(); queueTop = -1; } @@ -111,7 +113,9 @@ public int countFreq1(short[] datas, int sampleStep) throws UnsupportedEncodingE msg.what = MainActivity.MSG_CURRENT_FREQ; msg.obj = freq + ""; mHandler.sendMessage(msg); - Log.i("Record", "fre:" + freq); + if (freq > CodeBook.START_FREQ_HAMMING) { + Log.i("Record", "fre:" + freq); + } } return currentFreq; } @@ -208,6 +212,7 @@ public void decodeFre_74hamming(int fre) throws UnsupportedEncodingException { List cleanIndexs = dummyCodeIndexs(codeIndexs); Log.i("Record", "clearCodeIndexs:" + cleanIndexs); + Log.i("Record", "fracs: " + debugQueue.toString()); if (cleanIndexs.size() > 0) { showResult_74hamming(cleanIndexs); @@ -222,8 +227,10 @@ public void decodeFre_74hamming(int fre) throws UnsupportedEncodingException { if (codeIndex == CodeBook.DUPLICATE_INDEX_2_HAMMING || codeIndex == CodeBook.DUPLICATE_INDEX_1_HAMMING) { int value = codeQueue.getLast(); codeQueue.add(value); + debugQueue.add(value); } else { codeQueue.add(codeIndex); + debugQueue.add(codeIndex); } } if (codeQueue.size() >= 7) { @@ -238,9 +245,12 @@ public void decodeFre_74hamming(int fre) throws UnsupportedEncodingException { for (int j = 0; j < 7; ++j) { code[j] = (curr7bit >> j) & 0x1; } - int errorBit = code[0] + (code[1] << 1) + (code[3] << 2); + int ch1 = code[0] ^ code[2] ^ code[4] ^ code[6]; + int ch2 = code[1] ^ code[2] ^ code[5] ^ code[6]; + int ch3 = code[3] ^ code[4] ^ code[5] ^ code[6]; + int errorBit = ch1 + (ch2 << 1) + (ch3 << 2); if (errorBit != 0) { - code[errorBit-1] = ~code[errorBit-1]; + code[errorBit-1] = 1 - code[errorBit-1]; } int curr4bit = code[2] + (code[4] << 1) + (code[5] << 2) + (code[6] << 3); c += (curr4bit << (4 * i)); @@ -361,11 +371,11 @@ private String showResult_74hamming(List codeIndexs) throws Unsupported if (mHandler != null) { Message msg = mHandler.obtainMessage(); msg.what = MainActivity.MSG_RESULT; - msg.obj = codeIndexs.toString() + "\n" + text; + msg.obj = debugQueue.toString() + "\n" + text; mHandler.sendMessage(msg); } - Log.d(TAG, "showResult:" + "____" + re +"____"+ text); + Log.d(TAG, "showResult:" + "____" + codeIndexs +"____"+ text); return text; diff --git a/app/src/main/java/xwh/sound/Encoder.java b/app/src/main/java/xwh/sound/Encoder.java index c054faf..04dbff0 100644 --- a/app/src/main/java/xwh/sound/Encoder.java +++ b/app/src/main/java/xwh/sound/Encoder.java @@ -5,6 +5,7 @@ import java.io.UnsupportedEncodingException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; /** @@ -55,8 +56,11 @@ public static List convertTextToCode_74hamming(String text) throws Unsu StringBuilder binaryString = new StringBuilder(); // little endian for (byte b: bytes) { + int cb = b; + Log.i("byte", String.valueOf(cb)); for (int i = 0; i < 2; ++i) { int curr = (b >> (i * 4)) & 0xf; + Log.i("curr", String.valueOf(curr)); int d1 = curr & 1; int d2 = (curr >> 1) & 1; int d3 = (curr >> 2) & 1; @@ -70,10 +74,11 @@ public static List convertTextToCode_74hamming(String text) throws Unsu temp[1 + i * 7] = (d1 ^ d3 ^ d4); temp[3 + i * 7] = (d2 ^ d3 ^ d4); } + Log.i("bitarray", Arrays.toString(temp)); int last_code = -1; boolean odd = true; for (int i = 0; i < 7; ++i) { - int code = temp[i] + (temp[i+1] << 1); + int code = temp[i*2] + (temp[i*2+1] << 1); if (code != last_code) { odd = true; mCodes.add(code); @@ -89,7 +94,7 @@ public static List convertTextToCode_74hamming(String text) throws Unsu } mCodes.add(CodeBook.END_INDEX_HAMMING); mCodes.add(CodeBook.END_INDEX_HAMMING); - //Log.i("mCodes", "before: " + text + " after: " + mCodes); + Log.i("mCodes", "before: " + text + " after: " + mCodes); return mCodes; } } From 20477d74225e677e416ff887f34834c0c445f493 Mon Sep 17 00:00:00 2001 From: suchang <971622748@qq.com> Date: Wed, 14 Dec 2022 00:44:57 +0800 Subject: [PATCH 05/12] add webpage --- app/build.gradle | 11 ++-- app/src/main/AndroidManifest.xml | 43 ++++++++----- app/src/main/java/xwh/sound/MainActivity.java | 63 +++++++++++++------ app/src/main/java/xwh/sound/webpage.java | 39 ++++++++++++ app/src/main/res/layout/activity_webpage.xml | 13 ++++ build.gradle | 4 +- 6 files changed, 132 insertions(+), 41 deletions(-) create mode 100644 app/src/main/java/xwh/sound/webpage.java create mode 100644 app/src/main/res/layout/activity_webpage.xml diff --git a/app/build.gradle b/app/build.gradle index 1d25c1d..d1bd8d7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,11 +1,11 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 26 + compileSdkVersion 28 defaultConfig { applicationId "sound.xwh.communication" - minSdkVersion 15 - targetSdkVersion 26 + minSdkVersion 16 + targetSdkVersion 28 versionCode 1 versionName "1.0" } @@ -19,5 +19,8 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'com.android.support:appcompat-v7:26.1.0' + implementation 'com.android.support:appcompat-v7:28.0.0' + implementation 'com.android.support.constraint:constraint-layout:2.0.4' + // https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient + implementation 'org.apache.httpcomponents:httpclient:4.1' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2d38189..673f53a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,23 +1,32 @@ - + - + + - - - - + + + + + + + - - - - + + + + \ No newline at end of file diff --git a/app/src/main/java/xwh/sound/MainActivity.java b/app/src/main/java/xwh/sound/MainActivity.java index c11d69c..9c750dc 100644 --- a/app/src/main/java/xwh/sound/MainActivity.java +++ b/app/src/main/java/xwh/sound/MainActivity.java @@ -1,6 +1,8 @@ package xwh.sound; +import android.annotation.SuppressLint; import android.content.Context; +import android.content.Intent; import android.media.AudioManager; import android.os.Bundle; import android.os.Handler; @@ -9,14 +11,23 @@ import android.util.Base64; import android.util.Log; import android.view.View; +import android.webkit.WebView; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; +import android.webkit.WebViewClient; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; +import java.util.LinkedList; +import java.util.Queue; + +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.DefaultHttpClient; public class MainActivity extends AppCompatActivity { @@ -34,6 +45,9 @@ public class MainActivity extends AppCompatActivity { private Button btRecord; + private Queue url_queue = new LinkedList(); + + @SuppressLint("SetJavaScriptEnabled") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -48,6 +62,7 @@ public void handleMessage(Message msg) { String re = (String) msg.obj; if (msg.what == MSG_RESULT) { recordResult.append(re + "\n"); + url_queue.add(re); } else if (msg.what == MSG_CURRENT_FREQ) { currentFreq.setText(re + "HZ"); } @@ -125,33 +140,43 @@ public void run() { } } }).start(); + + // String name = "http://www.baidu.com/"; + new Thread(new Runnable() { + @Override + public void run() { + boolean flag = true; + while(flag){ + if (url_queue.size() > 0){ + String name = url_queue.poll(); + Runnable networkTask = () -> { + try{ + HttpGet httpRequest = new HttpGet(name); + HttpClient httpclient = new DefaultHttpClient(); + HttpResponse response = httpclient.execute(httpRequest); + if (response.getStatusLine().getStatusCode() == 200) { + Intent intent = new Intent(MainActivity.this,webpage.class); + intent.putExtra("context", name); + startActivity(intent); + } + }catch(Exception e){ + e.printStackTrace(); + } + }; + new Thread(networkTask).start(); + } + } + } + }).start(); + } } }); - findViewById(R.id.bt_play).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - // 播放声音在主线程会阻塞界面刷新,要放在子线程中 - new Thread(new Runnable() { - @Override - public void run() { - try { - int hz = Integer.parseInt(inputHz.getText().toString()); - PCMPlayer.getInstance().start(hz, 5000); - - PCMPlayer.getInstance().stop(); - } catch (NumberFormatException e) { - Toast.makeText(MainActivity.this, "Please input frequency", Toast.LENGTH_SHORT).show(); - } - } - }).start(); - } - }); } diff --git a/app/src/main/java/xwh/sound/webpage.java b/app/src/main/java/xwh/sound/webpage.java new file mode 100644 index 0000000..1b4ddf4 --- /dev/null +++ b/app/src/main/java/xwh/sound/webpage.java @@ -0,0 +1,39 @@ +package xwh.sound; + +import android.annotation.SuppressLint; +import android.content.Intent; +import android.os.Handler; +import android.os.Message; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import android.widget.TextView; + +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.DefaultHttpClient; + +public class webpage extends AppCompatActivity { + + + private WebView web; + @SuppressLint("SetJavaScriptEnabled") + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_webpage); + Intent intent=getIntent(); + String name=intent.getStringExtra("context"); + + web = this.findViewById(R.id.web_view); + web.getSettings().setJavaScriptEnabled(true); + web.loadUrl(name); + web.setWebViewClient(new WebViewClient()); + + + + + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_webpage.xml b/app/src/main/res/layout/activity_webpage.xml new file mode 100644 index 0000000..0c6267f --- /dev/null +++ b/app/src/main/res/layout/activity_webpage.xml @@ -0,0 +1,13 @@ + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 0acb022..d4d3baf 100644 --- a/build.gradle +++ b/build.gradle @@ -10,11 +10,13 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:4.2.0' - + + // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } + } allprojects { From 94f3774a01ecc37df3c885faf89b4dd6883dda45 Mon Sep 17 00:00:00 2001 From: Elliott Zhang <898016731@qq.com> Date: Thu, 15 Dec 2022 20:09:34 +0800 Subject: [PATCH 06/12] keep update --- app/src/main/java/xwh/sound/CodeBook.java | 17 ++++++++-------- app/src/main/java/xwh/sound/Decoder.java | 20 +++++++++++-------- app/src/main/java/xwh/sound/MainActivity.java | 2 +- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/xwh/sound/CodeBook.java b/app/src/main/java/xwh/sound/CodeBook.java index e813a2b..03ef6f5 100644 --- a/app/src/main/java/xwh/sound/CodeBook.java +++ b/app/src/main/java/xwh/sound/CodeBook.java @@ -21,10 +21,10 @@ public class CodeBook { public static int freqDistance = 500; // 两个频率之间的间距 public static final int START_INDEX_HAMMING = 4; - public static final int END_INDEX_HAMMING = 5; - public static final int DUPLICATE_INDEX_1_HAMMING = 6; + public static final int END_INDEX_HAMMING = 6; + public static final int DUPLICATE_INDEX_1_HAMMING = 5; public static final int DUPLICATE_INDEX_2_HAMMING = 7; - public static final int BASE_FREQ = 10000; + public static final int BASE_FREQ = 2000; public static final int START_FREQ_HAMMING = BASE_FREQ + freqDistance * START_INDEX_HAMMING; public static final int END_FREQ_HAMMING = BASE_FREQ + freqDistance * END_INDEX_HAMMING; public static final int DUP1_FREQ_HAMMING = BASE_FREQ + freqDistance * DUPLICATE_INDEX_1_HAMMING; @@ -65,7 +65,7 @@ public static int encode_74hamming(int index) { return DUP2_FREQ_HAMMING; } int freq_idx = _inv_gray(index, 2); - return freqsWave[freq_idx]; + return freqsWave[index]; } private static int _gray(int value, int bitNum) { @@ -110,10 +110,11 @@ public static int decode(int fre) { public static int decode_hamming(int fre) { int index = decode(fre); - if (index == -1 || index >= START_INDEX_HAMMING) { - return index; - } - index = _gray(index, 2); + //if (index == -1 || index >= START_INDEX_HAMMING) { + // return index; + //} + //index = _gray(index, 2); + if (index > DUPLICATE_INDEX_2_HAMMING) index = DUPLICATE_INDEX_2_HAMMING; return index; } } diff --git a/app/src/main/java/xwh/sound/Decoder.java b/app/src/main/java/xwh/sound/Decoder.java index d3002e6..20d5f75 100644 --- a/app/src/main/java/xwh/sound/Decoder.java +++ b/app/src/main/java/xwh/sound/Decoder.java @@ -34,13 +34,14 @@ public class Decoder { private Deque codeQueue; private Deque debugQueue; private int queueTop; + private int lastIndex; private Handler mHandler; private long lastStartTime; private static final int TIMEOUT = 10000; - private static final int COUNT_STEP_SIZE = 5; + private static final int COUNT_STEP_SIZE = 20; private FFT fft = new FFT(); @@ -50,6 +51,7 @@ public Decoder(Handler handler) { codeQueue = new LinkedList(); debugQueue = new LinkedList(); queueTop = -1; + lastIndex = -1; } public void countFreq(short[] datas, int sampleStep) { @@ -102,7 +104,7 @@ public int countFreq1(short[] datas, int sampleStep) throws UnsupportedEncodingE //waveCount = waveCount / 2; // 一上一下表示一个波形,所以要除以2 bufferFreqCount += waveCount; currentFreq = waveCount * COUNT_STEP_SIZE * sampleStep / 2; // 这里根据每小段得出频率(一秒内波形次数) - decodeFre_74hamming(currentFreq); + decodeFre(currentFreq); stepCount = 0; waveCount = 0; } @@ -194,6 +196,8 @@ public void decodeFre_74hamming(int fre) throws UnsupportedEncodingException { countStartCode++; if (countStartCode >= 2) { countEndCode = 0; + debugQueue.clear(); + codeQueue.clear(); startDecode = true; codeIndexs.clear(); lastStartTime = System.currentTimeMillis(); @@ -220,17 +224,17 @@ public void decodeFre_74hamming(int fre) throws UnsupportedEncodingException { } } else { countEndCode = 0; - if (queueTop != -1 && codeIndex == queueTop) { + if (lastIndex != -1 && codeIndex == lastIndex) { return; } else { - queueTop = codeIndex; - if (codeIndex == CodeBook.DUPLICATE_INDEX_2_HAMMING || codeIndex == CodeBook.DUPLICATE_INDEX_1_HAMMING) { - int value = codeQueue.getLast(); - codeQueue.add(value); - debugQueue.add(value); + lastIndex = codeIndex; + if (queueTop != -1 && (codeIndex == CodeBook.DUPLICATE_INDEX_2_HAMMING || codeIndex == CodeBook.DUPLICATE_INDEX_1_HAMMING)) { + codeQueue.add(queueTop); + debugQueue.add(queueTop); } else { codeQueue.add(codeIndex); debugQueue.add(codeIndex); + queueTop = codeIndex; } } if (codeQueue.size() >= 7) { diff --git a/app/src/main/java/xwh/sound/MainActivity.java b/app/src/main/java/xwh/sound/MainActivity.java index 9c750dc..773b51d 100644 --- a/app/src/main/java/xwh/sound/MainActivity.java +++ b/app/src/main/java/xwh/sound/MainActivity.java @@ -183,7 +183,7 @@ public void run() { private void testBase64() throws UnsupportedEncodingException { String test = inputHz.getText().toString(); String str = Base64.encodeToString(test.getBytes(), Base64.NO_WRAP | Base64.NO_PADDING); - List codes = Encoder.convertTextToCode_74hamming(str); + List codes = Encoder.convertTextToCodes(str); Log.d("Encode", "encodeArray:" + codes); PCMPlayer.getInstance().start(codes, 50); From b6198f2da6b48bc7f8efa3e93244f3453f9bcb0b Mon Sep 17 00:00:00 2001 From: Elliott Zhang <898016731@qq.com> Date: Thu, 15 Dec 2022 20:41:49 +0800 Subject: [PATCH 07/12] Change encoding policy --- app/src/main/java/xwh/sound/PCMPlayer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/xwh/sound/PCMPlayer.java b/app/src/main/java/xwh/sound/PCMPlayer.java index 28dbafb..c56a18c 100644 --- a/app/src/main/java/xwh/sound/PCMPlayer.java +++ b/app/src/main/java/xwh/sound/PCMPlayer.java @@ -105,7 +105,7 @@ public void start(List codeIndexs, int during){ int lengthItem = DEFAULT_SAMPLE_RATE * during / 1000 * 2; byte[] waveAll = new byte[lengthItem * codeIndexs.size()]; for(int i=0; i Date: Fri, 16 Dec 2022 00:39:07 +0800 Subject: [PATCH 08/12] Add Hamming Encoding over Sequence(Debug) --- app/src/main/java/xwh/sound/CodeBook.java | 8 +- app/src/main/java/xwh/sound/Decoder.java | 168 ++++++++++++++++-- app/src/main/java/xwh/sound/Encoder.java | 60 +++++++ app/src/main/java/xwh/sound/MainActivity.java | 4 +- 4 files changed, 219 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/xwh/sound/CodeBook.java b/app/src/main/java/xwh/sound/CodeBook.java index 03ef6f5..0450c7c 100644 --- a/app/src/main/java/xwh/sound/CodeBook.java +++ b/app/src/main/java/xwh/sound/CodeBook.java @@ -19,12 +19,14 @@ public class CodeBook { public static final int START_INDEX = DUPLICATE_INDEX_2 + 1; // 开始标记 public static final int END_INDEX = START_INDEX + 1; // 结束标记 - public static int freqDistance = 500; // 两个频率之间的间距 + public static final int SEP_INDEX = END_INDEX + 1; // 分割符 + + public static int freqDistance = 200; // 两个频率之间的间距 public static final int START_INDEX_HAMMING = 4; public static final int END_INDEX_HAMMING = 6; public static final int DUPLICATE_INDEX_1_HAMMING = 5; public static final int DUPLICATE_INDEX_2_HAMMING = 7; - public static final int BASE_FREQ = 2000; + public static final int BASE_FREQ = 5000; public static final int START_FREQ_HAMMING = BASE_FREQ + freqDistance * START_INDEX_HAMMING; public static final int END_FREQ_HAMMING = BASE_FREQ + freqDistance * END_INDEX_HAMMING; public static final int DUP1_FREQ_HAMMING = BASE_FREQ + freqDistance * DUPLICATE_INDEX_1_HAMMING; @@ -35,7 +37,7 @@ public class CodeBook { */ public final static String CONTENT_CODE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; // Base64编码 - public static int[] freqsWave = new int[12]; // 将声音频率划分成12段,每一段表示一个字典码。 + public static int[] freqsWave = new int[13]; // 将声音频率划分成12段,每一段表示一个字典码。 static { for(int i=0; i CodeBook.START_FREQ_HAMMING) { - Log.i("Record", "fre:" + freq); + //Log.i("Record", "fre:" + freq); } } return currentFreq; @@ -127,20 +127,14 @@ public int countFreq1(short[] datas, int sampleStep) throws UnsupportedEncodingE * @param fre */ public void decodeFre(int fre) { - int codeIndex = CodeBook.decode(fre); - if (codeIndex != -1) { - - Log.i("Record", "waveCount:" + waveCount + ", fre:" + fre + ", decode:" + codeIndex); - + //Log.i("Record", "waveCount:" + waveCount + ", fre:" + fre + ", decode:" + codeIndex); if (codeIndex == CodeBook.START_INDEX) { countEndCode = 0; - if (startDecode) { return; } - countStartCode++; if (countStartCode >= 2) { countStartCode = 0; @@ -150,27 +144,21 @@ public void decodeFre(int fre) { } } else if (startDecode) { countStartCode = 0; - if (System.currentTimeMillis() - lastStartTime > TIMEOUT) { startDecode = false; // 可能上一次结束码丢失,超时 return; } - if (codeIndex == CodeBook.END_INDEX) { countEndCode++; if (countEndCode >= 2) { countEndCode = 0; startDecode = false; List cleanIndexs = cleanCodeIndexs(codeIndexs); - Log.i("Record", "clearCodeIndexs:" + cleanIndexs); - if(cleanIndexs.size() > 0) { showResult(cleanIndexs); } - } - } else { countEndCode = 0; codeIndexs.add(codeIndex); @@ -179,8 +167,50 @@ public void decodeFre(int fre) { countStartCode = 0; countEndCode = 0; } + } + } - + public void decodeFre_SeqHamming(int fre) { + int codeIndex = CodeBook.decode(fre); + if (codeIndex != -1) { + //Log.i("Record", "waveCount:" + waveCount + ", fre:" + fre + ", decode:" + codeIndex); + if (codeIndex == CodeBook.START_INDEX) { + countEndCode = 0; + if (startDecode) { + return; + } + countStartCode++; + if (countStartCode >= 2) { + countStartCode = 0; + startDecode = true; + codeIndexs.clear(); + lastStartTime = System.currentTimeMillis(); + } + } else if (startDecode) { + countStartCode = 0; + if (System.currentTimeMillis() - lastStartTime > TIMEOUT) { + startDecode = false; // 可能上一次结束码丢失,超时 + return; + } + if (codeIndex == CodeBook.END_INDEX) { + countEndCode++; + if (countEndCode >= 2) { + countEndCode = 0; + startDecode = false; + List cleanIndexs = cleanCodeIndexs(codeIndexs); + Log.i("Record", "clearCodeIndexs:" + cleanIndexs); + if(cleanIndexs.size() > 0) { + showResult_SeqHamming(cleanIndexs); + } + } + } else { + countEndCode = 0; + codeIndexs.add(codeIndex); + } + } else { + countStartCode = 0; + countEndCode = 0; + } } } @@ -359,6 +389,112 @@ private String showResult(List indexs) { } + private String showResult_SeqHamming(List raw_indexs) { + List indexs = new ArrayList(); + if (raw_indexs.size() < 2) { + return null; + } + // 还原相邻相同字符 + while (raw_indexs.get(0) == CodeBook.DUPLICATE_INDEX_2 || raw_indexs.get(0) == CodeBook.DUPLICATE_INDEX_1) { + raw_indexs.remove(0); + } + int temp = raw_indexs.size(); + for (int i=raw_indexs.size()-1; i>=0; i--) { + if (raw_indexs.get(i) == CodeBook.DUPLICATE_INDEX_1 || raw_indexs.get(i) == CodeBook.DUPLICATE_INDEX_2) { + if (temp >= i) { + temp = i -1; + } + while(temp>0 && (raw_indexs.get(temp) == CodeBook.DUPLICATE_INDEX_1 || raw_indexs.get(temp) == CodeBook.DUPLICATE_INDEX_2)) { + temp --; + } + if (temp < 0) temp = 0; + raw_indexs.set(i, raw_indexs.get(temp)); + } + } + for (int i = 0; i < raw_indexs.size(); ++i) { + while (i < raw_indexs.size() && raw_indexs.get(i) == CodeBook.SEP_INDEX) { + i++; + } + int j = i; + while (j < raw_indexs.size() && raw_indexs.get(j) != CodeBook.SEP_INDEX) { + j++; + } + if (j > i) { + List sublist = new ArrayList<>(raw_indexs.subList(i, j)); + int[] corrected_units = correct(sublist); + for (int k = 0; k < 4; ++k) { + indexs.add(corrected_units[k]); + } + } + i = j; + } + StringBuilder mTextBuilder = new StringBuilder(); + for(int i=0; i frag) { + Log.d(TAG, "Received fragment: " + frag); + int[] indexs = new int[4]; + if (frag.size() < 7) { + Log.d(TAG, "Loss of units"); + while (frag.size() < 7) { + frag.add(0); + } + } + if (frag.size() > 7) { + Log.d(TAG, "Redundant of units"); + frag = frag.subList(0, 7); + } + if (frag.size() == 7) { + int pos = 0; + int chk1 = (frag.get(0) + frag.get(2) + frag.get(4) + frag.get(6)) % CodeBook.CODE_BOOK_LENGTH_CONTENT; + int chk2 = (frag.get(1) + frag.get(2) + frag.get(5) + frag.get(6)) % CodeBook.CODE_BOOK_LENGTH_CONTENT; + int chk3 = (frag.get(3) + frag.get(4) + frag.get(5) + frag.get(6)) % CodeBook.CODE_BOOK_LENGTH_CONTENT; + int offset = 0; + if (chk1 != 0) { + pos += 1; + offset = chk1; + } + if (chk2 != 0) { + pos += 2; + offset = chk1; + } + if (chk3 != 0) { + pos += 4; + offset = chk1; + } + if (pos != 0) { + pos -= 1; + int error_value = frag.get(pos); + frag.set(pos, (error_value + CodeBook.CODE_BOOK_LENGTH_CONTENT - offset) % CodeBook.CODE_BOOK_LENGTH_CONTENT); + } + Log.d(TAG, "Corrected fragment: " + frag); + indexs[0] = frag.get(2); + indexs[1] = frag.get(4); + indexs[2] = frag.get(5); + indexs[3] = frag.get(6); + } + return indexs; + } + private String showResult_74hamming(List codeIndexs) throws UnsupportedEncodingException { byte [] bytes = new byte[codeIndexs.size()]; for (int i = 0; i < codeIndexs.size(); ++i) { diff --git a/app/src/main/java/xwh/sound/Encoder.java b/app/src/main/java/xwh/sound/Encoder.java index 04dbff0..4446c61 100644 --- a/app/src/main/java/xwh/sound/Encoder.java +++ b/app/src/main/java/xwh/sound/Encoder.java @@ -47,6 +47,66 @@ public static List convertTextToCodes(String text) { return mCodes; } + public static List convertTextToCode_SeqHamming(String text) { + List mCodes = new ArrayList<>(); + Log.d(TAG, text); + if (!TextUtils.isEmpty(text)) { + mCodes.add(CodeBook.START_INDEX); //开始 + mCodes.add(CodeBook.START_INDEX); //开始(防止丢失,重复添加两组) + int len = text.length(); + if (len % 2 == 1) { + if (text.endsWith("0")) { + text = text.concat("1"); + } else { + text = text.concat("0"); + } + } else { + if (text.endsWith("0")) { + text = text.concat("11"); + } else { + text = text.concat("00"); + } + } + Log.d(TAG, text); + len = text.length(); + for (int i = 0; i < len; i+=2) { // 内容 + char ch1 = text.charAt(i); + char ch2 = text.charAt(i+1); + int[] indexs1 = Utils.char2Indexs(ch1); + int[] indexs2 = Utils.char2Indexs(ch2); + int chk1; + int chk2; + int chk3; + if (indexs1 != null && indexs2 != null) { + chk1 = (CodeBook.CODE_BOOK_LENGTH_CONTENT - ((indexs1[0] + indexs1[1] + indexs2[1]) % CodeBook.CODE_BOOK_LENGTH_CONTENT)) % CodeBook.CODE_BOOK_LENGTH_CONTENT; + chk2 = (CodeBook.CODE_BOOK_LENGTH_CONTENT - ((indexs1[0] + indexs2[0] + indexs2[1]) % CodeBook.CODE_BOOK_LENGTH_CONTENT)) % CodeBook.CODE_BOOK_LENGTH_CONTENT; + chk3 = (CodeBook.CODE_BOOK_LENGTH_CONTENT - ((indexs1[1] + indexs2[0] + indexs2[1]) % CodeBook.CODE_BOOK_LENGTH_CONTENT)) % CodeBook.CODE_BOOK_LENGTH_CONTENT; + mCodes.add(chk1); + mCodes.add(chk2); + mCodes.add(indexs1[0]); + mCodes.add(chk3); + mCodes.add(indexs1[1]); + mCodes.add(indexs2[0]); + mCodes.add(indexs2[1]); + mCodes.add(CodeBook.SEP_INDEX); + mCodes.add(CodeBook.SEP_INDEX); + } else { + Log.d(TAG, "invalidate char:" + ch1 + " or " + ch2); + } + } + mCodes.add(CodeBook.END_INDEX); //结束 + mCodes.add(CodeBook.END_INDEX); //结束(防止丢失,重复添加两组) + Log.d(TAG, mCodes.toString()); + // 替换内容相邻相同字符 + for (int i=mCodes.size()-3; i>2; i--) { + if (mCodes.get(i) == mCodes.get(i-1) && mCodes.get(i) != CodeBook.SEP_INDEX) { + mCodes.set(i, i%2 == 0 ? CodeBook.DUPLICATE_INDEX_1 : CodeBook.DUPLICATE_INDEX_2); + } + } + } + return mCodes; + } + public static List convertTextToCode_74hamming(String text) throws UnsupportedEncodingException { byte[] bytes = text.getBytes("UTF-8"); List mCodes = new ArrayList<>(); diff --git a/app/src/main/java/xwh/sound/MainActivity.java b/app/src/main/java/xwh/sound/MainActivity.java index 773b51d..59d8636 100644 --- a/app/src/main/java/xwh/sound/MainActivity.java +++ b/app/src/main/java/xwh/sound/MainActivity.java @@ -183,10 +183,10 @@ public void run() { private void testBase64() throws UnsupportedEncodingException { String test = inputHz.getText().toString(); String str = Base64.encodeToString(test.getBytes(), Base64.NO_WRAP | Base64.NO_PADDING); - List codes = Encoder.convertTextToCodes(str); + List codes = Encoder.convertTextToCode_SeqHamming(str); Log.d("Encode", "encodeArray:" + codes); - PCMPlayer.getInstance().start(codes, 50); + PCMPlayer.getInstance().start(codes, 100); } private void testCodes() { From d50921299919b8bb7088e69e382736001ee63fb5 Mon Sep 17 00:00:00 2001 From: Elliott Zhang <898016731@qq.com> Date: Sat, 17 Dec 2022 00:19:48 +0800 Subject: [PATCH 09/12] Add SeqHamming encoding --- app/src/main/java/xwh/sound/CodeBook.java | 8 +- app/src/main/java/xwh/sound/Decoder.java | 94 ++++++++++++------- app/src/main/java/xwh/sound/MainActivity.java | 2 +- 3 files changed, 66 insertions(+), 38 deletions(-) diff --git a/app/src/main/java/xwh/sound/CodeBook.java b/app/src/main/java/xwh/sound/CodeBook.java index 0450c7c..a42c503 100644 --- a/app/src/main/java/xwh/sound/CodeBook.java +++ b/app/src/main/java/xwh/sound/CodeBook.java @@ -16,17 +16,17 @@ public class CodeBook { public static final int CODE_BOOK_LENGTH_CONTENT = 8; // 内容编码长度 (0-7为内容) public static final int DUPLICATE_INDEX_1 = CODE_BOOK_LENGTH_CONTENT; // 重复标记1 public static final int DUPLICATE_INDEX_2 = DUPLICATE_INDEX_1 +1; // 重复标记2 - public static final int START_INDEX = DUPLICATE_INDEX_2 + 1; // 开始标记 - public static final int END_INDEX = START_INDEX + 1; // 结束标记 + public static final int END_INDEX = DUPLICATE_INDEX_2 + 1; // 开始标记 + public static final int START_INDEX = END_INDEX + 1; // 结束标记 - public static final int SEP_INDEX = END_INDEX + 1; // 分割符 + public static final int SEP_INDEX = START_INDEX + 1; // 分割符 public static int freqDistance = 200; // 两个频率之间的间距 public static final int START_INDEX_HAMMING = 4; public static final int END_INDEX_HAMMING = 6; public static final int DUPLICATE_INDEX_1_HAMMING = 5; public static final int DUPLICATE_INDEX_2_HAMMING = 7; - public static final int BASE_FREQ = 5000; + public static final int BASE_FREQ = 10000; public static final int START_FREQ_HAMMING = BASE_FREQ + freqDistance * START_INDEX_HAMMING; public static final int END_FREQ_HAMMING = BASE_FREQ + freqDistance * END_INDEX_HAMMING; public static final int DUP1_FREQ_HAMMING = BASE_FREQ + freqDistance * DUPLICATE_INDEX_1_HAMMING; diff --git a/app/src/main/java/xwh/sound/Decoder.java b/app/src/main/java/xwh/sound/Decoder.java index 08e633c..a9e7883 100644 --- a/app/src/main/java/xwh/sound/Decoder.java +++ b/app/src/main/java/xwh/sound/Decoder.java @@ -411,6 +411,7 @@ private String showResult_SeqHamming(List raw_indexs) { raw_indexs.set(i, raw_indexs.get(temp)); } } + // 截取字符段进行译码 for (int i = 0; i < raw_indexs.size(); ++i) { while (i < raw_indexs.size() && raw_indexs.get(i) == CodeBook.SEP_INDEX) { i++; @@ -434,6 +435,11 @@ private String showResult_SeqHamming(List raw_indexs) { mTextBuilder.append(c); } String re = mTextBuilder.toString(); + if(re.endsWith("0")) { + re = re.replaceAll("0+$", ""); + } else if (re.endsWith("1")) { + re = re.replaceAll("1+$", ""); + } String text = null; try { text = new String(Base64.decode(re, Base64.NO_WRAP | Base64.NO_PADDING)); @@ -446,55 +452,77 @@ private String showResult_SeqHamming(List raw_indexs) { msg.obj = indexs.toString() + "\n" + text; mHandler.sendMessage(msg); } - Log.d(TAG, "showResult:" + re +"____"+ text); + Log.d(TAG, "showResult:" + re +" --> "+ text); return text; } + // 译码及纠错 private int[] correct(List frag) { - Log.d(TAG, "Received fragment: " + frag); + Log.d(TAG, "correct: " + frag); int[] indexs = new int[4]; if (frag.size() < 7) { Log.d(TAG, "Loss of units"); - while (frag.size() < 7) { - frag.add(0); + if (frag.size() < 6) { + while (frag.size() < 7) { + frag.add(0); + } + process_complete_pack(frag, indexs); + } else { + for (int i = 0; i < 6; ++i) { + frag.add(i, 0); + int error_pos = process_complete_pack(frag, indexs); + if (error_pos == -1 || error_pos == i) { + return indexs; + } + frag.remove(i); + } } + return indexs; } - if (frag.size() > 7) { + else if (frag.size() > 7) { Log.d(TAG, "Redundant of units"); frag = frag.subList(0, 7); + process_complete_pack(frag, indexs); } - if (frag.size() == 7) { - int pos = 0; - int chk1 = (frag.get(0) + frag.get(2) + frag.get(4) + frag.get(6)) % CodeBook.CODE_BOOK_LENGTH_CONTENT; - int chk2 = (frag.get(1) + frag.get(2) + frag.get(5) + frag.get(6)) % CodeBook.CODE_BOOK_LENGTH_CONTENT; - int chk3 = (frag.get(3) + frag.get(4) + frag.get(5) + frag.get(6)) % CodeBook.CODE_BOOK_LENGTH_CONTENT; - int offset = 0; - if (chk1 != 0) { - pos += 1; - offset = chk1; - } - if (chk2 != 0) { - pos += 2; - offset = chk1; - } - if (chk3 != 0) { - pos += 4; - offset = chk1; - } - if (pos != 0) { - pos -= 1; - int error_value = frag.get(pos); - frag.set(pos, (error_value + CodeBook.CODE_BOOK_LENGTH_CONTENT - offset) % CodeBook.CODE_BOOK_LENGTH_CONTENT); - } - Log.d(TAG, "Corrected fragment: " + frag); - indexs[0] = frag.get(2); - indexs[1] = frag.get(4); - indexs[2] = frag.get(5); - indexs[3] = frag.get(6); + else { + process_complete_pack(frag, indexs); } return indexs; } + private int process_complete_pack(List _frag, int[] indexs) { + Log.d(TAG, "process: " + _frag); + List frag = new ArrayList(_frag); + int pos = 0; + int chk1 = (frag.get(0) + frag.get(2) + frag.get(4) + frag.get(6)) % CodeBook.CODE_BOOK_LENGTH_CONTENT; + int chk2 = (frag.get(1) + frag.get(2) + frag.get(5) + frag.get(6)) % CodeBook.CODE_BOOK_LENGTH_CONTENT; + int chk3 = (frag.get(3) + frag.get(4) + frag.get(5) + frag.get(6)) % CodeBook.CODE_BOOK_LENGTH_CONTENT; + int offset = 0; + if (chk1 != 0) { + pos += 1; + offset = chk1; + } + if (chk2 != 0) { + pos += 2; + offset = chk1; + } + if (chk3 != 0) { + pos += 4; + offset = chk1; + } + pos -= 1; + if (pos != -1) { + int error_value = frag.get(pos); + frag.set(pos, (error_value + CodeBook.CODE_BOOK_LENGTH_CONTENT - offset) % CodeBook.CODE_BOOK_LENGTH_CONTENT); + } + Log.d(TAG, "processed: " + frag); + indexs[0] = frag.get(2); + indexs[1] = frag.get(4); + indexs[2] = frag.get(5); + indexs[3] = frag.get(6); + return pos; + } + private String showResult_74hamming(List codeIndexs) throws UnsupportedEncodingException { byte [] bytes = new byte[codeIndexs.size()]; for (int i = 0; i < codeIndexs.size(); ++i) { diff --git a/app/src/main/java/xwh/sound/MainActivity.java b/app/src/main/java/xwh/sound/MainActivity.java index 59d8636..9cee876 100644 --- a/app/src/main/java/xwh/sound/MainActivity.java +++ b/app/src/main/java/xwh/sound/MainActivity.java @@ -186,7 +186,7 @@ private void testBase64() throws UnsupportedEncodingException { List codes = Encoder.convertTextToCode_SeqHamming(str); Log.d("Encode", "encodeArray:" + codes); - PCMPlayer.getInstance().start(codes, 100); + PCMPlayer.getInstance().start(codes, 50); } private void testCodes() { From 02e7b772dc250ca3b86c3c2a1b78b16f3007c152 Mon Sep 17 00:00:00 2001 From: Elliott Zhang <898016731@qq.com> Date: Sat, 17 Dec 2022 01:43:40 +0800 Subject: [PATCH 10/12] Fix SeqHamming --- app/src/main/java/xwh/sound/Decoder.java | 30 +++++++++++++++++------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/xwh/sound/Decoder.java b/app/src/main/java/xwh/sound/Decoder.java index a9e7883..a8a7f60 100644 --- a/app/src/main/java/xwh/sound/Decoder.java +++ b/app/src/main/java/xwh/sound/Decoder.java @@ -468,21 +468,33 @@ private int[] correct(List frag) { } process_complete_pack(frag, indexs); } else { - for (int i = 0; i < 6; ++i) { + for (int i = 0; i <= 6; ++i) { frag.add(i, 0); int error_pos = process_complete_pack(frag, indexs); if (error_pos == -1 || error_pos == i) { + Log.d(TAG, "correct success: " + error_pos + " = " + i); return indexs; } frag.remove(i); } } - return indexs; - } - else if (frag.size() > 7) { + } else if (frag.size() > 7) { Log.d(TAG, "Redundant of units"); - frag = frag.subList(0, 7); - process_complete_pack(frag, indexs); + if (frag.size() > 8) { + frag = frag.subList(0, 7); + process_complete_pack(frag, indexs); + } else { + for (int i = 0; i < 8; ++i) { + int tmp = frag.get(i); + frag.remove(i); + int error_pos = process_complete_pack(frag, indexs); + if (error_pos == -1) { + Log.d(TAG, "correct success: " + error_pos + " now i = " + i); + return indexs; + } + frag.add(i, tmp); + } + } } else { process_complete_pack(frag, indexs); @@ -504,18 +516,18 @@ private int process_complete_pack(List _frag, int[] indexs) { } if (chk2 != 0) { pos += 2; - offset = chk1; + offset = chk2; } if (chk3 != 0) { pos += 4; - offset = chk1; + offset = chk3; } pos -= 1; if (pos != -1) { int error_value = frag.get(pos); frag.set(pos, (error_value + CodeBook.CODE_BOOK_LENGTH_CONTENT - offset) % CodeBook.CODE_BOOK_LENGTH_CONTENT); } - Log.d(TAG, "processed: " + frag); + Log.d(TAG, "processed: " + frag + "corrected: " + pos); indexs[0] = frag.get(2); indexs[1] = frag.get(4); indexs[2] = frag.get(5); From de5fe23c4967b634c28c20a31e36f6d002aba41b Mon Sep 17 00:00:00 2001 From: suchang <971622748@qq.com> Date: Sat, 17 Dec 2022 14:52:21 +0800 Subject: [PATCH 11/12] androidui --- app/build.gradle | 9 +- app/src/main/AndroidManifest.xml | 7 +- app/src/main/java/xwh/sound/CodeBook.java | 61 ++-- app/src/main/java/xwh/sound/Decoder.java | 305 ++++++++++++++---- app/src/main/java/xwh/sound/Encoder.java | 60 ++++ app/src/main/java/xwh/sound/MainActivity.java | 89 ++++- app/src/main/java/xwh/sound/PCMPlayer.java | 4 +- app/src/main/java/xwh/sound/webpage.java | 20 +- app/src/main/network_security_config.xml | 8 + app/src/main/res/layout/activity_main.xml | 96 +++++- app/src/main/res/values/strings.xml | 5 +- 11 files changed, 545 insertions(+), 119 deletions(-) create mode 100644 app/src/main/network_security_config.xml diff --git a/app/build.gradle b/app/build.gradle index d1bd8d7..aff8b4f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -21,6 +21,11 @@ dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support.constraint:constraint-layout:2.0.4' - // https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient - implementation 'org.apache.httpcomponents:httpclient:4.1' +} + +android { + packagingOptions + { + exclude'META-INF/DEPENDENCIES' + } } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 673f53a..ead3894 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,8 +4,13 @@ - + + + + + freqsWave[0]) { // 太小的不要 + if ( fre + MainActivity.FREQ_DISTANCE > freqsWave[0]) { // 太小的不要 int min = Integer.MAX_VALUE; for(int i=0; i= START_INDEX_HAMMING) { - return index; - } - index = _gray(index, 2); + //if (index == -1 || index >= START_INDEX_HAMMING) { + // return index; + //} + //index = _gray(index, 2); + if (index > DUPLICATE_INDEX_2_HAMMING) index = DUPLICATE_INDEX_2_HAMMING; return index; } } diff --git a/app/src/main/java/xwh/sound/Decoder.java b/app/src/main/java/xwh/sound/Decoder.java index d3002e6..1657ea9 100644 --- a/app/src/main/java/xwh/sound/Decoder.java +++ b/app/src/main/java/xwh/sound/Decoder.java @@ -20,7 +20,7 @@ public class Decoder { - public static final String TAG = "Decoder"; + public static final String TAG = "Decoder"; private final static int UP = 1; private final static int DOWN = 2; @@ -34,13 +34,14 @@ public class Decoder { private Deque codeQueue; private Deque debugQueue; private int queueTop; + private int lastIndex; private Handler mHandler; private long lastStartTime; private static final int TIMEOUT = 10000; - private static final int COUNT_STEP_SIZE = 5; + private static final int COUNT_STEP_SIZE = 20; private FFT fft = new FFT(); @@ -50,6 +51,7 @@ public Decoder(Handler handler) { codeQueue = new LinkedList(); debugQueue = new LinkedList(); queueTop = -1; + lastIndex = -1; } public void countFreq(short[] datas, int sampleStep) { @@ -102,7 +104,12 @@ public int countFreq1(short[] datas, int sampleStep) throws UnsupportedEncodingE //waveCount = waveCount / 2; // 一上一下表示一个波形,所以要除以2 bufferFreqCount += waveCount; currentFreq = waveCount * COUNT_STEP_SIZE * sampleStep / 2; // 这里根据每小段得出频率(一秒内波形次数) - decodeFre_74hamming(currentFreq); + if (MainActivity.METHOD == 1) + decodeFre(currentFreq); + if (MainActivity.METHOD == 2) + decodeFre_74hamming(currentFreq); + if (MainActivity.METHOD == 3) + decodeFre_SeqHamming(currentFreq); stepCount = 0; waveCount = 0; } @@ -113,8 +120,8 @@ public int countFreq1(short[] datas, int sampleStep) throws UnsupportedEncodingE msg.what = MainActivity.MSG_CURRENT_FREQ; msg.obj = freq + ""; mHandler.sendMessage(msg); - if (freq > CodeBook.START_FREQ_HAMMING) { - Log.i("Record", "fre:" + freq); + if (freq > MainActivity.BASE_FREQ + MainActivity.FREQ_DISTANCE * CodeBook.START_INDEX_HAMMING) { + //Log.i("Record", "fre:" + freq); } } return currentFreq; @@ -125,20 +132,14 @@ public int countFreq1(short[] datas, int sampleStep) throws UnsupportedEncodingE * @param fre */ public void decodeFre(int fre) { - int codeIndex = CodeBook.decode(fre); - if (codeIndex != -1) { - - Log.i("Record", "waveCount:" + waveCount + ", fre:" + fre + ", decode:" + codeIndex); - + //Log.i("Record", "waveCount:" + waveCount + ", fre:" + fre + ", decode:" + codeIndex); if (codeIndex == CodeBook.START_INDEX) { countEndCode = 0; - if (startDecode) { return; } - countStartCode++; if (countStartCode >= 2) { countStartCode = 0; @@ -148,27 +149,21 @@ public void decodeFre(int fre) { } } else if (startDecode) { countStartCode = 0; - if (System.currentTimeMillis() - lastStartTime > TIMEOUT) { startDecode = false; // 可能上一次结束码丢失,超时 return; } - if (codeIndex == CodeBook.END_INDEX) { countEndCode++; if (countEndCode >= 2) { countEndCode = 0; startDecode = false; List cleanIndexs = cleanCodeIndexs(codeIndexs); - Log.i("Record", "clearCodeIndexs:" + cleanIndexs); - if(cleanIndexs.size() > 0) { showResult(cleanIndexs); } - } - } else { countEndCode = 0; codeIndexs.add(codeIndex); @@ -177,8 +172,50 @@ public void decodeFre(int fre) { countStartCode = 0; countEndCode = 0; } + } + } - + public void decodeFre_SeqHamming(int fre) { + int codeIndex = CodeBook.decode(fre); + if (codeIndex != -1) { + //Log.i("Record", "waveCount:" + waveCount + ", fre:" + fre + ", decode:" + codeIndex); + if (codeIndex == CodeBook.START_INDEX) { + countEndCode = 0; + if (startDecode) { + return; + } + countStartCode++; + if (countStartCode >= 2) { + countStartCode = 0; + startDecode = true; + codeIndexs.clear(); + lastStartTime = System.currentTimeMillis(); + } + } else if (startDecode) { + countStartCode = 0; + if (System.currentTimeMillis() - lastStartTime > TIMEOUT) { + startDecode = false; // 可能上一次结束码丢失,超时 + return; + } + if (codeIndex == CodeBook.END_INDEX) { + countEndCode++; + if (countEndCode >= 2) { + countEndCode = 0; + startDecode = false; + List cleanIndexs = cleanCodeIndexs(codeIndexs); + Log.i("Record", "clearCodeIndexs:" + cleanIndexs); + if(cleanIndexs.size() > 0) { + showResult_SeqHamming(cleanIndexs); + } + } + } else { + countEndCode = 0; + codeIndexs.add(codeIndex); + } + } else { + countStartCode = 0; + countEndCode = 0; + } } } @@ -194,6 +231,8 @@ public void decodeFre_74hamming(int fre) throws UnsupportedEncodingException { countStartCode++; if (countStartCode >= 2) { countEndCode = 0; + debugQueue.clear(); + codeQueue.clear(); startDecode = true; codeIndexs.clear(); lastStartTime = System.currentTimeMillis(); @@ -220,17 +259,17 @@ public void decodeFre_74hamming(int fre) throws UnsupportedEncodingException { } } else { countEndCode = 0; - if (queueTop != -1 && codeIndex == queueTop) { + if (lastIndex != -1 && codeIndex == lastIndex) { return; } else { - queueTop = codeIndex; - if (codeIndex == CodeBook.DUPLICATE_INDEX_2_HAMMING || codeIndex == CodeBook.DUPLICATE_INDEX_1_HAMMING) { - int value = codeQueue.getLast(); - codeQueue.add(value); - debugQueue.add(value); + lastIndex = codeIndex; + if (queueTop != -1 && (codeIndex == CodeBook.DUPLICATE_INDEX_2_HAMMING || codeIndex == CodeBook.DUPLICATE_INDEX_1_HAMMING)) { + codeQueue.add(queueTop); + debugQueue.add(queueTop); } else { codeQueue.add(codeIndex); debugQueue.add(codeIndex); + queueTop = codeIndex; } } if (codeQueue.size() >= 7) { @@ -305,47 +344,47 @@ private List dummyCodeIndexs(ArrayList codeIndexs) { private String showResult(List indexs) { - if (indexs.size() < 2) { - return null; - } - - // 还原相邻相同字符 - for (int i=indexs.size()-1; i>0; i--) { - if (indexs.get(i) == CodeBook.DUPLICATE_INDEX_1 || indexs.get(i) == CodeBook.DUPLICATE_INDEX_2) { - int temp = i -1; - while(temp>0 && (indexs.get(temp) == CodeBook.DUPLICATE_INDEX_1 || indexs.get(temp) == CodeBook.DUPLICATE_INDEX_2)) { - temp --; - continue; - } - - indexs.set(i, indexs.get(temp)); - } - } - - int crcContent0 = indexs.get(indexs.size() -2); + if (indexs.size() < 2) { + return null; + } + + // 还原相邻相同字符 + for (int i=indexs.size()-1; i>0; i--) { + if (indexs.get(i) == CodeBook.DUPLICATE_INDEX_1 || indexs.get(i) == CodeBook.DUPLICATE_INDEX_2) { + int temp = i -1; + while(temp>0 && (indexs.get(temp) == CodeBook.DUPLICATE_INDEX_1 || indexs.get(temp) == CodeBook.DUPLICATE_INDEX_2)) { + temp --; + continue; + } + + indexs.set(i, indexs.get(temp)); + } + } + + int crcContent0 = indexs.get(indexs.size() -2); int crcContent1 = indexs.get(indexs.size() -1); - int[] crc = Utils.crc(indexs, 0, indexs.size() -3); + int[] crc = Utils.crc(indexs, 0, indexs.size() -3); boolean crcResult = (crc[0] == crcContent0 && crc[1] == crcContent1); - StringBuilder mTextBuilder = new StringBuilder(); - for(int i=0; i indexs) { return text; - } + } + + private String showResult_SeqHamming(List raw_indexs) { + List indexs = new ArrayList(); + if (raw_indexs.size() < 2) { + return null; + } + // 还原相邻相同字符 + while (raw_indexs.get(0) == CodeBook.DUPLICATE_INDEX_2 || raw_indexs.get(0) == CodeBook.DUPLICATE_INDEX_1) { + raw_indexs.remove(0); + } + int temp = raw_indexs.size(); + for (int i=raw_indexs.size()-1; i>=0; i--) { + if (raw_indexs.get(i) == CodeBook.DUPLICATE_INDEX_1 || raw_indexs.get(i) == CodeBook.DUPLICATE_INDEX_2) { + if (temp >= i) { + temp = i -1; + } + while(temp>0 && (raw_indexs.get(temp) == CodeBook.DUPLICATE_INDEX_1 || raw_indexs.get(temp) == CodeBook.DUPLICATE_INDEX_2)) { + temp --; + } + if (temp < 0) temp = 0; + raw_indexs.set(i, raw_indexs.get(temp)); + } + } + // 截取字符段进行译码 + for (int i = 0; i < raw_indexs.size(); ++i) { + while (i < raw_indexs.size() && raw_indexs.get(i) == CodeBook.SEP_INDEX) { + i++; + } + int j = i; + while (j < raw_indexs.size() && raw_indexs.get(j) != CodeBook.SEP_INDEX) { + j++; + } + if (j > i) { + List sublist = new ArrayList<>(raw_indexs.subList(i, j)); + int[] corrected_units = correct(sublist); + for (int k = 0; k < 4; ++k) { + indexs.add(corrected_units[k]); + } + } + i = j; + } + StringBuilder mTextBuilder = new StringBuilder(); + for(int i=0; i "+ text); + return text; + } + + // 译码及纠错 + private int[] correct(List frag) { + Log.d(TAG, "correct: " + frag); + int[] indexs = new int[4]; + if (frag.size() < 7) { + Log.d(TAG, "Loss of units"); + if (frag.size() < 6) { + while (frag.size() < 7) { + frag.add(0); + } + process_complete_pack(frag, indexs); + } else { + for (int i = 0; i <= 6; ++i) { + frag.add(i, 0); + int error_pos = process_complete_pack(frag, indexs); + if (error_pos == -1 || error_pos == i) { + Log.d(TAG, "correct success: " + error_pos + " = " + i); + return indexs; + } + frag.remove(i); + } + } + } else if (frag.size() > 7) { + Log.d(TAG, "Redundant of units"); + if (frag.size() > 8) { + frag = frag.subList(0, 7); + process_complete_pack(frag, indexs); + } else { + for (int i = 0; i < 8; ++i) { + int tmp = frag.get(i); + frag.remove(i); + int error_pos = process_complete_pack(frag, indexs); + if (error_pos == -1) { + Log.d(TAG, "correct success: " + error_pos + " now i = " + i); + return indexs; + } + frag.add(i, tmp); + } + } + } + else { + process_complete_pack(frag, indexs); + } + return indexs; + } + + private int process_complete_pack(List _frag, int[] indexs) { + Log.d(TAG, "process: " + _frag); + List frag = new ArrayList(_frag); + int pos = 0; + int chk1 = (frag.get(0) + frag.get(2) + frag.get(4) + frag.get(6)) % CodeBook.CODE_BOOK_LENGTH_CONTENT; + int chk2 = (frag.get(1) + frag.get(2) + frag.get(5) + frag.get(6)) % CodeBook.CODE_BOOK_LENGTH_CONTENT; + int chk3 = (frag.get(3) + frag.get(4) + frag.get(5) + frag.get(6)) % CodeBook.CODE_BOOK_LENGTH_CONTENT; + int offset = 0; + if (chk1 != 0) { + pos += 1; + offset = chk1; + } + if (chk2 != 0) { + pos += 2; + offset = chk2; + } + if (chk3 != 0) { + pos += 4; + offset = chk3; + } + pos -= 1; + if (pos != -1) { + int error_value = frag.get(pos); + frag.set(pos, (error_value + CodeBook.CODE_BOOK_LENGTH_CONTENT - offset) % CodeBook.CODE_BOOK_LENGTH_CONTENT); + } + Log.d(TAG, "processed: " + frag + "corrected: " + pos); + indexs[0] = frag.get(2); + indexs[1] = frag.get(4); + indexs[2] = frag.get(5); + indexs[3] = frag.get(6); + return pos; + } private String showResult_74hamming(List codeIndexs) throws UnsupportedEncodingException { byte [] bytes = new byte[codeIndexs.size()]; @@ -371,7 +556,7 @@ private String showResult_74hamming(List codeIndexs) throws Unsupported if (mHandler != null) { Message msg = mHandler.obtainMessage(); msg.what = MainActivity.MSG_RESULT; - msg.obj = debugQueue.toString() + "\n" + text; + msg.obj = text; mHandler.sendMessage(msg); } @@ -381,4 +566,4 @@ private String showResult_74hamming(List codeIndexs) throws Unsupported } -} +} \ No newline at end of file diff --git a/app/src/main/java/xwh/sound/Encoder.java b/app/src/main/java/xwh/sound/Encoder.java index 04dbff0..4446c61 100644 --- a/app/src/main/java/xwh/sound/Encoder.java +++ b/app/src/main/java/xwh/sound/Encoder.java @@ -47,6 +47,66 @@ public static List convertTextToCodes(String text) { return mCodes; } + public static List convertTextToCode_SeqHamming(String text) { + List mCodes = new ArrayList<>(); + Log.d(TAG, text); + if (!TextUtils.isEmpty(text)) { + mCodes.add(CodeBook.START_INDEX); //开始 + mCodes.add(CodeBook.START_INDEX); //开始(防止丢失,重复添加两组) + int len = text.length(); + if (len % 2 == 1) { + if (text.endsWith("0")) { + text = text.concat("1"); + } else { + text = text.concat("0"); + } + } else { + if (text.endsWith("0")) { + text = text.concat("11"); + } else { + text = text.concat("00"); + } + } + Log.d(TAG, text); + len = text.length(); + for (int i = 0; i < len; i+=2) { // 内容 + char ch1 = text.charAt(i); + char ch2 = text.charAt(i+1); + int[] indexs1 = Utils.char2Indexs(ch1); + int[] indexs2 = Utils.char2Indexs(ch2); + int chk1; + int chk2; + int chk3; + if (indexs1 != null && indexs2 != null) { + chk1 = (CodeBook.CODE_BOOK_LENGTH_CONTENT - ((indexs1[0] + indexs1[1] + indexs2[1]) % CodeBook.CODE_BOOK_LENGTH_CONTENT)) % CodeBook.CODE_BOOK_LENGTH_CONTENT; + chk2 = (CodeBook.CODE_BOOK_LENGTH_CONTENT - ((indexs1[0] + indexs2[0] + indexs2[1]) % CodeBook.CODE_BOOK_LENGTH_CONTENT)) % CodeBook.CODE_BOOK_LENGTH_CONTENT; + chk3 = (CodeBook.CODE_BOOK_LENGTH_CONTENT - ((indexs1[1] + indexs2[0] + indexs2[1]) % CodeBook.CODE_BOOK_LENGTH_CONTENT)) % CodeBook.CODE_BOOK_LENGTH_CONTENT; + mCodes.add(chk1); + mCodes.add(chk2); + mCodes.add(indexs1[0]); + mCodes.add(chk3); + mCodes.add(indexs1[1]); + mCodes.add(indexs2[0]); + mCodes.add(indexs2[1]); + mCodes.add(CodeBook.SEP_INDEX); + mCodes.add(CodeBook.SEP_INDEX); + } else { + Log.d(TAG, "invalidate char:" + ch1 + " or " + ch2); + } + } + mCodes.add(CodeBook.END_INDEX); //结束 + mCodes.add(CodeBook.END_INDEX); //结束(防止丢失,重复添加两组) + Log.d(TAG, mCodes.toString()); + // 替换内容相邻相同字符 + for (int i=mCodes.size()-3; i>2; i--) { + if (mCodes.get(i) == mCodes.get(i-1) && mCodes.get(i) != CodeBook.SEP_INDEX) { + mCodes.set(i, i%2 == 0 ? CodeBook.DUPLICATE_INDEX_1 : CodeBook.DUPLICATE_INDEX_2); + } + } + } + return mCodes; + } + public static List convertTextToCode_74hamming(String text) throws UnsupportedEncodingException { byte[] bytes = text.getBytes("UTF-8"); List mCodes = new ArrayList<>(); diff --git a/app/src/main/java/xwh/sound/MainActivity.java b/app/src/main/java/xwh/sound/MainActivity.java index 9c750dc..bce7816 100644 --- a/app/src/main/java/xwh/sound/MainActivity.java +++ b/app/src/main/java/xwh/sound/MainActivity.java @@ -14,33 +14,51 @@ import android.webkit.WebView; import android.widget.Button; import android.widget.EditText; +import android.widget.RadioButton; +import android.widget.RadioGroup; import android.widget.TextView; import android.widget.Toast; import android.webkit.WebViewClient; import java.io.UnsupportedEncodingException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import java.util.LinkedList; import java.util.Queue; -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.DefaultHttpClient; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; public class MainActivity extends AppCompatActivity { public static final int MSG_RESULT = 1; public static final int MSG_CURRENT_FREQ = 2; - + public static int BASE_FREQ; + public static int FREQ_DISTANCE; + public static int METHOD; private EditText inputHz; + private EditText BaseFreq; + private EditText FreqDistance; private int[] cc = {0, 262, 294, 330, 349, 392, 440, 494}; private TextView recordResult; + private TextView Message; private TextView currentFreq; private Record record; - + private RadioGroup encodeMethod; + private RadioButton method1; + private RadioButton method2; + private RadioButton method3; private Handler mHandler; private Button btRecord; @@ -53,8 +71,15 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); inputHz = this.findViewById(R.id.input_hz); + BaseFreq = this.findViewById(R.id.baseFreq); + FreqDistance = this.findViewById(R.id.freqDistance); recordResult = this.findViewById(R.id.record_result); + Message = this.findViewById(R.id.message); currentFreq = this.findViewById(R.id.text_current_freq); + encodeMethod = this.findViewById(R.id.method); + method1 = this.findViewById(R.id.encoding1); + method2 = this.findViewById(R.id.encoding2); + method3 = this.findViewById(R.id.encoding3); mHandler = new Handler() { @Override @@ -120,6 +145,36 @@ public void run() { } }); + findViewById(R.id.bt_play).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + String encode_method = ""; + if(method1.isChecked()) { + encode_method = "Raw"; + METHOD = 1; + } + else if(method2.isChecked()) { + encode_method = "74Hamming"; + METHOD = 2; + } + else if(method3.isChecked()) { + encode_method = "SeqHamming"; + METHOD =3; + } + Message.setText(""); + BASE_FREQ = Integer.parseInt(BaseFreq.getText().toString()); + + FREQ_DISTANCE = Integer.parseInt(FreqDistance.getText().toString()); + + Message.append("The base frequency is "+BaseFreq.getText().toString()+" Hz.\n"); + Message.append("The frequency distance is "+FreqDistance.getText().toString() + " Hz.\n"); + Message.append("Current encoding policy is "+encode_method+"."); + + } + }); + + + btRecord = this.findViewById(R.id.bt_record); btRecord.requestFocus(); btRecord.setOnClickListener(new View.OnClickListener() { @@ -141,7 +196,6 @@ public void run() { } }).start(); - // String name = "http://www.baidu.com/"; new Thread(new Runnable() { @Override public void run() { @@ -151,10 +205,9 @@ public void run() { String name = url_queue.poll(); Runnable networkTask = () -> { try{ - HttpGet httpRequest = new HttpGet(name); - HttpClient httpclient = new DefaultHttpClient(); - HttpResponse response = httpclient.execute(httpRequest); - if (response.getStatusLine().getStatusCode() == 200) { + URL url = new URL(name); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + if (conn.getResponseCode() == 200) { Intent intent = new Intent(MainActivity.this,webpage.class); intent.putExtra("context", name); startActivity(intent); @@ -168,27 +221,29 @@ public void run() { } } }).start(); - } - - } }); + } - } - private void testBase64() throws UnsupportedEncodingException { String test = inputHz.getText().toString(); String str = Base64.encodeToString(test.getBytes(), Base64.NO_WRAP | Base64.NO_PADDING); - List codes = Encoder.convertTextToCode_74hamming(str); + List codes = Encoder.convertTextToCodes(str);; + if (METHOD == 2) + codes = Encoder.convertTextToCode_74hamming(str); + if (METHOD == 3) + codes = Encoder.convertTextToCode_SeqHamming(str); Log.d("Encode", "encodeArray:" + codes); PCMPlayer.getInstance().start(codes, 50); } + + private void testCodes() { List codes = new ArrayList<>(); codes.add(CodeBook.START_INDEX); diff --git a/app/src/main/java/xwh/sound/PCMPlayer.java b/app/src/main/java/xwh/sound/PCMPlayer.java index 28dbafb..b4c08df 100644 --- a/app/src/main/java/xwh/sound/PCMPlayer.java +++ b/app/src/main/java/xwh/sound/PCMPlayer.java @@ -105,7 +105,9 @@ public void start(List codeIndexs, int during){ int lengthItem = DEFAULT_SAMPLE_RATE * during / 1000 * 2; byte[] waveAll = new byte[lengthItem * codeIndexs.size()]; for(int i=0; i + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index fc8f2ca..9c905e1 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -13,11 +13,96 @@ android:layout_height="wrap_content" android:text=""/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +