Java 在Android中实现NLMS算法时显示奇怪值的变量

Java 在Android中实现NLMS算法时显示奇怪值的变量,java,android,signal-processing,audio-processing,Java,Android,Signal Processing,Audio Processing,我一整天都在为这件事挠头,现在已经没有主意了,所以我把它贴在这里 我正试图使用 我使用录音机从麦克风获取音频样本,并使用AudioTrack播放。我一次读入一个样本作为一个短变量,将其转换为double,通过我的算法,将其转换回short并发送给演讲者。然而,我在中间变量中得到了奇怪的值,我不明白为什么会发生这种情况。代码如下: public class MainActivity extends Activity { AudioManager am = null; AudioRe

我一整天都在为这件事挠头,现在已经没有主意了,所以我把它贴在这里

我正试图使用
我使用录音机从麦克风获取音频样本,并使用AudioTrack播放。我一次读入一个样本作为一个短变量,将其转换为double,通过我的算法,将其转换回short并发送给演讲者。然而,我在中间变量中得到了奇怪的值,我不明白为什么会发生这种情况。代码如下:

public class MainActivity extends Activity {
    AudioManager am = null;
    AudioRecord record =null;
    AudioTrack track =null;
    final int SAMPLE_FREQUENCY = 16000; // ORIGINAL 44100
    final int SIZE_OF_RECORD_ARRAY = 1;     // 1024 ORIGINAL; 1000 / 40 = 25
    // final int WAV_SAMPLE_MULTIPLICATION_FACTOR = 1;
    final double WAV_SAMPLE_MULTIPLICATION_FACTOR = 0.5;
    final int N = 4; // ORIGINAL 40
    final int FEEDBACK_DELAY_IN_MSEC = 1;   // use small integer values here to keep the calculation of NO_OF_DELAY_SAMPLES from becoming non-whole number
    // final int NO_OF_DELAY_SAMPLES = SAMPLE_FREQUENCY / (FEEDBACK_DELAY_IN_MSEC * 1000); // NO_OF_DELAY_SAMPLES = 16
    final int NO_OF_DELAY_SAMPLES = 0; 
    final int TOTAL_SIZE_OF_X = N + NO_OF_DELAY_SAMPLES;
    int i = 0, n = 0; // n represents nth sample
    boolean isPlaying = false; // represents if the Pass Through button is pressed
    boolean applyDsp = false; // represents if the Apply Filter button is pressed
    boolean bufferFull = false;
    private volatile boolean keepThreadRunning;
    double[] w = new double[N];     // w represents filter coefficients
    double[] x = new double[TOTAL_SIZE_OF_X];
    double e; 
    double d;
    double send_out;
    double mu;
    double y = 0;

    // /*
    private RandomAccessFile stateFile;
    String stateFileLoc = Environment.getExternalStorageDirectory().getPath();
    FileDescriptor fd;
    // */

    class MyThread extends Thread{
        private volatile boolean needsToPassThrough;
        // /*
        MyThread(){
            super();
        }

        MyThread(boolean newPTV){
            this.needsToPassThrough = newPTV;
        }
        // */

        // /*
        @Override
        public void run(){
            short[] lin = new short[SIZE_OF_RECORD_ARRAY];
            short[] speaker = new short[SIZE_OF_RECORD_ARRAY];
            double speaker_double;
            int num = 0;
            Log.d("MYLOG", "ENTERED RUN");
            if(needsToPassThrough){
                record.startRecording();
                track.play();
                Log.d("MYLOG", "COMES HERE BEFORE BTN PRESS?");
            }
                        n = TOTAL_SIZE_OF_X -1;
            while (keepThreadRunning) { // thread runs until this loop stops; this loop runs as long as the program is running
                num = record.read(lin, 0, SIZE_OF_RECORD_ARRAY);
                for(i=0;i<lin.length;i++)
                    d = (double)lin[i];         // this line requires that lin[] has to be a single element array 
                if(isPlaying){
                    if(applyDsp){
                        y=0.0; // initialize every time
                        for(i=0; i<N; i++){
                           y += w[N-1-i] * x[n-i - NO_OF_DELAY_SAMPLES];
                        }

                        // Implementing step 2
                        e = d - y;

                        // /*
                        try {
                            stateFile.writeDouble(e);
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }

                        // Implementing step 3
                        mu = 0.5 / (x[n] * x[n] + 0.01);

                        // Implementing step 4
                        for(i=0; i<N; i++){
                               w[N-1-i] = w[N-1-i] + 2.0*mu*e*x[n-i - NO_OF_DELAY_SAMPLES];
                        }
                    } // closing of if(applyDsp) block

                    // Implementing step 5
                        for(i=0;i<TOTAL_SIZE_OF_X-1;i++){
                            x[i] = x[i+1];
                        }

                    send_out = e;   
                    speaker_double = send_out * WAV_SAMPLE_MULTIPLICATION_FACTOR;

                    // implementing step 6
                    x[TOTAL_SIZE_OF_X -1] = speaker_double;

                    for(i=0;i<speaker.length; i++)
                        speaker[i] = (short)speaker_double;

                    track.write(speaker, 0, num);
                } // if(isPlaying) block closed; this represents if the "Pass Through" button has been clicked

            } // while (keepThreadRunning) closes here; this infinite loop runs as long as the program is running 
            record.stop();
            track.stop();
            record.release();
            track.release();
        }

        public void stopThread(){
            keepThreadRunning = false;
        }

    } // End of MyThread class

    MyThread newThread;  
公共类MainActivity扩展活动{
AudioManager am=null;
录音记录=空;
AudioTrack track=null;
最终整数采样频率=16000;//原始44100
记录数组的最终整数大小\u=1;//1024原始值;1000/40=25
//最终整数波形样本乘法因子=1;
最终双波形样本乘法系数=0.5;
最终整数N=4;//原40
final int FEEDBACK_DELAY_IN_MSEC=1;//在此处使用小整数值,以防止_DELAY_样本的NO_计算变成非整数
//最终int NO_OF_DELAY_SAMPLES=采样频率/(反馈_DELAY_IN_MSEC*1000);//NO_OF_DELAY_SAMPLES=16
延迟样本的最终整数编号=0;
最终整数X的总大小=N+N个延迟样本;
int i=0,n=0;//n表示第n个样本
布尔值isplay=false;//表示是否按下了直通按钮
布尔值applyDsp=false;//表示是否按下了应用过滤器按钮
布尔bufferFull=false;
私有volatile布尔保持线程运行;
double[]w=新的double[N];//w表示滤波器系数
double[]x=新的double[总大小(x)];
双e;
双d;
双重送出;
双亩;
双y=0;
// /*
私有随机存取文件状态文件;
字符串stateFileLoc=Environment.getExternalStorageDirectory().getPath();
文件描述符fd;
// */
类MyThread扩展线程{
私有易变布尔需要停止传递;
// /*
神话读物(){
超级();
}
MyThread(布尔newPTV){
this.needstopasthrough=newPTV;
}
// */
// /*
@凌驾
公开募捐{
short[]lin=新的short[记录数组的大小];
short[]speaker=新short[记录数组的大小];
双扬声器;
int num=0;
Log.d(“MYLOG”,“已进入运行”);
如果(需要停止通过){
record.startRecording();
track.play();
Log.d(“MYLOG”,“在BTN按下之前到达这里?”);
}
n=X-1的总尺寸;
while(keepThreadRunning){//thread一直运行到该循环停止;该循环在程序运行时一直运行
num=record.read(lin,0,记录数组的大小);

对于(i=0;iNot java,不是答案,但Python中的NLMS更简单。抱歉,我必须在Android中执行此操作。我也会查看您的链接,但这些问题可能是因为我没有正确理解NLMS算法。建议:您应该将NLMS代码分解到单独的类中,以便进行测试/单独调试它(例如,在测试工具中)。这样,您可以将特定数据输入其中,查看输出并查看内部情况。否则,调试将非常困难。Fwiw是Android的Python