【问题标题】:AudioTrack signal generator listening from gyroscopeAudioTrack 信号发生器监听陀螺仪
【发布时间】:2019-08-01 04:23:09
【问题描述】:

我正在尝试创建由陀螺仪传感器数据控制频率的信号发生器(通过移动手机)。问题是,我在onSensorChanged 中调用AudioTrack 并且我在输出上有“点击”,因为每次更新传感器时,我都会调用

stopSinus();
setSinus(Frequency);
startSinus();

是这样定义的

 siAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_RATE,
 AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT,
 buffsize, AudioTrack.MODE_STATIC);

public void stopSinus() {
        int checkPlay = siAudioTrack.getPlayState();
        if (checkPlay == 3) {  //
         siaudioTrack.stop();
         }
}

public void startSinus() {
        siAudioTrack.reloadStaticData();
        siAudioTrack.setLoopPoints(0, sampleCount, -1);  
        siAudioTrack.play();

}

public void setSinus(int frequency) {

    sampleCount = (int) ((float) SAMPLE_RATE / frequency);
    short sample[] = new short[sampleCount];
    int amplitude = 32767;
    double twoPi = 2 * Math.PI;;
    double phase = 0.0;

    for (int i = 0; i < sampleCount; i++) {
        sample[i] = (short) (amplitude * Math.sin(phase));
        phase += twoPi * frequency / SAMPLE_RATE;
    }
    siAudioTrack.write(sample, 0, sampleCount);
}

onSensorChanged 每秒变化几次,它会在波浪中间停止生成器 - 这就是“点击”的来源。

有人能告诉我如何在一波之后停止发电机吗?如何找出phase os 何时通过零?或者一些不同的解决方案?

【问题讨论】:

    标签: java android generator wave audiotrack


    【解决方案1】:

    没有实用的方法来确定应用于扬声器的相位何时超过 0。最好放弃。

    这是一个“不同”的解决方案,我认为您会发现效果更好:

    1. 切换到MODE_STREAM。要获得最低延迟,请使用最小的可用缓冲区大小 (getMinBufferSize())。
    2. 使用专用线程向AudioTrack 提供波形。该线程有一项工作:根据当前频率将一小段波形写入AudioTrack。 (您也可以使用主线程,并不断在AudioTrack 中添加非阻塞写入,但在我看来,使用单独的线程更优雅。线程将大部分时间卡在阻塞的write() 调用中,这意味着缓冲区保持最大填充,而工作量最少。)
    3. 摆脱startSinus()stopSinus()。从头开始播放音频,直到您离开应用后才停止播放。
    4. 更改setSinus(),使其简单地将当前频率值传递给步骤 2 中描述的线程。使用任何标准的线程间通信机制。
    5. 当该离开应用程序时,使用标准的线程间通信机制通知它应该终止的线程,然后join()它,清理等等。

    其他细节:

    • 使您的write()s 变小。一次可能只有 100 个样本。这有助于最大限度地减少延迟,同时仍保持理想的阻塞行为,并且无需担心AudioTrack 中有多少可用空间。
    • 在工作线程中,使用float 来跟踪阶段(就像您现在所做的那样)。根据频率增加相位,但不要让它变得太大!将其包裹在 0 到 2*PI 之间(否则,由于量化,较大的相位误差会蔓延,并且频率会意外变化)。显然,在填充每个微小的 100 个样本缓冲区后,您不会重置 phase。你只是让它继续滚动。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多