关键词搜索

源码搜索 ×
×

SDL 音频示例-打开音频设备播放和混流

发布2018-01-31浏览3335次

详情内容

SDL,即简单的DirectMedia Layer是一个跨平台开发库,旨在通过OpenGL和Direct3D提供对音频,键盘,鼠标,游戏杆和图形硬件的低级访问。 它被视频播放软件,模拟器和流行游戏使用,包括Valve的获奖产品目录和许多Humble Bundle游戏。
SDL正式支持Windows,Mac OS X,Linux,iOS和Android。 其他平台的支持可以在源代码中找到。
SDL是用C语言编写的,使用C ++进行本地工作,并且还有其他几种语言的绑定,包括C#和Python。
SDL 2.0是根据zlib许可证分发的。 此许可证允许您在任何软件中免费使用SDL。

SDL官网地址:https://www.libsdl.org/

SDL2-CS 是C#版本的SDL工具库:https://github.com/flibitijibibo/SDL2-CS

英文原文地址(SDL2.0.7):http://sdl.beuc.net/sdl.wiki/Audio_Examples

英文原文地址(SDL1.2.15):https://www.libsdl.org/release/SDL-1.2.15/docs/html/guideaudioexamples.html

打开音频设备

  1. SDL_AudioSpec wanted;
  2. extern void fill_audio(void *udata, Uint8 *stream, int len);
  3. /* Set the audio format */
  4. wanted.freq = 22050;
  5. wanted.format = AUDIO_S16;
  6. wanted.channels = 2; /* 1 = mono, 2 = stereo */
  7. wanted.samples = 1024; /* Good low-latency value for callback */
  8. wanted.callback = fill_audio;
  9. wanted.userdata = NULL;
  10. /* Open the audio device, forcing the desired format */
  11. if ( SDL_OpenAudio(&wanted, NULL) < 0 ) {
  12. fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
  13. return(-1);
  14. }
  15. return(0);

播放音频

  1. static Uint8 *audio_chunk;
  2. static Uint32 audio_len;
  3. static Uint8 *audio_pos;
  4. /* The audio function callback takes the following parameters:
  5. stream: A pointer to the audio buffer to be filled
  6. len: The length (in bytes) of the audio buffer
  7. */
  8. void fill_audio(void *udata, Uint8 *stream, int len)
  9. {
  10. /* Only play if we have data left */
  11. if ( audio_len == 0 )
  12. return;
  13. /* Mix as much data as possible */
  14. len = ( len > audio_len ? audio_len : len );
  15. SDL_MixAudio(stream, audio_pos, len, SDL_MIX_MAXVOLUME);
  16. audio_pos += len;
  17. audio_len -= len;
  18. }
  19. /* Load the audio data ... */
  20. ;;;;;
  21. audio_pos = audio_chunk;
  22. /* Let the callback function play the audio chunk */
  23. SDL_PauseAudio(0);
  24. /* Do some processing */
  25. ;;;;;
  26. /* Wait for sound to complete */
  27. while ( audio_len > 0 ) {
  28. SDL_Delay(100); /* Sleep 1/10 second */
  29. }
  30. SDL_CloseAudio();

播放流音频,混合2个(或更多)音频流

  1. #include <iostream>
  2. #include <cmath>
  3. #include "SDL/SDL.h"
  4. #include "SDL/SDL_main.h"
  5. /* linker options: -lmingw32 -lSDLmain -lSDL -mwindows */
  6. using namespace std;
  7. unsigned int sampleFrequency = 0;
  8. unsigned int audioBufferSize = 0;
  9. unsigned int outputAudioBufferSize = 0;
  10. unsigned int freq1 = 1000;
  11. unsigned int fase1 = 0;
  12. unsigned int freq2 = 5000;
  13. unsigned int fase2 = 0;
  14. void example_mixaudio(void *unused, Uint8 *stream, int len) {
  15. unsigned int bytesPerPeriod1 = sampleFrequency / freq1;
  16. unsigned int bytesPerPeriod2 = sampleFrequency / freq2;
  17. for (int i=0;i<len;i++) {
  18. int channel1 = int(150*sin(fase1*6.28/bytesPerPeriod1));
  19. int channel2 = int(150*sin(fase2*6.28/bytesPerPeriod2));
  20. int outputValue = channel1 + channel2; // just add the channels
  21. if (outputValue > 127) outputValue = 127; // and clip the result
  22. if (outputValue < -128) outputValue = -128; // this seems a crude method, but works very well
  23. stream[i] = outputValue;
  24. fase1++;
  25. fase1 %= bytesPerPeriod1;
  26. fase2++;
  27. fase2 %= bytesPerPeriod2;
  28. }
  29. }
  30. int main(int argc, char *argv[])
  31. {
  32. if( SDL_Init(SDL_INIT_TIMER | SDL_INIT_AUDIO ) <0 ) {
  33. cout << "Unable to init SDL: " << SDL_GetError() << endl;
  34. return 1;
  35. }
  36. /* setup audio */
  37. SDL_AudioSpec *desired, *obtained;
  38. /* Allocate a desired SDL_AudioSpec */
  39. desired = (SDL_AudioSpec *) malloc(sizeof(SDL_AudioSpec));
  40. /* Allocate space for the obtained SDL_AudioSpec */
  41. obtained = (SDL_AudioSpec *) malloc(sizeof(SDL_AudioSpec));
  42. /* choose a samplerate and audio-format */
  43. desired->freq = 44100;
  44. desired->format = AUDIO_S8;
  45. /* Large audio buffers reduces risk of dropouts but increases response time.
  46. *
  47. * You should always check if you actually GOT the audiobuffer size you wanted,
  48. * note that not hardware supports all buffer sizes (< 2048 bytes gives problems with some
  49. * hardware). Older versions of SDL had a bug that caused many configuration to use a
  50. * buffersize of 11025 bytes, if your sdl.dll is approx. 1 Mb in stead of 220 Kb, download
  51. * v1.2.8 of SDL or better...)
  52. */
  53. desired->samples = 4096;
  54. /* Our callback function */
  55. desired->callback=example_mixaudio;
  56. desired->userdata=NULL;
  57. desired->channels = 1;
  58. /* Open the audio device and start playing sound! */
  59. if ( SDL_OpenAudio(desired, obtained) < 0 ) {
  60. fprintf(stderr, "AudioMixer, Unable to open audio: %s\n", SDL_GetError());
  61. exit(1);
  62. }
  63. audioBufferSize = obtained->samples;
  64. sampleFrequency = obtained->freq;
  65. /* if the format is 16 bit, two bytes are written for every sample */
  66. if (obtained->format==AUDIO_U16 || obtained->format==AUDIO_S16) {
  67. outputAudioBufferSize = 2*audioBufferSize;
  68. } else {
  69. outputAudioBufferSize = audioBufferSize;
  70. }
  71. SDL_Surface *screen = SDL_SetVideoMode(200,200, 16, SDL_SWSURFACE);
  72. SDL_WM_SetCaption("Audio Example",0);
  73. SDL_PauseAudio(0);
  74. bool running = true;
  75. SDL_Event event;
  76. while (running) {
  77. while (SDL_PollEvent(&event)) {
  78. /* GLOBAL KEYS / EVENTS */
  79. switch (event.type) {
  80. case SDL_KEYDOWN:
  81. switch (event.key.keysym.sym) {
  82. case SDLK_ESCAPE:
  83. running = false;
  84. break;
  85. default: break;
  86. }
  87. break;
  88. case SDL_QUIT:
  89. running = false;
  90. break;
  91. }
  92. SDL_Delay(1);
  93. }
  94. SDL_Delay(1);
  95. }
  96. SDL_Quit();
  97. return EXIT_SUCCESS;
  98. }

SDL 更多API参考

https://www.libsdl.org/release/SDL-1.2.15/docs/html/index.html


相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载