java 录音

发布于 2025-01-01 14:02:51 字数 4799 浏览 3 评论 0原文

我有一个软件,可以记录 5 秒的声音间隔,然后将其发送进行处理。它以无限循环运行,如下所示:

while (true) {
    System.out.println("recording..");
    recorder.start();
    Thread.sleep(5000);
    recorder.stop();
    Thread.sleep(300);
    System.out.println("recording finished");

    data = toolkit.readInputStream(recorder.getInputStream());

    pkt = create(data);

    outport.send(pkt);
}

在上面的代码中,我必须在录制完成后添加一行 Thread.sleep(300); ,否则 recorder.getInputStream() 返回 null。为什么会发生这种情况?有没有办法改变它,这样就不需要延迟?

记录器代码:

    public class SoundRecorder implements Runnable{


        final int bufSize = 16384;

        AudioInputStream audioInputStream;
        String errStr;
        double duration, seconds;
        File file;

     public void start() {
                errStr = null;
                thread = new Thread(this);
                thread.setName("Capture");
                thread.start();
            }

            public void stop() {
                thread = null;
            }

 private void shutDown(String message) {
            if ((errStr = message) != null && thread != null) {
                thread = null;
                System.err.println(errStr);

            }
        }


      public void run() {

                duration = 0;
                audioInputStream = null;


                // define the required attributes for our line,
                // and make sure a compatible line is supported.

                AudioFormat format = getFormat();
                DataLine.Info info = new DataLine.Info(TargetDataLine.class,
                        format);

                if (!AudioSystem.isLineSupported(info)) {
                    shutDown("Line matching " + info + " not supported.");
                    return;
                }

                // get and open the target data line for capture.

                try {
                    line = (TargetDataLine) AudioSystem.getLine(info);
                    line.open(format, line.getBufferSize());
                } catch (LineUnavailableException ex) {
                    shutDown("Unable to open the line: " + ex);
                    return;
                } catch (SecurityException ex) {
                    shutDown(ex.toString());

                    return;
                } catch (Exception ex) {
                    shutDown(ex.toString());
                    return;
                }

                // play back the captured audio data
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                int frameSizeInBytes = format.getFrameSize();
                int bufferLengthInFrames = line.getBufferSize() / 8;
                int bufferLengthInBytes = bufferLengthInFrames * frameSizeInBytes;
                byte[] data = new byte[bufferLengthInBytes];
                int numBytesRead;

                line.start();

                while (thread != null) {
                    if ((numBytesRead = line.read(data, 0, bufferLengthInBytes)) == -1) {
                        break;
                    }
                    out.write(data, 0, numBytesRead);
                }

                // we reached the end of the stream.  stop and close the line.
                line.stop();
                line.close();
                line = null;

                // stop and close the output stream
                try {
                    out.flush();
                    out.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }

                // load bytes into the audio input stream for playback

                byte audioBytes[] = out.toByteArray();
                ByteArrayInputStream bais = new ByteArrayInputStream(audioBytes);
                audioInputStream = new AudioInputStream(bais, format, audioBytes.length / frameSizeInBytes);

                long milliseconds = (long) ((audioInputStream.getFrameLength() * 1000) / format.getFrameRate());
                duration = milliseconds / 1000.0;



                try {
                    audioInputStream.reset();
                } catch (Exception ex) {
                    ex.printStackTrace();
                    return;
                }


            }

    public AudioInputStream getInputStream() {
            return audioInputStream;
        }

    public AudioFormat getFormat() {

            AudioFormat.Encoding encoding = AudioFormat.Encoding.PCM_SIGNED;
            float rate = 44100.0F;
            int sampleSize = 16;
            boolean bigEndian = true;
            int channels = 2;

            return new AudioFormat(encoding, rate, sampleSize,
                    channels, (sampleSize / 8) * channels, rate, bigEndian);

        }
    }

I have a piece of software that records a 5 sec interval of sound and then it sends it for processing. It runs in a infinite loop and looks as follows:

while (true) {
    System.out.println("recording..");
    recorder.start();
    Thread.sleep(5000);
    recorder.stop();
    Thread.sleep(300);
    System.out.println("recording finished");

    data = toolkit.readInputStream(recorder.getInputStream());

    pkt = create(data);

    outport.send(pkt);
}

In the above code I had to add a line Thread.sleep(300); after the finish of recording because otherwise recorder.getInputStream() returns null. Why is it happening? Is there a way to change it so there won't bee a need for a delay?

The recorder code:

    public class SoundRecorder implements Runnable{


        final int bufSize = 16384;

        AudioInputStream audioInputStream;
        String errStr;
        double duration, seconds;
        File file;

     public void start() {
                errStr = null;
                thread = new Thread(this);
                thread.setName("Capture");
                thread.start();
            }

            public void stop() {
                thread = null;
            }

 private void shutDown(String message) {
            if ((errStr = message) != null && thread != null) {
                thread = null;
                System.err.println(errStr);

            }
        }


      public void run() {

                duration = 0;
                audioInputStream = null;


                // define the required attributes for our line,
                // and make sure a compatible line is supported.

                AudioFormat format = getFormat();
                DataLine.Info info = new DataLine.Info(TargetDataLine.class,
                        format);

                if (!AudioSystem.isLineSupported(info)) {
                    shutDown("Line matching " + info + " not supported.");
                    return;
                }

                // get and open the target data line for capture.

                try {
                    line = (TargetDataLine) AudioSystem.getLine(info);
                    line.open(format, line.getBufferSize());
                } catch (LineUnavailableException ex) {
                    shutDown("Unable to open the line: " + ex);
                    return;
                } catch (SecurityException ex) {
                    shutDown(ex.toString());

                    return;
                } catch (Exception ex) {
                    shutDown(ex.toString());
                    return;
                }

                // play back the captured audio data
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                int frameSizeInBytes = format.getFrameSize();
                int bufferLengthInFrames = line.getBufferSize() / 8;
                int bufferLengthInBytes = bufferLengthInFrames * frameSizeInBytes;
                byte[] data = new byte[bufferLengthInBytes];
                int numBytesRead;

                line.start();

                while (thread != null) {
                    if ((numBytesRead = line.read(data, 0, bufferLengthInBytes)) == -1) {
                        break;
                    }
                    out.write(data, 0, numBytesRead);
                }

                // we reached the end of the stream.  stop and close the line.
                line.stop();
                line.close();
                line = null;

                // stop and close the output stream
                try {
                    out.flush();
                    out.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }

                // load bytes into the audio input stream for playback

                byte audioBytes[] = out.toByteArray();
                ByteArrayInputStream bais = new ByteArrayInputStream(audioBytes);
                audioInputStream = new AudioInputStream(bais, format, audioBytes.length / frameSizeInBytes);

                long milliseconds = (long) ((audioInputStream.getFrameLength() * 1000) / format.getFrameRate());
                duration = milliseconds / 1000.0;



                try {
                    audioInputStream.reset();
                } catch (Exception ex) {
                    ex.printStackTrace();
                    return;
                }


            }

    public AudioInputStream getInputStream() {
            return audioInputStream;
        }

    public AudioFormat getFormat() {

            AudioFormat.Encoding encoding = AudioFormat.Encoding.PCM_SIGNED;
            float rate = 44100.0F;
            int sampleSize = 16;
            boolean bigEndian = true;
            int channels = 2;

            return new AudioFormat(encoding, rate, sampleSize,
                    channels, (sampleSize / 8) * channels, rate, bigEndian);

        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

黯然 2025-01-08 14:02:51

您告诉在后台运行的线程停止,并且编写的代码在退出时需要执行一些清理工作。因此,您必须等待线程完成才能使用某些功能。

您可以做的是将 stop 函数更改为如下所示:

public void stop() {
    Thread t = thread;
    thread = null;// this will cause your thread to exit
    t.join();//this will wait for the thread to exit before returning.
}

You're telling your thread running in the background to stop, and the code, as it's written, has some clean up work to do on exit. Therefore you have to wait for the thread to finish before being able to use some of the functionality.

What you could do is change the stop function to something like:

public void stop() {
    Thread t = thread;
    thread = null;// this will cause your thread to exit
    t.join();//this will wait for the thread to exit before returning.
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文