在我的应用程序中,我想使用AudioTrack
类播放我录制的一些声音。我通过AudioRecord
对象录制音频,读取对象,然后我想播放录制的声音。但是,我现在编程的方式将导致AudioTrack-JNI
中的错误,该错误会说“不支持缓冲区直接访问,无法记录”。
代码如下所示:
public class RecorderThread extends Thread{
private static AudioRecord mAudioRecorder;
private final int USE_MIC = MediaRecorder.AudioSource.MIC;
private static final int FREQUENCY = 8000;
private int mBuffSize, mChannel, mEncoding;
private byte[] mBuffer;
private Context mContext;
private volatile boolean mContinueLoop = true,
mDataPresent = false,
mProcessData = false;
private BroadcastReceiver mActionListener = new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent){
if(intent.getAction().equals(mContext.getString(R.string.STOP_THREAD))){
mContinueLoop = false;
Thread.currentThread().interrupt();
} else if(intent.getAction().equals(mContext.getString(R.string.START_RECORDING))){
mAudioRecorder.startRecording();
} else if(intent.getAction().equals(mContext.getString(R.string.STOP_RECORDING))){
mAudioRecorder.stop();
mDataPresent = true;
} else if(intent.getAction().equals(mContext.getString(R.string.PROCESS_DATA))){
if(mDataPresent){
mProcessData = true;
mDataPresent = false;
}
}
}
};
public RecorderThread(Context context){
mContext = context;
mChannel = AudioFormat.CHANNEL_IN_MONO;
mEncoding = AudioFormat.ENCODING_PCM_16BIT;
mBuffSize = AudioRecord.getMinBufferSize(FREQUENCY, mChannel, mEncoding);
mBuffer = new byte[FREQUENCY * 10];
mAudioRecorder = new AudioRecord(USE_MIC, FREQUENCY, mChannel, mEncoding, mBuffer.length);
IntentFilter filter = new IntentFilter();
filter.addAction(mContext.getString(R.string.START_RECORDING));
filter.addAction(mContext.getString(R.string.STOP_RECORDING));
filter.addAction(mContext.getString(R.string.PROCESS_DATA));
filter.addAction(mContext.getString(R.string.STOP_THREAD));
mContext.registerReceiver(mActionListener, filter);
}
@Override
public void run(){
while(mContinueLoop){
if(mProcessData){
// Process data.
ByteBuffer sampledData = ByteBuffer.wrap(mBuffer);
int readSamples = mAudioRecorder.read(sampledData, sampledData.limit());
processData(sampledData, readSamples);
mProcessData = false;
}
try{
Thread.sleep(100);
} catch(InterruptedException e){
e.printStackTrace();
}
}
mAudioRecorder.release();
}
private void processData(ByteBuffer sampledData, int readSamples) {
byte[] data = sampledData.array();
AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC,
FREQUENCY,
AudioFormat.CHANNEL_OUT_MONO,
mEncoding,
data.length,
AudioTrack.MODE_STATIC);
if(track != null){
track.write(data, 0, data.length);
track.play();
track.release();
}
}
}
我查看了制作AudioTrack-JNI
的本机代码(http://www.netmite.com/android/mydroid/1.6/frameworks/base/core/jni/android_media_AudioRecord.cpp),但这并没有让它更清楚。弹出此错误的唯一情况是缓冲区容量<= 0或此缓冲区的地址为空时。
所以是的,我不知道为什么这不起作用......任何有更多经验的人都可能......所以请赐教我?提前谢谢......
答案 0 :(得分:0)
音轨必须采用wav或采样音频数据 乐器数字接口(MIDI)数据
答案 1 :(得分:0)
我已经做了一些调试,发现问题不是AudioTrack
,而是使用AudioRecord.read()
方法。尽管如此,仍然没有得到解决方案......任何人?
答案 2 :(得分:0)
使用AudioRecord.read(short [],int,int)或AudioRecord.read(byte [],int,int) 而不是AudioRecord.read(java.nio.ByteBuffer,int);