我很抱歉,如果这是一个微不足道的问题,但我是Android的新手并且花了几天时间搜索,但没有答案或信息让我满意。
我希望使用Android手机每隔30秒录制一段长度约为3秒的录音。每条记录都会发送到我的PC(使用TCP / IP协议)进行进一步处理。
以下是Android方面的代码(我在这个问题中引用了@TechEnd的代码:Android AudioRecord example):
private final int AUD_RECODER_SAMPLERATE = 44100; // 44.1 kHz
private final int AUD_RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO;
private final int AUD_RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
private final int AUD_RECORDER_BUFFER_NUM_ELEMENTS = 131072; // ~~ 1.486 second ???
private final int AUD_RECORDER_BUFFER_BYTES_PER_ELEMENT = 2;
private AudioRecord audioRecorder = null;
private boolean isAudioRecording = false;
private Runnable runnable = null;
private Handler handler = null;
private final int AUD_RECORDER_RECORDING_PERIOD = 30000; // one fire every 30 seconds
private byte[] bData = new byte[AUD_RECORDER_BUFFER_NUM_ELEMENTS*AUD_RECORDER_BUFFER_BYTES_PER_ELEMENT];
public void start() {
audioRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, AUD_RECODER_SAMPLERATE, AUD_RECORDER_CHANNELS, AUD_RECORDER_AUDIO_ENCODING, AUD_RECORDER_BUFFER_NUM_ELEMENTS*AUD_RECORDER_BUFFER_BYTES_PER_ELEMENT);
audioRecorder.startRecording();
isAudioRecording = true;
handler = new Handler();
runnable = new Runnable() {
@Override
public void run() {
if (isAudioRecording) {
int nElementRead = audioRecorder.read(bData, 0, bData.length);
net_send(bData, 0, nElementRead);
}
handler.postDelayed(this, AUD_RECORDER_RECORDING_PERIOD);
}
};
handler.postDelayed(runnable, AUD_RECORDER_RECORDING_PERIOD);
}
public void stop() {
isAudioRecording = false;
if (audioRecorder != null) {
audioRecorder.stop();
audioRecorder.release();
audioRecorder = null;
}
handler.removeCallbacks(runnable);
}
public void net_send(byte[] data, int nbytes) {
try {
dataOutputStream.writeInt(nbytes);
dataOutputStream.write(data,0,nbytes);
} catch (IOException e) {
e.printStackTrace();
}
}
在PC端(用C编写的服务器),收到一条记录后(我检查了它们都是262144字节),我首先将字节数组写入二进制文件(扩展名为.raw)并用Free Audio打开编辑器(http://www.free-audio-editor.com/)并获得持续时间为1.486秒的结果 https://www.dropbox.com/s/xzml51jzvagl6dy/aud1.PNG?dl=0
然后我使用此函数将每两个连续字节转换为2字节整数
short bytes2short( const char num_buf[2] )
{
return(
( ( num_buf[1] & 0xFF ) << 8 ) |
( num_buf[0] & 0xFF )
);
}
并用Excel写入文件(长度为131072字节)和绘图(标准化的),得到类似的图形。
根据我的计算,一秒钟内记录的字节数为44100(样本/秒)* 1(秒)* 2(字节/样本/通道)* 1(通道)= 88200字节。 因此,对于长度为131072 * 2(字节)的缓冲区,相应的持续时间应为262144/88200 = 2.97秒。但我得到的结果只有一半。我尝试了三个运行Android OS版本2.3.3,2.3.4和4.3的不同设备,并获得了相同的结果。因此,这是我自己的问题。
在我的计算或代码中,有人能告诉我问题出在哪里吗?我的理解是正确的吗? 任何意见或建议将不胜感激。