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

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

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

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

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Q&A

解決済

3回答

2416閲覧

Android StudioでのFFT4の実行時のエラー

Keifjub

総合スコア6

Java

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

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

0グッド

0クリップ

投稿2018/07/31 16:52

前提・実現したいこと

AndroidStudio内でhttp://tb-lab.hatenablog.jp/entry/2015/02/14/210611こちらのサイトのFFTを動かそうと思い、既存のプログラムに追加したところコンパイルは問題ないのですが、デバッグの時にボタンを押すとアプリが落ちてしまいます。どのようにすれば解決するでしょうか?

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

08-01 01:39:07.278 28163-28626/jp.gr.asj.sampleapp E/AndroidRuntime: FATAL EXCEPTION: Thread-2 Process: jp.gr.asj.sampleapp, PID: 28163 java.lang.ArrayIndexOutOfBoundsException: length=3584; index=3584 at jp.gr.asj.sampleapp.MainActivity$7.run(MainActivity.java:406) at java.lang.Thread.run(Thread.java:761)

該当のソースコード

Java

1抜粋 2// サンプリングレート 3 int SAMPLING_RATE = 44100; 4 // FFTのポイント数 5 int FFT_SIZE = 4096; 6 7 // デシベルベースラインの設定 8 double dB_baseline = Math.pow(2, 15) * FFT_SIZE * Math.sqrt(2); 9 10 // 分解能の計算 11 double resol = ((SAMPLING_RATE / (double) FFT_SIZE)); 12 13 AudioRecord audioRec = null; 14 boolean bIsRecording = false; 15 int bufSize; 16 Thread fft; 17 18抜粋 19 private void startRecord() { 20 21 // 端末スリープさせなくする 22 getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 23 24 super.onResume(); 25 // AudioRecordの作成 26 audioRec = new AudioRecord(MediaRecorder.AudioSource.MIC, 27 SAMPLING_RATE, AudioFormat.CHANNEL_IN_MONO, 28 AudioFormat.ENCODING_PCM_16BIT, bufSize * 2); 29 audioRec.startRecording(); 30 bIsRecording = true; 31 32 //フーリエ解析スレッド 33 fft = new Thread(new Runnable() { 34 @Override 35 public void run() { 36 byte buf[] = new byte[bufSize * 2]; 37 while (bIsRecording) { 38 audioRec.read(buf, 0, buf.length); 39 40 //エンディアン変換 41 ByteBuffer bf = ByteBuffer.wrap(buf); 42 bf.order(ByteOrder.LITTLE_ENDIAN); 43 short[] s = new short[(int) bufSize]; 44 for (int i = bf.position(); i < bf.capacity() / 2; i++) { 45 s[i] = bf.getShort(); 46 } 47 48 //FFTクラスの作成と値の引き渡し 49 FFT4g fft = new FFT4g(FFT_SIZE); 50 double[] FFTdata = new double[FFT_SIZE]; 51 for (int i = 0; i < FFT_SIZE; i++) { 52 FFTdata[i] = (double) s[i]; 53 } 54 fft.rdft(1, FFTdata); 55 56 // デシベルの計算 57 double[] dbfs = new double[FFT_SIZE / 2]; 58 double max_db = -120d; 59 int max_i = 0; 60 for (int i = 0; i < FFT_SIZE; i += 2) { 61 dbfs[i / 2] = (int) (20 * Math.log10(Math.sqrt(Math 62 .pow(FFTdata[i], 2) 63 + Math.pow(FFTdata[i + 1], 2)) / dB_baseline)); 64 if (max_db < dbfs[i / 2]) { 65 max_db = dbfs[i / 2]; 66 max_i = i / 2; 67 } 68 } 69 70 //音量が最大の周波数と,その音量を表示 71 Log.d("fft","周波数:"+ resol * max_i+" [Hz] 音量:" + max_db+" [dB]"); 72 } 73 74 75 Button Button = (Button)findViewById(R.id.button); 76 Button.setOnClickListener(new View.OnClickListener() { 77 @Override 78 public void onClick(View v) { 79 // 録音停止 80 audioRec.stop(); 81 audioRec.release(); 82 } 83 }); 84 85 } 86 }); 87 //スレッドのスタート 88 fft.start(); 89 90 91 // 端末スリープ可にする 92 getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 93 94 95 96 } 97

試したこと

MainActivity.java:406はFFTdata[i] = (double) s[i];はこの部分でした。
Thread.java:761はわからなかったです。

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

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

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

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

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

guest

回答3

0

BufSizeは初期化されてないようです。
おそらく0になってますが、これでいいのでしょうか

投稿2018/08/01 00:07

y_waiwai

総合スコア87747

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

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

Keifjub

2018/08/01 12:24

コメントありがとうございます。 buffsizeの部分貼り忘れておりました。このように定義しています。 bufSize = AudioRecord.getMinBufferSize(SAMPLING_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
guest

0

short[] s = new short[(int) bufSize]; // size of s == buffer size

ok

double[] FFTdata = new double[FFT_SIZE];

ok

Android

1for (int i = 0; i < FFT_SIZE; i++) { 2 FFTdata[i] = (double) s[i]; // not okay both are different in 3length 4 }

投稿2018/07/31 17:00

AliHassan

総合スコア351

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

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

Keifjub

2018/08/01 12:32

ty for comment. sry i'm noob. do you say s=buffsize but s≠FFTdate so error occurred? please do y teach me how to rewrite?
guest

0

自己解決

一旦解決しました。
FFTのポイント数を3584以下にすると動作しました。
恐らく録音のループ時間がFFTのポイント数以下だったために起こったのではないかと思います。
正直まだ良くわかっていないのですが、動きはしたので解決にしておきます。

投稿2018/08/01 13:20

Keifjub

総合スコア6

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問