1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
package test;
import test.AudioSampleReader;
import test.fourier.FFT;
import java.io.*;
import javax.sound.sampled.*;
public class Decoder {
File audioFile;
public Decoder(File audioFile) {
this.audioFile = audioFile;
}
public String decodeMessage() throws UnsupportedAudioFileException {
String hiddenMessage="";
try {
AudioSampleReader sampleReader = new AudioSampleReader(audioFile);
int bytesRead = 0;
int nbChannels = sampleReader.getFormat().getChannels();
int totalBytes = (int) sampleReader.getSampleCount()*nbChannels;
int bytesToRead=4096*2; //some aribituary number thats 2^n
String[] messageAsBytes = new String[totalBytes/bytesToRead];
int currentCharIndex = 0;
int bitsSaved = 0;
double[] audioData = new double[totalBytes];
sampleReader.getInterleavedSamples(0, totalBytes, audioData);
while (bytesRead<totalBytes) {
if (totalBytes-bytesRead<bytesToRead) {
bytesToRead = totalBytes-bytesRead;
}
//read in the data
double[] samples = new double[bytesToRead];
for (int i = 0 ; i<samples.length ; i++) {
samples[i] = audioData[bytesRead+i];
}
bytesRead+=bytesToRead;
double[] channelOne = new double[samples.length/2];
sampleReader.getChannelSamples(0, samples, channelOne);
//take the FFT
channelOne = FFT.correctDataLength(channelOne);
double[][] freqMag = FFT.getMag(channelOne, (int) sampleReader.getFormat().getFrameRate());
//pick the fundamentalAmp
double fundamentalAmp = 0;
for (int i = 0 ; i<freqMag.length ; i++) {
if (Math.abs(freqMag[i][1])>fundamentalAmp) {
fundamentalAmp=freqMag[i][1];
}
}
boolean isRest = false;
if (fundamentalAmp<.01) {
isRest = true;
}
//get the amplitude of freq 20000
double ampToTest = 0;
if (!isRest) {
for (int i = 0 ; i<freqMag.length ; i++) { //you don't have to start from 0..
if (Math.abs(Math.abs(freqMag[i][0])-20000)<5) {
ampToTest = freqMag[i][1];
}
}
}
if (!isRest) {
//compare the overtones to see if there should be a 1 or 0
//int overtoneToTest = overtones.length;
//if (Math.abs(overtones[overtoneToTest-1][1]-expectedOvertones[overtoneToTest-1])>.0049) {
if (ampToTest>.009) { //just test a certain freq
//checking if something is null..
if (messageAsBytes[currentCharIndex]==null) {
messageAsBytes[currentCharIndex]="1";
} else {
messageAsBytes[currentCharIndex]="1"+messageAsBytes[currentCharIndex]; //adding a 1
}
} else {
if (messageAsBytes[currentCharIndex]==null) {
messageAsBytes[currentCharIndex]="0";
} else {
messageAsBytes[currentCharIndex]="0"+messageAsBytes[currentCharIndex]; //adding a 0
}
}
bitsSaved++;
if (bitsSaved%8==0) {
if (messageAsBytes[currentCharIndex].equals("00000000")) { //if null
System.out.println("The message is over.");
break; //the message is done
}
currentCharIndex++;
}
}
}
hiddenMessage=constructMessage(messageAsBytes);
} catch (IOException e) {
e.printStackTrace();
}
return hiddenMessage;
}
private static String constructMessage(String[] messageInBinary) {
String message = "";
for (int i = 0 ; i<messageInBinary.length ; i++) {
int byteAsInt = byteToInt(messageInBinary[i]);
if (byteAsInt!=-1) {
message = message + String.valueOf((char)byteAsInt);
}
}
return message;
}
private static int byteToInt(String byteAsString) {
if (byteAsString==null) {
return -1;
}
int byteAsInt = Integer.parseInt(byteAsString);
int intValue = 0;
for (int i = 1 ; i<9 ; i++) {
if ((numberOfPlaces( (int) (byteAsInt%Math.pow(10,i)) )==i) && (byteAsInt%Math.pow(10,i)!=0)) {
intValue+=Math.pow(2,(i-1));
}
}
return intValue;
}
private static int numberOfPlaces(int num) {
int toReturn;
if (num>9999999) {
toReturn = 8;
} else if (num>999999) {
toReturn = 7;
} else if (num>99999) {
toReturn = 6;
} else if (num>9999) {
toReturn = 5;
} else if (num>999) {
toReturn = 4;
} else if (num>99) {
toReturn = 3;
} else if (num>9) {
toReturn = 2;
} else {
toReturn = 1;
}
return toReturn;
}
public static void main(String args[]) throws UnsupportedAudioFileException {
String filePath = args[0];
Decoder decoder = new Decoder(new File(filePath));
System.out.println("The hidden message was: " + decoder.decodeMessage());
}
} |
Partager