android平台声波通讯源码

  • B6_893388
    了解作者
  • 65.3KB
    文件大小
  • zip
    文件格式
  • 0
    收藏次数
  • VIP专享
    资源类型
  • 0
    下载次数
  • 2022-04-07 04:44
    上传日期
一个使用fsk算法的声波通讯,android平台源码demo, 有较好的防干扰功能。传输速率1kbp/s左右
DigitalVoices-ASK-StopCollaborateListen.zip
内容介绍
package com.jonas.stopcollaboratelisten; /** * Copyright 2002 by the authors. All rights reserved. * * Author: Cristina V Lopes * (Modified by Jonas Michel, 2012) */ import java.io.ByteArrayOutputStream; import com.jonas.reedsolomon.CRCGen; /** * This class contains the signal processing functions. * * @author CVL */ public class Decoder implements Constants { /** * @param signal the audio samples to search * @param signalStrengths this will be filled in with the strengths for each frequency (NOTE THIS SIDE EFFECT) * @param granularity a correlation will be determined every granularity samples (lower is slower) * @return the index in signal of the key sequence, or -1 if it wasn't found (in which case signalStrengths is trashed) */ public static int findKeySequence(byte[] signal, double[] signalStrengths, int granularity, int keyFrequency){ int maxCorrelationIndex = -1; double maxCorrelation = -1; double minSignal = 0.003; double acceptedSignal = 0.01; int i=0; for(i = 0; i <= signal.length - kSamplesPerDuration; i += granularity){ //test the correlation byte[] partialSignal = ArrayUtils.subarray(signal, i, kSamplesPerDuration); double corr = complexDetect(partialSignal, keyFrequency) /* * 4 */; // System.out.println("Correlation at " + i + ":" + corr); if (corr > maxCorrelation){ maxCorrelation = corr; maxCorrelationIndex = i; } if(granularity <= 0){ break; } } //System.out.println("Searched to index:" + i); if (maxCorrelation < acceptedSignal && maxCorrelation > -1){ //System.out.println("Best Correlation:" + maxCorrelation); maxCorrelationIndex = -1; } //if(maxCorrelationIndex >= 0){ //System.out.println("\r\nMax Correlation:" + maxCorrelation + " index:" + maxCorrelationIndex); //System.out.println("signal.length:" + signal.length); //getKeySignalStrengths(ArrayUtils.subarray(signal, maxCorrelationIndex + kSamplesPerDuration, // kSamplesPerDuration * 2), // signalStrengths); //} return maxCorrelationIndex; } /** * @param startSignals the signal strengths of each of the frequencies * @param samples the samples * @return the decoded bytes */ public static byte[] decode(double[] startSignals, byte[] samples){ return decode(startSignals, getSignalStrengths(samples)); } /** * @param startSignals the signal strengths of each of the frequencies * @param signal the signal strengths for each frequency for each duration [strength][duration index] * SIDE EFFECT: THE signal PARAMETER WILL BE SCALED BY THE STARTSIGNALS * @return the decoded bytes */ private static byte[] decode(double[] startSignals, double[][] signal){ //normalize to the start signals for(int i = 0; i < (kBitsPerByte * kBytesPerDuration); i++){ for(int j = 0; j < signal[i].length; j++){ signal[i][j] = signal[i][j] / startSignals[i]; } } ByteArrayOutputStream baos = new ByteArrayOutputStream(); for(int i = 0; i < signal[0].length; i++){ for(int k = 0; k < kBytesPerDuration; k++){ byte value = 0; for(int j = 0; j < kBitsPerByte; j++){ if(signal[(k * kBitsPerByte) + j][i] > 0.4){ // detection threshold value = (byte)(value | ( 1 << j)); } else { } } baos.write(value); } } return baos.toByteArray(); } /** * @param input audio sample array * @return the signal strengths of each frequency in each duration: [signal strength][duration index] */ private static double[][] getSignalStrengths(byte[] input){ //detect the signal strength of each frequency in each duration int durations = input.length / kSamplesPerDuration; // rows are durations, cols are bit strengths double[][] signal = new double[kBitsPerByte * kBytesPerDuration][durations]; //for each duration, check each bit for representation in the input for(int i=0; i < durations; i++){ //separate this duration's input into its own array byte[] durationInput = ArrayUtils.subarray(input, i * kSamplesPerDuration, kSamplesPerDuration); //for each bit represented, detect for(int j = 0; j < kBitsPerByte * kBytesPerDuration; j++){ signal[j][i] = complexDetect(durationInput, Encoder.getFrequency(j)); /* if (j == 0) System.out.println("\nsignal[" + j + "][" + i + "]=" + signal [j][i]); else System.out.println("signal[" + j + "][" + i + "]=" + signal [j][i]); */ } } return signal; } public static void getKeySignalStrengths(byte[] signal, double[] signalStrengths){ byte[] partialSignal = ArrayUtils.subarray(signal, 0, kSamplesPerDuration); for(int j = 1; j < kBitsPerByte * kBytesPerDuration; j += 2){ signalStrengths[j] = complexDetect(partialSignal, Encoder.getFrequency(j)); } byte[] partialSignal2 = ArrayUtils.subarray(signal, kSamplesPerDuration, kSamplesPerDuration); for(int j = 0; j < kBitsPerByte * kBytesPerDuration; j += 2){ signalStrengths[j] = complexDetect(partialSignal2, Encoder.getFrequency(j)); //System.out.println(signalStrengths[j]); } } /** * @param input array of bytes with CRC appended at the end * @return true if appended CRC == calculated CRC, false otherwise */ public static boolean crcCheckOk(byte[] input) { return input[input.length - 1] == CRCGen.crc_8_ccitt(input, input.length - 1); } public static byte[] removeCRC(byte[] input) { return ArrayUtils.subarray(input, 0, input.length - 2); } /** * @param signal audio samples * @param frequence the frequency to search for in signal * @return the strength of the correlation of the frequency in the signal */ /* // fast variant with cached trig values, rps, doesn't actually seem to run any faster ! private static double complexDetect(byte[] signal, int frequency){ double realSum = 0; double imaginarySum = 0; // y = e^(ju) = cos(u) + j * sin(u) int table = trigTableforFrequency( frequency ); double[] rowCos = (double[]) trigTablesCos.elementAt(table); double[] rowSin = (double[]) trigTablesSin.elementAt(table); for(int i = 0; i < signal.length; i++){ //System.out.println("signal[" +i +"]: " +signal[i] + "; convert: " + (signal[i])/(float)Constants.kFloatToByteShift); //realSum = realSum + (Math.cos(i * u) * (signal[i]/(float)Constants.kFloatToByteShift)); //imaginarySum = imaginarySum + (Math.sin(i * u) * (signal[i]/(float)Constants.kFloatToByteShift)); realSum = realSum + (fastCos( i, rowCos) * signal[i]); imaginarySum = imaginarySum + (fastSin(i, rowSin) * signal[i]); } realSum = realSum / Constants.kFloatToByteShift; imaginarySum = imaginarySum /Constants.kFloatToByteShift; //System.out.println("realSum=" + realSum + "; imSum=" + imaginarySum); double realAve = realSum/signal.length; double imaginaryAve = imaginarySum/signal.length; // System.out.println("u:" + u + " realAve:" + realAve + " imaginaryAve:" + imaginaryAve // + " \r\nfrequency:" + frequency + " signal.length:" + signal.length // + " realSum:" + realSum + " imaginarySum:" + imaginarySum // + "signal[100]:" + (signal[100]/(float)Constants.kFloatToByteShift)); // return the abs ( realAve + imaginaryAve * i ) which equals sqrt( realAve^2 + imaginaryAve^2) Thread.yield(); return Math.sqrt( (realAve * realAve) + (imaginaryAve * imaginaryAve) ); } static Vector trigTablesFreq = new Vector(); static Vector trigTablesCos = new Vector(); static Vector trigTablesSin = new Vector(); static int trigTableforFrequency( int frequency ) { int t; for( t = 0; t < trigTablesFreq.size(); t ++ ) { int f = ((Integer)trigTablesFreq.elementAt(t)).intValue(); if( f == frequency ) return t; // already precalculated this frequency } System.out.println("trigTableforFrequency calculating
评论
    相关推荐
    • 银行家算法,android应用
      对I/O系统的死锁资源的问题的解决主要的方法是银行家算法,单种资源的银行家算法和多种资源的银行家算法的解决思路一致,要求设计实现多种银行家算法,并要求所涉及的模型最少更够满足如下要求: (1) 程序能够根据...
    • android 各种最短路径算法
      android 各种最短路径算法
    • 卡马克卷轴算法android
      卡马克卷轴算法android版,游戏开发,地图滚动算法优化
    • Android-Android平台实现FFTW算法
      Android平台实现FFTW算法
    • Android-Brotli压缩算法Android
      Brotli 是一个通用的无损压缩算法,它使用了 LZ77 算法的现代变体、Huffman 编码和二阶上下文建模的结合来压缩数据,因而有着媲美当前任何现代通用压缩算法高的压缩率。在速度上它与 deflate 算法类似,但提供了更高...
    • Android计步算法
      从github上搬运的Android计步算法,原作者是个歪果仁
    • TLD及CMT跟踪算法Android源码实现
      TLD及CMT目标跟踪算法Android版本实现,触屏选中物体进行跟踪,跟踪效果非常好。内有APK及源码,可能需要安装opencv manager,源码需要配置opencv android sdk。
    • android 引入A*算法
      A*源码免费开放,内涵main函数可执行测试之用。 沈阳-亚冰
    • android 各种加密算法
      base64,MD5,等各种加密算法汇总
    • RSA算法Android C#互通
      示例程序实现RSA算法Android端与C#互通。 Android加密 C#服务器解密 反之也行