赞
踩
为了快速掌握音频开发知识,秉承实用主义,我计划以下面思维导图方式介绍音频开发知识,以求最快速让开发者听到文件的声音。
在计算机平台下,二进制数据可用十六进制显示,文件数据可视化工具软件为为UltraEdit。
1 Qt播放音频文件Demo。
2 基于C、C++语言
使用ffmpeg 解码压缩音频数据;
使用SDL 播放原始音频数据;
使用winmm 播放原始音频数据;
音频播放控制,响度增大和音调不改变实现倍速播放。
声音(sound)是由物体振动产生的声波。是通过介质(空气或固体、液体)传播并能被人或动物听觉器官所感知的波动现象。最初发出振动(震动)的物体叫声源。声音以波的形式振动(震动)传播。声音是声波通过任何介质传播形成的运动。声音是一种波。可以被人耳识别的声(频率在20 Hz~20000 Hz之间),我们称之为声音。
音频是个专业术语,音频一词已用作一般性描述音频范围内和声音有关的设备及其作用。
1.Audio,指人耳可以听到声音的声波,称为音频。
2.指存储声音内容的文件。
3.在某些方面能指作为滤波的振动。
声音是一种压力波:当演奏乐器、拍打一扇门或者敲击桌面时,他们的振动会引起介质——空气分子有节奏的振动,使周围的空气产生疏密变化,形成疏密相间的纵波,这就产生了声波,这种现象会一直延续到振动消失为止。
声音作为波的一种,频率和振幅就成了描述波的重要属性,频率的大小与我们通常所说的音高对应,而振幅影响声音的大小。声音可以被分解为不同频率不同强度正弦波的叠加。这种变换(或分解)的过程,称为傅里叶变换(Fourier Transform)。
因此,一般的声音总是包含一定的频率范围。人耳可以听到的声音的频率范围在20到2万赫兹之间。高于这个范围的波动称为超声波,而低于这一范围的称为次声波。狗和蝙蝠等动物可以听得到高达16万赫兹的声音。鲸和大象则可以产生频率在15到35赫兹范围内的声音。
响度(loudness):人主观上感觉声音的大小(俗称音量),由“振幅”(amplitude)和人离声源的距离决定,振幅越大响度越大,人和声源的距离越小,响度越大。(单位:分贝dB)
音调(pitch):声音的高低(高音、低音),由“频率”(frequency)决定,频率越高音调越高(频率单位Hz(hertz),赫兹,人耳听觉范围20~20000Hz。20Hz以下称为次声波,20000Hz以上称为超声波)例如,低音端的声音或更高的声音,如细弦声。
音色(Timbre):又称音品,波形决定了声音的音色。声音因物体材料的特性而不同,音色本身是一种抽象的东西,但波形是把这个抽象直观的表现。波形不同,音色则不同。不同的音色,通过波形,完全可以分辨的。
音调,响度,音色是乐音的三个主要特征,人们就是根据他们来区分声音.
当两个物体碰撞后振动产生声音时,若两者振动频率比为不可化简的复杂比,如:201:388,那么我们分辨出来会觉得这个声音刺耳;相反,若两者振动频率比为可化简的简单比,如:3:7,那么我们分辨出来会觉得很动听。(毕达哥拉斯发现)
要在计算机内播放或是处理音频文件,也就是要对声音文件进行数、模转换,这个过程同样由采样和量化构成,人耳所能听到的声音,最低的频率是从20Hz起一直到最高频率20KHZ,20KHz以上人耳是听不到的,因此音频的最大带宽是20KHZ,故而采样速率需要介于40~50KHZ之间,而且对每个样本需要更多的量化比特数。音频数字化的标准是每个样本16位(16bit,即96dB)的信噪比,采用线性脉冲编码调制PCM,每一量化步长都具有相等的长度。在音频文件的制作中,正是采用这一标准。
DLL 文件是winmm 或者 winmm.dll,DLL 名称为Windows Multimedia, API描述是winmm.dll是Windows多媒体相关应用程序接口,用于低档的音频和游戏手柄。 系统文件winmm.dll是存放在Windows系统文件夹中的重要文件,通常情况下是在安装操作系统过程中自动创建的,对于系统正常运行来说至关重要。下为微软官方解释:
网站: User-Mode WDM Audio Components - Windows drivers | Microsoft Learn
SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux、Windows、Mac OS X等)的应用软件。现SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。
网站: Simple DirectMedia Layer - Homepage (libsdl.org)
FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多code都是从头开发的。
FFmpeg在Linux平台下开发,但它同样也可以在其它操作系统环境中编译运行,包括Windows、Mac OS X等。这个项目最早由Fabrice Bellard发起,2004年至2015年间由Michael Niedermayer主要负责维护。许多FFmpeg的开发人员都来自MPlayer项目,而且当前FFmpeg也是放在MPlayer项目组的服务器上。项目的名称来自MPEG视频编码标准,前面的"FF"代表"Fast Forward"。 [1]FFmpeg编码库可以使用GPU加速。
官网:FFmpeg
================================开始编程啦=================================
思路:获得一份音频文件时,通过windows I/O 函数,将音频文件读取到系统内存,如果是非压缩文件或者RAW文件,可以将内存数据传入至配置好的SDL 播放器中,直接播放;如果是压缩文件,需要将内存数据传入至配置好的FFMPEG音频解码器中,随后送入配置好的SDL 播放器中播放。SDL 播放器亦可换成WINMM。
1. 在上述官网分别下载FFMPEG/SDL库,WINMM 为系统内置,无需下载。
2.将头文件和LIB库分别加入到工程中。
SDL 播放PCM 代码部分
- // audio_play.cpp : 定义控制台应用程序的入口点。
- //
-
- #include "stdafx.h"
- #include <iostream>
- #include <algorithm>
- #include "SDL.h"
-
- #pragma comment(lib , "SDL2.lib")
-
-
-
- unsigned char* audio_chunk;
- unsigned int audio_len;
- unsigned char* audio_pos;
-
- const static uint32_t PCM_BUFFER_SIZE = 4096;
-
- //数据到来的回调函数
- void read_audio_data_cb(void* udata, Uint8* stream, int len)
- {
- SDL_memset(stream, 0, len);
- if (audio_len == 0)
- return;
- len = std::min(len, static_cast<int>(audio_len));
-
- SDL_MixAudio(stream, audio_pos, len, SDL_MIX_MAXVOLUME);
- audio_pos += len;
- audio_len -= len;
- }
- #undef main
- int main(int argc , char *argv[])
- {
- SDL_Init(SDL_INIT_AUDIO); //init
-
- SDL_AudioSpec spec;
- spec.freq = 44100;
- spec.format = AUDIO_S16SYS;
- spec.channels = 2;
- spec.samples = 1024;
- spec.callback = read_audio_data_cb;
- spec.userdata = NULL;
- //根据参数,打开音频设备
- if (SDL_OpenAudio(&spec, NULL) < 0)
- return -1;
-
- //打开文件
- FILE *f = fopen("yinpin.pcm", "rb+");
- if (f == nullptr) return -1;
- char* pcm_buffer = (char*)malloc(PCM_BUFFER_SIZE);
- //开始播放
- SDL_PauseAudio(0);
- int ret = 0;
- while (true)
- {
- ret = fread(pcm_buffer, 1, PCM_BUFFER_SIZE, f);
- if (ret == 0) break;
-
- audio_chunk = reinterpret_cast<Uint8*>(pcm_buffer);
- audio_len = ret; //读取到的字节数
- audio_pos = audio_chunk;
- std::cout << "play " << audio_len << " data" << std::endl;
- while (audio_len > 0) //等待audio_len长度的数据播放完成
- SDL_Delay(1);
- }
-
- free(pcm_buffer);
- SDL_Quit();
- return 0;
- }
==============歇了,有时间继续=============================================
未完成: ffmpeg 解码 winmm 播放
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。