- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在尝试用Java手动读取wav文件并读取字节数组,然后写入音频缓冲区进行播放。我正在接收回放,但它严重失真。 Java 声音支持 16 位采样率,但不支持 24 位。
我进入 Logic 9 并将 24 位音频文件导出为 16 位,然后与我的程序一起使用。最初,24 位样本会产生白噪声。现在我可以听到我的样本,但非常失真,听起来像是被压碎了。
有人可以帮助我获得干净的信号吗?
我对音频编程非常陌生,但我目前正在开发基本的数字音频工作站。
import javax.sound.sampled.*;
import javax.sound.sampled.DataLine.Info;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.io.*;
public class AudioData {
private String filepath;
private String filepath1;
private File file;
private byte [] fileContent;
private Mixer mixer;
private Mixer.Info[] mixInfos;
private AudioInputStream input;
private ByteArrayOutputStream byteoutput;
public static void main (String [] args) {
AudioData audiodata = new AudioData();
}
public AudioData () {
filepath = "/Users/ivaannagen/Documents/Samples/Engineering Samples - Obscure Techno Vol 3 (WAV)/ES_OT3_Kit03_Gmin_130bpm/ES_OT3_Kit03_FX_Fast_Snare_Riser_Gmin_130bpm.wav";
filepath1 = "/Users/ivaannagen/Documents/Samples/dawsampletest.wav";
file = new File (filepath1);
readAudio();
}
public void readAudio () {
mixInfos = AudioSystem.getMixerInfo();
mixer = AudioSystem.getMixer(mixInfos[0]);
AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 4, 44100, false);
// set up an audio format.
try {
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format); // creates data line with class type and audio format.
SourceDataLine source = (SourceDataLine) AudioSystem.getLine(info);
System.out.println("Size of data line buffer: " + source.getBufferSize());
fileContent = new byte [source.getBufferSize() / 50];
byteoutput = new ByteArrayOutputStream();
input = AudioSystem.getAudioInputStream(file);
int readBytes = 0;
while ((readBytes = input.read(fileContent, 0, fileContent.length)) != -1) {
byteoutput.write(fileContent, 0, readBytes);
}
System.out.println("Size of audio buffer: " + fileContent.length);
//byteoutput.write(0);
// byteoutput.write(0);
System.out.println("Size of audio buffer: " + byteoutput.size());
source.open(format, source.getBufferSize()); // line must be open to be recognised by the mixer.
Line[] lines = mixer.getSourceLines();
System.out.println("mixer lines: " + lines.length);
// for(byte bytes: fileContent) {
// System.out.println(bytes);
// }
Thread playback = new Thread () {
public void run () {
// System.out.println((byteoutput.size() +2) % 4);
source.start(); // play (buffer originally empty)
source.write(byteoutput.toByteArray(), 0, byteoutput.size()); // write input bytes to output buffer
} // end run (to do).
}; // end thread action
playback.start(); // start thread
}
catch (LineUnavailableException lue) {
System.out.println(lue.getMessage());
}
catch (FileNotFoundException fnfe) {
System.out.println(fnfe.getMessage());
}
catch(IOException ioe) {
System.out.println(ioe.getMessage());
}
catch(UnsupportedAudioFileException uafe) {
System.out.println(uafe.getMessage());
}
}
}
最佳答案
据我所知,是否可以加载和播放 24 位文件取决于系统。
我使用 Audacity 进行转换。您应该能够将文件导入 Audacity 并将其导出为 16 位、立体声、小端、44100 fps,然后使用 Java 的 AudioInputStream
加载该导出。
您在 Audacity 或 Java 中播放时听到的声音应该几乎相同(调整音量)。如果不是,最可能的原因可能与代码中的错误或疏忽有关,这很容易做到。
在代码中使用ByteOutputStream
是多余的。从 AudioInputStream
读取到固定大小的字节数组(大小是缓冲区长度,我建议首先尝试 8 或 16 * 1024 字节),然后使用 SourceDataLine
编写方法来传送该数组。
以下代码可在我的系统上运行,用于加载播放名为“a3.wav”的“CD 质量”wav,该 wav 与 Java 类位于同一目录中。您应该能够交换您自己的 44100、16 位、立体声、小端 wav 文件。
我已经注释掉了加载和播放名为“spoken8000_24.wav”的 24 位 wav 文件的尝试。那次尝试给了我一个IllegalArgumentException
:没有行匹配接口(interface)SourceDataLine支持格式PCM_SIGNED 8000.0 Hz,24位,立体声,6字节/帧,支持小尾数。
我必须承认,我不清楚我的系统是否没有提供所需的行,或者我是否可能错误地编码了格式!我的操作系统当然可以播放该文件。所以我认为操作系统可以做的事情和给定系统上的“混合器”为 Java 提供的事情之间是有区别的。
作为一种解决方法,我总是将所有内容转换为“CD 质量”格式,因为这似乎是最广泛支持的格式。
public class TriggerSound_SDL extends JFrame
{
public TriggerSound_SDL()
{
JButton button = new JButton("Play Sound");
button.addActionListener(e -> new Thread(() -> playBuzzer()).start());
getContentPane().add(button);
}
private void playBuzzer()
{
try
{
URL url;
url = getClass().getResource("a3.wav");
// url = getClass().getResource("spoken8000_24.wav");
AudioInputStream ais = AudioSystem.getAudioInputStream(url);
System.out.println(ais.getFormat());
AudioFormat audioFmt;
// "CD Quality" 44100 fps, 16-bit, stereo, little endian
audioFmt = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
44100, 16, 2, 4, 44100, false);
// 8000 fps, 32-bit, stereo
// audioFmt = new AudioFormat(
// AudioFormat.Encoding.PCM_SIGNED,
// 8000, 24, 2, 6, 8000, false);
Info info = new DataLine.Info(SourceDataLine.class,
audioFmt);
SourceDataLine sdl = (SourceDataLine)AudioSystem.getLine(info);
int bufferSize = 16 * 1024;
byte[] buffer = new byte[bufferSize];
sdl.open(audioFmt, bufferSize);
sdl.start();
int numBytesRead = 0;
while((numBytesRead = ais.read(buffer)) != -1)
{
sdl.write(buffer, 0, numBytesRead);
}
}
catch (IOException | UnsupportedAudioFileException
| LineUnavailableException ex)
{
ex.printStackTrace();
}
}
private static void createAndShowGUI()
{
JFrame frame = new TriggerSound_SDL();
frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(() -> createAndShowGUI());
}
}
这段代码经过一些小调整后应该至少可以让您测试不同的格式。
编辑:我知道你的目标是制作 DAW!在这种情况下,您需要将字节转换为 PCM 数据。我可以建议你从AudioCue借一些代码吗?我基本上将其编写为剪辑替代品,其中一部分涉及使 PCM 数据可用于操作。一些混音、不同频率播放、多线程的技术都可以在里面找到。
关于java - 不需要的下采样 : Java Sound,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51067250/
我正在尝试用 C 语言编写一个使用 gstreamer 的 GTK+ 应用程序。 GTK+ 需要 gtk_main() 来执行。 gstreamer 需要 g_main_loop_run() 来执行。
我已经使用 apt-get 安装了 opencv。我得到了以下版本的opencv2,它工作正常: rover@rover_pi:/usr/lib/arm-linux-gnueabihf $ pytho
我有一个看起来像这样的 View 层次结构(基于其他答案和 Apple 的使用 UIScrollView 的高级 AutoLayout 指南): ScrollView 所需的2 个步骤是: 为 Scr
我尝试安装 udev。 udev 在 ./configure 期间给我一个错误 --exists: command not found configure: error: pkg-config and
我正在使用 SQLite 3。我有一个表,forums,有 150 行,还有一个表,posts,有大约 440 万行。每个帖子都属于一个论坛。 我想从每个论坛中选择最新帖子的时间戳。如果我使用 SEL
使用 go 和以下包: github.com/julienschmidt/httprouter github.com/shwoodard/jsonapi gopkg.in/mgo.v2/bson
The database仅包含 2 个表: 钱包(100 万行) 事务(1500 万行) CockroachDB 19.2.6 在 3 台 Ubuntu 机器上运行 每个 2vCPU 每个 8GB R
我很难理解为什么在下面的代码中直接调用 std::swap() 会导致编译错误,而使用 std::iter_swap 编译却没有任何错误. 来自 iter_swap() versus swap() -
我有一个非常简单的 SELECT *用 WHERE NOT EXISTS 查询条款。 SELECT * FROM "BMAN_TP3"."TT_SPLDR_55E63A28_59358" SELECT
我试图按部分组织我的 .css 文件,我需要从任何文件访问文件组中的任何类。在 Less 中,我可以毫无问题地创建一个包含所有文件导入的主文件,并且每个文件都导入主文件,但在 Sass 中,我收到一个
Microsoft.AspNet.SignalR.Redis 和 StackExchange.Redis.Extensions.Core 在同一个项目中使用。前者需要StackExchange.Red
这个问题在这里已经有了答案: Updating from Rails 4.0 to 4.1 gives sass-rails railties version conflicts (4 个答案) 关
我们有一些使用 Azure DevOps 发布管道部署到的现场服务器。我们已经使用这些发布管道几个月了,没有出现任何问题。今天,我们在下载该项目的工件时开始出现身份验证错误。 部署组中的节点显示在线,
Tip: instead of creating indexes here, run queries in your code – if you're missing any indexes, you
你能解释一下 Elm 下一个声明中的意思吗? (=>) = (,) 我在 Elm architecture tutorial 的例子中找到了它 最佳答案 这是中缀符号。实际上,这定义了一个函数 (=>
我需要一个 .NET 程序集查看器,它可以显示低级详细信息,例如元数据表内容等。 最佳答案 ildasm 是 IL 反汇编程序,具有低级托管元数据 token 信息。安装 Visual Studio
我有两个列表要在 Excel 中进行比较。这是一个很长的列表,我需要一个 excel 函数或 vba 代码来执行此操作。我已经没有想法了,因此转向你: **Old List** A
Closed. This question does not meet Stack Overflow guidelines。它当前不接受答案。 想要改善这个问题吗?更新问题,以便将其作为on-topi
我正在学习 xml 和 xml 处理。我无法很好地理解命名空间的存在。 我了解到命名空间帮助我们在 xml 中分离相同命名的元素。我们不能通过具有相同名称的属性来区分元素吗?为什么命名空间很重要或需要
我搜索了 Azure 文档、各种社区论坛和 google,但没有找到关于需要在公司防火墙上打开哪些端口以允许 Azure 所有组件(blob、sql、compute、bus、publish)的简洁声明
我是一名优秀的程序员,十分优秀!