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音频文件 的相关文章

随机推荐

  • 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