Alsa snd_pcm_avail всегда возвращает 0

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

Алгоритм довольно прост: подождите 1 мс, затем проверьте, есть ли в кодеке более 160 сэмплов для чтения, а затем прочитайте сэмплы. Но каждый раз, когда я делаю чтение, он говорит, что отсчет выборки равен нулю.

Может кто-нибудь помочь мне понять, почему "rc = snd_pcm_avail(inputCodecHandle);" всегда возвращает ноль?

Вот нить с кодом в нем.

void CRadioStack::rcvThread() {
    ChannelBuffer_t *buffer_p = NULL;
    int8_t *inputBuf_p;
    int rc;
    int16_t *inputBuf16_p;
    int  samplesToRead;
    const int rxFrameSize = 160;
    snd_pcm_sframes_t delay;

    snd_pcm_nonblock(inputCodecHandle, 1);
    snd_pcm_prepare(inputCodecHandle);

    while (true) {
        TWTime::msleep(1);

        // get the number of samples available
        snd_pcm_delay(inputCodecHandle, &delay);
        rc = snd_pcm_avail(inputCodecHandle);
        if (rc < 0) {
            myLog->warn("Error in getting sample count: %s", snd_strerror(rc));
            snd_pcm_prepare(outputCodecHandle);
            continue;
        }
        samplesToRead = rc;

        // if number of samples > 160 then get 160 samples
        if (samplesToRead <= rxFrameSize) {
            continue;
        }

        // read the from the codec into the Channel Buffer.
        rc = snd_pcm_readi(inputCodecHandle, inputBuf_p, rxFrameSize);
        if (rc < 0) {
            myLog->warn("Error reading Codec: %s", snd_strerror(rc));
            continue;
        } else if (rc != rxFrameSize) {  // nothing to get
            myLog->warn("Input samples on codec not 160");
        }

        pushToInputQueue(inputBuf_p);
    }
}

А вот и код для открытия кодека.

bool CRadioStack::openInputCodec()
{
    unsigned int val;
    int dir;
    const int NUM_OF_CHAN = 1;
    codecRunning = false;
    snd_pcm_uframes_t frames;

    int rc;
    snd_pcm_t *handle;
    snd_pcm_hw_params_t *params;

    inputCodecHandle = nullptr;

    // Open pcm device for output
    rc = snd_pcm_open(&handle, "hw:0,0", SND_PCM_STREAM_CAPTURE, 0);
    if (rc < 0) {
        myLog->error("Unable to open input codec: %s", snd_strerror(rc));
        return false;
    }

    // allocate a hardware parameters object
    snd_pcm_hw_params_alloca(&params);

    // fill with default values
    snd_pcm_hw_params_any(handle, params);

    // now setup the hardware paramters
    snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);    // interleaved
    snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);            // 16bin linear little-endian
    snd_pcm_hw_params_set_channels(handle, params, NUM_OF_CHAN);                    // one channel
    val = 0;
    snd_pcm_hw_params_set_channels_near(handle, params, &val);                      // one channel
    val = 8000;
    dir = 0;
    snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir);                    // 8k sample rate.
    frames = 160;
    snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir);          // period size = 160 frames

    // save the hardware parameters
    rc = snd_pcm_hw_params(handle, params);
    if (rc < 0) {
        myLog->error("Unable to save hardware parameters to output codec.");
        return false;
    }

    // ready to write to output codec.
    // so save the handle so that it can be used elsewhere.
    inputCodecHandle = handle;
    return true;
}

Спасибо!

1 ответ

Решение

Устройство никогда не запускалось. Это произойдет автоматически с первым snd_pcm_read*() вызов, но также может быть сделано явно с snd_pcm_start(),

Другие вопросы по тегам