alsa USB拾音器接入

做下面这些工作的前提先把 alsa 的库安装好:

sudo apt-get install libasound2-dev

查找设备名:

alsa USB拾音器接入_第1张图片


API 库使用逻辑设备名而不是设备文件。设备名字可以是真实的硬件名字也可以是插件名字。硬件名
字使用hw:i,j这样的格式。其中i是卡号,j是这块声卡上的设备号。第一个声音设备是hw:0,0.这个


我的usb拾音器是4麦的,也统称的4通道

我的设备是16K的采样率(16000个数据/s), 根据自己的设备来, 填错了, 就会小姐姐变大叔

我的是小端 16位一个数据

设置每路通道每次采集128个数据

录制后我用测试

Code:

#include 
#include 
#include 
#include 

using namespace std;

#define REC_DEV "hw:1,0"
#define CHANNELS 4
#define RATE 16000
#define FRAMES 128
#define BITE 2
#define PATH "../bin/"
#define NAMELANGTH 128
bool g_bRecord;
bool g_bMainON;
FILE* g_pFile[CHANNELS];


void* run(void* args)
{
    #define ALSA_PCM_NEW_HW_PARAMS_API

    char cNamePath[NAMELANGTH];
    memset(cNamePath, 0, sizeof(char) * NAMELANGTH);
    for(int i = 0; i < CHANNELS; i++)
    {      
        sprintf(cNamePath,"%sData-%02d.pcm",PATH, i);
        if((g_pFile[i] = fopen(cNamePath, "w")) == NULL)
        {
            printf("Read local pcm path failed!\n");
            exit(0);
        }
    }
 
    int rc;            //一个int变量 ,用来存放 snd_pcm_open(访问硬件)的返回值 
    int size;        //一个int变量 
    snd_pcm_t * handle;        // 一个指向snd_pcm_t的指针 
    snd_pcm_hw_params_t * params;    // 一个指向 snd_pcm_hw_params_t的指针 
    unsigned int val = RATE;        // 无符号整型变量 ,用来存放录音时候的采样率 
    snd_pcm_uframes_t frames = FRAMES;        // snd_pcm_uframes_t 型变量 
    int channels = CHANNELS;
    int dir;            // 整型变量 
    char * buffer;        // 一个字符型指针 

    /* open PCM device for recording (capture). */
    // 访问硬件,并判断硬件是否访问成功 
    rc = snd_pcm_open(&handle, REC_DEV, SND_PCM_STREAM_CAPTURE,0);
    if( rc < 0 )
    {
        fprintf(stderr,
                "unable to open pcm device: %sn",
                snd_strerror(rc));
        exit(1);
    }
    /* allocate a hardware parameters object */
    // 分配一个硬件变量对象 
    snd_pcm_hw_params_alloca(¶ms);
    /* fill it with default values. */
    // 按照默认设置对硬件对象进行设置 
    snd_pcm_hw_params_any(handle,params);
    /* set the desired hardware parameters */
    /* interleaved mode 设置数据为交叉模式*/
    snd_pcm_hw_params_set_access(handle,params,
                                SND_PCM_ACCESS_RW_INTERLEAVED);
    /* signed 16-bit little-endian format */
    // 设置数据编码格式为PCM、有符号、16bit、LE格式 
    snd_pcm_hw_params_set_format(handle,params,
                                SND_PCM_FORMAT_S16_LE);
    /* two channels(stereo) */
    // 设置单声道 
    snd_pcm_hw_params_set_channels(handle,params,channels);
    /* sampling rate */
    // 设置采样率 
    snd_pcm_hw_params_set_rate_near(handle,params,&val,&dir);
    /* set period size */
    // 周期长度(帧数) 
    frames = 32;
    snd_pcm_hw_params_set_period_size_near(handle,params,&frames,&dir);
    /* write parameters to the driver */
    // 将配置写入驱动程序中
    // 判断是否已经配置正确 
    rc = snd_pcm_hw_params(handle,params);
    if ( rc < 0 )
    {
        fprintf(stderr,
                "unable to set hw parameters: %sn",
                snd_strerror(rc));
        exit(1);
    }
    /* use a buffer large enough to hold one period */
    // 配置一个缓冲区用来缓冲数据,缓冲区要足够大,此处看意思应该是只配置了
    // 够两个声道用的缓冲内存 
    snd_pcm_hw_params_get_period_size(params,&frames,&dir);
    size = frames * BITE * channels; /* 2 bytes/sample, 2channels */
    buffer = ( char * ) malloc(size);
    /* loop for 5 seconds */
    // 记录五秒长的声音 
    snd_pcm_hw_params_get_period_time(params, &val, &dir);
    printf("revord start!\n");
    while(g_bRecord)
    {
        rc = snd_pcm_readi(handle,buffer,frames);
        if ( rc == -EPIPE )
        {
            /* EPIPE means overrun */
            fprintf(stderr,"overrun occuredn");
            snd_pcm_prepare(handle);
        }
        else if ( rc < 0 )
        {
            fprintf(stderr,"error from read: %sn",
                    snd_strerror(rc));
        }
        else if ( rc != (int)frames)
        {
            fprintf(stderr,"short read, read %d framesn",rc);
        }
        // // 将音频数据写入文件 
        for(int i = 0; i

CMakeLists.txt

cmake_minimum_required(VERSION 3.5.1)

project(MakePCM)


set(CMAKE_CXX_STANDARD 11)


set(SOURCE_FILES 
    ./src/main.cpp
    )


set(INC_DIR ./3rdpart/include)

set(LINK_DIR ./3rdpart/lib)


include_directories(${INC_DIR})

link_directories(${LINK_DIR})

link_libraries(
    asound
    pthread
    )


add_executable(MakePCM ${SOURCE_FILES})

target_link_libraries(MakePCM 
    asound
    pthread
    )

你可能感兴趣的:(alsa USB拾音器接入)