SDL2.0例子代码分析---循环播放wav loopwav

[复制链接]

该用户从未签到

2380

主题

2433

帖子

9139

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
9139
QQ
跳转到指定楼层
楼主
发表于 2017-12-18 17:43:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

想要查看内容赶紧注册登陆吧!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
SDL2.0中循环播放一段声音文件 ,并且添加上注释。
  1. /*  加载并且循环播放一个WAV文件*/

  2. /* loopwaves.c is much more robust in handling WAVE files --
  3.         This is only for simple WAVEs
  4.         */
  5. #include "SDL_config.h"

  6. #include <stdio.h>
  7. #include <stdlib.h>

  8. #if HAVE_SIGNAL_H
  9. #include <signal.h>
  10. #endif

  11. #include "SDL.h"
  12. #include "SDL_audio.h"

  13. //sdl 播放缓冲区定义
  14. struct
  15. {
  16.         SDL_AudioSpec spec;
  17.         Uint8 *sound;               /*指向声音数据指针 */
  18.         Uint32 soundlen;            /* Length of wave data */
  19.         int soundpos;               /* Current play position */
  20. } wave;


  21. /* 调用这个函数退出SDL子系统 */
  22. static void
  23. quit(int rc)
  24. {
  25.         SDL_Quit();
  26.         exit(rc);
  27. }


  28. void SDLCALL
  29. fillerup(void *unused, Uint8 * stream, int len)
  30. {
  31.         Uint8 *waveptr;
  32.         int waveleft;

  33.         /*设置当前声音指针
  34.         声音指针+当前播放的位置
  35.         */
  36.         waveptr = wave.sound + wave.soundpos;
  37.         //剩余声音数据   声音数据长度-当前播放的位置
  38.         waveleft = wave.soundlen - wave.soundpos;

  39.         /* 如果剩余数据<需要的长度 */
  40.         while (waveleft <= len)
  41.         {
  42.                 //拷贝剩余数据到音频缓冲区
  43.                 SDL_memcpy(stream, waveptr, waveleft);
  44.                 //音频缓冲区stream指针后移
  45.                 stream += waveleft;
  46.                 //len=len-waveleft
  47.                 len -= waveleft;
  48.                 //拷贝玩剩余数据
  49.                 //waveptr指向 声音数据开头  
  50.                 waveptr = wave.sound;
  51.                 //长度等于len
  52.                 waveleft = wave.soundlen;
  53.                 //位置等于len
  54.                 wave.soundpos = 0;
  55.         }
  56.         //重新拷贝内存到 音频设备缓冲区  
  57.         //也就是循环播放
  58.         SDL_memcpy(stream, waveptr, len);  
  59.         //当前播放的位置 +=len
  60.         wave.soundpos += len;
  61. }

  62. static int done = 0;
  63. //退出信号
  64. void
  65. poked(int sig)
  66. {
  67.         done = 1;
  68. }

  69. int
  70. main(int argc, char *argv[])
  71. {
  72.         int i;
  73.         char filename[4096];

  74.         /* Enable standard application logging */
  75.         SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);

  76.         /* 初始化SDL音频库 */
  77.         if (SDL_Init(SDL_INIT_AUDIO) < 0) {
  78.                 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
  79.                 return (1);
  80.         }

  81.         //拷贝文件名字 到 filename 缓冲区
  82.         if (argc >= 1) {
  83.                 SDL_strlcpy(filename, argv[1], sizeof(filename));
  84.         }
  85.         else {
  86.                 SDL_strlcpy(filename, "D:\\vs2010_pro\\ffmpeg_test\\Output\\audio.aac", sizeof(filename));
  87.         }
  88.         /* 加载声音文件到内存 */
  89.         if (SDL_LoadWAV(filename, &wave.spec, &wave.sound, &wave.soundlen) == NULL) {
  90.                 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", argv[1], SDL_GetError());
  91.                 quit(1);
  92.         }
  93.         //音频回调 在回调函数中填充音频缓冲区 需求的大小的数据
  94.         wave.spec.callback = fillerup;
  95. #if HAVE_SIGNAL_H
  96.         /* Set the signals */
  97. #ifdef SIGHUP
  98.         signal(SIGHUP, poked);
  99. #endif
  100.         signal(SIGINT, poked);
  101. #ifdef SIGQUIT
  102.         signal(SIGQUIT, poked);
  103. #endif
  104.         signal(SIGTERM, poked);
  105. #endif /* HAVE_SIGNAL_H */

  106.         /* Show the list of available drivers */
  107.         SDL_Log("Available audio drivers:");
  108.         //打印电脑上的所有音频驱动
  109.         for (i = 0; i < SDL_GetNumAudioDrivers(); ++i) {
  110.                 SDL_Log("%i: %s", i, SDL_GetAudioDriver(i));
  111.         }

  112.         /*初始化音频设备  并且打开 因为我们输出的wav有头部信息所有 我们不需要设置参数*/
  113.         if (SDL_OpenAudio(&wave.spec, NULL) < 0) {
  114.                 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open audio: %s\n", SDL_GetError());
  115.                 SDL_FreeWAV(wave.sound);
  116.                 quit(2);
  117.         }

  118.         //打印当前音频设备
  119.         SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver());

  120.         /*开始播放声音  这个时候 SDL以异步线程的方式不停的回调 来取数据  */
  121.         SDL_PauseAudio(0);
  122.         //如果当前正在播放 那么 主线程 Delay 1s
  123.         //或者有退出信号 那么退出
  124.         while (!done && (SDL_GetAudioStatus() == SDL_AUDIO_PLAYING))
  125.                 SDL_Delay(1000);

  126.         /* 关闭音频 */
  127.         SDL_CloseAudio();
  128.         //释放分配的声音数据内存
  129.         SDL_FreeWAV(wave.sound);
  130.    //退出程序 和SDL
  131.         SDL_Quit();
  132.         return (0);
  133. }
复制代码


分享到:  QQ好友和群QQ好友和群
收藏收藏
回复

使用道具 举报

快速回复高级模式
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表