2

嗨朋友们,我正在尝试混合 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;
}
}
4

0 回答 0