在Java中生成非正弦声音输出

时间:2013-11-16 13:28:36

标签: java audio ppm

对于学校项目,我必须使用Java从我的计算机控制我的RC平面。 我想要实现这一目标的方法是通过3.5mm电缆(遥控器的训练器端口)将我的遥控器连接到我的MacBookPro。

我与遥控器通信的方式是通过PPm信号,如下所示:

enter image description here

以下是有关PPM信号的更多信息: https://www.insecure.ws/2010/03/09/control-rc-aircrafts-from-your-computer-for-0/#toc-2

我现在想知道的是,我如何使用Java生成所述PPM信号。 它必须是具有特定幅度的粗糙信号。

这里有人能帮助我吗?

修改
让我回答一下下面提到的一些问题:

该网站更好地解释了我认为我能做到的,但无论如何我都会尝试。

我想用我的电脑控制我的遥控飞机。 现在,我只希望我的油门工作。其余的将在稍后进行。

每帧长22.5ms,因为这是RC材料使用的格式。 每个帧由8个通道组成,它们之间有0.4ms的停止位置,还有一个空白信号,用于填补剩余的时间。

每个通道的振幅为1.3Volts,我将通过反复试验来实现(用我的音量播放直到烦人的哔哔声停止),并且是0.7 - 1.5ms。

我想要实现的是,有一个默认信号,7x 1.1ms和1x 0.7ms(所有伺服器中间位置为7x,最小1x节气门),当用户按下键盘上的按钮时会发生变化( 1将把油门的信号长度改变为0.7 + 0.1 ms => 0.8ms)。在用户按下0,1,2,3或4之前,信号将不断重复(每22.5ms 1帧),并改变通道1的长度。

到目前为止,我已在github上发布了我的内容。

1 个答案:

答案 0 :(得分:1)

要做你要求的事,你必须:

  1. 根据您的设置用Java打开音频输出 - 正确的采样率,通道数等
  2. 使用您的信号生成PCM(WAV)波形
  3. 将生成的波形推过输出线
  4. 您还必须在操作系统中禁用任何形式的后处理,并检查您的声卡是否能够在指定频率下准确生成信号。我没有任何使用Mac上的Java声音的经验,但是看到Windows和/或声音驱动程序可能不稳定,最好做好准备。

    用Java打开音频输出

    要用Java打开音频输出,您必须选择一种支持的音频格式,然后使用部分标准JDK API打开“源数据线”(音频输出)。

    旁注:JDK中的音频API在很长一段时间内没有改变;它几乎不具备任何自我描述性或直观性。例如,音频输出称为“源数据线”,而音频输入称为“目标数据线”。

    此代码段应该可以帮助您使用JDK API打开默认音频输出:

    import javax.sound.sampled.AudioFormat;
    import javax.sound.sampled.AudioSystem;
    import javax.sound.sampled.SourceDataLine;
    
    [...]
    
    // Constructs a Mono, 48kHz, 2-bytes per sample, one sample per frame format */
    AudioFormat af = new AudioFormat( AudioFormat.Encoding.PCM_SIGNED, 48000.0f, 16, 1, 2, 48000.0f, true );
    
    SourceDataLine output = AudioSystem.getSourceDataLine( af );
    output.open();
    output.start();  
    // `output` should be ready for writing
    

    生成信号的PCM(WAV)波形

    您链接到的网站包含应该生成信号的Python代码段。如果这正是您想要的信号,您应该将该段代码重写为Java。你说这是你的学校项目,从描述我可以假设这是作业的主要部分,所以让我们把它作为练习留给读者: - )

    将生成的波形推过输出线

    基本上,您必须将PCM样本写入音频输出:

    // Initialization
    final int byteBufferSizeBytes = AUDIO_BUFFER_SIZE_SAMPLES * af.getFrameSize();
    byte bbuf[] = new byte[byteBufferSizeBytes];
    
    // Inner loop
    while ( output.isActive() ) {
        // Read/generate piece of your data here and write it into bbuf array
    
        // Write contents of bbuf (PCM samples) to audio output
        output.write( bbuf, 0, byteBufferSizeBytes );
    }
    

    个人插头

    前段时间我写了一个Java程序,它从麦克风读取输入,根据ITU-R BS.1770-3建议分析其感知响度,并在超过预设响度阈值时显示信息。它有一点GUI,在Windows 7下它使用的CPU不到1%。

    代码在GitHub,但请注意,它是在一个全能的时候写的,所以它可能不是100%一致(说实话,我仍然认为我可以写得更好) 。我建议你从类AudioProcessor开始,因为它会进行输入/输出初始化。