LLAPNDK_DOUBLE声波发送代码分析

   日期:2020-10-01     浏览:93    评论:0    
核心提示:目录总览SoundPlayer.java功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入总览Project中主要的代码在这几个文件中,控制声波发送的代码主要在MainActivity.java和SoundPlayer.java

目录

  • 总览
    • SoundPlayer.java
    • MainActivicty.java

总览


Project中主要的代码在这几个文件中,控制声波发送的代码主要在MainActivity.java和SoundPlayer.java中。

SoundPlayer.java

void genTone(){ 
        // fill out the array
        for (int i = 0; i < numSamples; ++i) { 

            sample[i]=0;
              for(int j=0;j<numfreq;j++) { 
                sample[i] =sample[i]+ Math.cos(2 * Math.PI * i / (sampleRate / (freqOfTone[j])));//第i个采样点,t为i/sampleRate
            }
            sample[i]=sample[i]/numfreq;
        }

        // convert to 16 bit pcm sound array
        // assumes the sample buffer is normalised.
        int idx = 0;
        for (final double dVal : sample) { 
            // scale to maximum amplitude
            final short val = (short) ((dVal * 30000));//加振幅,加音量
            // in 16 bit wav PCM, first byte is the low order byte
            generatedSound[idx++] = (byte) (val & 0x00ff);//低8位
            generatedSound[idx++] = (byte) ((val & 0xff00) >>> 8);//高8位

        }
    }

该函数是生成声波的函数,先填入sample数组每个采样点的值。这里的声波是多个频率的cos函数相加除以频率数,论文中表示使用多个频率是为了减轻多径效应的影响。接着,该函数将声波的振幅调到最大,并且将声波信号转换成PCM编码,存入generatedSound数组中。sample[0]的低8位放在generatedSound[0]中,高8位放在generatedSound[1]中;然后sample[1]的低8位放在generatedSound[2]中,且将高8位放在generatedSound[3]中,以此类推。

public void PrepareSound() { 
        genTone();

        Log.d("llap", "" +audioTrack.write(generatedSound, 0, generatedSound.length));//write函数向audioTrack写入声波数据
        audioTrack.setLoopPoints(0, generatedSound.length / 2, -1);//循环
    }

该函数先调用genTone()函数,genTone()函数执行完后要发送的声波信号就转换为PCM编码储存在generatedSound数组中了。Log函数是把信息写到日志里,audioTrack.write函数将声波信号的PCM编码generatedSound写入audioTrack中,audioTrack.setLoopPoints函数用于设置循环数,把loopcount设置成了-1,表示无限循环。

SoundPlayer(int setsamplerate, int setnumfreq, double setfreqs[]) { 


        sampleRate=setsamplerate;
        numfreq=setnumfreq;
        for (int i=0;i<numfreq;i++)
        { 
            freqOfTone[i]=setfreqs[i];
        }
        //STREAM_MUSIC STREAM_VOICE_CALL
        audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, AudioFormat.CHANNEL_OUT_MONO,
                AudioFormat.ENCODING_PCM_16BIT, generatedSound.length, AudioTrack.MODE_STATIC);//初始化

        PrepareSound();
    }

该函数是SoundPlayer类的构造函数,给freqOfTone数组赋值,new一个audioTrack,调用PrepareSound函数生成声波并将声波的PCM编码传给AudioTrack。

MainActivicty.java

//初始化wavefreqs数组和wavelength数组
        for(int i=0;i<numfreq;i++)
        { 
            wavefreqs[i]=startfreq+i*freqinter;//直线,初始化,startfreq = 15050,freqinter = 350
            wavelength[i]=soundspeed/wavefreqs[i]*1000;
        }

此段代码在用于初始化wavefreqs数组和wavelength数组。

btnPlayRecord.setOnClickListener(new OnClickListener()
        { 
            @Override
            public void onClick(View v)
            { 
                btnPlayRecord.setEnabled(false);
                btnStopRecord.setEnabled(true);

                recBufSize = AudioRecord.getMinBufferSize(sampleRateInHz,
                        channelConfig, encodingBitrate);

                mylog( "recbuffersize:" + recBufSize);

                playBufSize = AudioTrack.getMinBufferSize(sampleRateInHz,
                        channelConfig, encodingBitrate);

                audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
                        sampleRateInHz, channelConfig, encodingBitrate, recBufSize);


                mylog("channels:" + audioRecord.getChannelConfiguration());

                new ThreadInstantPlay().start();
                new ThreadInstantRecord().start();
                new ThreadSocket().start();
            }
        });

该事件监听器负责配置audioRecord并且启动发送声波信号的线程。

    class ThreadInstantPlay extends Thread
    { 
        @Override
        public void run()
        { 
            SoundPlayer Player= new SoundPlayer(sampleRateInHz,numfreq,wavefreqs);
            blnPlayRecord=true;
            Player.play();
            while (blnPlayRecord==true){ }
            Player.stop();
        }
    }

该线程是发送声波信号的线程,new一个SoundPlayer并且调用play()方法发送声波。

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服