java声音采样器未完成获取缓冲区

laximzn5  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(346)

我有一个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),得到了相同的结果
有人知道这个问题是否可以避免吗?

vecaoik1

vecaoik11#

为什么代码只能使用一个麦克风而不能使用另一个?在我看来,只要线路是开放的,任何麦克风都会继续传输数据。
为了利用麦克风的输入线,在将字节组装到pcm之后,我将输入和输出浮点数组发送到并发安全fifo队列: ConcurrentLinkedQueue<Float[]> . 这样,就可以在不阻塞输入过程的情况下对输入的pcm执行操作。来自此队列的轮询不影响输入行添加到队列的能力。
idk如果这是处理麦克风输入的最有效的方法,或者它是否适合您的情况(您将它用作随机数生成器?),但也许这是一个值得考虑的计划/模式。

相关问题