asla四大开源组件应用示例(alsa-lib、alsa-utils、alsa-tools、alsa-plugins)

文章目录

    • alsa设备文件
      • /dev/snd/
      • /sys/class/sound
      • /proc/asound
    • alsa-lib
      • 示例1
    • alsa-utils
    • alsa-tools
    • alsa-plugins
    • 参考


alsa设备文件

/dev/snd/

alsa设备文件目录位于,/dev/snd,如下所示

root@xboard:~#ls /dev/snd -l
total 0
drwxr-xr-x 2 root root       60 Nov  6  2023 by-path
crw-rw---- 1 root audio 116,  4 Nov  6  2023 controlC0
crw-rw---- 1 root audio 116,  3 Nov  6  2023 pcmC0D0c
crw-rw---- 1 root audio 116,  2 Nov  6  2023 pcmC0D0p
crw-rw---- 1 root audio 116, 33 Nov  6  2023 timer

其中:

  • controlC0 用于声卡的控制,例如通道选择,音效控制等
  • pcmC0D0c 用于录音的pcm设备
  • pcmC0D0p 用于播放的pcm设备
  • timer 作为定时器
    有的还有:
  • /dev/snd/seq用于音序
  • /dev/snd/mixerCXDX用于mixer
  • /dev/snd/midiCXDX 用于原始MIDI

https://alsa-project.org/wiki/ALSA_Library_API

/sys/class/sound

root@xboard:~# ls /sys/class/sound/ -l
total 0
lrwxrwxrwx 1 root root 0 Nov  6  2023 card0 -> ../../devices/platform/sound/sound/card0
lrwxrwxrwx 1 root root 0 Nov  6  2023 controlC0 -> ../../devices/platform/sound/sound/card0/controlC0
lrwxrwxrwx 1 root root 0 Nov  6  2023 pcmC0D0c -> ../../devices/platform/sound/sound/card0/pcmC0D0c
lrwxrwxrwx 1 root root 0 Nov  6  2023 pcmC0D0p -> ../../devices/platform/sound/sound/card0/pcmC0D0p
lrwxrwxrwx 1 root root 0 Nov  6  2023 timer -> ../../devices/virtual/sound/timer

/proc/asound

root@xboard:~# ls /proc/asound/ -l
total 0
dr-xr-xr-x 4 root root 0 Jan  1 00:24 card0
-r--r--r-- 1 root root 0 Jan  1 00:24 cards
-r--r--r-- 1 root root 0 Jan  1 00:24 devices
-r--r--r-- 1 root root 0 Jan  1 00:24 pcm
lrwxrwxrwx 1 root root 5 Jan  1 00:24 sgtl5000 -> card0
-r--r--r-- 1 root root 0 Jan  1 00:24 timers
-r--r--r-- 1 root root 0 Jan  1 00:24 version

https://www.alsa-project.org/wiki/Main_Page
asla四大开源组件应用示例(alsa-lib、alsa-utils、alsa-tools、alsa-plugins)_第1张图片

alsa-lib

asla四大开源组件应用示例(alsa-lib、alsa-utils、alsa-tools、alsa-plugins)_第2张图片
在线API接口,

在线demo示例

示例1

/*
 *  This small demo sends a simple sinusoidal wave to your speakers.
 */
 
#include "config.h"
 
#include 
#include 
#include 
#include 
#include 
#include 
#include "../include/asoundlib.h"
#include 
#include 
 
#ifndef ESTRPIPE
#define ESTRPIPE ESPIPE
#endif
 
static char *device = "plughw:0,0";         /* playback device */
static snd_pcm_format_t format = SND_PCM_FORMAT_S16;    /* sample format */
static unsigned int rate = 44100;           /* stream rate */
static unsigned int channels = 1;           /* count of channels */
static unsigned int buffer_time = 500000;       /* ring buffer length in us */
static unsigned int period_time = 100000;       /* period time in us */
static double freq = 440;               /* sinusoidal wave frequency in Hz */
static int verbose = 0;                 /* verbose flag */
static int resample = 1;                /* enable alsa-lib resampling */
static int period_event = 0;                /* produce poll event after each period */
 
static snd_pcm_sframes_t buffer_size;
static snd_pcm_sframes_t period_size;
static snd_output_t *output = NULL;
 
static void generate_sine(const snd_pcm_channel_area_t *areas, 
              snd_pcm_uframes_t offset,
              int count, double *_phase)
{
   
    static double max_phase = 2. * M_PI;
    double phase = *_phase;
    double step = max_phase*freq/(double)rate;
    unsigned char *samples[channels];
    int steps[channels];
    unsigned int chn;
    int format_bits = snd_pcm_format_width(format);
    unsigned int maxval = (1 << (format_bits - 1)) - 1;
    int bps = format_bits / 8;  /* bytes per sample */
    int phys_bps = snd_pcm_format_physical_width(format) / 8;
    int big_endian = snd_pcm_format_big_endian(format) == 1;
    int to_unsigned = snd_pcm_format_unsigned(format) == 1;
    int is_float = (format == SND_PCM_FORMAT_FLOAT_LE ||
            format == SND_PCM_FORMAT_FLOAT_BE);
 
    /* verify and prepare the contents of areas */
    for (chn = 0; chn < channels; chn++) {
   
        if ((areas[chn].first % 8) != 0) {
   
            printf("areas[%u].first == %u, aborting...\n", chn, areas[chn].first);
            exit(EXIT_FAILURE);
        }
        samples[chn] = /*(signed short *)*/(((unsigned char *)areas[chn].addr) + (areas[chn].first / 8));
        if ((areas[chn].step % 16) != 0) {
   
            printf("areas[%u].step == %u, aborting...\n", chn, areas[chn].step);
            exit(EXIT_FAILURE);
        }
        steps[chn] = areas[chn].step / 8;
        samples[chn] += offset * steps[chn];
    }
    /* fill the channel areas */
    while (count-- > 0) {
   
        union {
   
            float f;
            int i;
        } fval;
        int res, i;
        if (is_float) {
   
            fval.f = sin(phase);
            res = fval.i;
        } else
            res = sin(phase) * maxval;
        if (to_unsigned)
            res ^= 1U << (format_bits - 1);
        for (chn = 0; chn < channels; chn++) {
   
            /* Generate data in native endian format */
            if (big_endian) {
   
                for (i = 0; i < bps; i++)
                    *(samples[chn] + phys_bps - 1 - i) = (res >> i * 8) & 0xff;
            } else {
   
                for (i = 0; i < bps; i++)
                    *(samples[chn] + i) = (res >>  i * 8) & 0xff;
            }
            samples[chn] += steps[chn];
        }
        phase += step;
        if (phase >= max_phase)
            phase -= max_phase;
    }
    *_phase = phase;
}
 
static int set_hwparams(snd_pcm_t *handle,
            snd_pcm_hw_params_t *params,
            snd_pcm_access_t access)
{
   
    unsigned int rrate;
    snd_pcm_uframes_t size;
    int err, dir;
 
    /* choose all parameters */
    err = snd_pcm_hw_params_any(handle, params);
    if (err < 0) {
   
        printf("Broken configuration for playback: no configurations available: %s\n", snd_strerror(err));
        return err;
    }
    /* set hardware resampling */
    err = snd_pcm_hw_params_set_rate_resample(handle, params, resample);
    if (err < 0) {
   
        printf("Resampling setup failed for playback: %s\n", snd_strerror(err));
        return err;
    }
    /* set the interleaved read/write format */
    err = snd_pcm_hw_params_set_access(handle, params, access);
    if (err < 0) {
   
        printf("Access type not available for playback: %s\n", snd_strerror(err));
        return err;
    }
    /* set the sample format */
    err = snd_pcm_hw_params_set_format(handle, params, format);
    if (err < 0) {
   
        printf("Sample format not available for playback: %s\n", snd_strerror(err));
        return err;
    }
    /* set the count of channels */
    err = snd_pcm_hw_params_set_channels(handle, params, channels);
    if

你可能感兴趣的:(alsa,alsa-lib,alsa-tools,alsa-plugins,alsa-utils)