我有一个java代码,它使用麦克风获取随机字节。
当我尝试使用java提供的类从麦克风中采样缓冲区时,遇到了一个问题。我有一个旧麦克风,这个密码一直都能用。但最近我买了一个更现代的网络摄像头(aukey pc-w1),它包括一个麦克风,当我配置windows10默认使用该输入声音设备时,声音采样功能并没有结束,因此无法获得声音缓冲区。
代码如下:
class CaptureAudioThread extends Thread
{
protected final static int BYTES_TO_READ = 64000;
protected AudioFormat _audioFormat = null;
protected TargetDataLine _targetDataLine = null;
protected int _bytesRead = 0;
protected byte[] _buffer = null;
public CaptureAudioThread( )
{
_buffer = new byte[ BYTES_TO_READ ];
}
protected AudioFormat getAudioFormat()
{
float sampleRate = 22000.0F;
//8000,11025,16000,22050,44100
int sampleSizeInBits = 16;
//8,16
int channels = 1;
//1,2
boolean signed = true;
//true,false
boolean bigEndian = true;
//true,false
return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed, bigEndian);
}//end getAudioFormat
@Override
public void run()
{
try
{
_audioFormat = getAudioFormat();
DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, _audioFormat);
if (!AudioSystem.isLineSupported(dataLineInfo))
{
throw( new RuntimeException( "Not supported audio format") );
}
_targetDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo);
_targetDataLine.open(_audioFormat);
_targetDataLine.start();
_bytesRead = _targetDataLine.read(_buffer, 0, _buffer.length);
}
catch( Exception th )
{
th.printStackTrace();
_bytesRead = 0;
}
finally
{
if( _targetDataLine != null )
{
_targetDataLine.stop();
_targetDataLine.close();
}
}
}
}
当我把这个程序和旧麦克风一起使用时,它工作得很好。但当我用新麦克风开始前一个线程时,它永远不会结束执行。
我已经检查了该代码是否适用于其他音频格式(比如使用samplerate=44100.0f和channels=2),得到了相同的结果
有人知道这个问题是否可以避免吗?
1条答案
按热度按时间vecaoik11#
为什么代码只能使用一个麦克风而不能使用另一个?在我看来,只要线路是开放的,任何麦克风都会继续传输数据。
为了利用麦克风的输入线,在将字节组装到pcm之后,我将输入和输出浮点数组发送到并发安全fifo队列:
ConcurrentLinkedQueue<Float[]>
. 这样,就可以在不阻塞输入过程的情况下对输入的pcm执行操作。来自此队列的轮询不影响输入行添加到队列的能力。idk如果这是处理麦克风输入的最有效的方法,或者它是否适合您的情况(您将它用作随机数生成器?),但也许这是一个值得考虑的计划/模式。