绘制动态图表以显示声音的分贝

时间:2014-01-12 06:09:13

标签: android charts achartengine android-mediarecorder

我使用MediaRecorder录制环境声音并计算其分贝。 现在我想画出分贝的活着图表。 我使用AChartEngine,但我不知道如何绘制它: 在arrey中保存db或不? PLZ帮助我, 在此先感谢。

这是我的代码:

    TextView tvDecible;
TextView tvRecord;

MediaPlayer mPlayer;

MediaRecorder mRecorder = null;
double mEMA = 0.0;
double REFERENCE = 1.0;
Timer timer = new Timer();

GraphicalView mChart;
XYMultipleSeriesDataset mDataset = new XYMultipleSeriesDataset();
XYMultipleSeriesRenderer mRenderer = new XYMultipleSeriesRenderer();
XYSeries mCurrentSeries;
XYSeriesRenderer mCurrentRenderer;
     @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button btnPlay = (Button) this.findViewById(R.id.btnDecible);
    tvDecible = (TextView) this.findViewById(R.id.tvDecible);
    Button btnRecord = (Button) this.findViewById(R.id.btnRecord);
    final Button btnStop = (Button) this.findViewById(R.id.btnStop);
    tvRecord = (TextView) this.findViewById(R.id.tvRecord);
    mPlayer = MediaPlayer.create(this, R.raw.sound5);

    initChart();

    btnPlay.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            AudioManager audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

            int origionalVolume = audio
                    .getStreamVolume(AudioManager.STREAM_MUSIC);

            audio.setStreamVolume(AudioManager.STREAM_MUSIC,
                    audio.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0);

            mPlayer.start();

            int currentVolume = audio
                    .getStreamVolume(AudioManager.STREAM_MUSIC);

            tvDecible.setText(String.valueOf(origionalVolume + "_"
                    + currentVolume));

        }
    });

    btnRecord.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

            startRecording();
            timer.scheduleAtFixedRate(tTask, 0, 1000);

        }
    });

    btnStop.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            timer.cancel();
            stopRecording();

        }

    });
}

TimerTask tTask = new TimerTask() {

    @Override
    public void run() {
        // TODO Auto-generated method stub
         int db = (int) getAmplitudeEMA();
        Log.i("Decibel", String.valueOf(db));
                       onResume();


        if (db >= 100) {

            runOnUiThread(new Runnable() {
                public void run() {

                    Uri alarm = RingtoneManager
                            .getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
                    Ringtone ring = RingtoneManager.getRingtone(
                            getApplicationContext(), alarm);
                    ring.play();

                }

            });

        } else {

        }





}
};

public void startRecording() {
    if (mRecorder == null) {
        mRecorder = new MediaRecorder();
        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        mRecorder.setOutputFile(getFilename());
        try {
            mRecorder.prepare();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        mRecorder.start();
        mEMA = 0.0;
    }
}

public void stopRecording() {
    if (mRecorder != null) {
        mRecorder.stop();
        mRecorder.release();
        mRecorder = null;
    }
}

@SuppressLint("SdCardPath")
private String getFilename() {
    File file = new File("/sdcard", "AUDIO_RECORDER_FOLDER");

    if (!file.exists()) {
        file.mkdirs();
    }

    return (file.getAbsolutePath() + "/" + System.currentTimeMillis() + ".mp3");
}

public double getAmplitude() {
    if (mRecorder != null)
        return (mRecorder.getMaxAmplitude());

    else
        return 0;

}

public double getAmplitudeEMA() {
    double amp = getAmplitude();
    mEMA = 20 * Math.log10(amp / REFERENCE);
    return mEMA;
}

private void initChart() {
    mCurrentSeries = new XYSeries("Sample Data");
    mDataset.addSeries(mCurrentSeries);
    mCurrentRenderer = new XYSeriesRenderer();
    mRenderer.addSeriesRenderer(mCurrentRenderer);
}

protected void onResume() {
    super.onResume();
    LinearLayout layout = (LinearLayout) findViewById(R.id.chart);
    if (mChart == null) {
        initChart();
         addData();
        mChart = ChartFactory.getCubeLineChartView(this, mDataset,
                mRenderer, 0.3f);
        layout.addView(mChart);
    }

    else {
        mChart.repaint();
    }

}

public void addData() {
    // TODO Auto-generated method stub



    mCurrentSeries.add(x[k], y[k]);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

2 个答案:

答案 0 :(得分:1)

因为您的情况下的声音实际上是时间的函数(如幅度值 特别是时间),使用TimeSeries更容易,而不是XYSeries。

对于简单化的事情:

    TimeSeries mCurrentSeries = new TimeSeries("Sample Data");
    ...
    public void addData(float amplitude) {
        Date currentTime = new Date();
        mCurrentSeries.add(currentTime, amplitude);
        mChart.repaint();
    }

如果您想要或不想在数据库/阵列中保存数据,则完全取决于您。 如果它在数据库中,只需在onCreate中读取它的所有数据并添加它 到TimeSeries。由于时间序列是排序的集合,你有你的 “阵列”已经。

希望我的问题是对的。

答案 1 :(得分:0)

我通过此代码绘制我的图表并且效果很好:

private LinearLayout thisLayout;
private FragmentActivity thisActivity;

List<Integer> copydb = new ArrayList<Integer>();
CalculateDecibel decibel = new CalculateDecibel();

GraphicalView mChart;
XYMultipleSeriesDataset mDataset = new XYMultipleSeriesDataset();
XYMultipleSeriesRenderer mRenderer = new XYMultipleSeriesRenderer();
XYSeries mCurrentSeries;
XYSeriesRenderer mCurrentRenderer;

public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    thisActivity = super.getActivity();
    thisLayout = (LinearLayout) inflater.inflate(
            R.layout.activity_db_chart, container, false);

    LinearLayout layout = (LinearLayout) thisLayout
            .findViewById(R.id.chart);
    initChart();

    mChart = ChartFactory.getCubeLineChartView(thisActivity, mDataset,
            mRenderer, 0.3f);

    layout.addView(mChart);


    return thisLayout;
}

private void initChart() {
    mCurrentSeries = new XYSeries("Sample Data");
    mDataset.addSeries(mCurrentSeries);
    mCurrentRenderer = new XYSeriesRenderer();
    mRenderer.addSeriesRenderer(mCurrentRenderer);
    mRenderer.setMarginsColor(Color.parseColor("#c05100"));
    mRenderer.setAxesColor(Color.parseColor("#AAAAAA"));
    mRenderer.setGridColor(Color.parseColor("#EEEEEE"));
    mRenderer.setMargins(new int[] { 0, 0, 0, 0 });
    mRenderer.setShowGrid(true);
    mCurrentRenderer.setColor(Color.WHITE);
    mCurrentRenderer.setPointStyle(PointStyle.SQUARE);
    mCurrentRenderer.setDisplayChartValues(true);
    mCurrentRenderer.setLineWidth(3);
    mCurrentRenderer.setFillPoints(true);

}

public void onResume() {
    super.onResume();
    // RefreshChart();
}

public void RefreshChart() {


    copydb.add(((MainActivity) getActivity()).db);



    if (((MainActivity) getActivity()).db < -10) {

        mCurrentSeries.add(mCurrentSeries.getItemCount() + 1, -10);

    } else {
        mCurrentSeries.add(mCurrentSeries.getItemCount() + 1,
                ((MainActivity) getActivity()).db);



    }


    mChart.repaint();
}


public void addList(int db) {
    copydb.add(db);
}

我在片段中写了这段代码。并在我的主要活动中获得Db o声音的计时器中调用RefreshChart()。