質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Q&A

解決済

1回答

3044閲覧

AndroidでFFTが安定しない

HiroakiTsugawa

総合スコア13

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

0グッド

1クリップ

投稿2016/05/19 03:20

編集2016/05/19 03:22

AudioRecordとjtransformsを使用してボタンをクリックするごとにFFTを行うプログラムを作っています。
しかし、値が安定せずに困っています。使い方が間違っているのでしょうか?
ご教授お願いいたします。
ある程度、ボタンを使い方は改造途中なので間違っています・・・

package com.example.testfft004;

import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import org.jtransforms.fft.DoubleFFT_1D;

public class MainActivity extends Activity implements View.OnClickListener {
/** Called when the activity is first created. */
final static int SAMPLING_RATE = 44100;
AudioRecord audioRec = null;
Button btn = null;
boolean bIsRecording = false;
int bufSize;
final static int FFT_SIZE = 512;

@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn = (Button)findViewById(R.id.button_id); btn.setOnClickListener(this); // バッファサイズの計算 bufSize = AudioRecord.getMinBufferSize( SAMPLING_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT); if (FFT_SIZE > bufSize) { bufSize = FFT_SIZE; } // AudioRecordの作成 audioRec = new AudioRecord( MediaRecorder.AudioSource.MIC, SAMPLING_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufSize); } @Override public void onClick(View v) { // TODO Auto-generated method stub if (v == btn) { if (bIsRecording) { bIsRecording = false; } else { // 録音開始 Log.v("AudioRecord", "startRecording"); audioRec.startRecording(); bIsRecording = true; // 録音スレッド new Thread(new Runnable() { @Override public void run() { byte buf[] = new byte[bufSize]; // TODO Auto-generated method stub // 録音データ読み込み audioRec.read(buf, 0, buf.length); // 録音停止 //audioRec.stop(); //高速フーリエ変換 DoubleFFT_1D fft = new DoubleFFT_1D(FFT_SIZE); double[] FFTdata = new double[FFT_SIZE]; for (int i = 0; i < FFT_SIZE; i++) { FFTdata[i] = (double) buf[i]; } fft.realForward(FFTdata); double[] dbfs = new double[FFT_SIZE / 2]; double max_db = 0; int max_i = 0; for (int i = 0; i < FFT_SIZE / 2; i += 2) { dbfs[i / 2] = (int) (Math.sqrt(Math.pow(FFTdata[i], 2) + Math.pow(FFTdata[i + 1], 2))); if (max_db < dbfs[i / 2]) { max_db = dbfs[i / 2]; max_i = i / 2; } } //Log.d("db", "Hz" + (SAMPLING_RATE/ (double) FFT_SIZE)*max_i*2 + "maxdb" + max_db); } }).start(); } } } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); audioRec.release(); }

}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

なんとなくですが、AudioFormat.ENCODING_PCM_16BIT なので、
FFTdata[i] = (double) buf[i]; としているところで
2バイト取ると良かったりしますかね?

投稿2016/05/19 09:07

m.h

総合スコア149

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.h

2016/05/20 04:07

例えば、こんな感じで。 FFTdata[i] = (double) (buf[i*2] << 8 + buf[i*2+1]); もしくは、 byte buf の型を short buf に変えるとか・・?
HiroakiTsugawa

2016/05/25 13:59

遅くなりましたがご返信ありがとうございます。 解決方法ですが、 fft.realForward(FFTdata); がライブラリにおいてFFTを行う関数なのですがwhile文の中に入れたところ安定した結果が得られるようになりました。audioRec.stop();はwhile文の外に出しました。 原因が正直分からないところです。 アドバイス誠にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問