- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试为 Android Wear 构建录音机应用。现在,我能够在 watch 上捕捉音频,将其传输到手机并保存在文件中。但是,音频文件存在间隙或裁剪部分。
我发现这回答了与我的问题相关的问题 link1 , link2 ,但他们帮不了我。
这是我的代码:
首先,在 watch 端,我使用 channelAPI 创建 channel ,并成功地将 watch 上捕获的音频发送到智能手机。
//here are the variables values that I used
//44100Hz is currently the only rate that is guaranteed to work on all devices
//but other rates such as 22050, 16000, and 11025 may work on some devices.
private static final int RECORDER_SAMPLE_RATE = 44100;
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO;
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
int BufferElements2Rec = 1024;
int BytesPerElement = 2;
//start the process of recording audio
private void startRecording() {
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
RECORDER_SAMPLE_RATE, RECORDER_CHANNELS,
RECORDER_AUDIO_ENCODING, BufferElements2Rec * BytesPerElement);
recorder.startRecording();
isRecording = true;
recordingThread = new Thread(new Runnable() {
public void run() {
writeAudioDataToPhone();
}
}, "AudioRecorder Thread");
recordingThread.start();
}
private void writeAudioDataToPhone(){
short sData[] = new short[BufferElements2Rec];
ChannelApi.OpenChannelResult result = Wearable.ChannelApi.openChannel(googleClient, nodeId, "/mypath").await();
channel = result.getChannel();
Channel.GetOutputStreamResult getOutputStreamResult = channel.getOutputStream(googleClient).await();
OutputStream outputStream = getOutputStreamResult.getOutputStream();
while (isRecording) {
// gets the voice output from microphone to byte format
recorder.read(sData, 0, BufferElements2Rec);
try {
byte bData[] = short2byte(sData);
outputStream.write(bData);
} catch (IOException e) {
e.printStackTrace();
}
}
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
然后,在智能手机端,我从 channel 接收音频数据并将其写入 PCM 文件。
public void onChannelOpened(Channel channel) {
if (channel.getPath().equals("/mypath")) {
Channel.GetInputStreamResult getInputStreamResult = channel.getInputStream(mGoogleApiClient).await();
inputStream = getInputStreamResult.getInputStream();
writePCMToFile(inputStream);
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(MainActivity.this, "Audio file received!", Toast.LENGTH_SHORT).show();
}
});
}
}
public void writePCMToFile(InputStream inputStream) {
OutputStream outputStream = null;
try {
// write the inputStream to a FileOutputStream
outputStream = new FileOutputStream(new File("/sdcard/wearRecord.pcm"));
int read = 0;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
System.out.println("Done writing PCM to file!");
} catch (Exception e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (outputStream != null) {
try {
// outputStream.flush();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
我做错了什么或者您有什么建议可以在智能手机上实现完美的无缝音频文件?提前致谢。
最佳答案
我注意到在您的代码中,您正在将所有内容读入一个 short[] 数组,然后将其转换为一个 byte[] 数组以供 Channel API 发送。您的代码还通过循环的每次迭代创建一个新的 byte[] 数组,这将为垃圾收集器创建大量工作。通常,您希望避免在循环内进行分配。
我会在顶部分配一个 byte[] 数组,让 AudioRecord 类将它直接存储到 byte[] 数组中(只要确保分配的字节数是 shorts 的两倍),代码如下:
mAudioTemp = new byte[bufferSize];
int result;
while ((result = mAudioRecord.read(mAudioTemp, 0, mAudioTemp.length)) > 0) {
try {
mAudioStream.write(mAudioTemp, 0, result);
} catch (IOException e) {
Log.e(Const.TAG, "Write to audio channel failed: " + e);
}
}
我还用 1 秒的音频缓冲区测试了这个,使用这样的代码,它运行良好。在开始出现问题之前,我不确定最小缓冲区大小是多少:
int bufferSize = Math.max(
AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT),
44100 * 2);
关于使用 ChannelAPI 的 Android Wear 录音机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31838129/
我正在使用 AppEngine 的 Channel API。该 API 每 2 小时断开一次连接,因此每当客户端调用 onError 或 onClose 时,我都必须在我这边处理重新连接。 问题是,我
Android Wear 提供多种方式在手持设备和智能 watch 之间同步数据。我想知道您什么时候应该使用 MessageApi以及何时使用 ChannelApi ? 当我第一次遇到这个问题时,我想
通过本地节点打开 channel 时: Wearable.NodeApi.getLocalNode(googleApiClient) ... onChannelOpened 监听器成功 触发。 但是,
我正在尝试为 Android Wear 构建录音机应用。现在,我能够在 watch 上捕捉音频,将其传输到手机并保存在文件中。但是,音频文件存在间隙或裁剪部分。 我发现这回答了与我的问题相关的问题 l
在我的 web.xml 中 channelConnected ChannelConnected channelConnected /_ah/channel/con
我是一名优秀的程序员,十分优秀!