音频流 - 捕获和读取麦克风数据

Posted

技术标签:

【中文标题】音频流 - 捕获和读取麦克风数据【英文标题】:Audio Streaming - Capturing and reading microphone data 【发布时间】:2020-10-01 16:48:41 【问题描述】:

我正在尝试从我的默认麦克风获取麦克风数据,并将其发送到我计算机上的另一个程序。发送有效,但我没有从麦克风读取任何数据,这是输出。无论我是否读取数据,输出都是相同的。

Output:
 This program: [B@ec7777
 Reciever program: b'\x00\x00\x00\x00\x00\x00\.....
import java.lang.*;
import java.util.*;

import java.net.SocketException;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.zip.DataFormatException;

import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.DatagramPacket;

import javax.sound.sampled.*;
import javax.sound.sampled.TargetDataLine;
import javax.sound.sampled.Audiosystem.*;
import java.io.ByteArrayOutputStream;

class mainclass 
    public static int buffer = 1472;
    public static byte[] data = new byte[buffer]; 
    private static AudioFormat format = new AudioFormat(10100.0f, 16, 1, true, true);
    

    public static void main(String[] args) throws SocketException, UnknownHostException,IOException, DataFormatException, InterruptedException, LineUnavailableException  
        DatagramSocket socket = new DatagramSocket();
        InetAddress address = InetAddress.getByName("my.ipa.ddr.ess");

        TargetDataLine microphone = AudioSystem.getTargetDataLine(format);
        int numBytesRead;
        DatagramPacket packet;
        microphone.start();
        ByteArrayOutputStream out  = new ByteArrayOutputStream();

        for(int i=0;i<10;i++)
            numBytesRead = microphone.read(data, 0, data.length);
            out.write(data,0,numBytesRead);
            System.out.println(data);
            packet = new DatagramPacket(data, data.length, address, myport);
            socket.send(packet);
        
        microphone.stop();
        microphone.close();
    

如果我不抛出它,我会得到一个 LineUnavailableException。

aud2.java:115: error: unreported exception LineUnavailableException; must be caught or declared to be thrown 
   TargetDataLine microphone = AudioSystem.getTargetDataLine(format);
//                                                          ^ pointing at (

【问题讨论】:

请显示您异常的完整堆栈跟踪。 @jmizv 没有抛出异常的错误:aud2.java:115:错误:未报告的异常 LineUnavailableException;必须被捕获或声明被抛出 TargetDataLine 麦克风 = AudioSystem.getTargetDataLine(format); 【参考方案1】:

您列出的AudioFormat 似乎不太可能是有效的。

44100 是更常见的采样率。此外,如果您使用 16 位编码,并且正在录制单声道,则每帧将有 2 个字节,而不是指定的 1 个。

我的猜测是,关闭这与获得“线路不可用”异常是一致的。可能还有其他问题。但是拥有 Java 支持的 AudioFormat 仍然是必要的第一步。

如果您需要使用较慢的采样率,11025 就在附近,您的系统可能支持它。另外,也许是 8000。也许是 16,000。但我还没有深入研究替代采样率。

教程Using Files and Format Converters中有关于测试音频格式是否支持的信息

对于我笔记本电脑的麦克风(在这台笔记本电脑上使用默认设置时),我使用非常简单的原版设置,有时称为“CD 质量”。规格如下:

编码:AudioFormat.Encoding.PCM_SIGNED 采样率:44100 以位为单位的样本大小:16 频道:2 帧大小:4 大端:假

如果确定你有单声道,channels 将为 1,帧大小 为 2。

【讨论】:

以上是关于音频流 - 捕获和读取麦克风数据的主要内容,如果未能解决你的问题,请参考以下文章

将音频流读取到输出设备

使用 .NET Framework 捕获麦克风音频流

在 Java 中创建音频(麦克风)和视频(桌面)流

使用 Java 混合器混合两个音频流

Java:从 2 个不同的麦克风输入中独立捕获音频

实时音频流库