给定一个包含压缩格式的音频数据(如MP3或OGG)的InputStream调用in,我希望创建一个byte包含输入数据的WAV转换的数组.不幸的是,如果您尝试这样做,JavaSound会向您发出以下错误:
java.io.IOException: stream length not specified
Run Code Online (Sandbox Code Playgroud)
我设法通过将wav写入临时文件然后将其重新读入来使其工作,如下所示:
AudioInputStream source = AudioSystem.getAudioInputStream(new BufferedInputStream(in, 1024));
AudioInputStream pcm = AudioSystem.getAudioInputStream(AudioFormat.Encoding.PCM_SIGNED, source);
AudioInputStream ulaw = AudioSystem.getAudioInputStream(AudioFormat.Encoding.ULAW, pcm);
File tempFile = File.createTempFile("wav", "tmp");
AudioSystem.write(ulaw, AudioFileFormat.Type.WAVE, tempFile);
// The fileToByteArray() method reads the file
// into a byte array; omitted for brevity
byte[] bytes = fileToByteArray(tempFile);
tempFile.delete();
return bytes;
Run Code Online (Sandbox Code Playgroud)
这显然不太理想.有没有更好的办法?
我使用Java 6运行Ubuntu 10.10并且无法获取FreeTTS来输出任何音频.我现在已经在3台不同的计算机上试过它,甚至要求我的一个伙伴在他的Ubuntu PC上试用它并且他遇到了同样的问题.绝对没有显示错误,在获得MBROLA后我甚至不再收到关于没有检测到MBROLA声音的警告.等等等等等等..
使用同一台计算机,我运行了一个虚拟盒并启动了Windows XP,我实际上能够在运行HelloWorld.jar和TTSHelloWorld.jar时获得音频,但是当我尝试输入自己的文本时,freetts.jar仍然是静默的.
我使用的命令.
java -jar lib/freetts.jar -text你好
当我按下Enter键时,它启动并用来给我丢失的MBROLA警告信息,但现在它只是坐在那里直到我按CTRL-C来阻止它.
我不明白我做错了什么以及为什么没有其他人遇到这个问题,当我在每台计算机上展示它时,它在Windows上有所作为.谁能帮我?
谢谢,
约翰
Java Sound提供FloatControl各种声线功能的实例,以及MASTER_GAIN和VOLUME控制类型.
这些控件可用于更改系统音量吗?
我正在使用Java Sound API,如果我想调整记录卷,我需要对操作系统公开给Java的硬件进行建模.事实证明,所呈现的内容有很多种.
因此,我谦虚地要求任何人能够帮助我在他们的计算机上运行以下内容并回发结果,以便我可以了解那里有什么.
提前感谢任何可以提供帮助的人:-)
import javax.sound.sampled.*;
public class SoundAudit {
public static void main(String[] args) { try {
System.out.println("OS: "+System.getProperty("os.name")+" "+
System.getProperty("os.version")+"/"+
System.getProperty("os.arch")+"\nJava: "+
System.getProperty("java.version")+" ("+
System.getProperty("java.vendor")+")\n");
for (Mixer.Info thisMixerInfo : AudioSystem.getMixerInfo()) {
System.out.println("Mixer: "+thisMixerInfo.getDescription()+
" ["+thisMixerInfo.getName()+"]");
Mixer thisMixer = AudioSystem.getMixer(thisMixerInfo);
for (Line.Info thisLineInfo:thisMixer.getSourceLineInfo()) {
if (thisLineInfo.getLineClass().getName().equals(
"javax.sound.sampled.Port")) {
Line thisLine = thisMixer.getLine(thisLineInfo);
thisLine.open();
System.out.println(" Source Port: "
+thisLineInfo.toString());
for (Control thisControl : thisLine.getControls()) {
System.out.println(AnalyzeControl(thisControl));}
thisLine.close();}}
for (Line.Info thisLineInfo:thisMixer.getTargetLineInfo()) {
if (thisLineInfo.getLineClass().getName().equals(
"javax.sound.sampled.Port")) {
Line thisLine …Run Code Online (Sandbox Code Playgroud) 我有一组简短的WAV文件,我想用Java处理各种数字信号处理算法.我需要为此目的获得一个int值样本数组,以11025 Hz帧速率编码.
源文件有几种不同的采样率,包括11025 Hz和44100 Hz.这是我试图用来读取它们的代码:
// read the WAV file
FileInputStream fileInputStream = new FileInputStream(new File("test.wav"));
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(fileInputStream );
// copy the AudioInputStream to a byte array called buffer
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] data = new byte[4096];
int tempBytesRead = 0;
int byteCounter = 0;
while ((tempBytesRead = audioInputStream.read(data, 0, data.length)) != -1) {
bos.write(data, 0, tempBytesRead);
byteCounter += tempBytesRead;
}
bos.close();
byte[] buffer = bos.toByteArray();
AudioFileFormat audioFileFormat = new AudioFileFormat(AudioFileFormat.Type.WAVE, audioInputStream.getFormat(), (int)audioInputStream.getFrameLength());
// get the …Run Code Online (Sandbox Code Playgroud) 我正在实现一个使用纯Java的VOIP应用程序.当用户不使用耳机时(主要是带有内置麦克风的笔记本电脑),会出现回声问题.
目前发生了什么
VOIP应用程序的细节只是Java媒体框架的简单数据.基本上,我想在将音频数据写入扬声器输出之前对音频数据执行一些数字信号处理.
public synchronized void addAudioData(byte[] ayAudioData)
{
m_oBuffer.enqueue(ayAudioData);
this.notify();
}
Run Code Online (Sandbox Code Playgroud)
如您所见,音频数据到达并在缓冲区中排队.这是为了迎合狡猾的连接并允许不同的数据包大小.这也意味着在我将音频数据播放到扬声器线路之前,我可以访问任何花哨的DSP操作所需的音频数据.
我已经管理了一个可以工作的回声消除器,但它需要大量的交互式用户输入,我想要一个自动回声消除器.
手动回声消除器
public static byte[] removeEcho(int iDelaySamples, float fDecay, byte[] aySamples)
{
m_awDelayBuffer = new short[iDelaySamples];
m_aySamples = new byte[aySamples.length];
m_fDecay = (float) fDecay;
System.out.println("Removing echo");
m_iDelayIndex = 0;
System.out.println("Sample length:\t" + aySamples.length);
for (int i = 0; i < aySamples.length; i += 2)
{
// update the sample
short wOldSample = getSample(aySamples, i);
// remove the echo
short wNewSample = (short) (wOldSample - fDecay * m_awDelayBuffer[m_iDelayIndex]); …Run Code Online (Sandbox Code Playgroud) 我在stackoverflow中发现了类似的问题.但我想要具体.我访问了一个网站screencast-o-matic.他们有一个java applet的web应用程序,它捕获屏幕以导出为视频.我想开发类似的应用程序.这样做需要哪些知识和步骤?
感谢致敬.
编辑另一个网站屏幕.
我们,我一直在试图让Java播放一些简单的wav文件,而没有任何运气.我试过这段代码:
Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = AudioSystem.getAudioInputStream(new ByteArrayInputStream(soundBytes));
clip.open(inputStream);
clip.start();
Run Code Online (Sandbox Code Playgroud)
对于带有异常的"clip.open(...)",此操作失败:
javax.sound.sampled.LineUnavailableException: line with format PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian not supported.
Run Code Online (Sandbox Code Playgroud)
我尝试过更复杂的(流媒体版):
int BUFFER_SIZE = 128000;
AudioInputStream audioStream = null;
AudioFormat audioFormat;
SourceDataLine sourceLine = null;
try {
audioStream = AudioSystem.getAudioInputStream(new ByteArrayInputStream(soundBytes));
} catch (Exception e){
e.printStackTrace();
}
audioFormat = audioStream.getFormat();
DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
try {
sourceLine = (SourceDataLine) AudioSystem.getLine(info);
sourceLine.open(audioFormat);
} catch (LineUnavailableException e) {
e.printStackTrace();
} catch (Exception …Run Code Online (Sandbox Code Playgroud) 我想在java中为麦克风创建一个音频电平表来检查输入的大小.它应该看起来像操作系统之一.我不是在询问gui.它只是计算出来的字节流中的音频电平
n = targetDataLine.read( tempBuffer , 0 , tempBuffer.length );
Run Code Online (Sandbox Code Playgroud)
所以我已经有一些正在运行的东西,但它甚至没有接近我操作系统的水平仪(窗口)它卡在中间.我有0到100之间的值是好的,但在中间音量,无论输入多么大,它都会在60左右.
这是我现在计算的方式:
amplitude = 0;
for (int j = 0; j < tempBuffer.length; j = j +2 ){
if (tempBuffer[j] > tempBuffer[j+1])
amplitude = amplitude + tempBuffer[j] - tempBuffer[j+1];
else amplitude = amplitude + tempBuffer[j + 1] - tempBuffer[j];
}
amplitude = amplitude / tempBuffer.length * 2;
Run Code Online (Sandbox Code Playgroud)
是否有更好/更精确的方法来计算音频电平来监控它?或者我可能犯了一个重大错误?
那是我的Audioformat:
public static AudioFormat getAudioFormat(){
float sampleRate = 20000.0F;
//8000,11025,16000,22050,44100
int sampleSizeInBits = 16;
//8,16
int channels = 1;
//1,2
boolean signed …Run Code Online (Sandbox Code Playgroud) 使用Java,我正在尝试从默认麦克风录制声音并显示当前音量和静音状态(在OS级别设置,如果可能,不检查字节的兴趣).到目前为止,我可以使用以下代码获取TargetDataLine并记录到它:
TargetDataLine line = (TargetDataLine) AudioSystem.getLine(new DataLine.Info(TargetDataLine.class, formato));
这在Windows上运行良好,line是使用OS选择的默认麦克风.
现在,要获得音量/静音控件,我有以下代码:
Mixer.Info[] mixerInfos = AudioSystem.getMixerInfo();
for (Mixer.Info mixerInfo : mixerInfos) {
Mixer mixer = AudioSystem.getMixer(mixerInfo);
if (mixer.getMaxLines(Port.Info.MICROPHONE) > 0) {
System.out.println("-------------");
System.out.println(mixerInfo);
Port line = (Port) mixer.getLine(Port.Info.MICROPHONE);
line.open();
Line.Info[] targets = mixer.getTargetLineInfo();
Control[] controls = line.getControls();
for (Control control : controls) {
if (control instanceof CompoundControl) {
Control[] subControls = ((CompoundControl) control).getMemberControls();
for (Control subControl : subControls) {
System.out.println(subControl);
}
} else {
System.out.println(control);
}
}
System.out.println("-----------");
}
}
Run Code Online (Sandbox Code Playgroud)
我的设置中有2个麦克风,我还没有找到一种方法可以知道哪个是默认麦克风(现在它是阵列中的第二个).
尝试 …