Я написал приложение, которое записывает мой голос и воспроизводит его. В части воспроизведения я использовал обзор переработчика. Каждый элемент описывает / оказывает определенный эффект на захват звука.
Сейчас я просто использовал эффект PresetReverb и играл с его конфигурациями, такими как LargeRoom, LargeHall и т. Д.
Когда я нажимаю на элементы, я слышу свой голос с некоторым эффектом, как и ожидалось, но через некоторое время он падает.
Ради краткости я хочу показать класс ViewHolder из RecyclerView, потому что этот внутренний класс прослушивает, по какому элементу щелкают, и на основании этого он вызывает правильный метод для установки желаемого эффекта:
public class SoundEffectAdapter extends RecyclerView.Adapter<SoundEffectAdapter.ViewHolder> {
// ...
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
private CardView mCardView;
public ViewHolder(CardView v){
super(v);
v.setOnClickListener(this);
mCardView = v;
}
@Override
public void onClick(View view) {
TextView mTextView = (TextView) mCardView.findViewById(R.id.soundEffectName);
String soundEffect = mTextView.getText().toString();
//Log.d("Sound", "" + soundEffect);
switch (soundEffect){
case "LargeRoom":
Log.d("Sound", "LargeRoom is clicked");
presetReverbWithLargeRoom();
break;
case "LargeHall":
Log.d("Sound", "LargeHall is clicked");
presetReverbWithLargeHall();
break;
case "MediumHall":
Log.d("Sound", "MediumHall is clicked");
presetReverbWithMediumHall();
break;
case "MediumRoom":
Log.d("Sound", "MediumRoom is clicked");
presetReverbWithMediumRoom();
break;
case "SmallRoom":
Log.d("Sound", "SmallRoom is clicked");
presetReverbWithSmallRoom();
break;
case "EnvironmentalReverb":
Log.d("Sound", "EnvironmentalReverb is clicked");
environmentalReverb();
break;
}
}
/* wrapper for the PRESET_ENVIRONMENTALREVERB effect*/
private void environmentalReverb() {
PresetReverbMethods presetReverb = new PresetReverbMethods();
presetReverb.environmentalReverb();
}
/* wrapper for the PRESET_SMALLROOM effect*/
private void presetReverbWithSmallRoom() {
PresetReverbMethods presetReverb = new PresetReverbMethods();
presetReverb.smallRoom();
}
/* wrapper for the PRESET_MEDIUMROOM effect*/
private void presetReverbWithMediumRoom() {
PresetReverbMethods presetReverb = new PresetReverbMethods();
presetReverb.mediumRoom();
}
/* wrapper for the PRESET_MEDIUMHALL effect*/
private void presetReverbWithMediumHall() {
PresetReverbMethods presetReverb = new PresetReverbMethods();
presetReverb.mediumHall();
}
/* wrapper for the PRESET_LARGEHALL effect*/
private void presetReverbWithLargeHall() {
PresetReverbMethods presetReverb = new PresetReverbMethods();
presetReverb.largeHall();
}
/* wrapper for the PRESET_LARGEROOM effect*/
private void presetReverbWithLargeRoom() {
PresetReverbMethods presetReverb = new PresetReverbMethods();
presetReverb.largeRoom();
}
// ... OTHER METHODS OF THE ADAPTER
// .... onCreateViewHolder() etc.
}
}
Теперь методы определены в PresetReverbMethods.java:
public class PresetReverbMethods {
public MediaPlayer mMediaPlayer;
public PresetReverbMethods() {
mMediaPlayer = new MediaPlayer();
}
public void largeRoom(){
mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.i(TAG, "onError called..." + " what: " + what + " extra: " + extra);
switch (what) {
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
Log.i(TAG, "Unknown error: " + extra);
return true;
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
Log.i(TAG, "Server died error: " + extra);
return true;
default:
Log.i(TAG, "Error not handled");
return false;
}
}
});
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
//called if
// no error listener set or
// if error listener returns false and
// when end of media source reached
Log.i(TAG, "in on completion listener");
// the player object is now in the PlaybackCompleted state.
}
});
try {
//transfers player from Idle state into initialized state
mMediaPlayer.setDataSource(FILE_NAME);
} catch (IOException e) {
Log.e(TAG, "IOException: " + e);
} catch (IllegalArgumentException e) {
Log.e(TAG, "IllegalArgumentException: " + e);
}
// asynchronously prepares the player for playback
mMediaPlayer.prepareAsync();
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
/* PresetReverbMethods with PRESET_LARGEROOM */
android.media.audiofx.PresetReverb mReverb = new android.media.audiofx.PresetReverb(0,mMediaPlayer.getAudioSessionId());
mReverb.setPreset(PresetReverb.PRESET_LARGEROOM);
mReverb.setEnabled(true);
mMediaPlayer.setAuxEffectSendLevel(1.0f);
// the media source is now ready for playback
mMediaPlayer.start();
}
});
}
public void largeHall(){
mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.i(TAG, "onError called..." + " what: " + what + " extra: " + extra);
switch (what) {
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
Log.i(TAG, "Unknown error: " + extra);
return true;
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
Log.i(TAG, "Server died error: " + extra);
return true;
default:
Log.i(TAG, "Error not handled");
return false;
}
}
});
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
//called if
// no error listener set or
// if error listener returns false and
// when end of media source reached
Log.i(TAG, "in on completion listener");
// the player object is now in the PlaybackCompleted state.
}
});
try {
//transfers player from Idle state into initialized state
mMediaPlayer.setDataSource(FILE_NAME);
} catch (IOException e) {
Log.e(TAG, "IOException: " + e);
} catch (IllegalArgumentException e) {
Log.e(TAG, "IllegalArgumentException: " + e);
}
// asynchronously prepares the player for playback
mMediaPlayer.prepareAsync();
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
/* PresetReverbMethods with PRESET_LARGEROOM */
android.media.audiofx.PresetReverb mReverb = new android.media.audiofx.PresetReverb(0,mMediaPlayer.getAudioSessionId());
mReverb.setPreset(PresetReverb.PRESET_LARGEHALL);
mReverb.setEnabled(true);
mMediaPlayer.setAuxEffectSendLevel(1.0f);
// the media source is now ready for playback
mMediaPlayer.start();
}
});
}
public void mediumHall(){
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.i(TAG, "onError called..." + " what: " + what + " extra: " + extra);
switch (what) {
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
Log.i(TAG, "Unknown error: " + extra);
return true;
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
Log.i(TAG, "Server died error: " + extra);
return true;
default:
Log.i(TAG, "Error not handled");
return false;
}
}
});
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
//called if
// no error listener set or
// if error listener returns false and
// when end of media source reached
Log.i(TAG, "in on completion listener");
// the player object is now in the PlaybackCompleted state.
}
});
try {
//transfers player from Idle state into initialized state
mMediaPlayer.setDataSource(FILE_NAME);
} catch (IOException e) {
Log.e(TAG, "IOException: " + e);
} catch (IllegalArgumentException e) {
Log.e(TAG, "IllegalArgumentException: " + e);
}
// asynchronously prepares the player for playback
mMediaPlayer.prepareAsync();
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
/* PresetReverbMethods with PRESET_LARGEROOM */
android.media.audiofx.PresetReverb mReverb = new android.media.audiofx.PresetReverb(0,mMediaPlayer.getAudioSessionId());
mReverb.setPreset(PresetReverb.PRESET_MEDIUMHALL);
mReverb.setEnabled(true);
mMediaPlayer.setAuxEffectSendLevel(1.0f);
// the media source is now ready for playback
mMediaPlayer.start();
}
});
}
public void mediumRoom() {
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.i(TAG, "onError called..." + " what: " + what + " extra: " + extra);
switch (what) {
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
Log.i(TAG, "Unknown error: " + extra);
return true;
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
Log.i(TAG, "Server died error: " + extra);
return true;
default:
Log.i(TAG, "Error not handled");
return false;
}
}
});
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
//called if
// no error listener set or
// if error listener returns false and
// when end of media source reached
Log.i(TAG, "in on completion listener");
// the player object is now in the PlaybackCompleted state.
}
});
try {
//transfers player from Idle state into initialized state
mMediaPlayer.setDataSource(FILE_NAME);
} catch (IOException e) {
Log.e(TAG, "IOException: " + e);
} catch (IllegalArgumentException e) {
Log.e(TAG, "IllegalArgumentException: " + e);
}
// asynchronously prepares the player for playback
mMediaPlayer.prepareAsync();
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
/* PresetReverbMethods with PRESET_LARGEROOM */
android.media.audiofx.PresetReverb mReverb = new android.media.audiofx.PresetReverb(0,mMediaPlayer.getAudioSessionId());
mReverb.setPreset(PresetReverb.PRESET_MEDIUMROOM);
mReverb.setEnabled(true);
mMediaPlayer.setAuxEffectSendLevel(1.0f);
// the media source is now ready for playback
mMediaPlayer.start();
}
});
}
public void smallRoom() {
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.i(TAG, "onError called..." + " what: " + what + " extra: " + extra);
switch (what) {
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
Log.i(TAG, "Unknown error: " + extra);
return true;
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
Log.i(TAG, "Server died error: " + extra);
return true;
default:
Log.i(TAG, "Error not handled");
return false;
}
}
});
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
//called if
// no error listener set or
// if error listener returns false and
// when end of media source reached
Log.i(TAG, "in on completion listener");
// the player object is now in the PlaybackCompleted state.
}
});
try {
//transfers player from Idle state into initialized state
mMediaPlayer.setDataSource(FILE_NAME);
} catch (IOException e) {
Log.e(TAG, "IOException: " + e);
} catch (IllegalArgumentException e) {
Log.e(TAG, "IllegalArgumentException: " + e);
}
// asynchronously prepares the player for playback
mMediaPlayer.prepareAsync();
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
android.media.audiofx.PresetReverb mReverb = new android.media.audiofx.PresetReverb(0,mMediaPlayer.getAudioSessionId());
mReverb.setPreset(PresetReverb.PRESET_SMALLROOM);
mReverb.setEnabled(true);
mMediaPlayer.setAuxEffectSendLevel(1.0f);
mMediaPlayer.start();
}
});
}
public void environmentalReverb(){
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.i(TAG, "onError called..." + " what: " + what + " extra: " + extra);
switch (what) {
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
Log.i(TAG, "Unknown error: " + extra);
return true;
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
Log.i(TAG, "Server died error: " + extra);
return true;
default:
Log.i(TAG, "Error not handled");
return false;
}
}
});
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
Log.i(TAG, "in on completion listener");
}
});
try {
mMediaPlayer.setDataSource(FILE_NAME);
} catch (IOException e) {
Log.e(TAG, "IOException: " + e);
} catch (IllegalArgumentException e) {
Log.e(TAG, "IllegalArgumentException: " + e);
} catch (RuntimeException e){
Log.e(TAG, "RuntimeException: " + e.getMessage() );
}
// asynchronously prepares the player for playback
mMediaPlayer.prepareAsync();
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
EnvironmentalReverb environmentalReverb = new EnvironmentalReverb(0, mMediaPlayer.getAudioSessionId());
environmentalReverb.setRoomLevel((short) -1000);
environmentalReverb.setRoomHFLevel((short) -500);
environmentalReverb.setDecayTime(3920);
environmentalReverb.setDecayHFRatio((short) 700);
environmentalReverb.setReflectionsLevel((short) -1230);
environmentalReverb.setReflectionsDelay(20);
environmentalReverb.setReverbLevel((short) -2);
environmentalReverb.setReverbDelay(29);
environmentalReverb.setDiffusion((short) 1000);
environmentalReverb.setDensity((short) 1000);
environmentalReverb.setEnabled(true);
mMediaPlayer.start();
}
});
}
}
Когда я запускаю приложение, все в порядке. Но после тестирования эффектов на аудио, которое я сделал, он вылетает со следующим сообщением об ошибке:
04-23 16:25:24.999 21821-21821/com.celik.abdullah.presetreverb
E/AudioEffect: set(): AudioFlinger could not create effect, status:
-38 04-23 16:25:24.999 21821-21821/com.celik.abdullah.presetreverb E/AudioEffects-JNI: Error setting AudioEffect 04-23 16:25:24.999
21821-21821/com.celik.abdullah.presetreverb E/AudioEffect-JAVA: Error
code -19 when initializing AudioEffect. 04-23 16:25:25.000
21821-21821/com.celik.abdullah.presetreverb D/AndroidRuntime: Shutting
down VM 04-23 16:25:25.005 21821-21821/com.celik.abdullah.presetreverb
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.celik.abdullah.presetreverb, PID: 21821
java.lang.RuntimeException: Cannot initialize effect engine for type: 47382d60-ddd8-11db-bf3a-0002a5d5c51b Error: -19
at android.media.audiofx.AudioEffect.<init>(AudioEffect.java:425)
at android.media.audiofx.PresetReverb.<init>(PresetReverb.java:128)
at com.celik.abdullah.presetreverb.PresetReverbMethods$15.onPrepared(PresetReverbMethods.java:347)
at android.media.MediaPlayer$EventHandler.handleMessage(MediaPlayer.java:3824)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6776)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)
Здесь GIF, который я сделал, чтобы лучше визуализировать всю проблему (его не видно, но я нажимаю на каждый из пунктов повторного просмотра, пока приложение не падает):
Почему это происходит? Что мне нужно сделать лучше?
Заранее благодарим за ваши усилия.