捕获声音以进行分析并可视化Android中的频率

adr*_*adr 8 android

我是Android的新手,我正在尝试创建一个捕获音频声音的程序,然后显示其中存在的频率.我找到了一个绘制图形均衡器图形部分的示例.在此示例中,它使用AudioRecord类型的对象来捕获音频声音.用于将音频信号分解为分量频率的技术采用称为离散傅立叶变换(DFT)的数学变换,并且为了执行DFT,使用快速傅里叶变换(FFT).此示例使用实现FFT的包.该软件包链接到www.netlib.org/fftpack/jfftpack.tgz.问题是,在我运行此示例后,按下开始按钮后,图形均衡器不会出现在显示屏上.

以下是活动类的源代码:

package com.audio.processing;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

import ca.uol.aig.fftpack.RealDoubleFFT;

public class AudioProcessing extends Activity implements OnClickListener{
    int frequency = 8000;
    int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
    int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;


    private RealDoubleFFT transformer;
    int blockSize = 256;
    Button startStopButton;
    boolean started = false;

    RecordAudio recordTask;

    ImageView imageView;
    Bitmap bitmap;
    Canvas canvas;
    Paint paint;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        startStopButton = (Button) this.findViewById(R.id.StartStopButton);
        startStopButton.setOnClickListener(this);

        transformer = new RealDoubleFFT(blockSize);

        imageView = (ImageView) this.findViewById(R.id.ImageView01);
        bitmap = Bitmap.createBitmap((int)256,(int)100,Bitmap.Config.ARGB_8888);
        canvas = new Canvas(bitmap);
        paint = new Paint();
        paint.setColor(Color.GREEN);
        imageView.setImageBitmap(bitmap);
    }

    private class RecordAudio extends AsyncTask<Void, double[], Void> {
        @Override
        protected Void doInBackground(Void... params) {
        try {
            int bufferSize = AudioRecord.getMinBufferSize(frequency,
                    channelConfiguration, audioEncoding);
                    AudioRecord audioRecord = new AudioRecord(
                    MediaRecorder.AudioSource.DEFAULT, frequency,
                    channelConfiguration, audioEncoding, bufferSize);

                    short[] buffer = new short[blockSize];
                    double[] toTransform = new double[blockSize];
                    audioRecord.startRecording();
                    while (started) {
                    int bufferReadResult = audioRecord.read(buffer, 0, blockSize);

                    for (int i = 0; i < blockSize && i < bufferReadResult; i++) {
                        toTransform[i] = (double) buffer[i] / 32768.0; // signed 16 bit
                        }

                    transformer.ft(toTransform);
                    publishProgress(toTransform);
                    }
                    audioRecord.stop();
                    } catch (Throwable t) {
                    Log.e("AudioRecord", "Recording Failed");
                    }
                    return null;
                    }
        }

    protected void onProgressUpdate(double[]... toTransform) {
        canvas.drawColor(Color.BLACK);
        for (int i = 0; i < toTransform[0].length; i++) {
        int x = i;
        int downy = (int) (100 - (toTransform[0][i] * 10));
        int upy = 100;
        canvas.drawLine(x, downy, x, upy, paint);
        }
        imageView.invalidate();
        }

        public void onClick(View v) {
        if (started) {
        started = false;
        startStopButton.setText("Start");
        recordTask.cancel(true);
        } else {
        started = true;
        startStopButton.setText("Stop");
        recordTask = new RecordAudio();
        recordTask.execute();
        }
        }
}
Run Code Online (Sandbox Code Playgroud)

这是main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<ImageView android:id="@+id/ImageView01" android:layout_width="wrap_content"
android:layout_height="wrap_content"></ImageView><Button android:text="Start"
android:id="@+id/StartStopButton" android:layout_width="wrap_content"
android:layout_height="wrap_content"></Button>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

在AndroidManifest.xml中,我设置了RECORD_AUDIO权限.提前致谢 !

Isu*_*nka 12

这是工作代码.我亲自尝试过.它工作正常.

package com.example.frequencytest;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import ca.uol.aig.fftpack.RealDoubleFFT;

public class MainActivity extends Activity implements OnClickListener {

    int frequency = 8000;
    int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
    int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
    private RealDoubleFFT transformer;
    int blockSize = 256;

    Button startStopButton;
    boolean started = false;

    RecordAudio recordTask;

    ImageView imageView;
    Bitmap bitmap;
    Canvas canvas;
    Paint paint;

    //AudioRecord audioRecord;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        startStopButton = (Button) this.findViewById(R.id.start_stop_btn);
        startStopButton.setOnClickListener(this);

        transformer = new RealDoubleFFT(blockSize);

        imageView = (ImageView) this.findViewById(R.id.imageView1);
        bitmap = Bitmap.createBitmap((int) 256, (int) 100,
                Bitmap.Config.ARGB_8888);
        canvas = new Canvas(bitmap);
        paint = new Paint();
        paint.setColor(Color.GREEN);
        imageView.setImageBitmap(bitmap);

    }

    public class RecordAudio extends AsyncTask<Void, double[], Void> {

        @Override
        protected Void doInBackground(Void... arg0) {

            try {
                // int bufferSize = AudioRecord.getMinBufferSize(frequency,
                // AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
                int bufferSize = AudioRecord.getMinBufferSize(frequency, 
                        channelConfiguration, audioEncoding); 

                AudioRecord audioRecord = new AudioRecord( 
                        MediaRecorder.AudioSource.MIC, frequency, 
                        channelConfiguration, audioEncoding, bufferSize); 

                short[] buffer = new short[blockSize];
                double[] toTransform = new double[blockSize];

                audioRecord.startRecording();

                // started = true; hopes this should true before calling
                // following while loop

                while (started) {
                    int bufferReadResult = audioRecord.read(buffer, 0,
                            blockSize);

                    for (int i = 0; i < blockSize && i < bufferReadResult; i++) {
                        toTransform[i] = (double) buffer[i] / 32768.0; // signed
                                                                        // 16
                    }                                       // bit
                        transformer.ft(toTransform);
                        publishProgress(toTransform);



                }

                audioRecord.stop();

            } catch (Throwable t) {
                t.printStackTrace();
                Log.e("AudioRecord", "Recording Failed");
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(double[]... toTransform) {

            canvas.drawColor(Color.BLACK);

            for (int i = 0; i < toTransform[0].length; i++) {
                int x = i;
                int downy = (int) (100 - (toTransform[0][i] * 10));
                int upy = 100;

                canvas.drawLine(x, downy, x, upy, paint);
            }

            imageView.invalidate();

            // TODO Auto-generated method stub
            // super.onProgressUpdate(values);
        }

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    public void onClick(View arg0) {
        // TODO Auto-generated method stub
        if (started) {
            started = false;
            startStopButton.setText("Start");
            recordTask.cancel(true);
        } else {
            started = true;
            startStopButton.setText("Stop");
            recordTask = new RecordAudio();
            recordTask.execute();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Hus*_*ein 3

是的,我也有这个项目,我有和你一样的错误,但添加下面的权限后,现在一切都好了。很可能您没有将其添加到 androidmanifest.xml 中的正确位置。它应该位于应用程序标记之外。

  <uses-permission android:name="android.permission.RECORD_AUDIO">
     </uses-permission>
Run Code Online (Sandbox Code Playgroud)