国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
Linux下ALSA聲卡編程

. 介紹

      ALSA 標(biāo)準(zhǔn)是一個(gè)先進(jìn)的linux聲音體系。它包含內(nèi)核驅(qū)動(dòng)集合,API庫和工具對(duì)Linux聲音進(jìn)行支持。ALSA 包含一系列內(nèi)核驅(qū)動(dòng)對(duì)不同的聲卡進(jìn)行支持,還提供了libasoundAPI庫。用這些進(jìn)行寫程序不需要打開設(shè)備等操作,所以編程人員在寫程序的時(shí)候不會(huì)被底層的東西困擾。與此相反OSS/Free 驅(qū)動(dòng)在內(nèi)核層次調(diào)用,需要指定設(shè)備名和調(diào)用ioctl。為提供向后兼容, ALSA 提供內(nèi)核模塊模仿 OSS/Free 驅(qū)動(dòng),所以大多數(shù)的程序不需要改動(dòng)。 ALSA 擁有調(diào)用插件的能力對(duì)新設(shè)備提供擴(kuò)展,包括那些用軟件模擬出來的虛擬設(shè)備。 ALSA 還提供一組命令行工具包括  mixer, sound file player 和工具控制一些特別的聲卡的特別的作用。

 

.ALSA 體系:

ALSA API 被主要分為以下幾種接口:

l         控制接口:提供靈活的方式管理注冊(cè)的聲卡和對(duì)存在的聲卡進(jìn)行查詢。

l         PCM接口:提供管理數(shù)字音頻的捕捉和回放。

l         原始 MIDI 接口: 支持 MIDI (Musical Instrument Digital Interface), 一種標(biāo)準(zhǔn)電子音樂指令集。 這些 API 提供訪問聲卡上的 MIDI 總線。這些原始借口直接工作在 The  MIDI 事件上,程序員只需要管理協(xié)議和時(shí)間。

l         記時(shí)接口: 為支持聲音的同步事件提供訪問聲卡上的定時(shí)器。

l         音序器接口:一個(gè)比原始MIDI接口高級(jí)的MIDI編程和聲音同步高層接口。它可以處理很多的MIDI協(xié)議和定時(shí)器。

l         混音器接口:控制發(fā)送信號(hào)和控制聲音大小的聲卡上的設(shè)備。

 

.聲卡的緩存和數(shù)據(jù)的傳輸:

      一塊聲卡有一個(gè)聲卡內(nèi)存用來存儲(chǔ)記錄的樣本。當(dāng)它被寫滿時(shí)就產(chǎn)生中斷。內(nèi)核驅(qū)動(dòng)就使用DMA將數(shù)據(jù)傳輸?shù)絻?nèi)存中。同樣地,當(dāng)在播放時(shí)就將內(nèi)存中的聲音樣本使用DMA傳到聲卡的內(nèi)存中!

      聲卡的緩存是環(huán)狀的,這里只討論應(yīng)用程序中的內(nèi)存結(jié)構(gòu):ALSA將數(shù)據(jù)分成連續(xù)的片段然后傳到按單元片段傳輸。

 

四:典型的聲音程序結(jié)構(gòu):

        open interface for capture or playback

        set hardware parameters

        (access mode, data format, channels, rate, etc.)

        while there is data to be processed:

        read PCM data (capture)

        or write PCM data (playback)

        close interface

 

.一些例子:

1.顯示一些PCM的類型和格式:

 

#include <iostream>

#include <alsa/asoundlib.h>

 

int main()

{

       std::cout << "ALSA library version: " << SND_LIB_VERSION_STR << std::endl;

 

       std::cout << "PCM stream types: " << std::endl;

 

       for (int val=0; val <= SND_PCM_STREAM_LAST; ++val)

              std::cout << snd_pcm_stream_name((snd_pcm_stream_t)val) << std::endl;

       std::cout << std::endl;

 

       std::cout << "PCM access types: " << std::endl;

       for (int val=0; val <= SND_PCM_ACCESS_LAST; ++val)

              std::cout << snd_pcm_access_name((snd_pcm_access_t)val) << std::endl;

       std::cout << std::endl;

 

       std::cout << "PCM subformats: " << std::endl;

       for (int val=0; val <= SND_PCM_SUBFORMAT_LAST; ++val)

              std::cout << snd_pcm_subformat_name((snd_pcm_subformat_t)val) << " (" << snd_pcm_subformat_description((snd_pcm_subformat_t)val) << ")" << std::endl;

       std::cout << std::endl;

 

       std::cout << "PCM states: " << std::endl;

       for (int val=0; val <= SND_PCM_STATE_LAST; ++val)

              std::cout << snd_pcm_state_name((snd_pcm_state_t)val) << std::endl;

       std::cout << std::endl;

 

 

       std::cout << "PCM formats: " << std::endl;

       for (int val=0; val <= SND_PCM_FORMAT_LAST; ++val)

              std::cout << snd_pcm_format_name((snd_pcm_format_t)val) << " (" << snd_pcm_format_description((snd_pcm_format_t)val) << ")" << std::endl;

       std::cout << std::endl;

      

}

 

2.打開PCM設(shè)備和設(shè)置參數(shù)

 

#include <iostream>

#include <alsa/asoundlib.h>

 

int main()

{

       int                               rc;

       snd_pcm_t*                         handle;

       snd_pcm_hw_params_t*      params;

       unsigned int                  val, val2;

       int                               dir;

       snd_pcm_uframes_t             frames;

 

       if ( (rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0)

       {

              std::cerr << "unable to open pcm devices: " << snd_strerror(rc) << std::endl;

              exit(1);

       }

 

       snd_pcm_hw_params_alloca(&params);

 

       snd_pcm_hw_params_any(handle, params);

 

       snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);

 

       snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);

 

       snd_pcm_hw_params_set_channels(handle, params, 2);

 

       val = 44100;

 

       snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir);

 

       if ( (rc = snd_pcm_hw_params(handle, params)) < 0)

       {

              std::cerr << "unable to set hw parameters: " << snd_strerror(rc) << std::endl;

              exit(1);

       }

 

       std::cout << "PCM handle name = " << snd_pcm_name(handle) << std::endl;

 

       std::cout << "PCM state = " << snd_pcm_state_name(snd_pcm_state(handle)) << std::endl;

 

       snd_pcm_hw_params_get_access(params, (snd_pcm_access_t *)&val);

 

       std::cout << "access type = " << snd_pcm_access_name((snd_pcm_access_t)val) << std::endl;

 

       snd_pcm_hw_params_get_format(params, (snd_pcm_format_t*)(&val));

      

       std::cout << "format = '" << snd_pcm_format_name((snd_pcm_format_t)val) << "' (" << snd_pcm_format_description((snd_pcm_format_t)val) << ")" << std::endl;

 

      snd_pcm_hw_params_get_subformat(params, (snd_pcm_subformat_t *)&val);

      std::cout << "subformat = '" <<

    snd_pcm_subformat_name((snd_pcm_subformat_t)val) << "' (" << snd_pcm_subformat_description((snd_pcm_subformat_t)val) << ")" << std::endl;

 

      snd_pcm_hw_params_get_channels(params, &val);

      std::cout << "channels = " << val << std::endl;

 

      snd_pcm_hw_params_get_rate(params, &val, &dir);

      std::cout << "rate = " << val << " bps" << std::endl;

 

       snd_pcm_hw_params_get_period_time(params, &val, &dir);

      std::cout << "period time = " << val << " us" << std::endl;

 

      snd_pcm_hw_params_get_period_size(params, &frames, &dir);

      std::cout << "period size = " << static_cast<int>(frames) << " frames" << std::endl;

 

       snd_pcm_hw_params_get_buffer_time(params, &val, &dir);

      std::cout << "buffer time = " << val << " us" << std::endl;

      

       snd_pcm_hw_params_get_buffer_size(params, (snd_pcm_uframes_t *) &val);

      std::cout << "buffer size = " << val << " frames" << std::endl;

 

      snd_pcm_hw_params_get_periods(params, &val, &dir);

      std::cout << "periods per buffer = " << val << " frames" << std::endl;

 

       snd_pcm_hw_params_get_rate_numden(params, &val, &val2);

      std::cout << "exact rate = " << val/val2 << " bps" << std::endl;

      

      val = snd_pcm_hw_params_get_sbits(params);

      std::cout << "significant bits = " << val << std::endl;

 

      snd_pcm_hw_params_get_tick_time(params, &val, &dir);

      std::cout << "tick time = " << val << " us" << std::endl;

 

      val = snd_pcm_hw_params_is_batch(params);

      std::cout << "is batch = " << val << std::endl;

 

      val = snd_pcm_hw_params_is_block_transfer(params);

      std::cout << "is block transfer = " << val << std::endl;

 

      val = snd_pcm_hw_params_is_double(params);

      std::cout << "is double = " << val << std::endl;

 

       val = snd_pcm_hw_params_is_half_duplex(params);

      std::cout << "is half duplex = " << val << std::endl;

 

       val = snd_pcm_hw_params_is_joint_duplex(params);

      std::cout << "is joint duplex = " << val << std::endl;

 

       val = snd_pcm_hw_params_can_overrange(params);

      std::cout << "can overrange = " << val << std::endl;

 

      val = snd_pcm_hw_params_can_mmap_sample_resolution(params);

      std::cout << "can mmap = " << val << std::endl;

 

      val = snd_pcm_hw_params_can_pause(params);

      std::cout << "can pause = " << val << std::endl;

 

       val = snd_pcm_hw_params_can_resume(params);

      std::cout << "can resume = " << val << std::endl;

 

      val = snd_pcm_hw_params_can_sync_start(params);

      std::cout << "can sync start = " << val << std::endl;

 

      snd_pcm_close(handle);

 

      return 0;

}

 

3.一個(gè)簡(jiǎn)單的聲音播放程序

 

#include <iostream>

#include <alsa/asoundlib.h>

 

int main()

{

       long                             loops;

       int                               rc;

       int                                       size;

       snd_pcm_t*                         handle;

       snd_pcm_hw_params_t*      params;

       unsigned int                  val;

       int                               dir;

       snd_pcm_uframes_t             frames;

       char*                                  buffer;

 

       if ( (rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0)

       {

              std::cerr << "unable to open pcm device: " << snd_strerror(rc) << std::endl;

              exit(1);

       }

 

       snd_pcm_hw_params_alloca(&params);

 

       snd_pcm_hw_params_any(handle, params);

 

       snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);

 

       snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);

 

       snd_pcm_hw_params_set_channels(handle, params, 2);

 

       val = 44100;

 

       snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir);

 

       frames = 32;

       snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir);

 

       if ( (rc = snd_pcm_hw_params(handle, params)) < 0)

       {

              std::cerr << "unable to set hw paramseters: " << snd_strerror(rc) << std::endl;

              exit(1);

       }

 

       snd_pcm_hw_params_get_period_size(params, &frames, &dir);

       size = frames * 4;

       buffer = new char[size];

 

       snd_pcm_hw_params_get_period_time(params, &val, &dir);

 

       loops = 5000000 / val;

 

       while (loops > 0) {

              loops--;

              if ( (rc = read(0, buffer, size)) == 0)

              {

                     std::cerr << "end of file on input" << std::endl;

                     break;

              }

              else if (rc != size)

                     std::cerr << "short read: read " << rc << " bytes" << std::endl;

 

              if ( (rc = snd_pcm_writei(handle, buffer, frames)) == -EPIPE)

              {

                     std::cerr << "underrun occurred" << std::endl;

                     snd_pcm_prepare(handle);

              }

              else if (rc < 0)

                     std::cerr << "error from writei: " << snd_strerror(rc) << std::endl;

              else if (rc != (int)frames)

                     std::cerr << "short write, write " << rc << " frames" << std::endl;

       }

 

       snd_pcm_drain(handle);

       snd_pcm_close(handle);

       free(buffer);

 

       return 0;

}

4.一個(gè)簡(jiǎn)單的記錄聲音的程序

 

#include <iostream>

#include <alsa/asoundlib.h>

 

int main()

{

       long                             loops;

       int                                       rc;

       int                                       size;

       snd_pcm_t*                         handle;

       snd_pcm_hw_params_t*      params;

       unsigned int                  val;

       int                                       dir;

       snd_pcm_uframes_t             frames;

       char*                                  buffer;

 

       if ( (rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_CAPTURE, 0)) < 0)

       {

              std::cerr << "unable to open pcm device: " << snd_strerror(rc) << std::endl;

              exit(1);

       }

 

       snd_pcm_hw_params_alloca(&params);

 

       snd_pcm_hw_params_any(handle, params);

 

       snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);

 

       snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);

 

       snd_pcm_hw_params_set_channels(handle, params, 2);

 

       val = 44100;

       snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir);

 

       if ( (rc = snd_pcm_hw_params(handle, params)) < 0)

       {

              std::cerr << "unable to set hw parameters: " << snd_strerror(rc) << std::endl;

              exit(1);

       }

 

       snd_pcm_hw_params_get_period_size(params, &frames, &dir);

 

       size = frames * 4;

       buffer = new char[size];

 

       snd_pcm_hw_params_get_period_time(params, &val, &dir);

 

       loops = 5000000 / val;

 

       while (loops > 0)

       {

              loops --;

              rc = snd_pcm_readi(handle, buffer, frames);

              if (rc == -EPIPE)

              {

                     std::cerr << "overrun occurred" << std::endl;

                     snd_pcm_prepare(handle);

              }

              else if (rc < 0)

                     std::cerr << "error from read: " << snd_strerror(rc) << std::endl;

              else if ( rc != (int)frames)

                     std::cerr << "short read, read " << rc << " frames" << std::endl;

              rc = write(1, buffer, size);

              if (rc != size)

                     std::cerr << "short write: wrote " << rc << " bytes" << std::endl;

       }

 

       snd_pcm_drain(handle);

       snd_pcm_close(handle);

       free(buffer);

      

       return 0;

}

 

編譯的參數(shù):g++ xxx.cpp -o xxx -lasound

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Linux Audio ALSA Technical specification(Linu...
alsa用戶空間編程
Linux音頻驅(qū)動(dòng)構(gòu)架及音頻設(shè)備簡(jiǎn)單測(cè)試方法 .
Linux 音頻設(shè)備驅(qū)動(dòng)
基于 libmad 的簡(jiǎn)單 MP3 流媒體播放器的實(shí)現(xiàn)
Linux ALSA聲卡驅(qū)動(dòng)之八:ASoC架構(gòu)中的Platform
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服