嗨朋友们,我正在尝试混合 2 个音频,结果是 SD 卡上的文件 mixed.wav,
但是我有一个问题,结果是白噪声,如何去除噪声并且效果好?
对不起我的英语。这是我的代码
package com.example.crazydoraemon;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
public class MainActivity extends Activity {
public static final int FREQUENCY = 44100;
private byte[] output;
private InputStream in1, in2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
mixSound();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void mixSound() throws IOException {
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT, 44100, AudioTrack.MODE_STREAM);
in1 = getResources().openRawResource(R.raw.a);
in2 = getResources().openRawResource(R.raw.b);
byte[] arrayMusic1 = null;
arrayMusic1 = new byte[in1.available()];
arrayMusic1 = createMusicArray(in1);
in1.close();
byte[] arrayMusic2 = null;
arrayMusic2 = new byte[in2.available()];
arrayMusic2 = createMusicArray(in2);
in2.close();
output = new byte[arrayMusic1.length];
for (int i = 0; i < output.length; i++) {
float samplef1 = arrayMusic1[i] / 128.0f;
float samplef2 = arrayMusic2[i] / 128.0f;
float mixed = samplef1 + samplef2;
// reduce the volume a bit:
mixed *= 0.8;
// hard clipping
if (mixed > 1.0f) mixed = 1.0f;
if (mixed < -1.0f) mixed = -1.0f;
byte outputSample = (byte) (mixed * 128.0f);
output[i] = outputSample;
}
properWAV();
}
public static byte[] createMusicArray(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buff = new byte[10240];
int i = Integer.MAX_VALUE;
while ((i = is.read(buff, 0, buff.length)) > 0) {
baos.write(buff, 0, i);
}
return baos.toByteArray(); // be sure to close InputStream in calling function
}
public static void convertByteToFile(byte[] fileBytes) throws FileNotFoundException {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(Environment.getExternalStorageDirectory().getPath()+"/mixed.wav"));
try {
bos.write(fileBytes);
bos.flush();
bos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* TODAY
* more info --> https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
*/
public void properWAV() {
try {
long mySubChunk1Size = 16;
int myBitsPerSample = 16;
int myFormat = 1;
long myChannels = 2;
long mySampleRate = 44100;
long myByteRate = mySampleRate * myChannels * myBitsPerSample/8;
int myBlockAlign = (int) (myChannels * myBitsPerSample/8);
long myDataSize = output.length;
long myChunk2Size = myDataSize * myChannels * myBitsPerSample/8;
long myChunkSize = 36 + myChunk2Size;
OutputStream os = new FileOutputStream(new File(Environment.getExternalStorageDirectory().getPath()+"/mixed.wav"));
BufferedOutputStream bos = new BufferedOutputStream(os);
DataOutputStream outFile = new DataOutputStream(bos);
outFile.writeBytes("RIFF"); // 00 - RIFF
outFile.write(intToByteArray((int)myChunkSize), 0, 4); // 04 - how big is the rest of this file?
outFile.writeBytes("WAVE"); // 08 - WAVE
outFile.writeBytes("fmt "); // 12 - fmt
outFile.write(intToByteArray((int)mySubChunk1Size), 0, 4); // 16 - size of this chunk
outFile.write(shortToByteArray((short)myFormat), 0, 2); // 20 - what is the audio format? 1 for PCM = Pulse Code Modulation
outFile.write(shortToByteArray((short)myChannels), 0, 2); // 22 - mono or stereo? 1 or 2? (or 5 or ???)
outFile.write(intToByteArray((int)mySampleRate), 0, 4); // 24 - samples per second (numbers per second)
outFile.write(intToByteArray((int)myByteRate), 0, 4); // 28 - bytes per second
outFile.write(shortToByteArray((short)myBlockAlign), 0, 2); // 32 - # of bytes in one sample, for all channels
outFile.write(shortToByteArray((short)myBitsPerSample), 0, 2); // 34 - how many bits in a sample(number)? usually 16 or 24
outFile.writeBytes("data"); // 36 - data
outFile.write(intToByteArray((int)myDataSize), 0, 4); // 40 - how big is this data chunk
outFile.write(output); // 44 - the actual data itself - just a long string of numbers
outFile.flush();
outFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static byte[] getBytesFromFile(File file) throws IOException {
InputStream is = new FileInputStream(file);
long length = file.length();
if (length > Integer.MAX_VALUE) {
}
byte[] bytes = new byte[(int)length];
int offset = 0;
int numRead = 0;
while (offset < bytes.length && (numRead = is.read(bytes, offset, Math.min(bytes.length - offset, 512*1024))) >= 0) {
offset += numRead;
}
if (offset < bytes.length) {
Log.i("xxx", "Could not completely read file");
}
is.close();
return bytes;
}
private static byte[] intToByteArray(int i) {
byte[] b = new byte[4];
b[0] = (byte) (i & 0x00FF);
b[1] = (byte) ((i >> 8) & 0x000000FF);
b[2] = (byte) ((i >> 16) & 0x000000FF);
b[3] = (byte) ((i >> 24) & 0x000000FF);
return b;
}
public static byte[] shortToByteArray(short data) {
return new byte[]{(byte)(data & 0xff),(byte)((data >>> 8) & 0xff)};
}
public static long byteArrayToLong(byte[] b) {
int start = 0;
int i = 0;
int len = 4;
int cnt = 0;
byte[] tmp = new byte[len];
for (i = start; i < (start + len); i++) {
tmp[cnt] = b[i];
cnt++;
}
long accum = 0;
i = 0;
for (int shiftBy = 0; shiftBy < 32; shiftBy += 8) {
accum |= ((long) (tmp[i] & 0xff)) << shiftBy;
i++;
}
return accum;
}
}