alsa学习--3.alsa的demo

本文通过三个示例程序介绍如何使用ALSA库进行声音编程。包括打印类型与格式、设置播放参数并播放声音等基本操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Introduction to Sound Programming with ALSA
http://www.linuxjournal.com/article/6735

1. 打印alsa中的类型及格式
Listing 1. Display Some PCM Types and Formats
  1. #include "utils.h"
  2. #include <alsa/asoundlib.h>
  3. #include <stdlib.h>

  4. int main ( int argc, char *argv[] )
  5. {
  6.     int i;
  7.     printf("<----- 1="" -----="">ALSA library version=%s\n", SND_LIB_VERSION_STR);

  8.     printf("\n<----- 2="" -----="">PCM stream types:\n");
  9.     for(i=0; i<=SND_PCM_STREAM_LAST; i++)
  10.         printf("%s\n", snd_pcm_stream_name((snd_pcm_stream_t)i));

  11.     printf("\n<----- 3="" -----="">PCM access type:\n");
  12.     for(i=0; i<=SND_PCM_ACCESS_LAST; i++)
  13.         printf("%s\n", snd_pcm_access_name((snd_pcm_access_t)i));

  14.     printf("\n<----- 4="" -----="">PCM formats:\n");
  15.     for(i=0; i<=SND_PCM_FORMAT_LAST; i++)
  16.     { 
  17.         if(NULL != snd_pcm_format_name((snd_pcm_format_t)i))
  18.         {
  19.             printf("%s:%s\n", snd_pcm_format_name((snd_pcm_format_t)i), 
  20.                     snd_pcm_format_description((snd_pcm_format_t)i));
  21.         }
  22.     }

  23.     printf("\n<----- 5="" -----="">PCM subformats:\n");
  24.     for(i=0; i<=SND_PCM_SUBFORMAT_LAST; i++)
  25.     { 
  26.         printf("%s:%s\n", snd_pcm_subformat_name((snd_pcm_subformat_t)i), 
  27.                 snd_pcm_subformat_description((snd_pcm_subformat_t)i));
  28.     }

  29.     printf("\n<----- 6="" -----="">PCM state:\n");
  30.     for(i=0; i<=SND_PCM_STATE_LAST; i++)
  31.     { 
  32.         printf("%s\n", snd_pcm_state_name((snd_pcm_state_t)i)); 
  33.     }
  34.     return EXIT_SUCCESS;
  35. }
Makefile
  1. EXE=start
  2. CC=gcc
  3. ALSA_PATH=/work/ffmpeg/test/alsa/alsa-lib-1.0.23/_install/
  4. RESOURCE=/work/ffmpeg/test/resource/

  5. CFLAGS=--O0
  6. CFLAGS += -I$(ALSA_PATH)/include
  7. LDFLAGS += -L$(ALSA_PATH)/lib/ -lrt -lasound -lm -ldl -lpthread

  8. SRC=$(wildcard *.c)
  9. OBJ=$(patsubst %.c,%.o,$(SRC))
  10. DEP=$(patsubst %.c,.%.d,$(SRC))
  11. $(EXE):$(OBJ)
  12.     $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS)

  13. $(DEP):.%.d:%.c
  14.     @set -e; rm -f $@; \
  15.     $(CC) -MM $< > $@.$$$$; \
  16.     sed 's,/($*/)/.o[ :]*,/1.o $@ : ,g' < $@.$$$$ > $@; \
  17.     rm -f $@.$$$$

  18. -include $(DEP)
  19. clean:
  20.     @rm $(EXE) $(OBJ) $(DEP) -f
  21. run:
  22.     export LD_LIBRARY_PATH=$(FFMPEG)/lib/ \
  23.     && ./$(EXE) $(RESOURCE)/test.wav
  24.     #&& ./$(EXE) ../resource/test.wmv
1.2 代码打包
1start.rar (下载后改名为1start.tar.gz)

二. param

  1. #include "utils.h"
  2. #include <alsa/asoundlib.h>
  3. #include <stdlib.h>

  4. int main ( int argc, char *argv[] )
  5. {
  6.     int i;
  7.     int ret;
  8.     int dir;
  9.     unsigned int val, val2;
  10.     snd_pcm_t* handle;
  11.     snd_pcm_hw_params_t* params;
  12.     //1. open
  13.     if( (ret = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0)
  14.     {
  15.         dbmsg("open pcm device error:%s", snd_strerror(ret));
  16.         return -1;
  17.     }
  18.     //2. alloc and init param
  19.     snd_pcm_hw_params_alloca(&params);
  20.     snd_pcm_hw_params_any(handle, params);
  21.     snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
  22.     snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);
  23.     snd_pcm_hw_params_set_channels(handle, params, 2);
  24.     val = 44100;
  25.     snd_pcm_hw_params_set_rate_near(handle,params, &val, &dir);
  26.     
  27.     //3. set param to driver
  28.     if((ret=snd_pcm_hw_params(handle, params)) < 0)
  29.     {
  30.         dbmsg("set hw params error:%s", snd_strerror(ret));
  31.         return -1;
  32.     }
  33.     
  34.     printf("PCM handle name=%s\n", snd_pcm_name(handle));
  35.     printf("PCM state=%s\n", snd_pcm_state_name(snd_pcm_state(handle)));
  36.     
  37.     snd_pcm_hw_params_get_access(params, (snd_pcm_access_t*)&val);
  38.     printf("access type=%s\n",snd_pcm_access_name((snd_pcm_access_t)val));

  39.     snd_pcm_hw_params_get_format(params, &val);
  40.     printf("format=%s (%s)\n",snd_pcm_format_name((snd_pcm_format_t)val),
  41.             snd_pcm_format_description((snd_pcm_format_t)val));
  42.     
  43.     snd_pcm_close(handle);
  44.     return EXIT_SUCCESS;
  45. }
2.2 代码打包
2param.rar (下载后改名为2param.tar.gz)

三.play sound
3.1 
  1. #include "utils.h"
  2. #define ALSA_PCM_NEW_HW_PARAMS_API
  3. #include <alsa/asoundlib.h>
  4. #include <stdlib.h>

  5. int main ( int argc, char *argv[] )
  6. {
  7.     int i;
  8.     int ret, dir, size;
  9.     long loops;
  10.     unsigned int val, val2;
  11.     char* buffer;
  12.     snd_pcm_t* handle;
  13.     snd_pcm_hw_params_t* params;
  14.     snd_pcm_uframes_t frames;
  15.     //1. open
  16.     if( (ret = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0)
  17.     {
  18.         dbmsg("open pcm device error:%s", snd_strerror(ret));
  19.         return -1;
  20.     }
  21.     //2. alloc and init param
  22.     snd_pcm_hw_params_alloca(&params);
  23.     snd_pcm_hw_params_any(handle, params);
  24.     snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
  25.     snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);
  26.     snd_pcm_hw_params_set_channels(handle, params, 2);
  27.     val = 44100;
  28.     snd_pcm_hw_params_set_rate_near(handle,params, &val, &dir);
  29.     frames = 32;
  30.     snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir);
  31.     //3. set param to driver
  32.     if((ret=snd_pcm_hw_params(handle, params)) < 0)
  33.     {
  34.         dbmsg("set hw params error:%s", snd_strerror(ret));
  35.         return -1;
  36.     }

  37.     snd_pcm_hw_params_get_period_size(params, &frames, &dir);
  38.     size = frames*4; //2byte/smaple, 2 channels
  39.     buffer = (char*)malloc(size);

  40.     snd_pcm_hw_params_get_period_time(params, &val, &dir);
  41.     loops = 5000000/val;
  42.     dbmsg("next in loop,loops=%ld,val=%d",loops, val);
  43.     while(loops>0)
  44.     {
  45.         loops --;
  46.         ret = read(0, buffer, size);
  47.         dbmsg("ret =%d", ret);
  48.         if(ret==0)
  49.         {
  50.             dbmsg("end of file");
  51.             return 0;
  52.         }else if (ret!=size)
  53.         {
  54.             dbmsg("short read");
  55.         }
  56.         
  57.         ret = snd_pcm_writei(handle, buffer, frames);
  58.         if(ret == -EPIPE)
  59.         {
  60.             dbmsg("-EPIPE");
  61.             snd_pcm_prepare(handle);
  62.         }
  63.     }
  64.     
  65.     snd_pcm_drain(handle);
  66.     snd_pcm_close(handle);
  67.     free(buffer);
  68.     return EXIT_SUCCESS;
  69. }
运行,会听到一些杂音
  1. cong@msi:/work/ffmpeg/test/alsa/testalsa/3play$ ./play < /dev/urandom
3.1代码打包 
3play.rar (下载后改名为3play.)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值