web-dev-qa-db-ja.com

AndroidでAudioTrackを使用してWAVファイルを再生する

私はAndroidを使用して、AudioTrackアプリケーションにWindows .wavファイル(Tada.wav)を再生させようとしています。率直に言って、それほど難しくはないはずですが、奇妙なことをたくさん聞いています。ファイルは私の携帯電話のミニSDカードに保存されており、コンテンツの読み取りは問題ないようですが、ファイルを再生すると(私はPRETTY SUREだけが正しいパラメーターです)、数秒のホワイトノイズが発生します音が適切なものに自分自身を解決する前に。

電話で自分の声を録音して再生しました-この例の指示に従って.pcmファイルを作成しました:

http://emeadev.blogspot.com/2009/09/raw-audio-manipulation-in-Android.html

(後方マスキングなし)...

誰かがAndroidで.wavファイルを再生するためのいくつかの提案やウェブ上の例の認識を得ましたか?

ありがとう、R。

25
Rich

私は答えを偶然見つけました(率直に言って&^ @!私はうまくいくとは思わなかった)誰かが興味を持っている場合に備えて...私の元のコード(元の投稿のリンクの例から派生したもの)で、データは次のようにファイルから読み取られます。

    InputStream             is  = new FileInputStream       (file);
    BufferedInputStream     bis = new BufferedInputStream   (is, 8000);
    DataInputStream         dis = new DataInputStream       (bis);      //  Create a DataInputStream to read the audio data from the saved file

    int i = 0;                                                          //  Read the file into the "music" array
    while (dis.available() > 0)
    {
        music[i] = dis.readShort();                                     //  This assignment does not reverse the order
        i++;
    }

    dis.close();                                                        //  Close the input stream

このバージョンでは、music []はSHORTSの配列です。したがって、データが16ビットPCMであるため、readShort()メソッドはここでは意味をなすように見えます...しかし、Androidでは、問題のようです。そのコードを変更しました次へ:

     music=new byte[(int) file.length()];//size & length of the file
    InputStream             is  = new FileInputStream       (file);
    BufferedInputStream     bis = new BufferedInputStream   (is, 8000);
    DataInputStream         dis = new DataInputStream       (bis);      //  Create a DataInputStream to read the audio data from the saved file

    int i = 0;                                                          //  Read the file into the "music" array
    while (dis.available() > 0)
    {
        music[i] = dis.readByte();                                      //  This assignment does not reverse the order
        i++;
    }

    dis.close();                                                        //  Close the input stream

このバージョンでは、music []はBYTESの配列です。私はまだAudioTrackに16ビットPCMデータであることを伝えていますが、私のAndroidはこのように構成されたAudioTrackへのバイトの配列の書き込みに問題がないようです...とにかく、ようやく正しく聞こえるので、誰かがAndroidでWindowsのサウンドを再生したい場合は、なんらかの理由でそれが解決策です。ああ、エンディアン...

R.

26
Rich

この質問に対する長い回答がたくさん見つかりました。すべての切り取りと貼り付けが私のものではないという私の最終的な解決策は、次のようになります:

public boolean play() {

    int i = 0;
    byte[] music = null;
    InputStream is = mContext.getResources().openRawResource(R.raw.noise);

    at = new AudioTrack(AudioManager.STREAM_MUSIC, 44100,
        AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT,
        minBufferSize, AudioTrack.MODE_STREAM);

    try{
        music = new byte[512];
        at.play();

        while((i = is.read(music)) != -1)
            at.write(music, 0, i);

    } catch (IOException e) {
        e.printStackTrace();
    }

    at.stop();
    at.release();
    return STOPPED;
}

STOPPEDは、一時停止/再生ボタンをリセットする信号として返される単なる「true」です。そしてクラス初期化子で:

public Mp3Track(Context context) {
    mContext = context;
    minBufferSize = AudioTrack.getMinBufferSize(44100,
        AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
}

コンテキストは、呼び出しアクティビティからの単なる「これ」です。 sdcardなどでFileInputStreamを使用できます。私のファイルはres/rawにあります

9
R Earle Harris

ファイルの残りのデータをバッファにダンプする前に、ファイルの最初の44バイトをスキップしていますか?最初の44バイトはWAVEヘッダーであり、再生しようとするとランダムノイズのように聞こえます。

また、再生しようとしているWAVEと同じプロパティ(サンプルレート、ビットレート、チャネル数など)でAudioTrackを作成していますか? Windowsは、実際には、[ファイルのプロパティ]ページでこの情報を適切に提供します。 alt text

6
Aaron C

Aaron C で述べたように、最初の44バイトをスキップするか、(私が好むように)WAVEヘッダーである最初の44バイトを読み取る必要があります。このようにして、WAVEに含まれるチャネル数、サンプルあたりのビット数、長さなどがわかります。

ここ WAVEヘッダーパーサー/ライターの適切な実装を見つけることができます。

2
sixro

ひどい解析コードを永続化しないでください。 WAVの解析は簡単に実装できます http://soundfile.sapp.org/doc/WaveFormat/ そして、サンプリングレート、ビット深度、数などを解析できることに感謝しますチャンネル。

また、x86とARM(少なくともデフォルトでは)はどちらもリトルエンディアンなので、ネイティブエンディアンのWAVファイルはシャッフルせずに問題ありません。

1
yano

サンプルwavファイル:
http://www.mauvecloud.net/sounds/pcm1644m.wav

サンプルコード:

public class AudioTrackPlayer {
    Context mContext;
    int minBufferSize;
    AudioTrack at;
    boolean STOPPED;

    public AudioTrackPlayer(Context context) {
        Log.d("------","init");
        mContext = context;
        minBufferSize = AudioTrack.getMinBufferSize(44100,
                AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
    }

    public boolean play() {
        Log.d("------","play");
        int i = 0;
        byte[] music = null;
        InputStream is = mContext.getResources().openRawResource(R.raw.pcm1644m);

        at = new AudioTrack(AudioManager.STREAM_MUSIC, 44100,
                AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT,
                minBufferSize, AudioTrack.MODE_STREAM);
        try {
            music = new byte[512];
            at.play();

            while ((i = is.read(music)) != -1)
                at.write(music, 0, i);

        } catch (IOException e) {
            e.printStackTrace();
        }
        at.stop();
        at.release();
        return STOPPED;
    }
}
0
Yang

AudioTrack.MODE_STREAMではなくAudioTrack.MODE_STATICAudioTrackコンストラクター:

AudioTrack at = new AudioTrack(
  AudioManager.STREAM_MUSIC,
  sampleRate,
  AudioFormat.CHANNEL_IN_STEREO,
  AudioFormat.ENCODING_PCM_16BIT,
  // buffer length in bytes
  outputBufferSize,
  AudioTrack.MODE_STREAM
);
0
Sabin