加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 将音频立体声转换为音频字节

发布时间:2020-12-15 04:10:00 所属栏目:Java 来源:网络整理
导读:我正在尝试进行一些音频处理,我真的陷入了立体声到单声道转换.我在网上查看了立体声到单声道转换. 据我所知,我可以采用左声道,右声道,将它们相加并除以2.但是当我再次将结果转换为WAV文件时,我得到了很多前景噪声.我知道处理数据时可能会产生噪声,字节变量会
我正在尝试进行一些音频处理,我真的陷入了立体声到单声道转换.我在网上查看了立体声到单声道转换.

据我所知,我可以采用左声道,右声道,将它们相加并除以2.但是当我再次将结果转换为WAV文件时,我得到了很多前景噪声.我知道处理数据时可能会产生噪声,字节变量会有一些溢出.

这是从我的MP3文件中检索byte []数据块的类:

public class InputSoundDecoder {

private int BUFFER_SIZE = 128000;
private String _inputFileName;
private File _soundFile;
private AudioInputStream _audioInputStream;
private AudioFormat _audioInputFormat;
private AudioFormat _decodedFormat;
private AudioInputStream _audioInputDecodedStream;

public InputSoundDecoder(String fileName) throws UnsuportedSampleRateException{
    this._inputFileName = fileName;
    this._soundFile = new File(this._inputFileName);
    try{
        this._audioInputStream = AudioSystem.getAudioInputStream(this._soundFile);
    }
    catch (Exception e){
        e.printStackTrace();
        System.err.println("Could not open file: " + this._inputFileName);
        System.exit(1);
    }

    this._audioInputFormat = this._audioInputStream.getFormat();

    this._decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,44100,16,2,1,false);
    this._audioInputDecodedStream = AudioSystem.getAudioInputStream(this._decodedFormat,this._audioInputStream);

    /** Supported sample rates */
    switch((int)this._audioInputFormat.getSampleRate()){
        case 22050:
                this.BUFFER_SIZE = 2304;
            break;

        case 44100:
                this.BUFFER_SIZE = 4608;
            break;

        default:
            throw new UnsuportedSampleRateException((int)this._audioInputFormat.getSampleRate());
    }

    System.out.println ("# Channels: " + this._decodedFormat.getChannels());
    System.out.println ("Sample size (bits): " + this._decodedFormat.getSampleSizeInBits());
    System.out.println ("Frame size: " + this._decodedFormat.getFrameSize());
    System.out.println ("Frame rate: " + this._decodedFormat.getFrameRate());

}

public byte[] getSamples(){
    byte[] abData = new byte[this.BUFFER_SIZE];
    int bytesRead = 0;

    try{
        bytesRead = this._audioInputDecodedStream.read(abData,abData.length);
    }
    catch (Exception e){
        e.printStackTrace();
        System.err.println("Error getting samples from file: " + this._inputFileName);
        System.exit(1);
    }

    if (bytesRead > 0)
        return abData;
    else
        return null;
}

}

这意味着,每次调用getSamples时,它都返回一个数组,如:

buff = {Lchannel,Rchannel,Lchannel,Rchannel ……}

转换为单声道的处理程序如下所示:

byte[] buff = null;
        while( (buff = _input.getSamples()) != null ){

            /** Convert to mono */
            byte[] mono = new byte[buff.length/2];

            for (int i = 0 ; i < mono.length/2; ++i){
                int left = (buff[i * 4] << 8) | (buff[i * 4 + 1] & 0xff);
                int right = (buff[i * 4 + 2] <<8) | (buff[i * 4 + 3] & 0xff);
                int avg = (left + right) / 2;
                short m = (short)avg; /*Mono is an average between 2 channels (stereo)*/
                mono[i * 2] = (byte)((short)(m >> 8));
                mono[i * 2 + 1] = (byte)(m & 0xff);
            }

}

并使用以下方法写入wav文件:

public static void writeWav(byte [] theResult,int samplerate,File outfile) {
        // now convert theResult into a wav file
        // probably should use a file if samplecount is too big!
        int theSize = theResult.length;


        InputStream is = new ByteArrayInputStream(theResult);
        //Short2InputStream sis = new Short2InputStream(theResult);

        AudioFormat audioF = new AudioFormat(
                AudioFormat.Encoding.PCM_SIGNED,samplerate,// channels
                2,// framesize
                samplerate,false
        );

        AudioInputStream ais = new AudioInputStream(is,audioF,theSize);

        try {
            AudioSystem.write(ais,AudioFileFormat.Type.WAVE,outfile);
        } catch (IOException ioe) {
            System.err.println("IO Exception; probably just done with file");
            return;
        }


    }

以44100作为采样率.

请记住,实际上我已经得到它的byte []数组已经是pcm,所以mp3 – > pcm转换是通过指定完成的

06003

正如我所说,当写入Wav文件时,我有很多噪音.我假装将每个字节块应用于FFT,但我认为由于噪音很大,结果不正确.

因为我正在拍两首歌,其中一首是另一首20秒的作物,当将作物fft结果与原始的20秒子集进行比较时,它根本不匹配.

我认为这是不正确的转换立体声 – >单声道的原因.

希望有人知道这件事,

问候.

解决方法

正如评论中指出的那样,字节顺序可能是错误的.此外,转换为带符号的短路并将其移位可能会导致第一个字节为0xFF.

尝试:

int HI = 0; int LO = 1;
int left = (buff[i * 4 + HI] << 8) | (buff[i * 4 + LO] & 0xff);
int right = (buff[i * 4 + 2 + HI] << 8) | (buff[i * 4 + 2 + LO] & 0xff);
int avg = (left + right) / 2;
mono[i * 2 + HI] = (byte)((avg >> 8) & 0xff);
mono[i * 2 + LO] = (byte)(avg & 0xff);

然后切换HI和LO的值以查看它是否变好.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读