• 沒有找到結果。

Raw Audio Capture and Playback Example

在文檔中 Android media (頁 186-193)

Here is a full example that records using AudioRecord and plays back using AudioTrack.

Each of these operations lives in their own thread through the use of AsyncTask, so that they don’t make the application become unresponsive by running in the main thread.

package com.apress.proandroidmedia.ch07.altaudiorecorder;

public class AltAudioRecorder extends Activity implements OnClickListener {

We have two inner classes defined—one for the recording and one for the playback.

Each one extends AsyncTask.

RecordAudio recordTask;

PlayAudio playTask;

Button startRecordingButton, stopRecordingButton, startPlaybackButton, stopPlaybackButton;

TextView statusText;

File recordingFile;

We’ll use Booleans to keep track of whether we should be recording and playing. These will be used in the loops in recording and playback tasks.

boolean isRecording = false;

boolean isPlaying = false;

Here are the variables that we’ll use to define the configuration of both the AudioRecord and AudioTrack objects.

// These should really be constants themselves int frequency = 11025;

int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;

int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;

@Override

public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

setContentView(R.layout.main);

statusText = (TextView) this.findViewById(R.id.StatusTextView);

startRecordingButton = (Button) this .findViewById(R.id.StartRecordingButton);

stopRecordingButton = (Button) this .findViewById(R.id.StopRecordingButton);

startPlaybackButton = (Button) this .findViewById(R.id.StartPlaybackButton);

stopPlaybackButton = (Button) this.findViewById(R.id.StopPlaybackButton);

startRecordingButton.setOnClickListener(this);

stopRecordingButton.setOnClickListener(this);

startPlaybackButton.setOnClickListener(this);

stopPlaybackButton.setOnClickListener(this);

stopRecordingButton.setEnabled(false);

startPlaybackButton.setEnabled(false);

stopPlaybackButton.setEnabled(false);

The last thing we’ll do in the constructor is create the file that we’ll record to and play back from. In this case, we are creating the file in the preferred location for files associated with an application on the SD card.

File path = new File(Environment.getExternalStorageDirectory()

.getAbsolutePath() + "/Android/data/com.apress.proandroidmedia.ch07

.altaudiorecorder/files/");

path.mkdirs();

try {

recordingFile = File.createTempFile("recording", ".pcm", path);

} catch (IOException e) {

throw new RuntimeException("Couldn't create file on SD card", e);

} }

The onClick method handles the Button presses generated by the user. Each one corresponds to a specific method.

public void onClick(View v) {

To start playback, we construct a new PlayAudio object and call its execute method, which is inherited from AsyncTask.

public void play() {

startPlaybackButton.setEnabled(true);

playTask = new PlayAudio();

playTask.execute();

stopPlaybackButton.setEnabled(true);

}

To stop playback, we set the isPlaying Boolean to false and that’s it. This will cause the PlayAudio object’s loop to finish.

public void stopPlaying() { isPlaying = false;

stopPlaybackButton.setEnabled(false);

startPlaybackButton.setEnabled(true);

}

To start recording, we construct a RecordAudio object and call its execute method.

public void record() {

startRecordingButton.setEnabled(false);

stopRecordingButton.setEnabled(true);

// For Fun

startPlaybackButton.setEnabled(true);

recordTask = new RecordAudio();

recordTask.execute();

}

To stop recording, we simply set the isRecording Boolean to false. This allows the RecordAudio object to stop looping and perform any cleanup.

public void stopRecording() { isRecording = false;

}

Here is our PlayAudio inner class. This class extends AsyncTask and uses an AudioTrack object to play back the audio.

private class PlayAudio extends AsyncTask<Void, Integer, Void> { @Override

audioTrack.play();

Last is our RecordAudio class, which extends AsyncTask. This class runs an AudioRecord object in the background and calls publishProgress to update the UI with an indication of recording progress.

private class RecordAudio extends AsyncTask<Void, Integer, Void> { @Override

r++;

When publishProgress is called, onProgressUpdate is the method called.

protected void onProgressUpdate(Integer... progress) { statusText.setText(progress[0].toString());

}

When the doInBackground method completes, the following onPostExecute method is called.

Here is the layout XML for the foregoing example:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

<TextView

android:layout_width="fill_parent"

android:layout_height="wrap_content" android:text="Status" android:id=

"@+id/StatusTextView"/>

<Button android:layout_width="wrap_content" android:layout_height="wrap_content"

android:text="Start Recording" android:id="@+id/StartRecordingButton"></Button>

<Button android:layout_width="wrap_content" android:layout_height="wrap_content"

android:text="Stop Recording" android:id="@+id/StopRecordingButton"></Button>

<Button android:layout_width="wrap_content" android:layout_height="wrap_content"

android:text="Start Playback" android:id="@+id/StartPlaybackButton"></Button>

<Button android:layout_width="wrap_content" android:layout_height="wrap_content"

android:text="Stop Playback" android:id="@+id/StopPlaybakButton" ></Button>

</LinearLayout>

And, we’ll need to add these permissions to AndroidManifest.xml.

<uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">

</uses-permission>

As we have seen, using the AudioRecord and AudioTrack classes to create a capture and playback application is much more cumbersome than working with the MediaRecorder and MediaPlayer classes. But as we’ll see in the next chapter, it is worth the effort when we need to do any type of audio processing or want to synthesize audio.

Summary

In this chapter, we looked at three different methods for recording audio on Android.

Each of them comes with their own plusses and minuses. Using the built-in sound recorder is great for no-fuss audio recordings, where little or no programmatic control is needed. Using the MediaRecorder allows us to take it a step further, allowing control over the length of time media is recorded and other aspects but leaving the interface up to us. Last we investigated the ability to record raw samples with AudioRecord. Using this we have the most control and flexibility but have to do the most work in order to capture and work with the audio.

In the next chapter, we’ll look more at audio possibilities, investigating audio processing and synthesis.

Download from Wow! eBook <www.wowebook.com>

179

Chapter

Audio Synthesis

在文檔中 Android media (頁 186-193)