如何从线条显示/绘制频谱频率到条形(android)?

时间:2015-04-14 17:57:23

标签: android android-studio

我正在学习如何制作频谱分析仪。我从教程中学习,这里是代码

package com.example.prasetyo.spectrumanalyzer;

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 SpectrumActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_spectrum);
    }*/

public class SpectrumActivity extends Activity implements OnClickListener {

    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();
        }
    }

    int frequency = 8000;
    int channelConfiguration = AudioFormat.CHANNEL_IN_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;



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

        startStopButton = (Button) this.findViewById(R.id.StartStopButton);
        startStopButton.setOnClickListener(this);
        transformer = new RealDoubleFFT(blockSize);
        imageView = (ImageView) this.findViewById(R.id.ImageView01);
        bitmap = Bitmap.createBitmap(256, 100, Bitmap.Config.ARGB_8888);
        canvas = new Canvas(bitmap);
        paint = new Paint();
        paint.setColor(Color.GREEN);
        imageView.setImageBitmap(bitmap);
    }

    /*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();
        }
    }*/


    private class RecordAudio extends AsyncTask<Void, double[], Void> {
        @Override
        protected Void doInBackground(Void... params) {


            if(isCancelled()){
                return null;
            }

            //try {
                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];

            try {
                audioRecord.startRecording();
            }
            catch (IllegalStateException e) {
                Log.e("Recording Failed", e.toString());
            }
                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);
                    //Log.e("AudioRecord", "Recording Failed");
                    //return null;
                }
            return null;
        }


        protected void onProgressUpdate(double[]... toTransform) {
            canvas.drawColor(Color.BLACK);
            for (int i = 0; i < toTransform[0].length; i++) {
                int x;
                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();
            }
        }*/
    }
}

频谱将显示为每个频率的线。如果我没有弄错的话,因为drawLine方法出现了显示的行。有没有办法显示其他形状(条形)的频率?真的需要帮助:) 这里的插图是ilustration https://drive.google.com/open?id=0B3jsXXkRa7pLclFYMDdmUlk5MEU&authuser=0

1 个答案:

答案 0 :(得分:0)

您可以将canvas.drawLine(x, downy, x, upy, paint);替换为canvas.drawRect(x * 5, downy, x * 5 + 4, upy, paint);

Canvas.drawRect