Java:生成音频并以.wav格式保存

时间:2016-12-05 13:11:29

标签: java audio fft wav javasound

我在声音处理方面真的很新,到目前为止我已经能够理解(有很多帮助和批评:P )如何(1)采取另外,2个频率然后从中产生音频。 然后,(2)将该音频写为可由媒体播放器播放的.wav文件。 然后,(3)而不是时间我以位(最多8个字节)的形式从用户那里获取输入,当有' 0'在给定的输入中,我采用了第一频率,如果是' 1'第二频率。 我附上了上面提到的代码,'(3)' ,仅仅是为了帮助需要它的人。 If you want to see my previous code, click here

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;

public class AudioBits {

    public static void main(String[] args) throws IOException {

        Scanner in = new Scanner(System.in);
        final double SAMPLING_RATE = 44100;             // Audio sampling rate
        float timeInterval = in.nextFloat();            //Time specified by user in milliseconds for each bit to be played
        int frequency1 = in.nextInt();                  //Frequency1 specified by the user in hz
        int frequency2 = in.nextInt();                  //Frequency2 specified by the user in hz

        //To check if the user enters the value in the form of 0-1 or not, as that what is required
        //And also the bits entered should not be greater than 8
        while (!in.hasNext("[0-1]{1,8}")) {
            System.out.println("Wrong input.");
            in.next();
        }
        //Value in zero-one form. Where there is '0' it means one frequency and incase of '1' it means the other frequency
        String binary = in.next();

        //Converting the String value of one-zero form into its equivalent integer
        int value = Integer.parseInt(binary, 2);

        int binVal = 0b10000000;                        //Used to perform '&' operation with 'value'

        //Size of buffer[], which in case of 2 sec is 88.2
        float buffer[] = new float[((int) (timeInterval * SAMPLING_RATE)) / 1000];

        //Size of buffer1[], which in case of 2 sec is 88.2
        float buffer1[] = new float[((int) (timeInterval * SAMPLING_RATE)) / 1000];

        for (int sample = 0; sample < buffer.length; sample++) {    //range from zero to buffer.length
            double cycle = sample / SAMPLING_RATE;                  //Fraction of cycle between samples
            buffer[sample] = (float) (Math.sin(2 * Math.PI * frequency1 * cycle));  //value at every point of the cycle
        }
        for (int sample = 0; sample < buffer1.length; sample++) {
            double cycle = sample / SAMPLING_RATE;                  //Fraction of cycle between samples
            buffer1[sample] = (float) (Math.sin(2 * Math.PI * frequency2 * cycle));
        }

        byte byteBuffer[] = new byte[buffer.length * 2];            //Size of byteBuffer
        byte byteBuffer1[] = new byte[buffer1.length * 2];          //Size of byteBuffer1

        int count = 0;

        //Analog to digital
        for (int i = 0; i < byteBuffer.length; i++) {
            int x = (int) (buffer[count++] * Short.MAX_VALUE);
            byteBuffer[i++] = (byte) x;
            byteBuffer[i] = (byte) (x / 256);
        }

        count = 0;
        for (int i = 0; i < byteBuffer1.length; i++) {
            int x = (int) (buffer1[count++] * Short.MAX_VALUE);
            byteBuffer1[i++] = (byte) x;
            byteBuffer1[i] = (byte) (x / 256);
        }

        byte[] merge = new byte[8 * byteBuffer.length];    //Merged Array's length

        //Merging the two frequencies into one. Where there is '0' adding 1st frequency and in case of '1' adding 2nd
        for (int i = 0; i < 8; i++) {               //Loop for 8 Bits
            int c = value & binVal;                 //'&' operation to check whether 'c' contains zero or not in every iteration
            if (c == 0) {
                System.arraycopy(byteBuffer, 0, merge, i * (byteBuffer.length), byteBuffer.length);   //Adds 1st frequency
            } else {
                System.arraycopy(byteBuffer1, 0, merge, i * (byteBuffer.length), byteBuffer1.length); //Adds 2nd frequency
            }
            binVal = binVal >> 1;                           //Right Shifting the value of 'binVal' to be used for 'c'
        }

        File out = new File("E:/RecordAudio30.wav"); //The path where user want the file data to be written

        //Construct an audio format, using 44100hz sampling rate, 16 bit samples, mono, and big 
        // endian byte ordering
        AudioFormat format = new AudioFormat((float) SAMPLING_RATE, 16, 1, true, false);

        // It uses 'merge' as its buffer array that contains bytes that may be read from the stream.
        ByteArrayInputStream bais = new ByteArrayInputStream(merge);

        //Constructs an audio input stream that has the requested format and length in sample frames, using audio data 
        //from the specified input stream.
        AudioInputStream audioInputStream = new AudioInputStream(bais, format, (long) (8 * (byteBuffer.length / 2)));

        //Writes a stream of bytes representing an audio file of the specified file type to the external file provided.
        AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE, out);

        audioInputStream.close();       //Closes this audio input stream
    }
}

0 个答案:

没有答案