我正在尝试将音频数据记录(捕获)到新的wav文件中。 我正在使用Oboe c ++根据此Example code
缓冲音频这是我将音频数据从混音器捕获到RecordBuffer阵列的方法:
void Mixer::renderAudio(int16_t *audioData, int32_t numFrames) {
int32_t count = numFrames * kChannelCount;
// Zero out the incoming container array
for (int j = 0; j < count; ++j) {
audioData[j] = 0;
}
for (int i = 0; i < mNextFreeTrackIndex; ++i) {
mTracks[i]->renderAudio(mixingBuffer, numFrames);
for (int j = 0; j < count; ++j) {
data = mixingBuffer[j];
data*= volume;
audioData[j] += data;
if(recording && recordFrames < kMaxRecordSize){
if(data != 0)
recordBuffer[recordFrames++] = data;
}
}
}
}
停止记录并获取Java代码的简短数组
jshortArray Mixer::getRecordingData(JNIEnv *env) {
recording = false;
jshortArray result = env->NewShortArray(recordFrames);
env->SetShortArrayRegion(result,0,recordFrames,recordBuffer);
return result;
}
然后用Java代码创建wav文件:
public class Wave {
private final int LONGINT = 4;
private final int SMALLINT = 2;
private final int INTEGER = 4;
private final int ID_STRING_SIZE = 4;
private final int WAV_RIFF_SIZE = LONGINT+ID_STRING_SIZE;
private final int WAV_FMT_SIZE = (4*SMALLINT)+(INTEGER*2)+LONGINT+ID_STRING_SIZE;
private final int WAV_DATA_SIZE = ID_STRING_SIZE+LONGINT;
private final int WAV_HDR_SIZE = WAV_RIFF_SIZE+ID_STRING_SIZE+WAV_FMT_SIZE+WAV_DATA_SIZE;
private final short PCM = 1;
private final int SAMPLE_SIZE = 2;
int cursor, nSamples;
byte[] output;
int sampleRate = 48000;
short channels = 2;
public Wave( short[] data, int start, int end) {
nSamples=end-start+1;
cursor=0;
output=new byte[nSamples*SMALLINT+WAV_HDR_SIZE];
buildHeader(sampleRate,channels);
writeData(data,start,end);
}
private void buildHeader(int sampleRate, short nChannels) {
write("RIFF");
write(output.length);
write("WAVE");
writeFormat(sampleRate, nChannels);
}
public void writeFormat(int sampleRate, short nChannels){
write("fmt ");
write(WAV_FMT_SIZE-WAV_DATA_SIZE);
write(PCM);
write(nChannels);
write(sampleRate);
write(nChannels * sampleRate * SAMPLE_SIZE);
write((short)(nChannels * SAMPLE_SIZE));
write((short)16);
}
public void writeData(short[] data, int start, int end)
{
write("data");
write(nSamples*SMALLINT);
for(int i=start; i<=end; write(data[i++]));
}
private void write(byte b) {
output[cursor++]=b;
}
private void write(String id) {
if(id.length()!=ID_STRING_SIZE) {}
else {
for(int i=0; i<ID_STRING_SIZE; ++i) write((byte)id.charAt(i));
}
}
private void write(int i) {
write((byte) (i&0xFF)); i>>=8;
write((byte) (i&0xFF)); i>>=8;
write((byte) (i&0xFF)); i>>=8;
write((byte) (i&0xFF));
}
private void write(short i) {
write((byte) (i&0xFF)); i>>=8;
write((byte) (i&0xFF));
}
public boolean wroteToFile() {
boolean ok;
try {
File path = FileManager.generateNewFile(String.valueOf(sampleRate + " " + channels));
FileOutputStream outFile = new FileOutputStream(path);
outFile.write(output);
outFile.close();
ok=true;
} catch (FileNotFoundException e) {
e.printStackTrace();
ok=false;
} catch (IOException e) {
ok=false;
e.printStackTrace();
}
return ok;
}
}
结果非常接近,但是质量很差。 有人知道我在做什么错吗? btw只有当我每个演奏1个样本时,它才能很好地工作。
答案 0 :(得分:1)
这是将Oboe输入流记录到Android版C ++中的.Wav文件中的一种方法: https://github.com/reuniware/OboeAudioRecorder/blob/master/app/src/main/cpp/OboeAudioRecorder.cpp