介绍如何调用alsa api来进行音频数据的播放和录制。

简介

主要使用的API介绍:
打开PCM设备:

int snd_pcm_open(snd_pcm_t **pcm, const char *name,snd_pcm_stream_t stream, int mode);

使用标准的malloc申请内存:

int snd_pcm_hw_params_malloc(snd_pcm_hw_params_t **ptr);

填充pcm默认参数:

int snd_pcm_hw_params_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);

pcm设备读/写

snd_pcm_sframes_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);snd_pcm_sframes_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);

关闭PCM设备:

int snd_pcm_close(snd_pcm_t *pcm);

播放音频示例

播放音频主要流程为:

  1. 打开设备

  2. 设置参数

  3. 写入数据

  4. 关闭设备

#include <stdio.h>
#include <stdlib.h>
#include <alsa/asoundlib.h>
          
void main (int argc, char *argv[])
{
        int i;
        int err;
        short buf[128];
        snd_pcm_t *playback_handle;
        snd_pcm_hw_params_t *hw_params;

        if ((err = snd_pcm_open (&playback_handle, argv[1], SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
                fprintf (stderr, "cannot open audio device %s (%s)\n", 
                         argv[1],
                         snd_strerror (err));
                exit (1);
        }
           
        if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
                fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
                         snd_strerror (err));
                exit (1);
        }
                         
        if ((err = snd_pcm_hw_params_any (playback_handle, hw_params)) < 0) {
                fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
                         snd_strerror (err));
                exit (1);
        }

        if ((err = snd_pcm_hw_params_set_access (playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
                fprintf (stderr, "cannot set access type (%s)\n",
                         snd_strerror (err));
                exit (1);
        }

        if ((err = snd_pcm_hw_params_set_format (playback_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
                fprintf (stderr, "cannot set sample format (%s)\n",
                         snd_strerror (err));
                exit (1);
        }

        if ((err = snd_pcm_hw_params_set_rate_near (playback_handle, hw_params, 44100, 0)) < 0) {
                fprintf (stderr, "cannot set sample rate (%s)\n",
                         snd_strerror (err));
                exit (1);
        }

        if ((err = snd_pcm_hw_params_set_channels (playback_handle, hw_params, 2)) < 0) {
                fprintf (stderr, "cannot set channel count (%s)\n",
                         snd_strerror (err));
                exit (1);
        }

        if ((err = snd_pcm_hw_params (playback_handle, hw_params)) < 0) {
                fprintf (stderr, "cannot set parameters (%s)\n",
                         snd_strerror (err));
                exit (1);
        }

        snd_pcm_hw_params_free (hw_params);

        if ((err = snd_pcm_prepare (playback_handle)) < 0) {
                fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
                         snd_strerror (err));
                exit (1);
        }

        for (i = 0; i < 10; ++i) {
                if ((err = snd_pcm_writei (playback_handle, buf, 128)) != 128) {
                        fprintf (stderr, "write to audio interface failed (%s)\n",
                                 snd_strerror (err));
                        exit (1);
                }
        }

        snd_pcm_close (playback_handle);
        exit (0);
}

录制音频示例

录制音频与写入基本类似,只是写入改为读取。

#include <stdio.h>
#include <stdlib.h>
#include <alsa/asoundlib.h>
          
void main (int argc, char *argv[])
{
        int i;
        int err;
        short buf[128];
        snd_pcm_t *capture_handle;
        snd_pcm_hw_params_t *hw_params;

        if ((err = snd_pcm_open (&capture_handle, argv[1], SND_PCM_STREAM_CAPTURE, 0)) < 0) {
                fprintf (stderr, "cannot open audio device %s (%s)\n", 
                         argv[1],
                         snd_strerror (err));
                exit (1);
        }
           
        if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
                fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
                         snd_strerror (err));
                exit (1);
        }
                         
        if ((err = snd_pcm_hw_params_any (capture_handle, hw_params)) < 0) {
                fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
                         snd_strerror (err));
                exit (1);
        }

        if ((err = snd_pcm_hw_params_set_access (capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
                fprintf (stderr, "cannot set access type (%s)\n",
                         snd_strerror (err));
                exit (1);
        }

        if ((err = snd_pcm_hw_params_set_format (capture_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
                fprintf (stderr, "cannot set sample format (%s)\n",
                         snd_strerror (err));
                exit (1);
        }

        if ((err = snd_pcm_hw_params_set_rate_near (capture_handle, hw_params, 44100, 0)) < 0) {
                fprintf (stderr, "cannot set sample rate (%s)\n",
                         snd_strerror (err));
                exit (1);
        }

        if ((err = snd_pcm_hw_params_set_channels (capture_handle, hw_params, 2)) < 0) {
                fprintf (stderr, "cannot set channel count (%s)\n",
                         snd_strerror (err));
                exit (1);
        }

        if ((err = snd_pcm_hw_params (capture_handle, hw_params)) < 0) {
                fprintf (stderr, "cannot set parameters (%s)\n",
                         snd_strerror (err));
                exit (1);
        }

        snd_pcm_hw_params_free (hw_params);

        if ((err = snd_pcm_prepare (capture_handle)) < 0) {
                fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
                         snd_strerror (err));
                exit (1);
        }

        for (i = 0; i < 10; ++i) {
                if ((err = snd_pcm_readi (capture_handle, buf, 128)) != 128) {
                        fprintf (stderr, "read from audio interface failed (%s)\n",
                                 snd_strerror (err));
                        exit (1);
                }
        }

        snd_pcm_close (capture_handle);
        exit (0);
}
作者:SteveChen  创建时间:2025-03-30 18:01
最后编辑:SteveChen  更新时间:2025-03-30 18:03
上一篇:
下一篇: