banner
jzman

jzman

Coding、思考、自觉。
github

Android音声再生の詳細な解説

前面のいくつかの記事では、MediaCodecMediaMuxerAudioRecordなどの音声およびビデオに関連する知識について説明しました。これらはすべて Android の音声およびビデオ開発で必要なものであり、以下の関連記事へのリンクを含みます:

Android で一般的に使用されるオーディオ再生インターフェースには、MediaPlayerAudioTrackSoundPoolがあります。オーディオのレンダリングには、AudioTrackOpenSL ESが最も一般的に使用されます。以下では、AudioTrackに関連する情報を紹介します。主な内容は次のとおりです:

  1. AudioTrack の紹介
  2. AudioTrack の作成
  3. AudioTrack へのオーディオデータの書き込み
  4. AudioTrack のライフサイクル
  5. AudioTrack の使用方法

AudioTrack の紹介#

AudioTrackは、元のpcm形式のオーディオデータを再生するために使用されます。AudioTrackには 2 つの再生モードがあります:

  • MODE_STATIC:このモードでは、オーディオデータは一度にオーディオバッファに書き込まれます。メモリが少なく、できるだけ遅延の少ない短い音声シーン(ゲームの効果音、着信音、システムの通知音など)の処理に適しています。このモードでは、最小のオーバーヘッドが発生します。
  • MODE_STREAM:このモードでは、オーディオデータが継続的に書き込まれます。オーディオデータを継続的に受け取る必要がある場合に使用されます。このモードは、一部のオーディオデータが長時間続くか、またはオーディオの特性(高いサンプリングレート、より高いビット深度など)により、メモリに一度に書き込むことができない場合に使用されます。PCM形式のオリジナルオーディオデータを正常に再生するには、このモードを選択します。

MediaPlayerと比較すると、MediaPlayerは異なるタイプや形式の音声ファイルを再生できますが、内部で対応するオーディオデコーダが作成されます。一方、AudioTrackPCM形式のオリジナルオーディオデータのみを受け取ります。MediaPlayerは内部でAudioTrackを作成し、デコードされたPCMストリームをAudioTrackに渡し、AudioTrackAudioFlingerにミキシングされ、最終的にハードウェアで再生されます。

AudioTrack の作成#

AudioTrackは、次の方法で作成されます:

// Android 5.0以降
AudioTrack(
    attributes: AudioAttributes!, 
    format: AudioFormat!, 
    bufferSizeInBytes: Int, 
    mode: Int, 
    sessionId: Int)

上記のコンストラクタのパラメータは次のような意味を持ちます:

  • attributes:オーディオストリームの情報を表す属性のセットです。Android 5.0 以降では、AudioAttributesを使用してストリームタイプの設定を置き換えるようになりました。より多くの情報を伝えることができるため、オーディオの目的や内容などを設定するために使用されます。
  • format:AudioTrackが受け入れるオーディオフォーマットを表します。リニア PCM の場合、サンプルごとのサイズ(8、16、32 ビット)と表現形式(整数型、浮動小数点型)を反映します。オーディオフォーマットはAudioFormatで定義されており、一般的なオーディオデータフォーマットでは、AudioFormat.ENCODING_PCM_16BITのみがすべてのデバイスで正常に使用できることが保証されています。AudioFormat.ENCODING_PCM_8BITのようなフォーマットは、すべてのデバイスで正常に使用できることが保証されていません。
  • bufferSizeInBytes:オーディオデータバッファのサイズをバイト単位で表します。一般的に、バッファサイズはオーディオフレームサイズの非ゼロの倍数である必要があります。再生モードがMODE_STATICの場合、バッファサイズは再生するオーディオのサイズになります。再生モードがMODE_STREAMの場合、バッファサイズは最小バッファサイズより小さくすることはできず、getMinBufferSizeが返すサイズより小さくすることはできません。
  • mode:再生モードを表します。AudioTrackMODE_STATICMODE_STREAMの 2 つのモードを提供しています。MODE_STATICはオーディオリソースを一度にオーディオバッファに書き込みます。遅延が小さく、オーディオリソースのメモリ使用量が少ないシーン(着信音、システムの通知音など)に適しています。MODE_STREAMは、データを継続的に書き込む必要があるシーンに適しています。MODE_STATICに比べて遅延があるかもしれませんが、継続的にオーディオデータを受け取ることができます。
  • sessionId:オーディオセッション ID です。ここではAudioManager.AUDIO_SESSION_ID_GENERATEを使用して、下層のオーディオフレームワークが自動的にsessionIdを生成するようにします。

AudioTrack へのオーディオデータの書き込み#

ストリームモード(STREAM_MODE)または静的バッファモード(STATIC_MODE)のいずれかで、再生するためにはwriteメソッドを使用してオーディオデータを書き込む必要があります。主なwriteメソッドは次のとおりです:

// AudioTrackのコンストラクタで指定されたフォーマットはAudioFormat#ENCODING_PCM_8BITである必要があります
open fun write(audioData: ByteArray, offsetInBytes: Int, sizeInBytes: Int): Int
// AudioTrackのコンストラクタで指定されたフォーマットはAudioFormat#ENCODING_PCM_16BITである必要があります
open fun write(audioData: ShortArray, offsetInShorts: Int, sizeInShorts: Int): Int
// AudioTrackのコンストラクタで指定されたフォーマットはAudioFormat#ENCODING_PCM_FLOATである必要があります
open fun write(audioData: FloatArray, offsetInFloats: Int, sizeInFloats: Int, writeMode: Int): Int

オーディオデータの書き込みは、0 以上の値を返します。一般的なオーディオデータの読み取り例外は次のとおりです:

  1. ERROR_INVALID_OPERATION:AudioTrackが初期化されていません。
  2. ERROR_BAD_VALUE:パラメータが無効です。
  3. ERROR_DEAD_OBJECT:オーディオデータが一部転送された場合にエラーコードが返されない場合、次のwrite呼び出しでエラーコードが返されます。

これは、AudioRecordreadメソッドといくつかの類似点があります。詳細については、公式ドキュメントを参照してください。

AudioTrack のライフサイクル#

AudioTrackのライフサイクルは、主にSTATE_UNINITIALIZEDSTATE_INITIALIZEDSTATE_NO_STATIC_DATAの 3 つの状態で構成されます。STATE_INITIALIZEDSTREAM_MODEに対応し、STATE_NO_STATIC_DATASTATIC_MODEに対応します。再生状態はあまり重要ではありません。以下の図に示すようになります:

Mermaid Loading...

AudioTrack の使用方法#

AudioTrackの使用方法は、PCMファイルからデータを読み取り、読み取ったオーディオをAudioTrackに書き込んで再生することです。主なコードは次のとおりです:

// AudioTrackの初期化
private fun initAudioTrack() {
    bufferSize = AudioTrack
        .getMinBufferSize(SAMPLE_RATE, CHANNEL_CONFIG, AUDIO_FORMAT)
    attributes = AudioAttributes.Builder()
        .setUsage(AudioAttributes.USAGE_MEDIA) // オーディオの用途を設定
        .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) // オーディオのコンテンツタイプを設定
        .build()
    audioFormat = AudioFormat.Builder()
        .setSampleRate(SAMPLE_RATE)
        .setChannelMask(AudioFormat.CHANNEL_OUT_MONO)
        .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
        .build()
    audioTrack = AudioTrack(
        attributes, audioFormat, bufferSize,
        AudioTrack.MODE_STREAM, AudioManager.AUDIO_SESSION_ID_GENERATE
    )
}
// AudioTrackへのオーディオデータの書き込み
private fun writeAudioData(){
    scope.launch(Dispatchers.IO){
        val pcmFile = File(pcmFilePath)
        val ins = FileInputStream(pcmFile)
        val bytes = ByteArray(bufferSize)
        var len: Int
        while (ins.read(bytes).also { len = it } > 0){
            audioTrack.write(bytes, 0, len)
        }
        audioTrack.stop()
    }
}
// 再生を開始
private fun start(){
    audioTrack.play()
    writeAudioData()
}

AudioTrackの使用方法は基本的に上記のとおりです。AudioTrackでオーディオを再生する関連するコードに興味がある場合は、コメントを残してください。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。