- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我写了这个小信号生成方法。我的目标是在两个 channel (左和右)之间产生轻微的时间延迟或 channel 之间的增益略有差异时产生蜂鸣声。目前,我通过用一个 channel 的零和第二个 channel 的值填充缓冲区来创建延迟,并进一步向下交换 channel 之间的行为(如果您有任何提示或想法如何更好地做到这一点,我们将不胜感激。)下一阶段正在做类似的增益事情。我已经看到 Java 通过 FloatControl 提供内置增益控制:
FloatControl gainControl =
(FloatControl) sdl.getControl(FloatControl.Type.MASTER_GAIN);
但我不知道如何分别控制每个 channel 的增益。有内置的方法可以做到这一点吗?我是否需要两个独立的流,每个 channel 一个?如果是这样我如何同时播放它们?我对声音编程相当陌生,如果有更好的方法,请告诉我。很感谢任何形式的帮助。
这是我到目前为止的代码:
public static void generateTone(int delayR, int delayL, double gainRightDB, double gainLeftDB)
throws LineUnavailableException, IOException {
// in hz, number of samples in one second
int sampleRate = 100000; // let sample rate and frequency be the same
// how much to add to each side:
double gainLeft = 100;//Math.pow(10.0, gainLeftDB / 20.0);
double gainRight = 100;// Math.pow(10.0, gainRightDB / 20.0);;
// click duration = 40 us
double duration = 0.08;
double durationInSamples = Math.ceil(duration * sampleRate);
// single delay window duration = 225 us
double baseDelay = 0.000225;
double samplesPerDelay = Math.ceil(baseDelay * sampleRate);
AudioFormat af;
byte buf[] = new byte[sampleRate * 4]; // one second of audio in total
af = new AudioFormat(sampleRate, 16, 2, true, true); // 44100 Hz, 16 bit, 2 channels
SourceDataLine sdl = AudioSystem.getSourceDataLine(af);
sdl.open(af);
sdl.start();
// only one should be delayed at a time
int delayRight = delayR;
int delayLeft = delayL;
int freq = 1000;
/*
* NOTE:
* The buffer holds data in groups of 4. Every 4 bytes represent a single sample. The first 2 bytes
* are for the left side, the other two are for the right. We take 2 each time because of a 16 bit rate.
*
*
*/
for(int i = 0; i < sampleRate * 4; i++){
double time = ((double)i/((double)sampleRate));
// Left side:
if (i >= delayLeft * samplesPerDelay * 4 // when the left side plays
&& i % 4 < 2 // access first two bytes in sample
&& i <= (delayLeft * 4 * samplesPerDelay)
+ (4 * durationInSamples)) // make sure to stop after your delay window
buf[i] = (byte) ((1+gainLeft) * Math.sin(2*Math.PI*(freq)*time)); // sound in left ear
//Right side:
else if (i >= delayRight * samplesPerDelay * 4 // time for right side
&& i % 4 >= 2 // use second 2 bytes
&& i <= (delayRight * 4 * samplesPerDelay)
+ (4 * durationInSamples)) // stop after your delay window
buf[i] = (byte) ((1+gainRight) * Math.sin(2*Math.PI*(freq)*time)); // sound in right ear
}
for (byte b : buf)
System.out.print(b + " ");
System.out.println();
sdl.write(buf,0,buf.length);
sdl.drain();
sdl.stop();
sdl.close();
}
最佳答案
您希望发出嘟嘟声的距离有多远?我编写了一个程序,使正弦蜂鸣声的间隔高达几百帧(44100 fps),并用源代码 here 发布了它。欢迎您检查/复制/重写。
在如此低的分离度下,声音在感知上仍然保持融合,但可能开始移动到一只耳朵或另一只耳朵。我写这篇文章是因为我想将音量平移与基于延迟的平移进行比较。为了能够灵活地测试多个文件,代码比您开始使用的代码稍微更加模块化。不过,我不会声称我写的东西更好。
一个类采用单声道 PCM(范围为 float ,-1 到 1)数组,并将其转换为立体声数组,并在 channel 之间具有所需的帧延迟。同一类还可以将单声道文件拆分为立体声文件,其中唯一的区别是音量,并且有第三个选项,当您将单声道数据转换为立体声时,您可以使用延迟和音量差异的组合。
单文件:F1、F2、F3,...立体声 F1L、F1R、F2L、F2R、F3L、F3R、...
但是如果添加延迟,例如向右 2 帧:
立体声文件 F1L、0、F2L、0、F3L、F1R、F4L、F2R、...
其中 F 是表示音频波的归一化 float (介于 -1 和 1 之间)。
制作蜂鸣声的第一个单声道数组只需像您一样使用正弦函数即可。您可以通过在某些帧的过程中逐渐增大音量来“圆化边缘”,以最大程度地减少突然开始或停止的不连续性所产生的咔嗒声。
编写了另一个类,其唯一目的是通过 SourceDataLine 输出立体 float 组。通过将音频输出乘以 0 到 1 之间的系数来处理音量。标准化值乘以 32767 将其转换为带符号的 Shorts,并将 Shorts 分解为我使用的格式的字节(16 位、44100 fps、立体声、小端)。
拥有一个数组播放音频类是很巧妙的。它的数组很像 Clips,但您可以直接访问数据。通过此类,您可以构建和重用许多声音数组。我想我还包含一些代码,可以将 wav 文件加载到这个 DIY 剪辑中。
this thread at Java-Gaming.org上有关于此代码的更多讨论.
我最终使用了在这里学到的一些知识来制作一个简化的实时 3D 声音系统。不过,设置此类内容的“最佳”方法取决于您的目标。例如,对于我的 3D,我编写了一个延迟工具,允许从左右立体声单独读取,并且音频混合器和播放比简单的数组到 SourceDataLine 播放器更复杂。
关于java - 使用Java单独控制声道的增益,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36863481/
我试过了 alBufferf (myChannelId, AL_MAX_GAIN (and AL_GAIN), volumeValue); 并收到错误0xA002。 最佳答案 0xA002是Linux
我正在使用 Matlab 从 2 点灰度相机 (Flea2) 捕捉图像,我想更改相机的一些参数,例如自动曝光、增益和快门速度。到目前为止,我已经使用了这些命令: %Creating the two v
我正在尝试调整网络摄像头的亮度。我需要 3 张不同亮度设置的不同照片。我不想让它成为手动的,所以如果想在程序中包含设置。 下面是我正在使用的代码。使用方法 GetFrame() 可以从网络摄像头获取下
我想问一个我试图自己回答但无法想出任何解决方案的问题。 我想知道任何具有这些属性的算法(或者是否有可能至少证明一个算法是否存在) +-----------+ status_
我有一个OSX应用程序,该应用程序使用音频单元记录音频数据。可以将音频单元的输入设置为任何可用的输入源,包括内置输入。问题是,我从内置输入获得的音频经常被剪切,而在诸如Audacity(甚至Quick
我是一名优秀的程序员,十分优秀!