2010-07-27 96 views
3

我目前正在開發一個項目,要求我對Alsa進行一些抽樣。我正在嘗試正確配置所有內容,但我一直在堅持如何正確調整閱讀大小。正確調整Alsa緩衝區的大小,奇怪的API

有兩個原語,似乎是對我的任務有趣:

snd_pcm_hw_params_get_period_time 
snd_pcm_hw_params_get_buffer_size 

第一個的名字所暗示的輸出將是一個採樣週期的時間長度,但是這是奇怪的:如果我設置採樣率爲f = 44100Hz採樣週期(以納秒爲單位)應爲T0 = 1e9/44100 ~= 22676 ns,而函數將回答T1 = 725 us = 725000 ns。與此同時,即使我被要求使用非鎖定原語,我試圖分析鎖定'readi'所需的時間,事實證明,在最佳情況下樣本需要T2 = 8028603 ns,並且在最佳情況下需要T2 = 8028603 nsT3 = 12436217 ns在最壞的情況下。

最後,我無法找出什麼是以下兩個含義:

snd_pcm_hw_params_get_buffer_time 
snd_pcm_hw_params_get_period_size 

我不明白我怎麼能衡量時間的緩衝和大小的時期,但前者的回報與get_buffer_size相同的值,而後者返回與get_period_time相同的值。

任何提示?

回答

3

這是我的聲卡初始化函數。

首先,我設置所需要的參數

static 
int init_soundcard (snd_pcm_t *handle, unsigned *rate, uint8_t channels, 
        snd_pcm_uframes_t *nframes, unsigned *period) 
{ 
    snd_pcm_hw_params_t *hwparams; 
    int err; 

    snd_pcm_hw_params_alloca(&hwparams); 

    err = snd_pcm_hw_params_any(handle, hwparams); 
    if (err < 0) return err; 

    err = snd_pcm_hw_params_set_rate_near(handle, hwparams, rate, NULL); 
    if (err < 0) return err; 

    err = snd_pcm_hw_params_set_access(handle, hwparams, 
             SND_PCM_ACCESS_RW_INTERLEAVED); 
    if (err < 0) return err; 

    err = snd_pcm_hw_params_set_format(handle, hwparams, 
             SND_PCM_FORMAT_S16_LE); 
    if (err < 0) return err; 

    err = snd_pcm_hw_params_set_channels(handle, hwparams, channels); 
    if (err < 0) return err; 

當每一個參數是否已正確設置好的,參數被施加到手柄:

err = snd_pcm_hw_params(handle, hwparams); 
    if (err < 0) return err; 

後,它已應用於勇敢程序員可以獲得如下所需的數據:

get_period_size_min()給出了幀的最小大小將包含採樣的緩衝區。具有這種尺寸的緩衝區足夠寬。

err = snd_pcm_hw_params_get_period_size_min(hwparams, nframes, NULL); 
    if (err < 0) return err; 

這是非常不直觀的,但正如我們所想的那樣,正確的採樣週期並不是1/rate。我們可以使用get_period_time()原語來獲取採樣週期!

err = snd_pcm_hw_params_get_period_time(hwparams, period, NULL); 
    if (err < 0) return err; 

    return 0; 
} 
4

ALSA有一些怪^ Wspecific術語:

  • 幀:樣本x信道(即:立體聲幀由兩個樣品中,單聲道的幀是由1個採樣的,...)
  • 期:在設備確認傳輸到適配器之後(通常通過中斷),傳輸的樣本數量。

* _size函數似乎以幀的形式返回大小。

HTH

+0

他們回到什麼是返回類型,這是'snd_uframe_t'爲* _size和'unsigned'爲* _time明確獲得「真正的」採樣率,但我沒有得到什麼「緩衝時間」和「週期大小」的含義。 – Dacav 2010-07-27 15:34:33

+0

期大小:在幀 VAL返回週期近似尺寸 緩衝時間(當然這取決於當前配置):在 VAL返回的緩衝區時我們 – ninjalj 2010-07-27 15:40:35

+0

是,該文件具有的功能名稱的相同信息內容,但什麼是一個緩衝時間?緩衝區有一定的*大小*,而不是*時間*。 – Dacav 2010-07-27 15:43:04

1

從我理解的使用和閱讀ALSA庫中,這段時間與正在進行的硬件中斷有關。如果使用

snd_pcm_hw_params_get_period_size() 

它會返回通過中斷傳遞給hw的幀數。同樣,如果你使用

snd_pcm_hw_params_get_period_time() 

你會得到我們的時間(10^-6),這些幀將被插入。所以,如果能

snd_pcm_hw_params_get_period_size()*1000000/snd_pcm_hw_params_get_period_time()