首先介绍了音频的基本知识,然后介绍了音频量化与编码、音频压缩技术、音频编解码器的选择。
声音频率的高低叫做音调。表示人的听觉分辨一个声音的调子高低的程度。音调主要由声音的频率决定,同时也与声音强度有关。对一定强度的纯音,音调随频率的升降而升降;对一定频率的纯音、低频纯音的音调随声强增加而下降,高频纯音的音调却随强度增加而上升。
音量又称响度、音强,是指人耳对所听到的声音大小强弱的主观感受,其客观评价尺度是声音的振幅大小。这种感受源自物体振动时所产生的压力,即声压。物体振动通过不同的介质,将其振动能量传导开去。人们为了对声音的感受量化成可以监测的指标,就把声压分成“级”——声压级,以便能客观的表示声音的强弱,其单位称为“分贝”(dB)。
音色(Timbre)是指不同的声音的频率表现在波形方面总是有与众不同的特性。不同的物体振动都有不同的特点。
我们为什么要了解声音,音频技术不是有音频采集,音频编码,音频解码,算法等等就行了么,还要了解这么基本的知识有必要么,如果你了解个音频技术里的倍速播放功能时,就你会发现当你倍速播放时,音调也发生了变化。
音频采集一般使用 AudioRecod或者 MediaRecord
一般是指麦克风:MediaRecorder.AudioSource.MIC
关于音频是怎么采集的,到时候专门写一篇音频采集的文章,这章主要是了解音频基础知识。当我们采集到了声音数据后都要对声音数据进行量化。
获取模拟数据(即采集到的音频波片段的数据)——>采样(对音频波进行采样)——>量化(根据采样点的值进行一一量化)——>编码(根据样本序号进行编码)——>转换成数字信号(即把样本一一转换01这样的机器能识别的数字信号)
16bit 表示Y轴振幅的高度 2的16次方(声音的振幅最高也高示过65535)
以44.1K为例,就是说每秒在模拟信号上,我们采样441000次,比如说20Hz的频率(20Hz也就是人听到的最低频率,20Hz的频率即每秒采样了20次),每秒钟正弦波里,要采集多少次呢,要采样2000次,那么对于高频呢,比如20000Hz,那么就要采样2次
AudioFormat.CHANNEL_IN_MONO 单声道,一个声道进行采样
AudioFormat.CHANNEL_IN_STEREO 双声道,两个声道进行采样
采样精度:声音样本大小bit/s表示。位数越高,声音的保真度越高。
采样精度决定了记录声音的动态范围,它以位(Bit)为单位,比如8位、16位。8位可以把声波分成256级,16位可以把同样的波分成65536级的信号。
它反映度量声音波形幅度的精度。例如,每个声音样本用16位(2字节)表示,测得的声音样本值是在0~65535的范围里,它的精度就是输入信号的1/65536。样本位数的大小影响到声音的质量,位数越多,声音的质量越高,而需要的存储空间也越多;位数越少,声音的质量越低,需要的存储空间越少。
一般都采用这个 AudioFormat.ENCODING_PCM_16BIT(官方文档表示,该采样精度保证所有设备都支持)
要算一个PCM音频的码率是一件很轻松的事情,采样率 * 采样大小 * 声道数
例如:
采样率为44.1KHz
采样大小为16bit
双声道的PCM编码的WAV文件
它是码率为 44.1k * 16 * 2 =1411200b=1411.2Kb/s
每秒传送的比特(bit)数。单位为 bps(Bit Per Second),比特率越高,传送数据速度越快。
PCM
PCM是英文Pulse-code modulation的缩写,中文译名是脉冲编码调制。
我们知道在现实生活中,人耳听到的声音是模拟信号,PCM就是要把声音从模拟转换成数字信号的一种技术,他的原理简单地说就是利用一个固定的频率对模拟信号进行采样,采样后的信号在波形上看就像一串连续的幅值不一的脉冲,把这些脉冲的幅值按一定的精度进行量化,这些量化后的数值还要进行编码,就是用一组二进制码组来表示每一个量化值,然后记录到存储介质中,所有这些组成了数字音频的产生过程。
音频压缩技术有两种方法,如下:
在音频采集过程中,会采集到各种各样的声音,其中只有一部分声音是我们人能够识别出来的,其他声音我们可以直接删除掉,这样能够大大减少存储的数据,删除掉的这些数据,当我们压缩完之后是完全没有了也无法恢复。
将人无法识别的声音删除之后,留下来的声音对其压缩编码,压缩后的编码还能恢复为原来一模一样的数据,这就称为无损压缩技术。
压缩的主要方法是去除采集到的音频冗余信息,所谓冗余信息包括人耳听觉范围外的音频信号以及被掩蔽掉的音频信号
信号的掩蔽可以分为:频域掩蔽、时域掩蔽
频域掩蔽: 人耳所能察觉的声音信号的频率范围为20Hz~20KHz,在这个频率范围以外的音频信号属于冗余信号;或一个强纯音会掩蔽在其附近同时发声的弱纯音,那么弱纯音也被掩蔽,弱纯音属于冗余信号。
时域掩蔽: 在时间上相邻的声音之间也有掩蔽现象,主要原因是人的大脑处理信息需要花费时间。同步掩蔽效应和不同频率声音的频率和相对竟是有关,而时间掩蔽则仅仅和时间有关。如果两个声音在时间上特别接近,分辨会有困难(如两个声音音量相差较大且两个声音间隔时间低于5毫秒,则其中弱的那个声音会听不到)。
下面简单列出常见的音频压缩格式:
MP3,AAC,OGG,WMA,Opus,FLAC,APE,m4a,AMR,等等
时域转频域变换 —(声学模型)—> 量化编码 —> 比特流格式 (也可以添加辅助的数据)—> 比特流
常见的音频编码器
常见的音频编码器他们的性能对比就不一一列举了,感兴趣的可以网上查阅一下。下面重点介绍一下AAC编码器。
为什么重点介绍AAC呢?
- AAC是的应用范围广(市面上95%以上的都是AAC编码器)
- 传输协议是用rtmp,RTMP是支持AAC的不支持OPUS
- AAC是的编码质量非常高,有一个高保帧,保持音频的高保帧,这样也导致很多应用使用AAC
AAC为了解决什么问题?
- AAC(Advanced Audio Coding) 目的是取代MP3格式
- MPEG-4标准出现后,AAC加入了SBR技术和PS技术
- 目前常用的规格有AAC LC、AAC HE V1、AAC HE V2
AAC +SBR -> AAC HE V1
AAC+SBR+PS -> AAC HE V2
市面上的库:
Libfdk_AAC > ffmpeg AAC > libfaac > libvo_aacenc
Libfdk_AAC的编码效率更高
Android中播放音频文件一般都是使用MediaPlayer类来实现的,它对多种格式的音频文件提供了非常全面的控制
方法,从而使得播放音乐的工作变得十分简单。
首先创建一个MediaPlayer对象->调用setDataSource()方法来设置音频文件的路径->调用prepare()方法使MediaPlayer
进入到准备状态->调用start()方法可以播放音乐,pause()方法暂时停止播放,reset()方法完全停止播放->最后要调用release()方法释放资源
还是先看activity_main.xml
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
< Button
android:id="@+id/play"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Play" />
< Button
android:id="@+id/pause"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Pause" />
< Button
android:id="@+id/stop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Stop" />
主活动
package com.gougoucompany.clarence.playaudiotest;
import android.Manifest;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.os.EnvironmentCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.io.File;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private MediaPlayer mediaPlayer = new MediaPlayer();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button play = (Button) findViewById(R.id.play);
Button pause = (Button) findViewById(R.id.pause);
Button stop = (Button) findViewById(R.id.stop);
play.setOnClickListener(this);
pause.setOnClickListener(this);
stop.setOnClickListener(this);
if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.
WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[] {
Manifest.permission.WRITE_EXTERNAL_STORAGE
}, 1);
} else {
initMediaPlayer(); //初始化MediaPlayer
}
}
@Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.play:
if(!mediaPlayer.isPlaying()) {
mediaPlayer.start(); //开始播放
}
break;
case R.id.pause:
if(mediaPlayer.isPlaying()) {
mediaPlayer.pause(); //暂停播放
}
break;
case R.id.stop:
if(mediaPlayer.isPlaying()) {
mediaPlayer.reset(); //停止播放
initMediaPlayer();
}
break;
default:
break;
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch(requestCode) {
case 1:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
initMediaPlayer();
} else {
Toast.makeText(this, "拒绝权限将无法使用程序", Toast.LENGTH_SHORT).show();
finish();
}
break;
default:
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if(mediaPlayer != null){
mediaPlayer.stop();
mediaPlayer.release();
}
}
private void initMediaPlayer() {
try {
File file = new File(Environment.getExternalStorageDirectory(), "music.mp3");
mediaPlayer.setDataSource(file.getPath()); //指定音频文件的路径
mediaPlayer.prepare(); //让MediaPlayer进入到准备状态
} catch (Exception e) {
e.printStackTrace();
}
}
---------------------
交易额: 188.49万元
无 |河南省 |洛阳市 |洛龙区
交易额: 151.77万元
无 |浙江省 |台州市 |玉环县
交易额: 128.29万元
工作室 |广东省 |深圳市 |南山区
交易额: 110.67万元
公司 |浙江省 |温州市 |瓯海区
成为一品威客服务商,百万订单等您来有奖注册中
价格是多少?怎样找到合适的人才?
¥20000 已有1人投标
¥1000 已有2人投标
¥5000 已有0人投标
¥5000 已有0人投标
¥20000 已有0人投标
¥10000 已有7人投标
¥20000 已有2人投标
¥50000 已有0人投标