gpt4 book ai didi

java - 使用 javax.sound.sampled 生成声音

转载 作者:行者123 更新时间:2023-11-29 08:15:57 24 4
gpt4 key购买 nike

我正在尝试用 Java 生成声音。最后,我愿意不断地向声卡发送声音,但现在我可以发送一个独特的声波。

所以,我用 44100 个有符号整数填充了一个数组,表示一个简单的正弦波,我想将它发送到我的声卡,但我就是无法让它工作。

int samples = 44100; // 44100 samples/s
int[] data = new int[samples];

// Generate all samples
for ( int i=0; i<samples; ++i )
{
data[i] = (int) (Math.sin((double)i/(double)samples*2*Math.PI)*(Integer.MAX_VALUE/2));
}

然后我使用以下方式将其发送到声线:

AudioFormat format = new AudioFormat(Encoding.PCM_SIGNED, 44100, 16, 1, 1, 44100, false);

Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = new AudioInputStream(ais,format,44100);
clip.open(inputStream);
clip.start();

我的问题在于这些代码片段之间。我只是找不到将我的 int[] 转换为输入流的方法!

最佳答案

首先,我认为您需要short 示例而不是int:

short[] data = new short[samples];

因为您的AudioFormat 指定了 16 位样本。 short 是 16 位宽,而 int 是 32 位。

将其转换为流的简单方法是:

  • 分配一个ByteBuffer
  • 使用 putShort 调用填充它
  • 将生成的 byte[] 包装在 ByteArrayInputStream
  • ByteArrayInputStream创建一个AudioInputStream并格式化

例子:

float frameRate = 44100f; // 44100 samples/s
int channels = 2;
double duration = 1.0;
int sampleBytes = Short.SIZE / 8;
int frameBytes = sampleBytes * channels;
AudioFormat format =
new AudioFormat(Encoding.PCM_SIGNED,
frameRate,
Short.SIZE,
channels,
frameBytes,
frameRate,
true);
int nFrames = (int) Math.ceil(frameRate * duration);
int nSamples = nFrames * channels;
int nBytes = nSamples * sampleBytes;
ByteBuffer data = ByteBuffer.allocate(nBytes);
double freq = 440.0;
// Generate all samples
for ( int i=0; i<nFrames; ++i )
{
double value = Math.sin((double)i/(double)frameRate*freq*2*Math.PI)*(Short.MAX_VALUE);
for (int c=0; c<channels; ++ c) {
int index = (i*channels+c)*sampleBytes;
data.putShort(index, (short) value);
}
}

AudioInputStream stream =
new AudioInputStream(new ByteArrayInputStream(data.array()), format, nFrames*2);
Clip clip = AudioSystem.getClip();
clip.open(stream);
clip.start();
clip.drain();

注意:我将您的 AudioFormat 更改为立体声,因为当我请求单声道时它抛出了异常。我还将您的波形频率增加到可听范围内的频率。


更新 - 之前的修改(直接写入数据行)不是必需的 - 使用 Clip 效果很好。我还引入了一些变量以使计算更清楚。

关于java - 使用 javax.sound.sampled 生成声音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4889750/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com