如何在将声音写入文件之前不使用Java中的'clip'循环声音

Vibhav佛陀

首先,感谢大家为我的以前的问题提供帮助。

在下面的代码中,我交替使用两个频率,并将它们写入.wav格式,以便在Windows Media Player中在用户指定的时间段内运行它。我要了解的是如何使这些频率循环运行,以便在指定的时间交替运行,例如救护车的警笛声,而在我的程序中,这两种频率只能交替播放一次。例如,如果我将时间指定为10秒,则两个频率都将连续运行5秒。但是我想要的是第一个频率运行一秒钟或两秒钟(根据用户指定),然后第二个频率运行相同的秒数,然后再次运行第一个频率,它应该一直持续到指定的时间。

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;
import javax.sound.sampled.LineUnavailableException;

public class AudioWrite2New {

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

        Scanner in = new Scanner(System.in);
        final double SAMPLING_RATE = 44100;             // Audio sampling rate
        int time = in.nextInt();                        //Time specified by user in seconds
//        int time2 = in.nextByte();
        int frequency1 = in.nextInt();                   //Frequency1 specified by the user in hz
        int frequency2 = in.nextInt();                   //Frequency2 specified by the user in hz

        float buffer[] = new float[(int) (time/2 * SAMPLING_RATE)];   //Size of buffer[], which in case of 10 seconds is 441000
        float buffer1[] = new float[(int) (time/2 * SAMPLING_RATE)];   //Size of buffer1[], which in case of 10 seconds is 441000

        for (int sample = 0; sample < buffer.length; sample++) {
            double cycle = sample / SAMPLING_RATE;                  //Fraction of cycle between samples
            buffer[sample] = (float) (Math.sin(2 * Math.PI * frequency1 * cycle));
            //buffer1[sample] = (float) (Math.sin(2 * Math.PI * frequency2 * cycle));
        }
        for (int sample = 0; sample < buffer1.length; sample++) {
            double cycle = sample / SAMPLING_RATE;                  //Fraction of cycle between samples
            //buffer[sample] = (float) (Math.sin(2 * Math.PI * frequency1 * cycle));
            buffer1[sample] = (float) (Math.sin(2 * Math.PI * frequency2 * cycle));
        }
        //System.out.println(buffer[1]);
        byte byteBuffer[] = new byte[buffer.length * 2];            //Size of byteBuffer, in this case 882000
        byte byteBuffer1[] = new byte[buffer1.length * 2];            //Size of byteBuffer, in this case 882000

        int count = 0;
        for (int i = 0; i < byteBuffer.length; i++) {
            final 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++) {
            final int x = (int) (buffer1[count++] * Short.MAX_VALUE);
            byteBuffer1[i++] = (byte) x;
            byteBuffer1[i] = (byte) (x / 256);
        }

        //For merging the two frequencies
        byte[] merge = new byte[byteBuffer.length + byteBuffer1.length];
        System.arraycopy(byteBuffer, 0, merge, 0, byteBuffer.length);
        System.arraycopy(byteBuffer1, 0, merge, byteBuffer.length, byteBuffer1.length);

        File out = new File("E:/RecordAudio17.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 bytebuffer 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, buffer1.length + buffer.length);

        //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
    }
}

而且由于我在Java和JavaSounds中还很陌生,因此有时我可能会问一些愚蠢或不相关的问题。因此,请多多包涵,因为这是我学习的唯一途径。谢谢。

Vibhav佛陀

我解决了 尽管我需要处理一小部分。完成后,我将立即对其进行更新。

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;
import javax.sound.sampled.LineUnavailableException;

public class AudioWrite2New {

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

        Scanner in = new Scanner(System.in);
        final double SAMPLING_RATE = 44100;             // Audio sampling rate
        int time = in.nextInt();                        //Time specified by user in milliseconds
        int time2 = in.nextByte();
        int frequency1 = in.nextInt();                   //Frequency1 specified by the user in hz
        int frequency2 = in.nextInt();                   //Frequency2 specified by the user in hz

        float buffer[] = new float[((int) (time * SAMPLING_RATE))/1000];   //Size of buffer[], which in case of 10 seconds is 441000
        float buffer1[] = new float[((int) (time * SAMPLING_RATE))/1000];   //Size of buffer1[], which in case of 10 seconds is 441000

        //for (int a = 1; a <= time2 / 2; a++) {
        for (int sample = 0; sample < buffer.length; sample++) {
            double cycle = sample / SAMPLING_RATE;                  //Fraction of cycle between samples
            buffer[sample] = (float) (Math.sin(2 * Math.PI * frequency1 * cycle));
            //buffer1[sample] = (float) (Math.sin(2 * Math.PI * frequency2 * cycle));
        }
        for (int sample = 0; sample < buffer1.length; sample++) {
            double cycle = sample / SAMPLING_RATE;                  //Fraction of cycle between samples
            //buffer[sample] = (float) (Math.sin(2 * Math.PI * frequency1 * cycle));
            buffer1[sample] = (float) (Math.sin(2 * Math.PI * frequency2 * cycle));
        }
        //System.out.println(buffer[1]);
        byte byteBuffer[] = new byte[buffer.length * 2];            //Size of byteBuffer, in this case 882000
        byte byteBuffer1[] = new byte[buffer1.length * 2];            //Size of byteBuffer, in this case 882000

        int count = 0;
        for (int i = 0; i < byteBuffer.length; i++) {
            final 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++) {
            final int x = (int) (buffer1[count++] * Short.MAX_VALUE);
            byteBuffer1[i++] = (byte) x;
            byteBuffer1[i] = (byte) (x / 256);
        }

        int iterations = (1000*time2)/(2*time);
        byte[] merge = new byte[iterations*(byteBuffer.length + byteBuffer1.length)];
        for (int i = 0; i<iterations; i++)
        {
            //arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
            //For merging the two frequencies
            System.arraycopy(byteBuffer, 0, merge, 0+i*(byteBuffer.length + byteBuffer1.length), byteBuffer.length);
            System.arraycopy(byteBuffer1, 0, merge, byteBuffer.length+i*(byteBuffer.length + byteBuffer1.length), byteBuffer1.length);
        }

        File out = new File("E:/RecordAudio17.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 bytebuffer 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, (buffer1.length + buffer.length) * (time2/4));

        //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
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

使用javax.sound.sampled.Clip播放,循环播放和停止游戏中的多种声音。意外错误

如何使用pygame依次运行声音循环?

从列表循环播放声音

打破声音的循环。怎么修?

播放声音java时出错(无线匹配接口Clip支持格式)

播放声音文件而不循环

在PHP循环中播放声音onclick

Audiokit Cross Fade声音循环播放

动态声音条循环中的AddEventListener

在crafty.js中循环播放声音文件

在SoundEffect类Windows Phone 8中循环播放声音

在 jupyter notebook 中使用 python 循环播放声音

如何在主游戏循环中使用 sfml 只播放一次声音

如何在android中无间隙地循环播放mp3声音文件

如何在不使用预定义功能的情况下绘制声音文件的频谱图?

具有缓冲队列的NDK OpenSL ES循环声音

团结-像声音一样运行循环而不会摔倒

声音没有在 for 循环中播放 3 次 for timer

推送通知到达时播放声音循环

暂停后Iphone OpenAL循环声音未重新启动

如何在QT中启动之前播放声音?

如何确保指定声音的只有 1 个实例正在循环,以及如何阻止它循环?

Tensorflow:使用clip_by_norm 或clip_by_global_norm 时如何确定clip_norm 的值?

如何使用python播放声音并且没有while循环

如何在Swift应用中访问声音文件

如何在Foobar2000中播放flv文件(的声音)?

Java中的系统声音

如何在 Mac 终端中使用 sox 修剪子文件夹中的声音文件?

为什么我的Java应用程序没有在每个循环中播放声音?