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

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

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

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

Q&A

解決済

1回答

2564閲覧

android jtransformsで調べたデシベルがおかしい

退会済みユーザー

退会済みユーザー

総合スコア0

Android

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

0グッド

0クリップ

投稿2017/11/18 16:33

編集2017/11/18 16:55

やりたいこと・問題

静寂状態から喧騒状態になるのを検知し、音声認識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

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

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

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

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

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

guest

回答1

0

ベストアンサー

AudioRecord.startRecording()を書き忘れていただけでした。その他、初期化できているか確認するメソッドAudioRecord.getState()と、録音しているか確認できるメソッドAudioRecord.getgetRecordingState()もここに記しておきます。

RecordVoiceServiceクラスのstartAudioRecorder()

java

1 private void startAudioRecorder() { 2 new Thread(new Runnable() { 3 @Override 4 public void run() { 5 bIsRecording = true; 6 short buf[] = new short[bufferSize]; 7 audioRecord.startRecording(); 8 //stopRecordVoice()が呼ばれるまでbufに書き込む 9 while (bIsRecording) { 10 //bufに音声データを格納 11 audioRecord.read(buf, 0, buf.length); 12 Log.d("RecordingState", String.valueOf(audioRecord.getRecordingState())); 13 //省略

RecordVoiceServiceクラスのstartRecordVoice()

java

1 private void startRecordVoice() { 2 initAudioRecord(); 3 if (audioRecord.getState() == audioRecord.STATE_INITIALIZED) { 4 Log.d("AudioRecord", "state" + audioRecord.getState()); 5 startAudioRecorder(); 6 } else { 7 Log.w("AudioRecord", "state" + audioRecord.getState()); 8 } 9 }

AudioRecord.getState()と、AudioRecord.getgetRecordingState()を使ってみたのですが、書き方がこれでいいのか不安ですね。美しい書き方を教えていただくと幸いです。

試しに録音開始の後「OK Google」と言って、録音停止してみました。

11-19 15:06:28.479 18270-19294/com.example.ehu.recodevoiceinbackgroud D/db: Hz527.5634765625maxdb-35.0 11-19 15:06:28.570 18270-19294/com.example.ehu.recodevoiceinbackgroud D/db: Hz506.0302734375maxdb-47.0 11-19 15:06:28.627 18270-19294/com.example.ehu.recodevoiceinbackgroud D/db: Hz301.46484375maxdb-52.0 11-19 15:06:28.753 18270-19294/com.example.ehu.recodevoiceinbackgroud D/db: Hz10.7666015625maxdb-44.0 11-19 15:06:28.806 18270-19294/com.example.ehu.recodevoiceinbackgroud D/db: Hz0.0maxdb-47.0 11-19 15:06:28.916 18270-19294/com.example.ehu.recodevoiceinbackgroud D/db: Hz366.064453125maxdb-45.0 11-19 15:06:28.997 18270-19294/com.example.ehu.recodevoiceinbackgroud D/db: Hz236.865234375maxdb-48.0 11-19 15:06:29.125 18270-19294/com.example.ehu.recodevoiceinbackgroud D/db: Hz118.4326171875maxdb-51.0 11-19 15:06:29.198 18270-19294/com.example.ehu.recodevoiceinbackgroud D/db: Hz473.73046875maxdb-47.0 11-19 15:06:29.284 18270-19294/com.example.ehu.recodevoiceinbackgroud D/db: Hz0.0maxdb-68.0 11-19 15:06:29.373 18270-19294/com.example.ehu.recodevoiceinbackgroud D/db: Hz0.0maxdb-70.0

投稿2017/11/19 06:11

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問