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

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

ただいまの
回答率

90.47%

  • Java

    16160questions

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

  • Android

    7402questions

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

  • Eclipse

    1963questions

    Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

Androidアプリ開発~周波数解析~要約

受付中

回答 1

投稿

  • 評価
  • クリップ 3
  • VIEW 991

YuujiUnno

score 17

前回の投稿ではわかりにくかったかもしれませんので、改めて現在解決したい問題点を簡潔に説明します。

マイクから入力された外部音の周波数解析をしたいのですが、下のソースコードで動かすとpower配列の中で最も大きい値を示すのが常に6000~12000Hz程になってしまいます。
なぜ、低い周波数の音源を与えてもこの結果となってしまうのでしょうか?
確認方法、原因と思われるものなどありましたら教えてください。

/**
 * 
 */
package isa.android;

/**
 * @author Unno
 *
 */

import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.util.Log;

import java.lang.Math;

public class SoundRecord implements Runnable {
    // ボリューム感知リスナー
    
    /* (非 Javadoc)
     * @see java.lang.Runnable#run()
     */
    int pmax=0;
    public static double heltz;
    
    private OnReachedVolumeListener mListener;
    // 録音中フラグ
    private boolean isRecoding = true;
    // サンプリングレート
    private static final int SAMPLE_RATE = 44100;
    // FFTする要素数
    private final static int FFT_SIZE = 2048;
    // ボーダー音量
    private short mBorderVolume = 3000;
    // ボーダー音量をセット
    public void setBorderVolume(short volume) {
    mBorderVolume = volume;
    }
    // ボーダー音量を取得
    public short getBorderVolume() {
    return mBorderVolume;
    }
    // 録音を停止
    public void stop() {
    isRecoding = false;
    }
    // OnReachedVolumeListenerをセット
    public void setOnVolumeReachedListener(
    OnReachedVolumeListener listener) {
    mListener = listener;
    }
    // ボーダー音量を検知した時のためのリスナー
    public interface OnReachedVolumeListener {
    // ボーダー音量を超える音量を検知した時に
    // 呼び出されるメソッドです。
    void onReachedVolume(short volume);
    }
    
    public static int bufferSize = AudioRecord.getMinBufferSize(
            SAMPLE_RATE,
            AudioFormat.CHANNEL_CONFIGURATION_MONO,
            AudioFormat.ENCODING_PCM_16BIT);
            AudioRecord audioRecord = new AudioRecord(
            MediaRecorder.AudioSource.MIC,
            SAMPLE_RATE,
            AudioFormat.CHANNEL_CONFIGURATION_MONO,
            AudioFormat.ENCODING_PCM_16BIT,
            bufferSize);
    public static double[] fbuffer = new double[FFT_SIZE];
    public static double[] power = new double[FFT_SIZE/2];
    
    public void hamming(double[] x) /*ハミング窓*/
    {
    int i;

    for(i=0;i<FFT_SIZE;i++){
    x[i] = 0.54 - 0.46*Math.cos((2 * Math.PI * i)/(FFT_SIZE - 1));
    }
    }
    
    @Override
    // スレッド開始(録音を開始)
    public void run() {
        android.os.Process.setThreadPriority(
                android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
                
                short[] buffer = new short[FFT_SIZE];
                audioRecord.startRecording();
                while(isRecoding) {
                audioRecord.read(buffer, 0, FFT_SIZE);
                short max = 0;
                for (int i=0; i<FFT_SIZE; i++) {
                // 最大音量を計算
                max = (short)Math.max(max, buffer[i]);
                // 最大音量がボーダーを超えていたら
                if (max > mBorderVolume) {
                if (mListener != null) {
                // リスナーを実行
                mListener.onReachedVolume(max);
                FastFourieTransform fft = new FastFourieTransform();

                double[] x = new double[FFT_SIZE];
                hamming(x);
                for(int j=0; j < buffer.length; j++){
                    fbuffer[j] = buffer[j]*x[j];
                    }
                fft.fft(fbuffer , FFT_SIZE);
                
                //スペクトルを求める
                for(int k=0; k < power.length; k++){
                    power[k] = Math.sqrt(Math.pow(fbuffer[2*k], 2) + Math.pow(fbuffer[2*k + 1],2));
                    }
                //求めたスペクトルの最も大きな値を持つ添え字を求める
                for(int k=0; k < power.length; k++){
                    if(power[k] > power[pmax])
                        pmax = k;
                    Log.d("SoundRecord", "power[" + k + "] =" + power[k]);
                }
                
                //周波数を求める
                heltz = pmax * (SAMPLE_RATE/2) / (FFT_SIZE/2);
                //Log.d("SoundRecord", "heltz=" + heltz);
                Log.d("SoundRecord", "pmax=" + pmax);
                
                break;
        }
                }
                }
                }
                audioRecord.stop();
                audioRecord.release();
    }

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

まずは最大音量のチェックやスペクトルの最大値を気にせずスペクトログラムが正しく求められているかを確認する等、一つ一つの処理を細かく確認したほうが原因がわかると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.47%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Java

    16160questions

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

  • Android

    7402questions

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

  • Eclipse

    1963questions

    Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。