【问题标题】:Generating sound on Android with OpenSL ES使用 OpenSL ES 在 Android 上生成声音
【发布时间】:2016-02-24 15:16:01
【问题描述】:

我正在 Android 上制作音频应用程序,我可以简单地生成三种类型的声波 - 正弦波、锯齿波和方波。

波浪的产生很好。我打印了结果,看起来不错。但是声音很奇怪。 这是我记录的。 https://soundcloud.com/syntey/synth-sine-wave-test-nothing-to-do-here

sawtooth 和 square 是一样的,但是当我用sawtooth any A 弹奏时,声音是正常的。

有人知道出了什么问题吗?如果我增加缓冲区的大小,那么周期会更长,但仍然是同样的问题

生成正弦波的代码:

play(JNIEnv* env, jclass clazz, jint which, jint count, jdouble freqOfTone)
{
    unsigned i;
    int j = 0;
    double sampleRate = SAMPLERATE/freqOfTone;
    switch (which) {
case SINE:
        for (i = 0; i < TONE_FRAMES; ++i) {
            toneBuffer[i] = sin(2.0*M_PI * i/sampleRate) * 32768;                
        }
        nextBuffer = createResampledBuf(SINE, SL_SAMPLINGRATE_8, &nextSize);
        if(!nextBuffer) {
            nextBuffer = (short*) toneBuffer;
            nextSize  = sizeof(toneBuffer);
        }
        break;
    }
    nextCount = count;
    if (nextSize > 0) {
        SLresult result;
        result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, nextBuffer, nextSize);
        if (SL_RESULT_SUCCESS != result) {
            bqPlayerRecorderBusy = 1;
            return JNI_FALSE;
        }
    }

    return JNI_TRUE;
}

【问题讨论】:

    标签: android audio opensl sound-synthesis


    【解决方案1】:

    您在生成波浪时没有打印任何内容?

    但主要问题是您的合成循环。我猜你听到的点击是因为你跳过了样本(你在 for 循环和合成块中增加了两次 i。应该是这样来避免点击:

    for (i = 0; i < SIZE_OF_BUFFER; i++) {
            toneBuffer[i] = sin(2.0*M_PI * i/(44100/freqOfTone)) * 32768;
    }
    

    但我建议您使用阶段,对我来说,这在信号处理过程中更有意义

    float generateSineWave(float freq) {
        // Get phase, then get sample
        phase = 2 * M_PI * freq / 44100 + prev_phase;
        sample = sin(phase);
    
        // wrap phase
        if (phase > (2 * M_PI)) phase -= (2 * M_PI);
    
        prev_phase = phase
    
        return sample;
    }
    
    void yourSynthesisLoop() {
        for (int i = 0; i < SIZE_OF_BUFFER; i++) {
            toneBuffer[i] = generateSineWave(freqOfTone) * 32768;
        }
    }
    

    【讨论】:

    • 我把它复制错了那个双增量,对不起..我使用了你的代码,但它仍然点击..但有些音调让它更安静。我将在第一篇文章中发布更多代码
    • @Syntey hm 我在我的代码中运行了它,但我没有任何点击,你是如何在你的代码中设置 opensl 的?听起来还是一模一样吗?再次,如果您在生成波形时打印任何内容(或只是任何未完成的过程),您将获得点击,因为这些功能会减慢您的波形生成块。另外 - 确保将 prev_phase 初始化为 0 并作为静态变量,如果设置不正确,您可能会获得点击
    • 我正在使用原生音频项目,最近我编辑了第一篇文章,在那里我拥有完整的功能。是的,我将它初始化为 0
    • 我不得不说你当时的设置有些奇怪。例如,为什么要创建重采样缓冲区;为什么即使您的采样率为 44.1 kHz,它仍设置为 8 kHz 采样率?我想我必须查看您的整个 open sl 设置以帮助进一步调试,但请查看这篇关于如何为音频流设置 Open SL 的博文:audioprograming.wordpress.com/2012/03/03/…
    【解决方案2】:

    尝试从核心使用短数据类型而不是双精度数据类型。 OpenSLEL 无论如何都会将其转换为short,因此可能会丢失数据或添加噪音。也可以使用更高的采样率来获得高质量。

    【讨论】:

      猜你喜欢
      • 2014-02-06
      • 1970-01-01
      • 2016-03-05
      • 1970-01-01
      • 1970-01-01
      • 2012-07-04
      • 2012-12-23
      • 1970-01-01
      • 2013-08-23
      相关资源
      最近更新 更多