Enregistrement audio en direct et lecture sous Android et Thread & amp; gestion du rappel

Je veux enregistrer l'audio en direct et de le jouer.Aussi loin que l'INTERFACE utilisateur est concerné, l'application dispose de trois boutons:un pour commencer l'enregistrement et la diffusion, l'un pour la lecture d'un pré fichier enregistré et le dernier pour l'arrêt de la tâche en cours(enregistrement /lecture). Pour cela j'ai utilisé AudioRecord et AudioTrack des classes pour l'enregistrement et la lecture, respectivement. Mon Programme ressemble à....

/**
* @author amit
*
*/

public class AudioRecorder extends Activity {
private String LOG_TAG = null;
/* variables which are required to generate and manage the UI of the App */
//private RecordButton mRecordButton = null;
private Button recordBtn, stopBtn, playBtn;
/*
* variables which are required for the actual functioning of the recording
* and playing
*/
private AudioRecord recorder = null;
private AudioTrack player = null;
private AudioManager audioManager = null;
private int recorderBufSize, recordingSampleRate;
private int trackBufSize;
private short[] audioData;
private boolean isRecording = false, isPlaying = false;
private Thread startRecThread;
private AudioRecord.OnRecordPositionUpdateListener posUpdateListener;
/**
* constructor method for initializing the variables
*/
public AudioRecorder() {
super();
LOG_TAG = "Constructor";
recorderBufSize = recordingSampleRate = trackBufSize = 0;
//init function will initialize all the necessary variables ...
init();
if (recorder != null && player != null) {
Log.e(LOG_TAG, "recorder and player initialized");
audioData = new short[recorderBufSize / 2]; //since we r reading shorts
} else {
Log.e(LOG_TAG, "Problem inside init function ");
}
posUpdateListener = new AudioRecord.OnRecordPositionUpdateListener() {
int numShortsRead = 0;
@Override
public void onPeriodicNotification(AudioRecord rec) {
//TODO Auto-generated method stub
//             String LOG_TAG = Thread.currentThread().getName();
//              Log.e(LOG_TAG, "inside position listener");
audioData = new short[recorderBufSize / 2]; //divide by 2 since now we are reading shorts 
numShortsRead = rec.read(audioData, 0, audioData.length);
player.write(audioData, 0, numShortsRead);
}
@Override
public void onMarkerReached(AudioRecord recorder) {
//TODO Auto-generated method stub
Log.e(LOG_TAG, "Marker Reached");
}
};
//listener will be called every time 160 frames are reached
recorder.setPositionNotificationPeriod(160);
recorder.setRecordPositionUpdateListener(posUpdateListener);
Log.e(LOG_TAG, "inside constructor");
}
private void init() {
LOG_TAG = "initFunc";
//int[] mSampleRates = new int[] { 8000, 11025, 22050, 44100 };
short audioFormat = AudioFormat.ENCODING_PCM_16BIT;
//for (int rate : mSampleRates) {
this.recordingSampleRate = AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC);
try {
//Log.d(LOG_TAG, "Attempting rate " + rate + "Hz, bits: " +
//audioFormat);
int bufrSize = AudioRecord.getMinBufferSize(this.recordingSampleRate,
AudioFormat.CHANNEL_IN_MONO, audioFormat);
//lets find out the minimum required size for AudioTrack
int audioTrackBufSize = AudioTrack.getMinBufferSize(this.recordingSampleRate,
AudioFormat.CHANNEL_OUT_MONO, audioFormat);
if (bufrSize != AudioRecord.ERROR_BAD_VALUE
&& bufrSize != AudioRecord.ERROR) {
//check if we can instantiate and have a success
if(audioTrackBufSize >= bufrSize){
this.recorderBufSize = audioTrackBufSize;
}else{
this.recorderBufSize = bufrSize;
}
AudioRecord rec = new AudioRecord(
MediaRecorder.AudioSource.DEFAULT, this.recordingSampleRate,
AudioFormat.CHANNEL_IN_MONO, audioFormat, this.recorderBufSize);
if (rec != null
&& rec.getState() == AudioRecord.STATE_INITIALIZED) {
//storing variables for future use . . .
//                 this.recordingSampleRate = rate;
//                 this.recorderBufSize = bufrSize;
Log.e(LOG_TAG,
"Returning..(rate:channelConfig:audioFormat:recorderBufSize)"
+ this.recordingSampleRate + ":" + AudioFormat.CHANNEL_IN_MONO
+ ":" + audioFormat + ":" + this.recorderBufSize);
//Now create an instance of the AudioTrack
//                 int audioTrackBufSize = AudioTrack.getMinBufferSize(rate,
//                         AudioFormat.CHANNEL_OUT_MONO, audioFormat);
Log.e(LOG_TAG, "Audio Record /Track /Final buf size :" + bufrSize + "/" +audioTrackBufSize + "/"+this.recorderBufSize);
this.player = new AudioTrack(AudioManager.STREAM_MUSIC,
this.recordingSampleRate, AudioFormat.CHANNEL_OUT_MONO, audioFormat,
this.recorderBufSize, AudioTrack.MODE_STREAM);
this.recorder = rec;
this.player.stop();
this.player.flush();
this.player.setPlaybackRate(this.recordingSampleRate);
return;
}
}
} catch (IllegalArgumentException e) {
Log.d(LOG_TAG, this.recordingSampleRate + "Exception, keep trying.", e);
} catch (Exception e) {
Log.e(LOG_TAG, this.recordingSampleRate + "Some Exception!!", e);
}
//for loop for channel config ended here. . . .
//for loop for audioFormat ended here. . .
//}//for loop for sampleRate
return;
}
private void startPlaying() {
LOG_TAG = "startPlaying";
Log.e(LOG_TAG, "start Playing");
}
private void stopPlaying() {
LOG_TAG = "stopPlaying";
Log.e(LOG_TAG, "stop Playing");
}
private void startRecording() {
LOG_TAG = "startRecording"; 
/* start a separate recording thread from here . . . */
startRecThread = new Thread() {
@Override
public void run() {
//TODO Auto-generated method stub
android.os.Process
.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
//             String LOG_TAG = Thread.currentThread().getName();
if(recorder.getRecordingState() != AudioRecord.RECORDSTATE_RECORDING){
recorder.startRecording();
}
//             Log.e(LOG_TAG, "running" +recorder.getRecordingState());
while (recorder.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING) {
recorder.read(audioData, 0, audioData.length);
try {
Thread.sleep(1000); //sleep for 2s
} catch (InterruptedException e) {
//TODO Auto-generated catch block
Log.e("run Method", "recorder thread is interrupted");
e.printStackTrace();
}
}
}
};
setVolumeControlStream(AudioManager.STREAM_MUSIC);
audioManager.setSpeakerphoneOn(false);
player.flush();     
player.play();
startRecThread.start();
Log.e(LOG_TAG, "start Recording");
}
private void stopRecording() {
LOG_TAG = "stopRecording";
recorder.stop();
if (startRecThread != null && startRecThread.isAlive()) {           
startRecThread.destroy();
startRecThread = null;
}
player.stop();
player.flush();
Log.e(LOG_TAG, "stop Recording");
}
private void stop() {
if (isRecording) {
isRecording = false;
stopRecording();
}
if (isPlaying) {
isPlaying = false;
stopPlaying();
}
recordBtn.setEnabled(true);
playBtn.setEnabled(true);
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
LOG_TAG = "onCreate";
//     Log.e(LOG_TAG, "Create Called");
//getting the audio service
audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
LinearLayout ll = new LinearLayout(this);
//creating Buttons one by one . . . .
//button to start the recording process
recordBtn = new Button(this);
recordBtn.setText("Record");
recordBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//TODO Auto-generated method stub
recordBtn.setEnabled(false);
playBtn.setEnabled(false);
isRecording = true;
startRecording();
}
});
//single button to stop recording and playing as applicable
stopBtn = new Button(this);
stopBtn.setText("Stop");
stopBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//TODO Auto-generated method stub
stop();
}
});
//button to play the recorded sound
playBtn = new Button(this);
playBtn.setText("Play");
playBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//TODO Auto-generated method stub
//reverse the isPlaying
isPlaying = true;
recordBtn.setEnabled(false);
playBtn.setEnabled(false);
startPlaying();
}
});
ll.addView(recordBtn, new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT, 1));
ll.addView(playBtn, new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT, 1));
ll.addView(stopBtn, new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT, 1));
setContentView(ll);
}
@Override
protected void onDestroy() {
//Clean up code . ..
super.onDestroy();
if (recorder != null)
recorder.release();
if (startRecThread!=null && startRecThread.isAlive())
startRecThread.destroy();
if (recorder != null)
recorder.release();
if (player != null)
player.release();
startRecThread = null;
recorder = null;
player = null;
recordBtn = null;
stopBtn = null;
playBtn = null;
audioData = null;
System.gc();
}
}

Comme vous pouvez voir que startPlaying() et stopPlaying() fonctions ne sont pas encore mis en œuvre permet donc de ne pas en parler. Actuellement, je suis juste essayer d'enregistrer et de jouer.Quand je lance le programme, Il joue l'audio enregistré, mais l'audio semble venir de loin. Un autre problème est que thread de l'INTERFACE utilisateur de l'application se bloque si j'ai un thread séparé pour la lecture de l'Audio . S'il vous plaît aider....

source d'informationauteur Amit Dwivedi