• 尝试了一下alsa录音播放的编程。


    网上大部分文章比较老,最近这几年已经有新的接口了,一个snd_pcm_set_params函数搞定大部分参数设置

    简单一点,例子说话

    1。启动录音,第一打开第二设置

    #define DEVICE "default"

    int
    StartPCMRecording(AUDIO_RECORD *pAudioRecord) { int rc, size, dir; snd_pcm_t *handle; snd_pcm_hw_params_t *params; snd_pcm_uframes_t frames, ret; /* Open PCM device for record. */ rc = snd_pcm_open(&handle, DEVICE, SND_PCM_STREAM_CAPTURE, 0); if (rc!=0) printf("%d, return %d, %s ",__LINE__,rc,snd_strerror(rc)); #if 0 /* Allocate a hardware parameters object. */ rc = snd_pcm_hw_params_malloc(&params); if (rc!=0) printf("%d, return %d, %s ",__LINE__,rc,snd_strerror(rc)); /* Fill it in with default values. */ rc = snd_pcm_hw_params_any(handle, params); if (rc!=0) printf("%d, return %d, %s ",__LINE__,rc,snd_strerror(rc)); /* Signed 16-bit little-endian format */ rc = snd_pcm_hw_params_set_format(handle, params, FORMAT); if (rc!=0) printf("%d, return %d, %s ",__LINE__,rc,snd_strerror(rc)); /* One channels (stereo) */ rc = snd_pcm_hw_params_set_channels(handle, params, CHANNLE); if (rc!=0) printf("%d, return %d, %s ",__LINE__,rc,snd_strerror(rc)); rc = snd_pcm_hw_params_set_access (handle, params,SND_PCM_ACCESS_RW_INTERLEAVED ); if (rc!=0) printf("%d, return %d, %s ",__LINE__,rc,snd_strerror(rc)); /* 16000 sampling rate */ rc = snd_pcm_hw_params_set_rate(handle, params, SAMPLE_RATE, 0); if (rc!=0) printf("%d, return %d, %s ",__LINE__,rc,snd_strerror(rc)); frames = FRAMES_SIZE; rc = snd_pcm_sw_params_set_avail_min(handle,params,frames); if (rc!=0) printf("%d, return %d, %s ",__LINE__,rc,snd_strerror(rc)); /* Write the parameters to the driver */ rc = snd_pcm_hw_params(handle, params); if (rc!=0) printf("%d, return %d, %s ",__LINE__,rc,snd_strerror(rc)); #endif //int snd_pcm_set_params(snd_pcm_t *pcm, // snd_pcm_format_t format, // snd_pcm_access_t access, // unsigned int channels, // unsigned int rate, // int soft_resample, // unsigned int latency); snd_pcm_set_params(handle,SND_PCM_FORMAT_S16_LE,SND_PCM_ACCESS_RW_INTERLEAVED,1,48000,0,500000);

    从上面看到,以前设置pcm参数的一大堆函数调用已经简化成一个

    snd_pcm_set_params()

    2。录音代码

    int read_from_pcm(void *pDevice, void *pData, int samples)
    {
        int ret;
        snd_pcm_t *handle = (snd_pcm_t *)pDevice;
        int nData=samples;
    
        //snd_pcm_wait(handle,20) ;
        ret = snd_pcm_readi(handle, pData, nData);
        return samples;
    }

    3。结束代码

            snd_pcm_drain(handle);
            snd_pcm_close(handle);

    4。播放也类似,总共5个函数,open/setting/write/close

    void startPlaying(){
        /* Open PCM device for playback. */
        rc = snd_pcm_open(&handle,DEVICE, SND_PCM_STREAM_PLAYBACK, 0);
        printf("[StartPCMPlaying]:snd_pcm_open return value is %d
    ",rc);
        //int snd_pcm_set_params(snd_pcm_t *pcm,
        //                   snd_pcm_format_t format,
        //                   snd_pcm_access_t access,
        //                  unsigned int channels,
        //                   unsigned int rate,
        //                   int soft_resample,
        //                   unsigned int latency);
        snd_pcm_set_params(handle,SND_PCM_FORMAT_S16_LE,SND_PCM_ACCESS_RW_INTERLEAVED,1,48000,1,500000);
    #if 0    
        /* Allocate a hardware parameters object. */
        rc = snd_pcm_hw_params_malloc(&params);
        if (rc!=0) printf("%d, return %d, %s 
    ",__LINE__,rc,snd_strerror(rc));
    
        /* Fill it in with default values. */
        rc=snd_pcm_hw_params_any(handle, params);
        if (rc!=0) printf("%d, return %d, %s 
    ",__LINE__,rc,snd_strerror(rc));
    
        /* Signed 16-bit little-endian format */
        rc=snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);
        if (rc!=0) printf("%d, return %d, %s 
    ",__LINE__,rc,snd_strerror(rc));
    
        /* Two channels (stereo) */
        rc=snd_pcm_hw_params_set_channels(handle, params, 1);
        if (rc!=0) printf("%d, return %d, %s 
    ",__LINE__,rc,snd_strerror(rc));
    
        /* 44100 bits/second sampling rate (CD quality) */
        int val = 16000;
        rc=snd_pcm_hw_params_set_rate_near(handle, params,     &val, &dir);
        if (rc!=0) printf("%d, return %d, %s 
    ",__LINE__,rc,snd_strerror(rc));
    
        rc = snd_pcm_hw_params_set_access (handle, params,SND_PCM_ACCESS_RW_INTERLEAVED );
        if (rc!=0) printf("%d, return %d, %s 
    ",__LINE__,rc,snd_strerror(rc));
    
    
        rc = snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir);
        if (rc!=0) printf("%d, return %d, %s 
    ",__LINE__,rc,snd_strerror(rc));
    
        /* Write the parameters to the driver */
        rc = snd_pcm_hw_params(handle, params);
        if (rc < 0)
        {
            fprintf(stderr, "unable to set hw parameters: %s
    ",
                    snd_strerror(rc));
            exit(1);
        }
     #endif   
    }
    
    void write_to_pcm(void *pDevice, void *pData, int frames)
    {
        int nlen = frames ;
        int rc = snd_pcm_writei(pDevice, pData, nlen);
    }
    
    void int StopPlaying(void *pDevice)
    {
        snd_pcm_drain(pDevice;
        snd_pcm_close(pDevice);
    }

     其中device可以用arecord -l 或aplay -l查看

    通常用default是比较通用的选择,有耳麦用耳麦没耳麦用笔记本的

  • 相关阅读:
    《鱼嘤嘤小分队》第一次作业:项目选题
    第一次博客作业
    csp 201709-2 优先队列模拟
    csp 201403-2
    csp 201809-2 买菜
    JavaScript中伪协议
    修改placeholder的样式
    jQuery对象与DOM对象之间的转换方法
    a的样式
    Guid.NewGuid() 和 new Guid()的区别
  • 原文地址:https://www.cnblogs.com/shinedream/p/12815154.html
Copyright © 2020-2023  润新知