在处理中获取多个音频输入

Posted

技术标签:

【中文标题】在处理中获取多个音频输入【英文标题】:Getting Multiple Audio Inputs in Processing 【发布时间】:2016-10-23 00:02:20 【问题描述】:

我目前正在编写一个需要访问多个音频输入的处理草图,但处理只允许访问默认线路。我尝试直接从 Java 混音器(在处理中访问)获取线路,但我仍然只从我机器上当前设置为默认值的那条线路获取信号。

我已经开始考虑通过 OSC 从 SuperCollider 发送声音,推荐 here。但是,由于我对 SuperCollider 非常陌生,并且他们的文档和支持更侧重于生成声音而不是访问输入,所以我下一步可能会按照 here 的建议与 Beads 和 Jack 一起玩。

是否有人有 (1) 其他建议,或 (2) 从 SuperCollider 或 Beads/Jack 获取多个输入到处理的具体示例?

提前谢谢你!

编辑:声音将用于驱动自定义音乐可视化(想想 iTunes 可视化器,但更多的是歌曲特定)。我们可以处理多个 mp3;现在我需要的是能够从每个麦克风中获取一个 float[] 缓冲区。希望有 9 个不同的麦克风,不过如果更可行,我们会选择 4 个。

对于硬件,此时,我们只使用麦克风和 XLR 转 USB 电缆。 (考虑过前置放大器,但到目前为止这已经足够了。)我目前使用的是 Windows,但我认为我们最终会切换到 Mac。

这是我仅使用 Beads 的尝试(它适用于笔记本电脑,因为我先做一个,但耳机缓冲区全为 0;如果我切换它们并首先放置耳机,耳机缓冲区将是正确的,但笔记本电脑将包含全 0):

void setup() 
    size(512, 400);

    JavaSoundAudioIO  headsetAudioIO = new JavaSoundAudioIO();
    JavaSoundAudioIO  laptopAudioIO = new JavaSoundAudioIO();

    headsetAudioIO.selectMixer(5);
    headsetAudioCon  = new AudioContext(headsetAudioIO);

    laptopAudioIO.selectMixer(4);
    laptopAudioCon  = new AudioContext(laptopAudioIO);

    headsetMic  = headsetAudioCon.getAudioInput();
    laptopMic  = headsetAudioCon.getAudioInput();
 // setup()

void draw() 
    background(100,0, 75);

    laptopMic.start();
    laptopMic.calculateBuffer();
    laptopBuffer   = laptopMic.getOutBuffer(0);

    for (int j = 0; j < laptopBuffer.length - 1; j++)
    
        println("laptop; " + j + ": " + laptopBuffer[j]);
        line(j, 200+laptopBuffer[j]*50, j+1, 200+laptopBuffer[j+1]*50);
    
    laptopMic.kill();

    headsetMic.start();
    headsetMic.calculateBuffer();

    headsetBuffer  = headsetMic.getOutBuffer(0);


    for (int j = 0; j < headsetBuffer.length - 1; j++)
    
        println("headset; " + j + ": " + headsetBuffer[j]);
        line(j, 50+headsetBuffer[j]*50, j+1, 50+headsetBuffer[j+1]*50);
    

    headsetMic.kill();
 // draw()

我添加 Jack 的尝试包含这一行:

ac = new AudioContext(new AudioserverIO.Jack(), 44100, new IOAudioFormat(44100, 16, 4, 4));

但我得到了错误:

Jun 22, 2016 9:17:24 PM org.jaudiolibs.beads.AudioServerIO$1 run
SEVERE: null
org.jaudiolibs.jnajack.JackException: Can't find native library
    at org.jaudiolibs.jnajack.Jack.getInstance(Jack.java:428)
    at org.jaudiolibs.audioservers.jack.JackAudioServer.initialise(JackAudioServer.java:102)
    at org.jaudiolibs.audioservers.jack.JackAudioServer.run(JackAudioServer.java:86)
    at org.jaudiolibs.beads.AudioServerIO$1.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.UnsatisfiedLinkError: Unable to load library 'jack': Native library (win32-x86-64/jack.dll) not found in resource path ([file:/C:/Users/...etc...)

当我在 Jack 中时,我看不到我的麦克风(这对我来说似乎是一个巨大的危险信号,尽管我对 Jack 完全陌生)。这个 AudioContext 是否应该在 Jack 中显示为输入?反之亦然——先在那儿找到我的麦克风,然后再从 Jack 那里拿到 Processing?

(请原谅我的经验不足,再次感谢您!我对 Jack 的了解不足让我想知道是否应该重新访问 SuperCollider...)

【问题讨论】:

您能否提供更多背景信息(例如,您将如何处理传入的音频)、有关您正在使用的硬件的一些信息,以及可能显示您已经尝试过的代码示例? @mbaytas 扩展了帖子以包含有关项目和当前硬件的信息,并添加了代码示例。 【参考方案1】:

几年前我遇到了同样的问题,我使用了 JACK、JNAJack 和 Beads 的组合。您可以关注此Beads Google Group thread 了解更多详情。

当时我不得不使用this version of Beads (2012-04-23),但我希望这些更改现在可能已经成为主要项目。

作为参考,这是我使用的基本类:

import java.util.Arrays;

import org.jaudiolibs.beads.AudioServerIO;

import net.beadsproject.beads.analysis.featureextractors.FFT;
import net.beadsproject.beads.analysis.featureextractors.PowerSpectrum;
import net.beadsproject.beads.analysis.segmenters.ShortFrameSegmenter;
import net.beadsproject.beads.core.AudioContext;
import net.beadsproject.beads.core.AudioIO;
import net.beadsproject.beads.core.UGen;
import net.beadsproject.beads.ugens.Gain;
import processing.core.PApplet;


public class BeadsJNA extends PApplet 

    AudioContext ac;
    ShortFrameSegmenter sfs;
    PowerSpectrum ps;

    public void setup()
        //defining audio context with 6 inputs and 6 outputs - adjust this based on your sound card / JACK setup
        ac = new AudioContext(new AudioServerIO.Jack(),512,AudioContext.defaultAudioFormat(6,6));

        //getting 4 audio inputs (channels 1,2,3,4)
        UGen microphoneIn = ac.getAudioInput(new int[]1,2,3,4);
        Gain g = new Gain(ac, 1, 0.5f);
        g.addInput(microphoneIn);
        ac.out.addInput(g);

        println("no. of inputs:  " + ac.getAudioInput().getOuts()); 

        //test get some FFT power spectrum data form the 
        sfs = new ShortFrameSegmenter(ac);
        sfs.addInput(ac.out);
        FFT fft = new FFT();
        sfs.addListener(fft);
        ps = new PowerSpectrum();
        fft.addListener(ps);
        ac.out.addDependent(sfs);

        ac.start();
    
    public void draw()
        background(255);
        float[] features = ps.getFeatures();
        if(features != null)
            for(int x = 0; x < width; x++)
              int featureIndex = (x * features.length) / width;
              int barHeight = Math.min((int)(features[featureIndex] *
                                                height), height - 1);
              line(x, height, x, height - barHeight);
             
        
    

    public static void main(String[] args) 
        PApplet.main(BeadsJNA.class.getSimpleName());
    


【讨论】:

谢谢!遇到上面的“找不到本机库”错误。可能是 JNA 或 JNAJack 的问题?我尝试将 jna.jar 添加到草图的代码文件夹中,并将 org\jaaudiolibs\jnajack 放入 Processing 的库文件夹中。 我当时使用 eclipse,因为它更容易处理所有不同的库,这些库大多是纯 java 格式(而不是使用处理库文件夹结构)。你能改用eclipse吗? @Aemilia 我已经上传了我的旧 Eclipse 项目here。您应该能够将其解压缩并在 eclipse 中导入。确保您有 Jack 正在运行,并且您的输入根据需要进行路由。默认情况下,它将在第 26 行查找 1 个音频输入。您可以根据第 25 行(尝试使用 4 个音频输入)将其调整为您的设置需要。

以上是关于在处理中获取多个音频输入的主要内容,如果未能解决你的问题,请参考以下文章

从浏览器中的麦克风获取音频输入并提取特征

EZAudio 中的音频输入源

如何从多个音频文件中获取总音频持续时间

保存多个录制音频文件并获取所有录制音频

如何在不使用相同音频 ID 的情况下播放从数据库中获取的多个音频文件

使用 FFmpeg 将一个视频处理为多个输出会导致最后一个输出中没有音频