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

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

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

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

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

Q&A

0回答

2305閲覧

AudioRecordでリアルタイムFFT・周波数検知・バイブレーション通知

tcb78

総合スコア5

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

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

0グッド

0クリップ

投稿2018/09/05 11:34

編集2018/09/06 04:28

前提・実現したいこと

音の録音・フーリエ変換をするAndroidアプリを作成しています。
最初の画面で検出したい周波数と閾値を入力してスイッチを押すと処理が開始します。
音を録音すると同時にリアルタイムでフーリエ変換(FFT)をして、検出したい周波数が入力した閾値以上を超えればバイブレーションによって通知するシステムです。

イメージ説明

発生している問題・エラーメッセージ

エラーメッセージは特にありませんが、明らかに閾値以上であるはずなのに安定してバイブレーション通知が行われません。
例えば、20kHzの音が大音量で出ているときに、20kHzが明らかに届く距離にいるのに、バイブレーションが遅れたり、バイブレーションが作動しなかったりします。

該当のソースコード

lang

1package com.example.xxxx.receiver; 2 3import java.nio.ByteBuffer; 4import java.nio.ByteOrder; 5import android.app.Activity; 6import android.media.AudioFormat; 7import android.media.AudioRecord; 8import android.media.MediaRecorder; 9import android.os.Bundle; 10import android.os.Vibrator; 11import android.util.Log; 12import android.widget.CompoundButton; 13import android.widget.CompoundButton.OnCheckedChangeListener; 14import android.widget.Switch; 15import android.widget.EditText; 16import android.widget.TextView; 17 18public class MainActivity extends Activity implements OnCheckedChangeListener { 19 20 int RECVFREQ; 21 double DECIBEL; 22 int FFTPOINT; 23 24 //サンプリングレート 25 int RecvSR = 44100; 26 //FFTのポイント数 27 int fftSize = 4096; 28 //デシベルベースラインの設定 29 double dB_baseline = Math.pow(2, 15) * fftSize * Math.sqrt(2); 30 //分解能の計算 31 double resol = RecvSR / (double) fftSize; 32 Vibrator vib; 33 AudioRecord audioRec = null; 34 boolean bIsRecording = false; 35 int RecvBufSize; 36 Thread fft; 37 38 @Override 39 public void onCreate(Bundle savedInstanceState) { 40 super.onCreate(savedInstanceState); 41 setContentView(R.layout.activity_main); 42 43 TextView RecvfreqText = findViewById(R.id.RecvfreqText); 44 RecvfreqText.setText(R.string.RecvfreqText); 45 TextView decibelText = findViewById(R.id.decibelText); 46 decibelText.setText(R.string.decibelText); 47 Switch switch1 = findViewById(R.id.Switch); 48 switch1.setOnCheckedChangeListener(this); 49 } 50 51 @Override 52 public void onResume() { 53 super.onResume(); 54 } 55 56 @Override 57 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 58 59 if(isChecked) { 60 61 EditText RecvfreqEdit = findViewById(R.id.RecvfreqEdit); 62 EditText decibelEdit = findViewById(R.id.decibelEdit); 63 64 RECVFREQ = Integer.parseInt(RecvfreqEdit.getText().toString()); 65 DECIBEL = Integer.parseInt(decibelEdit.getText().toString()); 66 67 if(RECVFREQ == 18000) FFTPOINT = 3344; 68 else if(RECVFREQ == 18500) FFTPOINT = 3436; 69 else if(RECVFREQ == 19000) FFTPOINT = 3530; 70 else if(RECVFREQ == 19500) FFTPOINT = 3622; 71 else if(RECVFREQ == 20000) FFTPOINT = 3716; 72 else if(RECVFREQ == 20500) FFTPOINT = 3808; 73 else if(RECVFREQ == 21000) FFTPOINT = 3900; 74 else if(RECVFREQ == 21500) FFTPOINT = 3994; 75 else if(RECVFREQ == 22000) FFTPOINT = 4086; 76 77 RecvBufSize = AudioRecord.getMinBufferSize( 78 RecvSR, 79 AudioFormat.CHANNEL_IN_MONO, 80 AudioFormat.ENCODING_PCM_16BIT) + 4608; 81 82 audioRec = new AudioRecord( 83 MediaRecorder.AudioSource.MIC, 84 RecvSR, 85 AudioFormat.CHANNEL_IN_MONO, 86 AudioFormat.ENCODING_PCM_16BIT, 87 RecvBufSize); 88 89 //Vibratorクラスのインスタンス取得 90 vib = (Vibrator)getSystemService(VIBRATOR_SERVICE); 91 92 audioRec.startRecording(); 93 bIsRecording = true; 94 95 //フーリエ解析スレッドを生成 96 fft = new Thread(new Runnable() { 97 @Override 98 public void run() { 99 100 byte buf[] = new byte[RecvBufSize]; 101 while (bIsRecording) { 102 audioRec.read(buf, 0, buf.length); 103 104 //エンディアン変換 105 //配列bufをもとにByteBufferオブジェクトbfを作成 106 ByteBuffer bf = ByteBuffer.wrap(buf); 107 //バッファをクリア(データは削除されない) 108 bf.clear(); 109 //バイト順序をビッグエンディアンに変更 110 bf.order(ByteOrder.BIG_ENDIAN); 111 short[] s = new short[RecvBufSize / 2]; 112 //位置から容量まで 113 for (int i = bf.position(); i < bf.capacity() / 2; i++) { 114 //short値を読むための相対getメソッド 115 //現在位置の2バイトを読み出す 116 s[i] = bf.getShort(); 117 } 118 119 //FFTクラスの作成と値の引き渡し 120 FFT4g fft = new FFT4g(fftSize); 121 double[] FFTdata = new double[fftSize]; 122 for (int i = 2048; i < fftSize; i++) { 123 FFTdata[i] = (double) s[i]; 124 } 125 fft.rdft(1, FFTdata); 126 127 // デシベルの計算 128 double[] dbfs = new double[fftSize / 2]; 129 for (int i = 2048; i < fftSize; i += 2) { 130 dbfs[i / 2] = (int) (20 * Math.log10(Math.sqrt(Math 131 .pow(FFTdata[i], 2) 132 + Math.pow(FFTdata[i + 1], 2)) / dB_baseline)); 133 134 if(i == FFTPOINT && dbfs[i / 2] > DECIBEL){ 135 vib.vibrate(100); 136 } 137 } 138 Log.d("audioRec","audioRec"); 139 } 140 audioRec.stop(); 141 audioRec.release(); 142 } 143 144 }); 145 //スレッドのスタート 146 fft.start(); 147 148 } else { 149 150 Log.d("value","RECVFREQ1:" + String.valueOf(RECVFREQ)); 151 Log.d("value","DECIBEL:" + String.valueOf(DECIBEL)); 152 153 if(audioRec.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING) { 154 audioRec.stop(); 155 //audioRec.release(); 156 bIsRecording = false; 157 } 158 } 159 } 160 161 @Override 162 public void onPause() { 163 super.onPause(); 164 165 if(audioRec.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING) { 166 audioRec.stop(); 167 bIsRecording = false; 168 } 169 170 } 171 172 @Override 173 public void onDestroy() { 174 super.onDestroy(); 175 176 if(audioRec.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING) { 177 audioRec.stop(); 178 audioRec.release(); 179 bIsRecording = false; 180 } 181 182 } 183 184}

試したこと

スレッド処理の中でバイブレーションを作動させるという処理が正常に動いてないのかもしれません。
しかし、どこをどう改善すればよいかわかりません。
そもそも違った原因があるのかもしれません。

補足情報(FW/ツールのバージョンなど)

FFT4gは大浦版FFTを使用しています。
パーミッションの付与はうまくいっています。

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

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

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

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

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

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問