2016-08-05 159 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