对于我的文凭,我需要对音频中的一些数据进行编码,通过扬声器播放,在其他Android手机上重现此音频并对其进行解码。对于这种情况,我选择了一个调幅罪,在java中它看起来像这样:
void genTone(){
// fill out the array
for (int i = 0; i < numSamples; ++i) {
sample[i] = (binareArray.get(i))*Math.sin((2 * Math.PI - .001) * i / (sampleRate/freqOfTone));
}
// convert to 16 bit pcm sound array
// assumes the sample buffer is normalised.
int idx = 0;
int ramp = numSamples / 20;
for (int i = 0; i < ramp; i++) {
// scale to maximum amplitude
final short val = (short) ((sample[i] * 32767) * i / ramp);
// in 16 bit wav PCM, first byte is the low order byte
generatedSnd[idx++] = (byte) (val & 0x00ff);
generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8);
}
for (int i = ramp; i < numSamples - ramp; i++) {
// scale to maximum amplitude
final short val = (short) ((sample[i] * 32767));
// in 16 bit wav PCM, first byte is the low order byte
generatedSnd[idx++] = (byte) (val & 0x00ff);
generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8);
}
for (int i = numSamples - ramp; i < numSamples; i++) {
// scale to maximum amplitude
final short val = (short) ((sample[i] * 32767) * (numSamples - i) / ramp);
// in 16 bit wav PCM, first byte is the low order byte
generatedSnd[idx++] = (byte) (val & 0x00ff);
generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8);
}
}
void playSound(){
final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
sampleRate, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length,
AudioTrack.MODE_STATIC);
audioTrack.write(generatedSnd, 0, generatedSnd.length);
audioTrack.play();
}
现在数据随机生成,然后从Dec转换为Bin,如下所示:
void genArray(){
Random random = new Random();
ArrayList<Integer> randArray = new ArrayList<>();
binareArray = new ArrayList<>();
for (int i = 0; i<numSamples; i++) {
randArray.add(random.nextInt(100));
}
for (int i = 0; i<numSamples; i++) {
String s = Integer.toBinaryString(randArray.get(i));
for (String q : (s.split(""))) {
if (q.equals("")){}
else {
binareArray.add(Integer.parseInt(q));
}
}
}
textView.setText(binareArray.toString());
}
所以现在我一直坚持接收和解码数据。您能否给我一个建议,如何有效地接收和解码数据?附:这是由PC麦克风(LINK)
录制的音频示例答案 0 :(得分:0)
我建议您定义一个独特的开始和结束序列。添加数据之前和之后的数据。让控制序列例如是“START”和“END”。所以您发送的数据如下:
STARTyour data you want to sendEND
在Android设备上,您可以连续解码收到的音频,直到您在流上找到“START”。然后存储解码的内容,直到“END”在流上。
您收到的内容应如下所示:
noisenoisenoiseSTARTyour data you want to sendENDnoisenoisenoise
对于开始和结束序列,您必须使用无法在数据中显示的序列。如果您的数据可以是完全随机的,则必须定义一个块编码,该编码保留至少一个块以标记控制信号。将“X”作为控制块标记。您可以通过知道X之后的块是命令来将BEGIN和END定义为“XB”和“XE”。
您的数据部分不应该很长,最好多次发送。否则你需要一些纠错。然后我建议研究现有的传输协议,而不是实现自己的传输协议。
答案 1 :(得分:0)
binareArray.get(i)似乎将为i的每个值提供不同的样本。您绝对不希望以比载波频率快的速度更改样本。 老实说,我无法告诉您“斜坡”在做什么。似乎有点同步头,可以确定数据前后的范围,但该计算不会涉及数据。
就解码而言,在信号中寻找峰值,这些峰值应该是您的数据。如果您将它们与运营商同步,这将变得很容易。然后,您只需要按比例缩放标题中的最小和最大值即可。