SDL2文章列表
SDL2入门
SDL2事件处理
SDL2纹理渲染
本来计划写FFmpeg+SDL2视频播放,但是发现要说的内容有点多,所以还是先从简单的音频数据播放开始,一步一步来。
打开音频设备
1 2 3 4
| int SDLCALL SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained);
|
SDL_AudioSpec
1 2 3 4 5 6 7 8 9 10 11 12 13
| typedef struct SDL_AudioSpec { int freq; SDL_AudioFormat format; Uint8 channels; Uint8 silence; Uint16 samples; Uint16 padding; Uint32 size; SDL_AudioCallback callback; void *userdata; } SDL_AudioSpec;
|
SDL_AudioCallback
当音频设备需要更多数据的时候会调用该回调函数。
1 2 3 4 5 6
|
void (SDLCALL * SDL_AudioCallback) (void *userdata, Uint8 *stream, int len);
|
播放音频数据
1 2
| void SDLCALL SDL_PauseAudio(int pause_on)
|
播放PCM音频Demo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| #include <stdio.h> #include <tchar.h> #include <SDL_types.h> #include "SDL.h"
static Uint8 *audio_chunk; static Uint32 audio_len; static Uint8 *audio_pos; int pcm_buffer_size = 4096;
void read_audio_data(void *udata, Uint8 *stream, int len) { SDL_memset(stream, 0, len); if (audio_len == 0) return; len = (len > audio_len ? audio_len : len);
SDL_MixAudio(stream, audio_pos, len, SDL_MIX_MAXVOLUME); audio_pos += len; audio_len -= len; }
int WinMain(int argc, char *argv[]) { if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_TIMER)) { printf("Could not initialize SDL - %s\n", SDL_GetError()); return -1; } SDL_AudioSpec spec; spec.freq = 44100; spec.format = AUDIO_S16SYS; spec.channels = 1; spec.silence = 0; spec.samples = 1024; spec.callback = read_audio_data; spec.userdata = NULL;
if (SDL_OpenAudio(&spec, NULL) < 0) { printf("can't open audio.\n"); return -1; }
FILE *fp = fopen("C:\\Users\\lenovo\\Desktop\\1111111.pcm", "rb+"); if (fp == NULL) { printf("cannot open this file\n"); return -1; } char *pcm_buffer = (char *) malloc(pcm_buffer_size);
SDL_PauseAudio(0);
while (1) { if (fread(pcm_buffer, 1, pcm_buffer_size, fp) != pcm_buffer_size) { break; }
audio_chunk = (Uint8 *) pcm_buffer; audio_len = pcm_buffer_size; audio_pos = audio_chunk;
while (audio_len > 0) SDL_Delay(1); } free(pcm_buffer); SDL_Quit();
return 0; }
|
OK!第一步完成,能正常播放出声音了。
想要录制PCM自己试一下?可以试试用这个Android音视频(五) OpenSL ES录制、播放音频(带源码)录制一段。
源码 GitHub-SimplePlayer-pcm_player
====== 更新 完成了FFmpeg+SDL2播放音频流的开发,代码请看源码 GitHub-SimplePlayer-audio_player