Эффективное использование api pa_simple - PullRequest
0 голосов
/ 10 февраля 2019

Я играю с pa_simple API, чтобы лучше понять цифровой звук.Я написал некоторый код для подачи сгенерированных пользователем аудиоданных на сервер pulseaudio:

char buff[2];
while (playing) {
    timePassed += periodMicros;
    int val = userFunc(timePassed/1000000.0);
    buff[0] = (val >> 0) & 0xff;
    buff[1] = (val >> 1) & 0xff;
    int error;
    pa_simple_write(s, buff, 2, &error);
}

func генерирует простую синусоидальную волну, подобную этой:

uint16_t func(double time)
{   
    double op = sin(2*3.14*freq * time);
    return op * 100;
}

Создает заметкукак и ожидалось, но потребляет до 50% процессора на моей машине из-за неограниченного цикла while в первом кодовом блоке.Поэтому я попытался исправить это так:

void _mainLoop() {
    char buff[2*bufSize];
    while (playing) {
        for ( int i = 0; i < bufSize; i++ ) {
            uint8_t word = userFunc(timePassed/1000000.0);
            timePassed += periodMicros;
            buff[i*2+0] = (word >> 0) & 0xff;
            buff[i*2+1] = (word >> 1) & 0xff;
        }
        pa_simple_write(s, buff, 2*bufSize, &error);
        this_thread::sleep_for(chrono::microseconds(bufSize*periodMicros));
    }
}

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

Я хотел знать, как правильно использовать pa_simple api без моего кода, пожирающего процессор.

Примечаниечто звук, генерируемый вторым кодом, не исправлен, даже если я изменил bufSize на 1 и удалил строку sleep.

Редактировать: Вот как я инициализировал соединение pulseaudio:

pa_sample_spec ss = {
    .format = PA_SAMPLE_S16LE,
    .channels = 1,
    .rate = 44100
};
s = pa_simple_new(
    NULL,
    "SYNTH",
    PA_STREAM_PLAYBACK,
    NULL,
    "Music",
    &ss,
    NULL,
    NULL,
    NULL
);

1 Ответ

0 голосов
/ 10 февраля 2019

Это была ошибка в программе.Я сохранял вывод userFunc в uint, поэтому отрицательные значения были обрезаны.Изменение этого значения на int и удаление вызова sleep устранило проблему, поскольку pa_simple api в synchronous.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...