当前位置:   article > 正文

FFMPEG+SDL2播放音频-1(音频知识和代码)

sdl2播放音频

       为了快速掌握音频开发知识,秉承实用主义,我计划以下面思维导图方式介绍音频开发知识,以求最快速让开发者听到文件的声音。

f428ae8fdf764e9db93ddca9fafc06ec.png

概述

开发者基础

计算机平台下,二进制数据可用十六进制显示,文件数据可视化工具软件为为UltraEdit。

开发者收获

1 Qt播放音频文件Demo。

2 基于C、C++语言

   使用ffmpeg 解码压缩音频数据;

   使用SDL      播放原始音频数据;

   使用winmm 播放原始音频数据;

   音频播放控制,响度增大和音调不改变实现倍速播放。

知识目录

1 声音是什么?

        声音(sound)是由物体振动产生的声波。是通过介质(空气或固体、液体)传播并能被人或动物听觉器官所感知的波动现象。最初发出振动(震动)的物体叫声源。声音以波的形式振动(震动)传播。声音是声波通过任何介质传播形成的运动。声音是一种波。可以被人耳识别的声(频率在20 Hz~20000 Hz之间),我们称之为声音。

2 声音和音频有什么关系?

        音频是个专业术语,音频一词已用作一般性描述音频范围内和声音有关的设备及其作用。

        1.Audio,指人耳可以听到声音的声波,称为音频。

        2.指存储声音内容的文件。

        3.在某些方面能指作为滤波的振动。 

3 声音怎么被我们听到?

        声音是一种压力波:当演奏乐器、拍打一扇门或者敲击桌面时,他们的振动会引起介质——空气分子有节奏的振动,使周围的空气产生疏密变化,形成疏密相间的纵波,这就产生了声波,这种现象会一直延续到振动消失为止。

        声音作为波的一种,频率和振幅就成了描述波的重要属性,频率的大小与我们通常所说的音高对应,而振幅影响声音的大小。声音可以被分解为不同频率不同强度正弦波的叠加。这种变换(或分解)的过程,称为傅里叶变换(Fourier Transform)。

        因此,一般的声音总是包含一定的频率范围。人耳可以听到的声音的频率范围在20到2万赫兹之间。高于这个范围的波动称为超声波,而低于这一范围的称为次声波。狗和蝙蝠等动物可以听得到高达16万赫兹的声音。鲸和大象则可以产生频率在15到35赫兹范围内的声音。

4 不同的声音有什么区别?

  1. 响度(loudness):人主观上感觉声音的大小(俗称音量),由“振幅”(amplitude)和人离声源的距离决定,振幅越大响度越大,人和声源的距离越小,响度越大。(单位:分贝dB)

  2. 音调(pitch):声音的高低(高音、低音),由“频率”(frequency)决定,频率越高音调越高(频率单位Hz(hertz),赫兹,人耳听觉范围20~20000Hz。20Hz以下称为次声波,20000Hz以上称为超声波)例如,低音端的声音或更高的声音,如细弦声。

  3. 音色(Timbre):又称音品,波形决定了声音的音色。声音因物体材料的特性而不同,音色本身是一种抽象的东西,但波形是把这个抽象直观的表现。波形不同,音色则不同。不同的音色,通过波形,完全可以分辨的。

  4. 音调,响度,音色是乐音的三个主要特征,人们就是根据他们来区分声音.

  5. 当两个物体碰撞后振动产生声音时,若两者振动频率比为不可化简的复杂比,如:201:388,那么我们分辨出来会觉得这个声音刺耳;相反,若两者振动频率比为可化简的简单比,如:3:7,那么我们分辨出来会觉得很动听。(毕达哥拉斯发现)

5 声音怎么被存储下来?

        要在计算机内播放或是处理音频文件,也就是要对声音文件进行数、模转换,这个过程同样由采样和量化构成,人耳所能听到的声音,最低的频率是从20Hz起一直到最高频率20KHZ,20KHz以上人耳是听不到的,因此音频的最大带宽是20KHZ,故而采样速率需要介于40~50KHZ之间,而且对每个样本需要更多的量化比特数。音频数字化的标准是每个样本16位(16bit,即96dB)的信噪比,采用线性脉冲编码调制PCM,每一量化步长都具有相等的长度。在音频文件的制作中,正是采用这一标准。

c8bc7865bd9b42958ca2ff6b0dea5002.png

6 Winmm 是什么?

        DLL 文件是winmm 或者 winmm.dll,DLL 名称为Windows Multimedia, API描述是winmm.dll是Windows多媒体相关应用程序接口,用于低档的音频和游戏手柄。 系统文件winmm.dll是存放在Windows系统文件夹中的重要文件,通常情况下是在安装操作系统过程中自动创建的,对于系统正常运行来说至关重要。下为微软官方解释:

网站: User-Mode WDM Audio Components - Windows drivers | Microsoft Learn

81280a30285d4183a7839b8a0f2c83ba.png

7 SDL是什么?

        SDL(Simple DirectMedia Layer)是一套开放源代码跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux、Windows、Mac OS X等)的应用软件。现SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。

 网站: Simple DirectMedia Layer - Homepage (libsdl.org)

8ed493e5527a4d9ba017c9e26e81a8b7.png

8 ffmpeg 是什么?

        FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPLGPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多code都是从头开发的。

FFmpeg在Linux平台下开发,但它同样也可以在其它操作系统环境中编译运行,包括WindowsMac OS X等。这个项目最早由Fabrice Bellard发起,2004年至2015年间由Michael Niedermayer主要负责维护。许多FFmpeg的开发人员都来自MPlayer项目,而且当前FFmpeg也是放在MPlayer项目组的服务器上。项目的名称来自MPEG视频编码标准,前面的"FF"代表"Fast Forward"。 [1]FFmpeg编码库可以使用GPU加速。

官网:FFmpeg

b785c1b548db461d889b80cec6cbf415.png

================================开始编程啦=================================

9 声音怎么被计算机播放出来?

        思路:获得一份音频文件时,通过windows  I/O 函数,将音频文件读取到系统内存,如果是非压缩文件或者RAW文件,可以将内存数据传入至配置好的SDL 播放器中,直接播放;如果是压缩文件,需要将内存数据传入至配置好的FFMPEG音频解码器中,随后送入配置好的SDL 播放器中播放。SDL 播放器亦可换成WINMM。

1. 在上述官网分别下载FFMPEG/SDL库,WINMM 为系统内置,无需下载。

2.将头文件和LIB库分别加入到工程中。

SDL 播放PCM 代码部分

  1. // audio_play.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include <iostream>
  5. #include <algorithm>
  6. #include "SDL.h"
  7. #pragma comment(lib , "SDL2.lib")
  8. unsigned char* audio_chunk;
  9. unsigned int audio_len;
  10. unsigned char* audio_pos;
  11. const static uint32_t PCM_BUFFER_SIZE = 4096;
  12. //数据到来的回调函数
  13. void read_audio_data_cb(void* udata, Uint8* stream, int len)
  14. {
  15. SDL_memset(stream, 0, len);
  16. if (audio_len == 0)
  17. return;
  18. len = std::min(len, static_cast<int>(audio_len));
  19. SDL_MixAudio(stream, audio_pos, len, SDL_MIX_MAXVOLUME);
  20. audio_pos += len;
  21. audio_len -= len;
  22. }
  23. #undef main
  24. int main(int argc , char *argv[])
  25. {
  26. SDL_Init(SDL_INIT_AUDIO); //init
  27. SDL_AudioSpec spec;
  28. spec.freq = 44100;
  29. spec.format = AUDIO_S16SYS;
  30. spec.channels = 2;
  31. spec.samples = 1024;
  32. spec.callback = read_audio_data_cb;
  33. spec.userdata = NULL;
  34. //根据参数,打开音频设备
  35. if (SDL_OpenAudio(&spec, NULL) < 0)
  36. return -1;
  37. //打开文件
  38. FILE *f = fopen("yinpin.pcm", "rb+");
  39. if (f == nullptr) return -1;
  40. char* pcm_buffer = (char*)malloc(PCM_BUFFER_SIZE);
  41. //开始播放
  42. SDL_PauseAudio(0);
  43. int ret = 0;
  44. while (true)
  45. {
  46. ret = fread(pcm_buffer, 1, PCM_BUFFER_SIZE, f);
  47. if (ret == 0) break;
  48. audio_chunk = reinterpret_cast<Uint8*>(pcm_buffer);
  49. audio_len = ret; //读取到的字节数
  50. audio_pos = audio_chunk;
  51. std::cout << "play " << audio_len << " data" << std::endl;
  52. while (audio_len > 0) //等待audio_len长度的数据播放完成
  53. SDL_Delay(1);
  54. }
  55. free(pcm_buffer);
  56. SDL_Quit();
  57. return 0;
  58. }

==============歇了,有时间继续=============================================

未完成: ffmpeg 解码  winmm 播放

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/948405
推荐阅读
相关标签
  

闽ICP备14008679号