当前位置: 首页 > news >正文

SDL录制音频并播放

摘要:在ubuntu 20.04中使用QAudioInput、PortAduio、ffmpeg打开音频设备录制音频都显示失败,最后没办法选择了SDL2.0,SDL2.0录制音频十分方便,使用也非常简单。
疑问:不知道SDL是如何区分打开的设备是录制还是播放。(已解决,通过打开设备时设置iscapture参数的值,0表示录制,非0表示播放)
主要函数简介:

SDL_Init(SDL_INIT_AUDIO)

此函数用于初始化音频。

SDL_AudioSpec want, have;
SDL_zero(want);
want.freq = 44100;
want.format = AUDIO_S16SYS;
want.channels = 2;
want.samples = 288;
want.callback = audioCallback;

设置音频数据的格式。

//参数iscapture 0表示播放音频  非0表示录制音频
SDL_AudioDeviceID deviceId = SDL_OpenAudioDevice(nullptr, 2, &want, &have, SDL_AUDIO_ALLOW_FORMAT_CHANGE);

此函数用于打开音频设备,音频的录制和播放取决于第二个参数,若第二个参数设置为0,此函数表示的打开录制音频。非0表示打开播放音频。

SDL_QueueAudio(deviceIdO,stream,len);

若不用回调函数,可以使用此函数对音频进行播放操作。

SDL_DequeueAudio(deviceIdO,stream,len);

若不用回调函数,可以使用此函数定时读取录制的音频数据。

SDL_MixAudioFormat(stream, stream, AUDIO_S16SYS, len, 100);

可用于混音和调节音频的音量。

在下面的demo中,音频的录制采用了回调函数,音频的播放采用了SDL_QueueAudio函数。

SDL_AudioDeviceID deviceIdO;//全局播放音频设备id
//回调函数,用在音频录制
void audioCallback(void *userdata, Uint8 * stream,int len)
{Q_UNUSED(userdata);// Sint16* audioData = reinterpret_cast<Sint16*>(stream);// int numSamples = len / sizeof(Sint16);// for (int i = 0; i < numSamples; ++i) {//     // 假设放大倍数为 2//     audioData[i] *= 2;// }SDL_MixAudioFormat(stream, stream, AUDIO_S16SYS, len, 100);mp3InFILE.write((char *)stream,len);//从缓存区播放音频SDL_QueueAudio(deviceIdO,stream,len);
}
	if(SDL_Init(SDL_INIT_AUDIO) < 0){qDebug() << "SDL  INIT ERROR" << SDL_GetError();return ;}SDL_AudioSpec want, have;SDL_zero(want);want.freq = 44100;want.format = AUDIO_S16SYS;want.channels = 2;want.samples = 288;want.callback = audioCallback;//参数iscapture 0表示播放音频  非0表示录制音频SDL_AudioDeviceID deviceId = SDL_OpenAudioDevice(nullptr, 2, &want, &have, SDL_AUDIO_ALLOW_FORMAT_CHANGE);//开启音频播放设备want.callback = nullptr;deviceIdO = SDL_OpenAudioDevice(nullptr, 0, &want, &have, SDL_AUDIO_ALLOW_FORMAT_CHANGE);if (deviceIdO == 0) {qDebug() << "SDL could not open audio device! SDL Error: " << SDL_GetError();return;}//分别开启音频录制和音频播放。SDL_PauseAudioDevice(deviceId,0);SDL_PauseAudioDevice(deviceIdO,0);

http://www.mrgr.cn/news/36882.html

相关文章:

  • 鸿蒙界面开发(九):列表布局 (List)
  • C#中实现压缩包(如ZIP)的解压功能
  • LeetCode 136. 只出现一次的数字
  • C++面向对象基础
  • SU03T(语音识别播报模块)
  • Jenkins本地安装配置与远程访问管理本地服务详细流程
  • 菱形继承、菱形虚拟继承、菱形继承中多态问题、菱形虚拟继承中多态问题
  • 【C++与数据结构】搜索二叉树(BinarySearchTree)
  • 【WSL——Windows 上使用 Linux 环境】
  • 关于vue2+uniapp+uview+vuex 私募基金项目小程序总结
  • note-Redis实战6 核心-构建应用程序组件2
  • 云手机的默认ip地址是什么
  • Cgroup介绍
  • p,div等里面支持br换行 对应后台换过来的textarea的富文本内容
  • 书生大模型实战营学习[7] InternLM + LlamaIndex RAG 实践
  • 集翼智能视频营销管理平台 丨OPENAIGC开发者大赛企业组AI创作力奖
  • 【CAS框架自定义登录异常提示-固定时间内限制登录失败次数提醒】
  • 手机也可以更换任意IP地址吗?
  • 无人机之物流货运篇
  • Rust编程的if选择语句