前提・実現したいこと
現在android studioでアプリ開発を行っております。
http://tb-lab.hatenablog.jp/entry/2015/02/14/210611
こちらのサイトを参考に、録音中にFFTを行い、指定の周波数のみの結果を取り出し、その結果を縦db,横時間でplotしていくようなシステムの構築を目指しています。FFTの結果をtxtに出力するまでは行えました。
発生している問題・エラーメッセージ
ここからリアルタイムで処理を行っていてもplot点数が足りず、オーバーラップ処理を用いて、plot点数を増やそうとしました。
http://www.asahi-net.or.jp/~es3t-kbt/fft/overlap.html
こちらのサイトのようなシステムで行いたいのですが、AudioRecordクラスで時間をずらしてバッファの取得をすれば良いのかわからず困っています。
あまりプログラム自体触ったことがなく、間違ったことを言っていれば指摘して頂けるとありがたいです。
ご存じの方いらっしゃいましたら教えて頂けると幸いです。
該当のソースコード
Java
1private void startRecord() { 2 3 // 端末スリープさせなくする 4 getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 5 6 super.onResume(); 7 // AudioRecordの作成 8 audioRec = new AudioRecord(MediaRecorder.AudioSource.MIC, 9 SAMPLING_RATE, AudioFormat.CHANNEL_IN_MONO, 10 AudioFormat.ENCODING_PCM_16BIT, bufSize ); 11 audioRec.startRecording(); 12 bIsRecording = true; 13 14 //フーリエ解析スレッド 15 fft = new Thread(new Runnable() { 16 @Override 17 public void run() { 18 byte buf[] = new byte[bufSize]; 19 20 21 while (bIsRecording) { 22 audioRec.read(buf, 0, buf.length); 23 24 //エンディアン変換 25 ByteBuffer bf = ByteBuffer.wrap(buf); 26 bf.order(ByteOrder.LITTLE_ENDIAN); 27 short[] s = new short[(int) bufSize]; 28 for (int i = bf.position(); i < bf.capacity() / 2; i++) { 29 s[i] = bf.getShort(); 30 } 31 32 //FFTクラスの作成と値の引き渡し 33 FFT4g fft = new FFT4g(FFT_SIZE2); 34 double[] FFTdata = new double[FFT_SIZE2]; 35 for (int i = 0; i < FFT_SIZE2; i++) { 36 FFTdata[i] = (double) s[i]; // not okay both are different in length 37 } 38 fft.rdft(1, FFTdata); 39 40 // デシベルの計算 41 double[] dbfs = new double[FFT_SIZE2 / 2]; 42 double max_db = -120d; 43 int max_i = 0; 44 for (int i = 0; i < FFT_SIZE2; i += 2) { 45 dbfs[82 / 2] = (int) (20 * Math.log10(Math.sqrt(Math 46 .pow(FFTdata[41], 2) 47 + Math.pow(FFTdata[41 + 1], 2)) / dB_baseline)); 48 if (0 < i) { 49 if (max_db < dbfs[82 / 2]) { 50 max_db = dbfs[82 / 2]; 51 max_i = 82 / 2; 52 } 53 } 54 } 55 56 double[] dbfs2 = new double[FFT_SIZE2 / 2]; 57 double max_db2 = -120d; 58 int max_i2 = 0; 59 for (int i = 0; i < FFT_SIZE2; i += 2) { 60 dbfs2[136 / 2] = (int) (20 * Math.log10(Math.sqrt(Math 61 .pow(FFTdata[68], 2) 62 + Math.pow(FFTdata[68 + 1], 2)) / dB_baseline)); 63 if (i > 1) { 64 if (max_db2 < dbfs[136 / 2]) { 65 max_db2 = dbfs2[136 / 2]; 66 max_i2 = 136 / 2; 67 } 68 } 69 } 70 double max_db3 = -120d; 71 //max_db3 = (int) log10(Math.pow(10,(0.1 * max_db)) + Math.pow(10,(0.1 * max_db2))); 72 max_db3 = max_db + max_db2; 73 74 try { 75 // FileWriterクラスのオブジェクトを生成する 76 FileWriter file = new FileWriter("/storage/emulated/0/Android/data/jp.gr.asj.sampleapp/files/" + _FILENAME_TXT_, true); 77 // PrintWriterクラスのオブジェクトを生成する 78 PrintWriter pw = new PrintWriter(new BufferedWriter(file)); 79 // PrintWriterクラスのオブジェクトを生成するPrintWriter pw = new PrintWriter(new BufferedWriter(file)); 80 //ファイルに追記する 81 pw.println(max_db3); 82 //ファイルを閉じる 83 pw.close(); 84 } catch (IOException e) { 85 e.printStackTrace(); 86 } 87 88 89 } 90 91 } 92 93 94 95 96 97 98 99 100 }); 101 //スレッドのスタート 102 fft.start(); 103 104 105
試したこと
audioRec.read(buf, 0, buf.length)でオフセット値を設定してwhile loopを二つ処理しようと思ったのですが、出来ませんでした。
補足情報(FW/ツールのバージョンなど)
Android 7.0(端末は買い替え予定ですのでver上がっても問題ありません)
minSdkVersion 21
targetSdkVersion 26
あなたの回答
tips
プレビュー