我想出了一个简单的 Java 解决方案,它能够使用 3x 过采样重建比特流。下面的示例涉及 2 个信号,但这不是问题陈述的一部分。
import java.util.LinkedList;
import java.util.Queue;
public class SampleQueue {
private double oversampleratio;
private Queue<Character> output;
public SampleQueue(double oversampleratio) {
this.oversampleratio = oversampleratio;
this.output = new LinkedList<Character>();
}
public char[] process(String sampled) {
char currentchar = sampled.charAt(0);
int charcounter = 0;
for(int i = 0; i < sampled.length(); i++) {
if(currentchar == sampled.charAt(i)) {
charcounter++;
}
else {
process(currentchar, charcounter);
charcounter = 1;
currentchar = sampled.charAt(i);
}
}
if(charcounter > 0) {
process(currentchar, charcounter);
}
return getString();
}
private char[] getString() {
int length = output.size();
char[] str = new char[length];
for(int i = 0; i < length; i++) {
str[i] = output.poll();
}
return str;
}
private void process(char currentchar, int charcounter) {
int actualsamples = (int) Math.round(charcounter / (double) oversampleratio);
for(int i = 0; i < actualsamples; i++) {
output.add(currentchar);
}
}
}
import org.apache.commons.lang3.StringUtils;
public class DataAndClockSignal {
private double phase;
private double sampleperiod;
private String data;
private String sampleddata;
private String clock;
private String sampledclock;
private int clocklevel;
public DataAndClockSignal(double phase, double sampleperiod) {
this.clocklevel = 0;
this.phase = phase;
this.sampleperiod = sampleperiod;
this.data = "";
this.clock = "";
this.sampledclock = "";
this.sampleddata = "";
}
public void generateRandomSamples(int numsamples) {
MersenneTwisterFast mtf = new MersenneTwisterFast();
int maxvalue = (int) Math.pow(2, 12);
int generatedsamples = 0;
while(generatedsamples < numsamples) {
for(int i = 0; i < 10 + mtf.nextInt(25); i++) {
addData(mtf.nextInt(maxvalue));
generatedsamples++;
}
}
dump();
}
public void addData(int dataint) {
String str = Integer.toBinaryString(dataint);
data += StringUtils.leftPad(str, 12, '0');
transitionClock();
if(clocklevel == 0) {
clock += "000000000000";
}
else {
clock += "111111111111";
}
}
private void transitionClock() {
clocklevel = (clocklevel + 1) % 2;
}
public void dump() {
sampledclock = "";
sampleddata = "";
double sampletime = phase;
for(int i = 0; i < data.length(); ) {
sampledclock += clock.charAt(i);
sampleddata += data.charAt(i);
sampletime += sampleperiod;
i = (int) sampletime;
}
System.out.println("Clock: " + clock);
System.out.println("Data: " + data);
System.out.println("SampledClock: " + sampledclock);
System.out.println("SampledData: " + sampleddata);
}
public String getData() {
return data;
}
public String getSampleddata() {
return sampleddata;
}
public String getClock() {
return clock;
}
public String getSampledclock() {
return sampledclock;
}
public static void main(String[] args) {
DataAndClockSignal randomsig = new DataAndClockSignal(0.37, 0.34);
randomsig.generateRandomSamples(500);
}
}
public class Reconstruction {
private String data;
private String clock;
private double sampleperiod;
public Reconstruction(double sampleperiod) {
this.sampleperiod = sampleperiod;
}
public void processRandomData(double timeoffset) {
DataAndClockSignal dataandclock = new DataAndClockSignal(timeoffset, sampleperiod);
dataandclock.generateRandomSamples(500);
data = dataandclock.getData();
clock = dataandclock.getClock();
char[] reconstructeddata = reconstruct(dataandclock.getSampleddata());
char[] reconstructedclock = reconstruct(dataandclock.getSampledclock());
System.out.print("Reconstructed Clock: ");
System.out.println(reconstructedclock);
System.out.print("Reconstructed Data: ");
System.out.println(reconstructeddata);
if(new String(reconstructeddata).equalsIgnoreCase(data)) {
System.out.println("Data matches!");
}
else {
System.out.println("Data does not match!");
}
if(new String(reconstructedclock).equalsIgnoreCase(clock)) {
System.out.println("Clock matches!");
}
else {
System.out.println("Clock does not match!");
}
}
private char[] reconstruct(String sampled) {
SampleQueue samplequeue = new SampleQueue(1 / sampleperiod);
return samplequeue.process(sampled);
}
public static void main(String[] args) {
double sampleperiod = 0.34;
double timeoffset = 0.37;
Reconstruction reconstruction = new Reconstruction(sampleperiod);
reconstruction.processRandomData(timeoffset);
}
}