ubuntu / 麒麟 播放PCM音频文件

2023-05-16

ubuntu18.04 / 麒麟 播放PCM音频文件,源码来源于网友文章再修改,仅测试用!

如果应用在产品上需要再优化。

/**
* 最简单的SDL2播放音频的例子(SDL2播放PCM)
* Simplest Audio Play SDL2 (SDL2 play PCM)
*
* 本程序使用SDL2播放PCM音频采样数据。SDL实际上是对底层绘图
* API(Direct3D,OpenGL)的封装,使用起来明显简单于直接调用底层
* API。
*
* 函数调用步骤如下:
*
* [初始化]
* SDL_Init(): 初始化SDL。
* SDL_OpenAudio(): 根据参数(存储于SDL_AudioSpec)打开音频设备。
* SDL_PauseAudio(): 播放音频数据。
*
* [循环播放数据]
* SDL_Delay(): 延时等待播放完成。
*
* This software plays PCM raw audio data using SDL2.
* SDL is a wrapper of low-level API (DirectSound).
* Use SDL is much easier than directly call these low-level API.
*
* The process is shown as follows:
*
* [Init]
* SDL_Init(): Init SDL.
* SDL_OpenAudio(): Opens the audio device with the desired
*                  parameters (In SDL_AudioSpec).
* SDL_PauseAudio(): Play Audio.
*
* [Loop to play data]
* SDL_Delay(): Wait for completetion of playback.
*/

//	gcc pcm_demo.c -o pcm_demo -L../SDL2-2.0.14/build/.libs/ -lSDL2

#include <stdio.h>
#include <bits/types.h>

typedef __uint8_t uint8_t;
typedef __uint16_t uint16_t;
typedef __uint32_t uint32_t;
typedef __uint64_t uint64_t;

//extern "C" {
#include "../SDL2-2.0.14/include/SDL.h"
#include "../SDL2-2.0.14/include/SDL_audio.h"
//};

int32_t  data_len = 0;//音频数据大小
uint8_t  *pData = NULL;//指向音频数据的指针


/**回调函数(由系统调用)
*  函数声明:typedef void (SDLCALL * SDL_AudioCallback) 
*            (void *userdata, uint8_t * stream, int len);
*  This function is called when the audio device needs more data.
*
*  userdata: An application-specific parameter saved in the SDL_AudioSpec structure(SDL_AudioSpec结构中的用户自定义数据,一般情况下可以不用)
*  stream:   A pointer to the audio data buffer.(该指针指向需要填充的音频缓冲区)
*  len:      The length of that buffer in bytes.(音频缓冲区的大小,以字节为单位)
*
*  Once the callback returns, the buffer will no longer be valid.
*  Stereo samples are stored in a LRLRLR ordering.
*
*  You can choose to avoid callbacks and use SDL_QueueAudio() instead, if
*  you like. Just open your audio device with a NULL callback.
*/

void  fill_audio(void *userdata, uint8_t *stream, int len)
{
	//SDL2中必须首先使用SDL_memset()将stream中的数据设置为0
	int stream_len = 0;

	if (data_len <= 0)		/*  Only  play  if  we  have  data  left  */
	{
		return;
	}

	if(data_len > len)
	{
		stream_len = len;
	}
	else
	{
		stream_len = data_len;
	}
	/*  Mix  as  much  data  as  possible  */
	SDL_memset(stream, 0, len);
	/**
	*  函数声明:extern DECLSPEC void SDLCALL 
	*  SDL_MixAudio(uint8_t * dst, const uint8_t * src, Uint32 len, int volume);
	*  This takes two audio buffers of the playing audio format and mixes
	*  them, performing addition, volume adjustment, and overflow clipping.
	*  The volume ranges from 0 - 128, and should be set to ::SDL_MIX_MAXVOLUME
	*  for full audio volume.  Note this does not change hardware volume.
	*  This is provided for convenience -- you can mix your own audio data.
	*
	*  #define SDL_MIX_MAXVOLUME 128
	*/

	SDL_MixAudio(stream, pData, len, SDL_MIX_MAXVOLUME);
	pData += stream_len;
	data_len -= stream_len;
}

int main(int argc, char* argv[])
{
	//初始化SDL
	if (SDL_Init(SDL_INIT_AUDIO))
	{
		printf("Could not initialize SDL - %s\n", SDL_GetError());
		return -1;
	}

	//SDL_AudioSpec初始化
	SDL_AudioSpec wanted, have;
	wanted.freq = 48000;			//音频数据的采样率(常用的有48000,44100等)
	wanted.format = AUDIO_S16SYS;  //音频数据的格式  AUDIO_S16LSB
	wanted.channels = 1;			//声道数(例如单声道取值为1,立体声取值为2)
	wanted.silence = 0;			//设置静音的值
	wanted.samples = 1024;		    //音频缓冲区中的采样个数(要求必须是2的n次方)
	wanted.callback = fill_audio;  //填充音频缓冲区的回调函数

	//打开音频
	if (SDL_OpenAudio(&wanted, NULL) < 0)
	{
		printf("%s\n", SDL_GetError());
        	
		goto clean;
	}

	FILE *fp_pcm = fopen(argv[1], "rb");
	if (fp_pcm == NULL)
	{
		printf("cannot open file:%s\n", argv[1]);
		goto clean;
	}

	int pcm_buffer_size = 8192;//每次读取4096字节的数据,同时也是音频帧大小
	char *pcm_buffer = (char *)malloc(pcm_buffer_size);

	//播放音频数据
	SDL_PauseAudio(0);

	while (1)
	{
        if(0 == data_len)
        {
            int ret = fread(pcm_buffer, 1, pcm_buffer_size, fp_pcm);
            printf("playing %d Bytes data.\n", ret);
            
            if(ret > 0)
            {
                pData = (uint8_t *)pcm_buffer;
                //Audio buffer length 
                data_len = pcm_buffer_size;
            }
            else
            {
                break;
            }
        }
        else
        {
            SDL_Delay(10);
        }
	}

	free(pcm_buffer);
	fclose(fp_pcm);
clean:	
    SDL_CloseAudio();
    SDL_Quit();
    printf("exit\n");
	return 0;
}

1.编译SDL2-2.0.14:直接进入目录./configure,   make -j4

2.编译demo:gcc方法在文件顶部。

3.运行demo:./demo test.pcm

 

关于No such audio device 错误,是因为sdl用了dsp驱动播放声音,不是期望的声卡驱动pulseaudio。

可以运行测试程序:SDL2-2.0.14/test中的 ./testaudioinfo

只显示有1,2,3,驱动(下图)

1.安装完libasound2-dev和 libpulse-dev后重启。

sudo apt-get install libasound2-dev

sudo apt-get install libpulse-dev

解决安装错误报依赖关系时可以用aptitude install代替apt-get install。

2. 再编译SDL库。

./configure 

make -j4 

make install 

3.运行测试程序:./testaudioinfo 

新增0:pulseaudio驱动。

4.问题解决。

这个错误还会表现为在终端上运行测试程序正常,在QT中运行又报No such audio device (猜测跟环境变量有关)

如:设置SDL_AUDIODRIVER=pulse。最终还是要安装上面的库才行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ubuntu / 麒麟 播放PCM音频文件 的相关文章

  • apt-get 无法在 ubuntu dockerfile 中工作

    我对 docker 相当陌生 正在尝试通过编写自己的镜像来学习 并且目前正在阅读 Docker 的实际操作 ISBN 1633430235 在我自己的代码和书中的示例 第 146 页 中 我想通过 dockerfile 安装 git My
  • 如何在 Ubuntu VirtualBox 中运行 Meteor 应用程序并使用 Windows 主机上的编辑器进行编辑?

    我希望在运行 Ubuntu 的 virtualbox 来宾中运行一个用于开发目的的流星服务器 该项目将位于主机上的一个文件夹内 该文件夹将共享给来宾 该文件夹本身位于 Dropbox 文件夹内 这样我可以在多个虚拟机和工作站之间共享开发 但
  • PostgreSQL - 致命:用户“myuser”身份验证失败[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我刚刚在我的 Ubuntu Box 中安装了 PostGreSQL 我想做的第一件事就是创建一个数据库 我读了文档 http www postgres
  • 让 Rails 生产在端口 80 上运行

    我正在尝试让我的 Rails 应用程序在生产模式下运行 但遇到了一些困难 我正在使用 Passenger 和 apache 并运行 Ubuntu 12 04 我已经配置和创建了生产数据库 并设置了乘客 状态如下 rvmsudo passen
  • 交叉编译armv5,但它创建v7二进制文件

    我设法为arm926ej s创建了一个目标文件我在 qemu 上使用 Debian Arm arm linux gnueabi gcc 4 4 static O c mcpu arm926ej s hello c o hello root
  • 卷曲选项 -:未知

    我运行此命令在 ubuntu 18 04 上安装更新版本的 nodejs curl sL https deb nodesource com setup 12 x sudo E bash 我收到错误 curl 选项 未知 我在多个系统上尝试过
  • Ubuntu 上的 Vim:文本渲染错误,奇怪地重复和消失

    不久前我在 ubuntu 12 04 上安装了 vim 有时 当我在代码上运行光标 使用键盘 而不是鼠标 时 文本会消失 就好像渲染字符时出现问题一样 当我再次运行光标时 它通常会重新出现 这似乎是随机发生的 但通常足以让人恼火 为了更清楚
  • 如何通过ssh检查ubuntu服务器上是否存在php和apache

    如何通过ssh检查Ubuntu服务器上apache是 否安装了php和mysql 另外如果安装的话在哪个目录 如果安装了其他软件包 例如 lighttpd 那么它在哪里 确定程序是否已安装的另一种方法是使用which命令 它将显示您正在搜索
  • 有人可以解释一下 Postgresql 角色、Postgresql 用户和 Linux 用户之间的关系吗?

    我正在尝试在 Ubuntu 14 服务器上设置 Postgres 9 3 此时我感到非常沮丧 我以前使用过 MySQL 所以我对一般数据库概念以及客户端 服务器模型等很满意 我从两个用户开始 root 和 sam 我 作为 sam 我使用
  • Linux中使用管道进行进程间通信

    我已经编写了在 linux 中写入数字以进行管道传输的代码 如下所示 但显示错误 任何人都可以帮助我解决这个问题 基本上该程序的问题陈述如下 一个程序将打开一个管道 向管道写入一个数字 其他程序将打开同一管道 读取数字并打印它们 关闭两个管
  • dpkg 错误:pycompile:未找到

    sudo apt get remove purge mysql server mysql client mysql common 当我尝试使用上述命令删除 mysql 时 出现以下错误 Reading package lists Done
  • Docker Desktop 未安装,提示 docker-ce-cli 无法安装

    在一次在线培训课程中 讲师提到他有 安装了 Docker Desktop 的 Ubuntu 虚拟机 因此 我尝试在 Windows 10 物理主机上安装相同的程序指示 https docs docker com desktop linux
  • BASH 中的空函数

    我正在使用 FPM 工具创建 deb 包 此工具在从支持的文件中删除包之前 之后创建 不幸的是FPM生成的bash脚本包含这样的函数 dummy 该脚本退出时出现错误 语法错误 意外 BASH 不允许空函数吗 哪个版本的 bash linu
  • 在 ubuntu 中找不到 .android 文件夹 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我在哪里可以找到 android在 Ubuntu 中 我想使用debug keystore 转到您的主文件夹并按 ctrl h 瞧
  • Eclipse Kepler 在 64 位 ubuntu 上冻结

    几天前我刚刚将 Ubuntu 升级到 14 04 并在此过程中从 32 位切换到 64 位 从那时起 Eclipse 就变得非常不稳定 运行几分钟后 它将开始随机冻结越来越长的时间 特别是在代码完成时 已经必须禁用它 而且在剪切 粘贴时 偶
  • 有没有办法在 TypeScript 2+ 中全局添加类型定义?

    我有一堆简单的 ts files 不是项目 即独立的 ts 脚本 他们使用一些 Node js 功能 TypeScript 和节点类型定义通过安装 npm install g typescript npm install g types n
  • PMA 4.5.2.0 file_exists():open_basedir 限制生效

    从 PPA 在我的 Ubuntu 服务器上安装 phpMyAdmin 后 https launchpad net nijel archive ubuntu phpmyadmin https launchpad net nijel archi
  • 如何为 Python 2 安装 pip

    I run python version and get Python 2 7 3 I run pip version and get pip 1 5 from usr local lib python3 2 dist packages p
  • 早于 0.4.12 的 Node.js 无法在 AWS EC2 上正常工作。为什么?

    我无法在 AWS EC2 Ubuntu 或 CentOs 没关系 上安装 node js v0 6 1 安装后我输入node 处理器负载达到100 但 v0 4 12 工作正常 可能只有我有这个问题 那不好意思了 请告诉我我做错了什么 提前
  • ubuntu 中的 echo -e 选项不起作用

    我的同事使用Ubuntu 我使用openSUSE 我们使用相同的makefile编译相同的源代码 我的环境运行良好 但我的同事不能 总是输出无法识别 e选项 我们检查makefile 只发现echo命令使用 e option Ubuntu的

随机推荐

  • DOS 命令访问FTP错误:425Failed to establish connection

    在windows命令窗口访问FTP服务会出现425Failed to establish connection的错误 解决办法 xff1a 1 关闭本队防火墙 2 在防火墙允许通过的程序中 xff0c 根据所用网络勾选 文件传送程序
  • 串口通信协议简介—学习笔记

    串口通信协议简介 学习笔记 文章目录 串口通信协议简介 学习笔记一 串口 COM口 UART口 TTL RS 232 RS 485区别详解1 物理接口形式2 电平标准2 1 TTL 2 2 RS232 2 3 RS485 2 4 TTL标准
  • Python 爬虫下一代网络请求库 httpx 和 parsel 解析库测评

    这是 进击的Coder 的第 437 篇技术分享 作者 xff1a 大江狗 来源 xff1a Python Web与Django开发 阅读本文大概需要 8 分钟 Python 网络爬虫领域两个最新的比较火的工具莫过于 httpx 和 par
  • ubuntu下rsync两个服务器同步文件

    前言 文件服务器为ubuntu的 xff0c 客户端为windows的环境 主服务器配置 在Ubuntu下安装rsync通过以步骤可以实现 xff1a span class token function sudo span span cla
  • ROS总结——ROS消息发布和订阅

    消息发布器和订阅器 C 43 43 本博客总结绍如何用 C 43 43 编写消息发布器节点和订阅器节点 1 编写发布器节点 节点 Node 是指 ROS 网络中可执行文件 接下来 xff0c 将会创建一个发布器节点 talker xff0c
  • 无线充电器的CE认证、FCC认证、IC认证测试标准

    无线充电器是指不用传统的充电电源线连接到需要充电的终端设备上的充电器 xff0c 采用电磁感应原理 xff0c 通过线圈进行能量耦合实现能量的传递 从理论来说 xff0c 无线充电技术对人体安全无害处 xff0c 无线充电使用的共振原理是磁
  • STM32 uart空闲中断

    文章目录 目的 xff1a 前提 xff1a 相关代码 xff1a 使能UART IT IDLE中断中断处理函数中添加回调回调处理函数 目的 xff1a 使用UART空闲中断接收不定长消息 前提 xff1a stm32CubeMX工具配置u
  • 远程访问如此简单,通过 ZeroTier 和 Tailscale 轻松组建虚拟局域网,实现内网穿透。

    因为最近用了 Plex 所以研究了一下远程访问 xff0c 经过一番折腾基本上算是搞明白了 xff0c 在这里分享一些自己的经验给和我一样的小白 xff0c 如果有不对的地方欢迎指正 这里的远程访问是指在局域网外通过网络访问局域网 xff0
  • 组网必看,有线 MESH 全攻略。

    之前写过几篇关于 MESH 组网的文章 xff0c 主要讲解了如何布线 xff0c 路由器和光猫 交换机等设备应该怎样连接 xff0c 但通过大家的反馈我发现我漏掉了一个重点 xff0c 就是光猫和路由器应该如何设置 xff0c 这也是很多
  • 给 iOS 装上旧版 APP,十年前的 iPad mini 重获新生!

    不知道有没有人像我一样 xff0c 还留着五年前 十年前的老 iPad 老 iPhone xff0c 如果有 xff0c 你们一定知道有些老 iPad 老 iPhone 已经停在一个系统版本无法再继续升级了 xff0c 或者因为害怕升级变卡
  • Stable Diffusion WebUI 1.4「gradio」报错解决方案

    今天有很多朋友在运行 Stable Diffusion WebUI 1 4 时都遇到了 ModuleNotFoundError No module named 39 gradio 39 这个报错 xff0c 在这里给大家一个解决方案 xff
  • 如何在 macOS 使用 AList + RCLONE 把网盘挂载到本地

    之前接触最多的可能还是百度网盘 xff0c 它的免费容量比较大 xff0c 我们在下载和分享一些文件的时候经常会用到 xff0c 但是如果文件比较大 xff0c 加上限速 xff0c 使用体验并不算太好 其实除了下载文件 xff0c 我很少
  • jdk 安卓sdk 安装

    https www cnblogs com gufengchen p 11038029 html jdk sdk安装详细步骤 https www jianshu com p 8fb367a51b9f utm campaign 61 haru
  • 通过 Plex + Trakt 同步观看状态和评分,轻松记录你的追剧观影史

    喜欢看电影 追剧 追综艺的朋友想必都有做记录的习惯 xff0c Plex 的用户里用豆瓣的人估计不少 xff0c 使用豆瓣标记电影 写影评 短评和参与线上讨论是非常方便的 xff0c 但是豆瓣对电视剧的支持相对还是比较弱 xff0c 很多剧
  • macOS 如何设置 AList、RCLONE、xTeVe 开机启动后台运行

    之前和大家分享了 macOS 上 AList RCLONE xTeVe 的使用教程 xff0c 他们基本上都是通过终端命令或者 Unix 可执行文件运行的 xff0c 启动后需要保持运行状态才能持续提供服务 xff0c 今天分享一下如何让它
  • zynqmp zcu102 SD卡驱动调试

    新板卡使用sdhci0 xff0c 以前是sdhci1 xff0c 由于官方没有使用sdhci0所以需要手动添加设备树 xff1a amp sdhci0 clock frequency 61 lt 60000000 gt status 61
  • zynqmp zcu102 arm linux (uboot网卡输出调试信息)

    需求 xff1a 使用网卡输出自检 调试信息 由于uboot启动完成就退出运行 xff0c 进入Linux启动 xff0c 不是进入消息循环处理网络协议栈 xff0c 且没有现成的udp接口发送数据 xff0c 所以想在启动中输出调试信息调
  • libiec61850-1.4 库的使用和修改(goose)

    目的 xff1a 使用libiec61850 1 4 库接收和发送goose数据 xff0c 环境Ubuntu 18 04 4 LTS 问题 xff1a 使用libiec61850 1 4 examples goose publisher例
  • zynqmp zcu102 arm 裸机SD卡驱动

    1 加载PL端提供的 HDF 2 创建hello world例程 xff08 bsp xff09 3 在main函数中调用驱动初始化sd卡 void mmc test void s32 Status XSdPs InstancePtr XS
  • ubuntu / 麒麟 播放PCM音频文件

    ubuntu18 04 麒麟 播放PCM音频文件 xff0c 源码来源于网友文章再修改 xff0c 仅测试用 xff01 如果应用在产品上需要再优化 最简单的SDL2播放音频的例子 xff08 SDL2播放PCM xff09 Simples