やりたいこと・問題
静寂状態から喧騒状態になるのを検知し、音声認識APIで文字起こしをするアルゴリズムを作っています。喧騒状態の検知にはある程度デシベルが大きかったら検知するようにするつもりです。デシベルを調べるにはFFTであるjtransformsを使用しました。まず、この記事を参考にしてdbを取得できるようにコード書いたところ問題が発生しました。以下のクラスRecordVoiceService
を実行してもD/db: Hz0.0maxdb-120.0
としか出力されません(MediaRecorder.AudioSource.VOICE_RECOGNITIONをMediaRecorder.AudioSource.MICにしても結果は同じでした)。これはAudioRecord
クラス上で音を拾えてないと言うことでしょうか?(もし、音を拾えているか確認する手段があるなら教えてください。)なぜ、このようになるのでしょうか?
参考にした記事
Androidで録音する 2 FFTして周波数とdBFSを調べる。
Androidで周波数を解析してみよう
Android プログラミング 研究
AndroidでFFTはJTransformsが楽だった
コード
RecordVoiceServiceクラス
java
1import android.app.Service; 2import android.content.Intent; 3import android.media.AudioFormat; 4import android.media.AudioRecord; 5import android.media.MediaRecorder; 6import android.os.Environment; 7import android.os.IBinder; 8import android.support.annotation.Nullable; 9import android.util.Log; 10 11import org.jtransforms.fft.DoubleFFT_1D; 12 13/** 14 * Created by kaikoro on 2017/11/13. 15 */ 16 17public class RecordVoiceService extends Service { 18 //録音クラスの宣言 19 AudioRecord audioRecord; 20 //録音フラグ。録音を開始するなら、true。停止するなら、false。ボタンで切り替える 21 boolean bIsRecording = false; 22 int bufferSize = 0; 23 final static int FFT_SIZE = 4096; 24 double dB_baseline = Math.pow(2, 15) * FFT_SIZE * Math.sqrt(2); 25 26 @Nullable 27 @Override 28 public IBinder onBind(Intent intent) { 29 return null; 30 } 31 32 @Override 33 public void onCreate() { 34 super.onCreate(); 35 Log.d("LifeCycle", "onCreate"); 36 } 37 38 @Override 39 public int onStartCommand(Intent intent, int flags, int startId) { 40 startRecordVoice(); 41 Log.d("LifeCycle", "onStartCommand"); 42 return super.onStartCommand(intent, flags, startId); 43 } 44 45 46 //録音開始 47 private void startRecordVoice() { 48 initAudioRecord(); 49 startAudioRecorder(); 50 } 51 52 53 public void getVoice() { 54 55 } 56 57 //録音停止 58 private void stopRecordVoice() { 59 //録音フラグを停止にする 60 bIsRecording = false; 61 Log.d("bIsRecording", String.valueOf(bIsRecording)); 62 } 63 64 @Override 65 public void onDestroy() { 66 super.onDestroy(); 67 Log.d("LifeCycle", "onDestroy"); 68 stopRecordVoice(); 69 } 70 71 //初期化 72 public void initAudioRecord() { 73 int audioSource = MediaRecorder.AudioSource.VOICE_RECOGNITION; 74 int rate = 44100; 75 int channelConfig = AudioFormat.CHANNEL_IN_MONO; 76 int audioFormat = AudioFormat.ENCODING_PCM_16BIT; 77 bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat); 78 if (FFT_SIZE > bufferSize) bufferSize = FFT_SIZE; 79 80 audioRecord = new AudioRecord(audioSource, rate, channelConfig, audioFormat, bufferSize * 2); 81 } 82 83 //録音開始、停止が押されるまで録音する 84 private void startAudioRecorder() { 85 new Thread(new Runnable() { 86 @Override 87 public void run() { 88 bIsRecording = true; 89 short buf[] = new short[bufferSize]; 90 //stopRecordVoice()が呼ばれるまでbufに書き込む 91 while (bIsRecording) { 92 //bufに音声データを格納 93 audioRecord.read(buf, 0, buf.length); 94 Log.d("bIsRecording", String.valueOf(bIsRecording)); 95 96 //FFTで解析 97 DoubleFFT_1D fft = new DoubleFFT_1D(FFT_SIZE); 98 double[] FFTdata = new double[FFT_SIZE]; 99 for (int i = 0; i < FFT_SIZE; i++) { 100 FFTdata[i] = (double) buf[i]; 101 } 102 fft.realForward(FFTdata); 103 //dBFS計算 104 double[] dbfs = new double[FFT_SIZE / 2]; 105 double max_db = -120d; 106 int max_i = 0; 107 for (int i = 0; i < FFT_SIZE; i += 2) { 108 dbfs[i / 2] = (int) 109 (20 * Math.log10(Math.sqrt(Math.pow(FFTdata[i], 2) 110 + Math.pow(FFTdata[i + 1], 2)) / dB_baseline)); 111 if (max_db < dbfs[i / 2]) { 112 max_db = dbfs[i / 2]; 113 max_i = i / 2; 114 } 115 } 116 Log.d("db", "Hz" + (44100 / (double) FFT_SIZE) * max_i + "maxdb" + max_db); 117 } 118 // 録音停止 119 audioRecord.stop(); 120 audioRecord.release(); 121 } 122 }).start(); 123 } 124}
Logcat
11-19 01:09:14.750 16266-16683/com.example.ehu.recodevoiceinbackgroud D/db: Hz0.0maxdb-120.0 11-19 01:09:14.778 16266-16683/com.example.ehu.recodevoiceinbackgroud D/db: Hz0.0maxdb-120.0 11-19 01:09:14.805 16266-16683/com.example.ehu.recodevoiceinbackgroud D/db: Hz0.0maxdb-120.0 11-19 01:09:14.832 16266-16683/com.example.ehu.recodevoiceinbackgroud D/db: Hz0.0maxdb-120.0 11-19 01:09:14.859 16266-16683/com.example.ehu.recodevoiceinbackgroud D/db: Hz0.0maxdb-120.0 11-19 01:09:14.887 16266-16683/com.example.ehu.recodevoiceinbackgroud D/db: Hz0.0maxdb-120.0 11-19 01:09:14.914 16266-16683/com.example.ehu.recodevoiceinbackgroud D/db: Hz0.0maxdb-120.0 11-19 01:09:14.942 16266-16683/com.example.ehu.recodevoiceinbackgroud D/db: Hz0.0maxdb-120.0 11-19 01:09:14.970 16266-16683/com.example.ehu.recodevoiceinbackgroud D/db: Hz0.0maxdb-120.0 11-19 01:09:14.998 16266-16683/com.example.ehu.recodevoiceinbackgroud D/db: Hz0.0maxdb-120.0 11-19 01:09:15.025 16266-16683/com.example.ehu.recodevoiceinbackgroud D/db: Hz0.0maxdb-120.0
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。