2016-08-05 160 views
0

我想从我的编解码器读取数据。由于我的项目中的原因,我希望进行非阻塞操作,但每次读取编解码器上可用的字节数时,它都会显示为零。Alsa snd_pcm_avail总是返回一个0

该算法非常简单:等待1ms,然后检查编解码器中是否有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; 
} 

谢谢!

回答

2

该设备从未启动。 这会在第一次拨打snd_pcm_read*()时自动发生,但也可以使用snd_pcm_start()明确完成。

+0

谢谢!就是这样。 – user846566