Генерация звука на Android с OpenSL ES

Я делаю аудио-приложение на Android, и у меня есть простая генерация трех типов звуковых волн - синусоидальной, пилообразной и квадратной.

Генерация волн в порядке. Я распечатал результат, и он выглядит хорошо. Но звук странный. Вот что я записал. https://soundcloud.com/syntey/synth-sine-wave-test-nothing-to-do-here

То же самое для пилообразного и квадратного, но когда я играю пилообразной любой 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;
}

person Syntey    schedule 24.02.2016    source источник


Ответы (2)


Вы ничего не печатаете при генерации волны?

Но также главная проблема - это ваш цикл синтеза. Я собираюсь предположить, что щелчки, которые вы слышите, вызваны пропуском семплов (вы увеличиваете i дважды в цикле for и в блоке синтеза. Это должно быть так, чтобы избежать щелчков:

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;
    }
}
person yun    schedule 24.02.2016
comment
Я неправильно скопировал это с двойным увеличением, извините .. Я использовал ваш код, но он все равно щелкает ... но на некоторых тонах он тише. Я опубликую больше кода в первом посте - person Syntey; 24.02.2016
comment
@Syntey hm У меня это работает в моем коде, и у меня нет щелчка, как вы настраиваете openl в своем коде? Он по-прежнему звучит точно так же? И снова, если вы распечатываете что-либо (или просто какой-либо незавершенный процесс) во время генерации сигнала, вы получите щелчки, поскольку эти функции замедлят ваш блок генерации сигнала. ТАКЖЕ - убедитесь, что вы инициализировали prev_phase равным 0 и в качестве статической переменной вы можете получить клики, если они не настроены правильно. - person yun; 24.02.2016
comment
Я использую собственный аудиопроект, и недавно я отредактировал первый пост, в котором у меня есть вся функция. Да, я инициализировал его на 0 - person Syntey; 24.02.2016
comment
Я собираюсь сказать что-то странное в том, как вы тогда настраиваетесь. Например, зачем вы создаете буфер с передискретизацией; почему он установлен на частоту дискретизации 8 кГц, хотя ваша частота дискретизации была на уровне 44,1 кГц? Думаю, мне нужно было бы увидеть всю вашу настройку open sl, чтобы помочь в дальнейшей отладке, но посмотрите этот пост в блоге о том, как настроить Open SL для потоковой передачи звука: audioprograming.wordpress.com/2012/03/03/ - person yun; 24.02.2016

Попробуйте использовать короткий тип данных вместо двойного из основного. OpenSLEL в любом случае преобразует его в короткий, следовательно, возможна потеря данных или добавлен шум. Также для хорошего качества используйте более высокую частоту дискретизации.

person user2609137    schedule 07.03.2016