Androidオーディオ処理-AudioRecordを使用して、機能の録音、再生、停止、削除のためにPCMファイルを保存します



Android Audio Processing Use Audiorecord Save Pcm Files



http://blog.csdn.net/qq_26787115/article/details/53078951


オーディオは非常に広範で深遠です。ここでは絶対に高度なことについて話すことはできません。せいぜい、それはほんの一部の基本的な知識です。まず、Androidが提供するレコーディングクラスを紹介します。実際、彼には2つあります。1つはMediaRecorderで、もう1つは今日使用するAudioRecordです。それらの違いは何ですか?



1.違い

MediaRecorderとAudioRecordの両方がオーディオを録音できます。違いは、MediaRecorderによって録音されたオーディオファイルが圧縮されており、エンコーダーを設定する必要があることです。また、録音したオーディオファイルは、システム独自のミュージックプレーヤーで再生できます。

AudioRecordは、オーディオファイルをPCM形式で録音します。これは、最下層に近いAudioTrackで再生する必要があります。



PCMはオーディオソースファイルとしてより理解しやすいかもしれません

2.長所と短所

  • AudioRecord

主に録音と放送、およびリアルタイムのオーディオ処理を実現することです。この機能により、音声の利点により適したものになります

利点:音声のリアルタイム処理、コードを使用してさまざまなオーディオパッケージを実現できます



短所:出力はPCM形式のファイルです。オーディオファイルとして保存されている場合、プレーヤーで再生できないため、データのエンコードと圧縮を実現するためのコードを作成する必要があります。

  • MediaRecorder

は、録音、エンコード、圧縮などを統合しており、おそらくaac、amr、3gpなどの少数の録音オーディオ形式をサポートしています。

利点:統合、関連するインターフェースを直接呼び出すだけで、コードの量が少ない

短所:オーディオをリアルタイムで処理できない出力オーディオ形式が多くない、たとえば、出力mp3形式ファイルがない

三。準備

私たちが達成したいのは、録音、再生、停止、その他の機能のリアルタイムテストケースです。次に、何かを準備する必要があります。たとえば、ここでプロジェクトを作成します-PCMSample

次に、レイアウトを作成します

layout_main.xml

<LinearLayout xmlns:android='http://schemas.android.com/apk/res/android' android:layout_width='match_parent' android:layout_height='match_parent' android:orientation='vertical' android:padding='10dp'> <Button android:id='@+id/startAudio' android:layout_width='match_parent' android:layout_height='wrap_content' android:background='@drawable/button_bg' android:text='start recording' android:textColor='@android:color/white'/> <Button android:id='@+id/stopAudio' android:layout_width='match_parent' android:layout_height='wrap_content' android:layout_marginBottom='10dp' android:layout_marginTop='5dp' android:background='@drawable/button_bg' android:enabled='false' android:text='Stop recording' android:textColor='@android:color/white'/> <Button android:id='@+id/playAudio' android:layout_width='match_parent' android:layout_height='wrap_content' android:background='@drawable/button_bg' android:enabled='false' android:text='Play audio' android:textColor='@android:color/white'/> <Button android:id='@+id/deleteAudio' android:layout_width='match_parent' android:layout_height='wrap_content' android:layout_marginTop='5dp' android:background='@drawable/button_bg' android:text='Remove PCM' android:textColor='@android:color/white'/> <ScrollView android:id='@+id/mScrollView' android:layout_width='match_parent' android:layout_height='0dp' android:layout_marginTop='5dp' android:layout_weight='1'> <TextView android:id='@+id/tv_audio_succeess' android:layout_width='wrap_content' android:layout_height='wrap_content' android:text='loading finished....' android:textColor='@color/colorAccent'/> ScrollView> LinearLayout>
  • 1
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 十一
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 2. 3
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 3. 4
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • フォーファイブ
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

プレビューできます

画像

ここでは、ボタンにフラット効果を追加しました。実際、私はxmlを作成しました。これは非常に単純です。

button_bg.xml

<selector xmlns:android='http://schemas.android.com/apk/res/android'> <item android:state_pressed='true'> <shape> <corners android:radius='30dp'/> <solid android:color='@color/colorPrimary'/> shape> item> <item android:state_pressed='false'> <shape> <corners android:radius='30dp'/> <solid android:color='@color/colorPrimaryDark'/> shape> item> selector>
  • 1
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 十一
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

さて、トピックに戻ります。ここには4つのボタンがあり、1つは開始用です。停止、再生、削除、これら4つの機能を実行する必要があります。その前に、メモリカードファイルを記録および書き込みたいため、これら2つのアクセス許可が必要なため、アクセス許可を追加する必要があります。

<uses-permission android:name='android.permission.RECORD_AUDIO' /> <uses-permission android:name='android.permission.WRITE_EXTERNAL_STORAGE' />
  • 1
  • 3
  • 4

ここでは初期化については何も言いません。トピックに直接進みましょう

4.録音を開始します

記録を開始する場合、ここでは、制御する変数isRecordingを定義します。これにより、終了する方が適切です。記録をUIスレッドに配置できないことに注意してください。したがって、記録を開始するメソッドを記述できます。

//start recording public void StartRecord() { Log.i(TAG,'start recording') //16K acquisition rate int frequency = 16000 //format int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO //16Bit int audioEncoding = AudioFormat.ENCODING_PCM_16BIT //Generate PCM file file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + '/reverseme.pcm') Log.i(TAG,'Generate file') //If it exists, delete and then create if (file.exists()) file.delete() Log.i(TAG,'Delete Files') try { file.createNewFile() Log.i(TAG,'Create a file') } catch (IOException e) { Log.i(TAG,'Failed to create') throw new IllegalStateException('Failed to create' + file.toString()) } try { //Output stream OutputStream os = new FileOutputStream(file) BufferedOutputStream bos = new BufferedOutputStream(os) DataOutputStream dos = new DataOutputStream(bos) int bufferSize = AudioRecord.getMinBufferSize(frequency, channelConfiguration, audioEncoding) AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, frequency, channelConfiguration, audioEncoding, bufferSize) short[] buffer = new short[bufferSize] audioRecord.startRecording() Log.i(TAG, 'start recording') isRecording = true while (isRecording) { int bufferReadResult = audioRecord.read(buffer, 0, bufferSize) for (int i = 0 i catch (Throwable t) { Log.e(TAG, 'Recording failed') } }
  • 1
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 十一
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 2. 3
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 3. 4
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • フォーファイブ
  • 46
  • 47
  • 48

まず、ここでは、サンプリングレート、エンコーディング、オーディオストリームなどの基本的な概念を理解します。残りのほとんどは、ストリームの読み取りと書き込みの操作です。定義したisRecordingコントロールを使用して、pcmファイルを書き込むAudioRecordを作成し、whileループを定義します。これにより、クリックイベントが発生します。

case R.id.startAudio: Thread thread = new Thread(new Runnable() { @Override public void run() { StartRecord() Log.e(TAG,'start') } }) thread.start() printLog('start recording') ButtonEnabled(false, true, false) break
  • 1
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 十一
  • 12

ここでは、thread.start()に注意を払う必要があります。スレッドを開始し、同時にログを出力します。具体的なコードは次のとおりです。

//Print log private void printLog(final String resultString) { tv_audio_succeess.post(new Runnable() { @Override public void run() { tv_audio_succeess.append(resultString + ' ') mScrollView.fullScroll(ScrollView.FOCUS_DOWN) } }) }
  • 1
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

ここでは、ANRを防ぐために、ボタンのフォーカスを制御しました

//Get/lost focus private void ButtonEnabled(boolean start, boolean stop, boolean play) { startAudio.setEnabled(start) stopAudio.setEnabled(stop) playAudio.setEnabled(play) }
  • 1
  • 3
  • 4
  • 5
  • 6

さて、それを実行しましょう

画像

変更はないようですが、メモリカードに余分なpcmファイルがあります

画像

もちろん、クリックして録音を開始した場合、このpcmファイルは生成されません。録音を停止するには、停止ボタンをクリックする必要があります。

5.録音を停止します

記録を停止するのは簡単です。書き込みストリームを変更することで記録を制御できます。

case R.id.stopAudio: isRecording = false ButtonEnabled(true, false, true) printLog('Stop recording') break
  • 1
  • 3
  • 4
  • 5

これによりPCMが生成されます

6つの再生オーディオ

PCMができたので、再生を試みて、再生メソッドを記述できます。

//Play file public void PlayRecord() { if(file == null){ return } //Read file int musicLength = (int) (file.length() / 2) short[] music = new short[musicLength] try { InputStream is = new FileInputStream(file) BufferedInputStream bis = new BufferedInputStream(is) DataInputStream dis = new DataInputStream(bis) int i = 0 while (dis.available() > 0) { music[i] = dis.readShort() i++ } dis.close() AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 16000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, musicLength * 2, AudioTrack.MODE_STREAM) audioTrack.play() audioTrack.write(music, 0, musicLength) audioTrack.stop() } catch (Throwable t) { Log.e(TAG, 'Playing failed') } }
  • 1
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 十一
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 2. 3
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

上記のように、AudioTrackを使用して再生し、彼のplayメソッドを呼び出し、いくつかのパラメーターを設定する必要があります。

セブン。音声を削除する

オーディオを削除するには、このpcmファイルを削除するだけです。

//Delete Files private void deleFile() { if(file == null){ return } file.delete() printLog('File deleted successfully') }
  • 1
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

これは一般的な記録ロジックです。見た目はシンプルですが、これは多くの音声や音声、特に音声の最も基本的な部分です。あなたが声の仕事に従事しているなら、私はあなたが私に感謝すると信じています!

さて、最後に完全なコードを入れてください:

MainActivity

package com.liuguilin.pcmsample import android.media.AudioFormat import android.media.AudioManager import android.media.AudioRecord import android.media.AudioTrack import android.media.MediaRecorder import android.os.Bundle import android.os.Environment import android.support.v7.app.AppCompatActivity import android.util.Log import android.view.View import android.widget.Button import android.widget.ScrollView import android.widget.TextView import java.io.BufferedInputStream import java.io.BufferedOutputStream import java.io.DataInputStream import java.io.DataOutputStream import java.io.File import java.io.FileInputStream import java.io.FileOutputStream import java.io.IOException import java.io.InputStream import java.io.OutputStream public class MainActivity extends AppCompatActivity implements View.OnClickListener { public static final String TAG = 'PCMSample' //Whether it is recording private boolean isRecording = false //start recording private Button startAudio //End recording private Button stopAudio //Play recording private Button playAudio //Delete Files private Button deleteAudio private ScrollView mScrollView private TextView tv_audio_succeess //pcm file private File file @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) initView() } //Initialize View private void initView() { mScrollView = (ScrollView) findViewById(R.id.mScrollView) tv_audio_succeess = (TextView) findViewById(R.id.tv_audio_succeess) printLog('Initialization successful') startAudio = (Button) findViewById(R.id.startAudio) startAudio.setOnClickListener(this) stopAudio = (Button) findViewById(R.id.stopAudio) stopAudio.setOnClickListener(this) playAudio = (Button) findViewById(R.id.playAudio) playAudio.setOnClickListener(this) deleteAudio = (Button) findViewById(R.id.deleteAudio) deleteAudio.setOnClickListener(this) } //Click event @Override public void onClick(View v) { switch (v.getId()) { case R.id.startAudio: Thread thread = new Thread(new Runnable() { @Override public void run() { StartRecord() Log.e(TAG,'start') } }) thread.start() printLog('start recording') ButtonEnabled(false, true, false) break case R.id.stopAudio: isRecording = false ButtonEnabled(true, false, true) printLog('Stop recording') break case R.id.playAudio: PlayRecord() ButtonEnabled(true, false, false) printLog('Play recording') break case R.id.deleteAudio: deleFile() break } } //Print log private void printLog(final String resultString) { tv_audio_succeess.post(new Runnable() { @Override public void run() { tv_audio_succeess.append(resultString + ' ') mScrollView.fullScroll(ScrollView.FOCUS_DOWN) } }) } //Get/lost focus private void ButtonEnabled(boolean start, boolean stop, boolean play) { startAudio.setEnabled(start) stopAudio.setEnabled(stop) playAudio.setEnabled(play) } //start recording public void StartRecord() { Log.i(TAG,'start recording') //16K acquisition rate int frequency = 16000 //format int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO //16Bit int audioEncoding = AudioFormat.ENCODING_PCM_16BIT //Generate PCM file file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + '/reverseme.pcm') Log.i(TAG,'Generate file') //If it exists, delete and then create if (file.exists()) file.delete() Log.i(TAG,'Delete Files') try { file.createNewFile() Log.i(TAG,'Create a file') } catch (IOException e) { Log.i(TAG,'Failed to create') throw new IllegalStateException('Failed to create' + file.toString()) } try { //Output stream OutputStream os = new FileOutputStream(file) BufferedOutputStream bos = new BufferedOutputStream(os) DataOutputStream dos = new DataOutputStream(bos) int bufferSize = AudioRecord.getMinBufferSize(frequency, channelConfiguration, audioEncoding) AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, frequency, channelConfiguration, audioEncoding, bufferSize) short[] buffer = new short[bufferSize] audioRecord.startRecording() Log.i(TAG, 'start recording') isRecording = true while (isRecording) { int bufferReadResult = audioRecord.read(buffer, 0, bufferSize) for (int i = 0 i catch (Throwable t) { Log.e(TAG, 'Recording failed') } } //Play file public void PlayRecord() { if(file == null){ return } //Read file int musicLength = (int) (file.length() / 2) short[] music = new short[musicLength] try { InputStream is = new FileInputStream(file) BufferedInputStream bis = new BufferedInputStream(is) DataInputStream dis = new DataInputStream(bis) int i = 0 while (dis.available() > 0) { music[i] = dis.readShort() i++ } dis.close() AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 16000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, musicLength * 2, AudioTrack.MODE_STREAM) audioTrack.play() audioTrack.write(music, 0, musicLength) audioTrack.stop() } catch (Throwable t) { Log.e(TAG, 'Playing failed') } } //Delete Files private void deleFile() { if(file == null){ return } file.delete() printLog('File deleted successfully') } }
  • 1
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 十一
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 2. 3
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 3. 4
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • フォーファイブ
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212

オーディオテストのためにこれらのpcmファイルをデバッグしたい場合は、Audacityソフトウェアを使用することをお勧めします。ご覧のとおり、左上隅にあるfile-import-sourceファイルを直接クリックして、16Kに設定します。

画像

デバッグできるように

画像

最後に、完全なスクリーンショットを置きます

画像

さて、この記事はここにあります、まだいくつかの基本があります、私はあなたに次回より高度な記事を持ってくることができることを願っています、そしてグループに参加することに興味がある人:555974449

サンプルダウンロード: http://download.csdn.net/detail/qq_26787115/9676003