SDL相关函数的使用及注意事项(正确关闭SDL音频设备)

阅读: 评论:0

SDL相关函数的使用及注意事项(正确关闭SDL音频设备)

SDL相关函数的使用及注意事项(正确关闭SDL音频设备)

本文主要的目的在于讲解SDL2库常用的函数库以及讲述在项目中遇到的使用SDL,将记录SDL的初始化以及如何使用SDL开启渲染音频和关闭。


一、SDL播放音频使用步骤及函数说明

(1)SDL初始化:

int SDLCALL SDL_Init(Uint32 flags)

说明:该函数是用于激活需要激活的子系统的初始化函数,其中该SDL的子系统有很多例如音频和视频等子系统,传入的参数具有如下,常用的有 SDL_INIT_AUDIO和SDL_INIT_VIDEO :

#define SDL_INIT_TIMER          0x00000001
#define SDL_INIT_AUDIO          0x00000010
#define SDL_INIT_VIDEO          0x00000020 
#define SDL_INIT_JOYSTICK       0x00000200 
#define SDL_INIT_HAPTIC         0x00001000
#define SDL_INIT_GAMECONTROLLER 0x00002000 
#define SDL_INIT_EVENTS         0x00004000
#define SDL_INIT_NOPARACHUTE    0x00100000 
#define SDL_INIT_EVERYTHING ( SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER )

(2)打开设备函数:

int SDLCALL SDL_OpenAudio(SDL_AudioSpec * desired,SDL_AudioSpec * obtained);

说明:这个函数是用于打开设备使用的,以及通过SDL_AudioSpec * desired传入所需要的参数,如下为该结构体的定义,包括了音频的格式(SDL_AudioFormat format)、音频的通道数(Uint8 channels)以及比较重要的回调函数指针(SDL_AudioCallback callback)等:

typedef struct SDL_AudioSpec
{int freq;                   /**< DSP frequency -- samples per second */SDL_AudioFormat format;     /**< Audio data format */Uint8 channels;             /**< Number of channels: 1 mono, 2 stereo */Uint8 silence;              /**< Audio buffer silence value (calculated) */Uint16 samples;             /**< Audio buffer size in samples (power of 2) */Uint16 padding;             /**< Necessary for some compile environments */Uint32 size;                /**< Audio buffer size in bytes (calculated) */SDL_AudioCallback callback;void *userdata;
} SDL_AudioSpec;

(3)启停音频设备函数:

void SDLCALL SDL_PauseAudio(int pause_on);

说明:在使用 SDL_OpenAudio()函数后,应该需要使用SDL_PauseAudio(0)函数且传入参数0来使SDL调用回调函数来播放音频;若传入的是大于0的值此时将暂停音频播放设备,期间将传入静音数据。

(4)对音频数据进行混音函数

void SDLCALL SDL_MixAudio(Uint8 * dst, const Uint8 * src,Uint32 len, int volume);

说明:这是一个混音函数,可以将两段音频进行混音播放。

三、关闭函数特别说明:

因为当使用了SDL_OpenAudio()函数后,回调函数就会以线程的方式启动的,同时如果当需要关闭SDL音频设备时 ,仅仅使用SDL_CloseAudio()时不够的,下次如果再次使用SDL_OpenAudio()会报错,此时还需要进行一个操作就是需要停止掉回调线程,本文使用了一个参数int is_stop_sdl_audio_player = false;来控制线程的启停。

如下为回调函数对该参数的判断,和退出情况,当is_stop_sdl_audio_player为true时结束线程,完成关闭SDL全部操作。

…..
if (is_stop_sdl_audio_player == true)
{//is_stop_sdl_audio_player = false;//清零xhlog("exit fillaudion");return ;
}…..

四、代码展示

(1)SDL初始化函数

extern int audio_sample_rate;//rtmp中获取得到的音频采样频率,默认是44.1khz
int SDL_INIT_PLAYER(void)
{//Initint ret = 0;if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_TIMER| SDL_INIT_VIDEO )) {//printf("Could not initialize SDL - %sn", SDL_GetError());xhlog("Could not initialize SDL - %sn", SDL_GetError());return -1;}//SDL_AudioSpecSDL_AudioSpec wanted_spec;//wanted_spec.freq = 44100;wanted_spec.freq = audio_sample_rate;wanted_spec.format = AUDIO_S16SYS;wanted_spec.channels = 2;wanted_spec.silence = 0;wanted_spec.samples = 1024;//1024;wanted_spec.callback = fill_audio;if (SDL_OpenAudio(&wanted_spec, NULL)<0) {//printf("can't open audio.n");xhlog("can't open audio.n");return -1;}SDL_PauseAudio(0);is_stop_sdl_audio_player = false;return 0;
}

(2)填充数据播放

/*函数名称:SDL_START_PLAYER
*函数功能:使用SDL播放PCM,使用线程来播放
*传入参数:unsigned char *data_pcm:pcm的数据指针;
*			int len_data_pcm:pcm数据的长度
*函数返回值:成功返回0,失败返回-1;
*函数作者:吴豪乐
*日期:2020年7月29日
*/
#if 0
int SDL_START_PLAYER(unsigned char *data_pcm, int len_data_pcm)
#endif
DWORD WINAPI SDL_START_PLAYER(LPVOID lpParam)
{audio_chunk = (Uint8 *)lpParam;if (audio_chunk == NULL){xhlog("audio audio_chunk is NULLn");return -1;}//SDL_LockAudio();audio_pos = audio_chunk;int pcm_buffer_size = 4096;//Audio buffer lengthaudio_len = pcm_buffer_size;while (audio_len > 0)//Wait until finish{SDL_Delay(1);}return 0;
}

(3)循环读取数据线程函数

/* Audio Callback* The audio function callback takes the following parameters: * stream: A pointer to the audio buffer to be filled * len: The length (in bytes) of the audio buffer * 
*/ 
int is_stop_sdl_audio_player = false;
void  fill_audio(void *udata,Uint8 *stream,int len){ int count_played = 0;//已经播放了数据大小if (is_stop_sdl_audio_player == true){//is_stop_sdl_audio_player = false;//清零xhlog("exit fillaudion");return ;}if (len == 4096 && audio_len == 0){//xhlog("temp:%dn", temp);//if(temp == 4096)//audio_len = len;SDL_memset(stream, 0, temp);//return;//这一句测试一下是否导致噪点,检测后发现这个return注释掉会噪点少很多}pcm_ptr_save = pcm_ptr;pcm_ptr = audio_pos;while (len > 0 && audio_len > 0){SDL_memset(stream, 0, audio_len);if (audio_len == 0){continue;}temp = (len > audio_len ? audio_len : len);//SDL_MIX_MAXVOLUMESDL_MixAudio(stream, audio_pos, temp, SDL_MIX_MAXVOLUME);audio_pos += temp;audio_len -= temp;stream += temp;len -= temp;}
} 

(4)停止播放函数

/*函数名称:SDL_STOP_PLAYER
*函数功能:停止SDL播放PCM,关闭线程来播放
*传入参数:无
*函数返回值:成功返回0,失败返回-1;
*函数作者:吴豪乐
*日期:2020年11月27日
*/
void SDL_STOP_PLAYER(void)
{printf("stop audioplayern");is_stop_sdl_audio_player = true;SDL_CloseAudio();
}

每写一篇文章都不容易,尊重别人的知识产权才是对自己和技术的尊重。为了避免发生知识产权被侵权的情况,我决定做出以下声明:

1.博客中标注原创的文章,版权归原作者 吴豪乐工作室 所有;

2.未经原作者允许不得转载本文内容,否则将视为侵权;

3.转载或者引用本文内容请注明来源及原作者;

4.对于不遵守此声明或者其他违法使用本文内容者,本人依法保留追究权等。

本文发布于:2024-02-08 19:45:09,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170739279168432.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:函数   注意事项   正确   音频设备   SDL
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23