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

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

我有一个java代码,它使用麦克风获取随机字节。
当我尝试使用java提供的类从麦克风中采样缓冲区时,遇到了一个问题。我有一个旧麦克风,这个密码一直都能用。但最近我买了一个更现代的网络摄像头(aukey pc-w1),它包括一个麦克风,当我配置windows10默认使用该输入声音设备时,声音采样功能并没有结束,因此无法获得声音缓冲区。
代码如下:

  1. class CaptureAudioThread extends Thread
  2. {
  3. protected final static int BYTES_TO_READ = 64000;
  4. protected AudioFormat _audioFormat = null;
  5. protected TargetDataLine _targetDataLine = null;
  6. protected int _bytesRead = 0;
  7. protected byte[] _buffer = null;
  8. public CaptureAudioThread( )
  9. {
  10. _buffer = new byte[ BYTES_TO_READ ];
  11. }
  12. protected AudioFormat getAudioFormat()
  13. {
  14. float sampleRate = 22000.0F;
  15. //8000,11025,16000,22050,44100
  16. int sampleSizeInBits = 16;
  17. //8,16
  18. int channels = 1;
  19. //1,2
  20. boolean signed = true;
  21. //true,false
  22. boolean bigEndian = true;
  23. //true,false
  24. return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed, bigEndian);
  25. }//end getAudioFormat
  26. @Override
  27. public void run()
  28. {
  29. try
  30. {
  31. _audioFormat = getAudioFormat();
  32. DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, _audioFormat);
  33. if (!AudioSystem.isLineSupported(dataLineInfo))
  34. {
  35. throw( new RuntimeException( "Not supported audio format") );
  36. }
  37. _targetDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo);
  38. _targetDataLine.open(_audioFormat);
  39. _targetDataLine.start();
  40. _bytesRead = _targetDataLine.read(_buffer, 0, _buffer.length);
  41. }
  42. catch( Exception th )
  43. {
  44. th.printStackTrace();
  45. _bytesRead = 0;
  46. }
  47. finally
  48. {
  49. if( _targetDataLine != null )
  50. {
  51. _targetDataLine.stop();
  52. _targetDataLine.close();
  53. }
  54. }
  55. }
  56. }

当我把这个程序和旧麦克风一起使用时,它工作得很好。但当我用新麦克风开始前一个线程时,它永远不会结束执行。
我已经检查了该代码是否适用于其他音频格式(比如使用samplerate=44100.0f和channels=2),得到了相同的结果
有人知道这个问题是否可以避免吗?

vecaoik1

vecaoik11#

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

相关问题