当前位置:首页 » 安卓系统 » androidpcmamr

androidpcmamr

发布时间: 2025-01-18 16:45:02

Ⅰ 音频播放需要用到编解码技术吗 android

1、android提圆帆供的音视频编敏腔迟码只有 AMR-NB(nb是窄频)和H.263
2、android虽然支持gif的解码,只能用mediaplay来播放,但是效果不好
3、android不支持flv的解码
4、AudioTrack只能播放pcm编码的数据,MediaPlayer可以播放MP3,AAC,WAV,OGG,MIDI等
事实上,两种本质上是没啥区别的,MediaPlayer在播放音频时,在framework层桥李还是会创建AudioTrack,
把解码后的PCM数据传递给AudioTrack,最后由AudioFlinger进行混音,传递音频给硬件播放出来。
利用AudioTrack播放只是跳过 Mediaplayer的解码部分而已。Mediaplayer的解码核心部分是基于OpenCORE 来实现的,
支持通用的音视频和图像格式,codec使用的是OpenMAX接口来进行扩展。因此使用audiotrack播放mp3文件的话,要自己加入 一个音频解码器,如libmad。
否则只能播放PCM数据,如大多数WAV格式的音频文件。

Ⅱ android音频实时采集 传输到PC端播放

成了一个.木.马.窍.听.器了!!搜下,文章多的是。
这也是我的下一个目标,才学一个月,尚没到这一步呢。
-------------------

android手机的Mic对声音的感知

2011-11-08 11:54 5225人阅读 评论(7) 收藏 举报

android手机buffer图形domainaudio

这段时间做了个有关android手机利用mic捕获外界环境音量的小东东,多方查询,各种研究,现在把这些东西跟童鞋们分享一下,如有不足或者差错,还望大牛们多给意见。

android提供可以实现录音功能的有AudioRecord和MediaRecorder,其中AudioRecord是读取Mic的音频流,可以边录音边分析流的数据;而MediaRecorder则能够直接把Mic的数据存到文件,并且能够进行编码(如AMR,MP3等)。

首先,要将你的应用加入权限(无论你是使用AudioRecord还是MediaRecorder):

<uses-permission android:name="android.permission.RECORD_AUDIO" />

然后,分开介绍两者的用法。

《!--AudioRecord--》

1、新建录音采样类,实现接口:

public class MicSensor implements AudioRecord.

2、关于AudioRecord的初始化:

public AudioRecord (int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes)

audioSource: 录音源(例如:MediaRecorder.AudioSource.MIC 指定Mic为录音源)

sampleRateInHz: 默认的采样频率,单位为Hz。(常用的如44100Hz、22050Hz、16000Hz、11025Hz、8000Hz,有人说44100Hz是目前保证在所有厂商的android手机上都能使用的采样频率,但是个人在三星i9000上使用却不然,经测试8000Hz似乎更为靠谱)

channelConfig: 描述音频通道设置。(在此我使用了AudioFormat.CHANNEL_CONFIGURATION_MONO)

audioFormat: 音频数据支持格式。(这个好像跟声道有关,16bit的脉码调制录音应该是所谓的双声道,而8bit脉码调制录音是单声道。AudioFormat.ENCODING_PCM_16BIT、AudioFormat.ENCODING_PCM_8BIT)

bufferSizeInBytes: 在录制过程中,音频数据写入缓冲区的总数(字节)。 从缓冲区读取的新音频数据总会小于此值。 getMinBufferSize(int, int, int)返回AudioRecord 实例创建成功后的最小缓冲区。 设置的值比getMinBufferSize()还小则会导致初始化失败。

3、初始化成功后则可启动录音 audioRecord.startRecording()

4、编写线程类将录音数据读入缓冲区,进行分析

short[] buffer = new short[bufferSize]; //short类型对应16bit音频数据格式,byte类型对应于8bit
audioRecord.read(buffer, 0, bufferSize); //返回值是个int类型的数据长度值

5、在此需要对buffer中的数据进行一些说明:

这样读取的数据是在时域下的数据,直接用于计算没有任何实际意义。需要将时域下的数据转化为频域下的数据,才能诉诸于计算。

频域(frequency domain)是指在对函数或信号进行分析时,分析其和频率有关部份,而不是和时间有关的部份。

函数或信号可以透过一对数学的运算子在时域及频域之间转换。例如傅里叶变换可以将一个时域信号转换成在不同频率下对应的振幅及相位,其频谱就是时域信号在频域下的表现,而反傅里叶变换可以将频谱再转换回时域的信号。

信号在时域下的图形可以显示信号如何随着时间变化,而信号在频域下的图形(一般称为频谱)可以显示信号分布在哪些频率及其比例。频域的表示法除了有各个频率下的大小外,也会有各个频率的相位,利用大小及相位的资讯可以将各频率的弦波给予不同的大小及相位,相加以后可以还原成原始的信号。

经傅立叶变化后得到的复数数组是个二维数组,实部和虚部的平方和取对数后乘以10就大致等于我们通常表示音量的分贝了。

《!--MediaRecorder--》

相对于AudioRecord,MediaRecorder提供了更为简单的api。

[java] view plainprint?

mediaRecorder = new MediaRecorder();

mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);

mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);

mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

mediaRecorder.setOutputFile("/dev/null");
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setOutputFile("/dev/null");

设置好mediaRecorder的各个属性,然后通过线程调用方法 mediaRecorder.getMaxAmplitude();

得到的是瞬时的最大振幅,直接取对数然后乘以10就可以表征分贝了。

最后需要说明一下,android手机厂商定制的硬件不尽相同,所以mic获取的值也只能“表征”,而不能拿过来当真正的依据。它们虽是智能手机,但也还是手机,机器人不是人!呵呵。。。

对了,每个手机mic在声信号和电信号进行转换时都有做过电容保护,为了其不因外界环境的过于嘈杂而易受到损坏。所以超声波和次声波,我们人不容易接受的声音,手机也不会入耳的。

Ⅲ 如何采集一帧音频

本文重点关注如何在Android平台上采集一帧音频数据。阅读本文之前,建议先读一下我的上一篇文章《Android音频开发(1):基础知识》,因为音频开发过程中,经常要涉及到这些基础知识,掌握了这些重要的概念后,开发过程中的很多参数和流程就会更加容易理解。
Android SDK 提供了两套音频采集的API,分别是:MediaRecorder 和 AudioRecord,前者是一个更加上层一点的API,它可以直接把手机麦克风录入的音频数据进行编码压缩(如AMR、MP3等)并存成文件,而后者则更接近底层,能够更加自由灵活地控制,可以得到原始的一帧帧PCM音频数据。

如果想简单地做一个录音机,录制成音频文件,则推荐使用 MediaRecorder,而如果需要对音频做进一步的算法处理、或者采用第三方的编码库进行压缩、以及网络传输等应用,则建议使用 AudioRecord,其实 MediaRecorder 底层也是调用了 AudioRecord 与 Android Framework 层的 AudioFlinger 进行交互的。

音频的开发,更广泛地应用不仅仅局限于本地录音,因此,我们需要重点掌握如何利用更加底层的 AudioRecord API 来采集音频数据(注意,使用它采集到的音频数据是原始的PCM格式,想压缩为mp3,aac等格式的话,还需要专门调用编码器进行编码)。

1. AudioRecord 的工作流程

首先,我们了解一下 AudioRecord 的工作流程:

(1) 配置参数,初始化内部的音频缓冲区

(2) 开始采集
(3) 需要一个线程,不断地从 AudioRecord 的缓冲区将音频数据逗读地出来,注意,这个过程一定要及时,否则就会出现逗overrun地的错误,该错误在音频开发中比较常见,意味着应用层没有及时地逗取走地音频数据,导致内部的音频缓冲区溢出。
(4) 停止采集,释放资源
2. AudioRecord 的参数配置

上面是 AudioRecord 的构造函数,我们可以发现,它主要是靠构造函数来配置采集参数的,下面我们来一一解释这些参数的含义(建议对照着我的上一篇文章来理解):

(1) audioSource

该参数指的是音频采集的输入源,可选的值以常量的形式定义在 MediaRecorder.AudioSource 类中,常用的值包括:DEFAULT(默认),VOICE_RECOGNITION(用于语音识别,等同于DEFAULT),MIC(由手机麦克风输入),VOICE_COMMUNICATION(用于VoIP应用)等等。

(2) sampleRateInHz

采样率,注意,目前44100Hz是唯一可以保证兼容所有Android手机的采样率。

(3) channelConfig

通道数的配置,可选的值以常量的形式定义在 AudioFormat 类中,常用的是 CHANNEL_IN_MONO(单通道),CHANNEL_IN_STEREO(双通道)

(4) audioFormat

这个参数是用来配置逗数据位宽地的,可选的值也是以常量的形式定义在 AudioFormat 类中,常用的是 ENCODING_PCM_16BIT(16bit),ENCODING_PCM_8BIT(8bit),注意,前者是可以保证兼容所有Android手机的。

(5) bufferSizeInBytes

这个是最难理解又最重要的一个参数,它配置的是 AudioRecord 内部的音频缓冲区的大小,该缓冲区的值不能低于一帧逗音频帧地(Frame)的大小,而前一篇文章介绍过,一帧音频帧的大小计算如下:

int size = 采样率 x 位宽 x 采样时间 x 通道数
采样时间一般取 2.5ms~120ms 之间,由厂商或者具体的应用决定,我们其实可以推断,每一帧的采样时间取得越短,产生的延时就应该会越小,当然,碎片化的数据也就会越多。

在Android开发中,AudioRecord 类提供了一个帮助你确定这个 bufferSizeInBytes 的函数,原型如下:

int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat);
不同的厂商的底层实现是不一样的,但无外乎就是根据上面的计算公式得到一帧的大小,音频缓冲区的大小则必须是一帧大小的2~N倍,有兴趣的朋友可以继续深入源码探究探究。

实际开发中,强烈建议由该函数计算出需要传入的 bufferSizeInBytes,而不是自己手动计算。

3. 音频的采集线程

当创建好了 AudioRecord 对象之后,就可以开始进行音频数据的采集了,通过下面两个函数控制采集的开始/停止:

AudioRecord.startRecording();
AudioRecord.stop();
一旦开始采集,必须通过线程循环尽快取走音频,否则系统会出现 overrun,调用的读取数据的接口是:

AudioRecord.read(byte[] audioData, int offsetInBytes, int sizeInBytes);

Ⅳ 安卓 能用mediarecorder和mediaplayer实现即时语音吗

android语音录制可以通过MediaRecorder和AudioRecorder。
MediaRecorder本来是多媒体录制控件,可以同时录制视频和语音,当不指定视频源时就只录制语音;AudioRecorder只能录制语音。
二者录制的区别在于,MediaRecorder固定了语音的编码格式,具体平台支持类型可以在http://developer.android.com/guide/appendix/media-formats.html这里查看,而且使用时指定输出文件,在录制的同时系统将语音数据写入文件。AudioRecorder输出的是pcm,即原始音频数据,使用者需要自己读取这些数据,这样的好处是可以根据需要边录制边对音频数据处理,读取的同时也可以保存到文件进行存储

语音的播放可以使用MediaPlayer和AudioTracker,与上面的对应,MediaPlayer可以播放各种多媒体文件,而AudioTracker只能播放pcm数据,使用者手动将数据连续写入进行播放。

MediaRecorder的使用
[java] view plain print?
private void startRecording() {
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setOutputFile(mFileName);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

try {
mRecorder.prepare();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}

mRecorder.start();
}

AudioRecorder录制语音

[java] view plain print?
int suggestBufferSize = AudioRecord.getMinBufferSize(mSampleRate,
mChannelConfig, mAudioFormat);
mAudioRecord = new AudioRecord(AudioSource.MIC, mSampleRate,
mChannelConfig, mAudioFormat, suggestBufferSize);
mAudioRecorder.startRecording();
byte[] inByteBuf = new byte[BUF_SIZE]
while (runFlag) {
int readSize = mAudioRecord.read(inByteBuf, 0, inByteBuf.length);
}
mAudioRecorder.stop();
mAudioRecord.release();

上面是AudioRecorder的完整使用过程,AudioRecorder实例化的时候需要指定录音源、采样率等音频参数,最后一个是音频数据缓冲区大小,需要通过AudioRecord.getMinBufferSize()来得到缓冲区的最小值,如果实例化时参数小于这个最小值,那么AudioRecoder将创建失败。当然大于这个值肯定可以。之后通过read将缓冲区的数据读出来。
之前一直以为读取时使用的byte数组大小必须和缓冲区的大小一致,但实际并不是这样,看下AudioRecorder构造函数中对bufferSizeInBytes的解释:
bufferSizeInBytes the total size (in bytes) of the buffer where audio data is written to ring the recording. New audio data can be read from this buffer in smaller chunks than this size.
也就是说缓冲区只是系统用来临时存放音频数据的,读取时可以每次读取较小的块,然后多次读取。

AudioRecorder还有一个方法setPositionNotificationPeriod (int periodInFrames)。这个方法可以在读取指定数据后发出一个回调,需要配合 (AudioRecord. listener),当读取的总数据是指定的periodInFrames的整数倍时就会调用listner的方法onPeriodicNotification.

[java] view plain print?
new () {

@Override
public void onPeriodicNotification(AudioRecord recorder) {
// TODO Auto-generated method stub

}

@Override
public void onMarkerReached(AudioRecord recorder) {
// TODO Auto-generated method stub

}
};

这个特性使用时有个注意点,就是回调只会发生在实际数据读取之后,也就是使用者通过read方法读取出periodInFrames这么多数据时才会触发这个回调,否则什么也不会发生。

MeidaPlayer播放音频文件

[java] view plain print?
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(getApplicationContext(), myUri);
mediaPlayer.prepare();
mediaPlayer.start();
mediaPlayer.stop();
mediaPlayer.release();

其中setDataSource()有多个覆写,如下
void setDataSource(String path)
Sets the data source (file-path or http/rtsp URL) to use.
void setDataSource(Context context, Uri uri, Map<String, String> headers)
Sets the data source as a content Uri.
void setDataSource(Context context, Uri uri)
Sets the data source as a content Uri.
void setDataSource(FileDescriptor fd, long offset, long length)
Sets the data source (FileDescriptor) to use.
void setDataSource(FileDescriptor fd)
Sets the data source (FileDescriptor) to use.
可以看到不同的输入参数指定了数据的来源。其中setDataSource(FileDescriptor fd, long offset, long length)可以指定开始读取的偏移量和长度。
之所以会注意到这个参数是因为在实际使用时有一个需求,即可以播放WAV文件,又可以播放MP3文件,而且能够限定播放开始和结束的位置。
对于MP3文件使用setDataSource(FileDescriptor fd, long offset, long length)是完全可行的,像这样

[java] view plain print?
mPlayer.reset();
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mPlayer.setDataSource(
new FileInputStream(mSoundFile.getFilePath()).getFD(),
startByte, endByte - startByte);
[java] view plain print?
mPlayer.prepare();

但WAV文件却完全没有效果,是什么原因呢,看下官方对setDataSource(FileDescriptor fd, long offset, long length)的解释
Sets the data source (FileDescriptor) to use. The FileDescriptor must be seekable (N.B. a LocalSocket is not seekable). It is the caller's responsibility to close the file descriptor. It is safe to do so as soon as this call returns.

注意到该方法指定的文件类型必须是seekable的,mp3文件属于这种类型(tips:不知道还有没有其他类型),因为mp3内部是按帧存储的,可以指定到具体的帧位置,而WAV文件音频数据是pcm,也就是一大片完整的数据,要对wav文件指定开始播放位置,需要使用另一个方法seekTo (int msec)。这里指定的参数是毫秒。

开始时间可以指定了,那结束播放的时间如何指定?

MediaPlayer有另外两个方法:getDuration ()和getCurrentPosition (),这两个返回的都是时间信息,前者返回总的播放时间,后者返回当前播放位置的时间。

那返回的结果对于mp3和wav是否会不同呢?会!
对WAV类型,getDuration返回的是音频文件的总时间,getCurrentPosition返回的是从文件起始到现在的播放时间;而对mp3类型,getDuration返回的是startByte和endByte之间播放的时间间隔,getCurrentPosition返回从startByte到现在的播放时间。想一下原因也可以明白,因为MP3是可以精确指定起始位置的,所以所有计算都可以从指定的位置开始,而wav文件一切只能从最开始的位置计算。

Ⅳ 移动端短语音消息音频格式选择

1. 移动端原生音频支持

1.1 android Supported media formats

https://developer.android.com/guide/topics/media/media-formats

Format / File Type(s) / Container Formats

AAC LC••Support for mono/stereo/5.0/5.1 content with standard sampling rates from 8 to 48 kHz.• 3GPP (.3gp)

• MPEG-4 (.mp4, .m4a)

• ADTS raw AAC (.aac, decode in Android 3.1+, encode in Android 4.0+, ADIF not supported)

• MPEG-TS (.ts, not seekable, Android 3.0+)

HE-AACv1 (AAC+)•

(Android 4.1+)



HE-AACv2 (enhanced AAC+)•Support for stereo/5.0/5.1 content with standard sampling rates from 8 to 48 kHz.

AAC ELD (enhanced low delay AAC)•

(Android 4.1+)



(Android 4.1+)

Support for mono/stereo content with standard sampling rates from 16 to 48 kHz

AMR-NB••4.75 to 12.2 kbps sampled @ 8kHz3GPP (.3gp)

AMR-WB••9 rates from 6.60 kbit/s to 23.85 kbit/s sampled @ 16kHz3GPP (.3gp)

FLAC•

(Android 4.1+)



(Android 3.1+)

Mono/Stereo (no multichannel). Sample rates up to 48 kHz (but up to 44.1 kHz is recommended on devices with 44.1 kHz output, as the 48 to 44.1 kHz downsampler does not include a low-pass filter). 16-bit recommended; no dither applied for 24-bit.FLAC (.flac) only

MIDI•MIDI Type 0 and 1. DLS Version 1 and 2. XMF and Mobile XMF. Support for ringtone formats RTTTL/RTX, OTA, and iMelody• Type 0 and 1 (.mid, .xmf, .mxmf)

• RTTTL/RTX (.rtttl, .rtx)

• OTA (.ota)

• iMelody (.imy)

MP3•Mono/Stereo 8-320Kbps constant (CBR) or variable bit-rate (VBR)MP3 (.mp3)

Opus•

(Android 5.0+)

Matroska (.mkv)

PCM/WAVE•

(Android 4.1+)

•8- and 16-bit linear PCM (rates up to limit of hardware). Sampling rates for raw PCM recordings at 8000, 16000 and 44100 Hz.WAVE (.wav)

Vorbis•• Ogg (.ogg)

• Matroska (.mkv, Android 4.0+)

1.2 Supported Audio File and Data Formats in OS X

https://developer.apple.com/library/content/documentation/MusicAudio/Conceptual/CoreAudioOverview/SupportedAudioFormatsMacOSX/SupportedAudioFormatsMacOSX.html

Allowable data formats for each file format.

File FormatData Formats

AAC (.aac, .adts)'aac '

AC3 (.ac3)'ac-3'

AIFC (.aif, .aiff,.aifc)BEI8, BEI16, BEI24, BEI32, BEF32, BEF64, 'ulaw', 'alaw', 'MAC3', 'MAC6', 'ima4' , 'QDMC', 'QDM2', 'Qclp', 'agsm'

AIFF (.aiff)BEI8, BEI16, BEI24, BEI32

Apple Core Audio Format (.caf)'.mp3', 'MAC3', 'MAC6', 'QDM2', 'QDMC', 'Qclp', 'Qclq', 'aac ', 'agsm', 'alac', 'alaw', 'drms', 'dvi ', 'ima4', 'lpc ', BEI8, BEI16, BEI24,BEI32, BEF32, BEF64, LEI16, LEI24, LEI32, LEF32, LEF64, 'ms\x00\x02', 'ms\x00\x11', 'ms\x001', 'ms\x00U', 'ms \x00', 'samr', 'ulaw'

MPEG Layer 3 (.mp3)'.mp3'

MPEG 4 Audio (.mp4)'aac '

MPEG 4 Audio (.m4a)'aac ', alac'

NeXT/Sun Audio (.snd, .au)BEI8, BEI16, BEI24, BEI32, BEF32, BEF64, 'ulaw'

Sound Designer II (.sd2)BEI8, BEI16, BEI24, BEI32

WAVE (.wav)LEUI8, LEI16, LEI24, LEI32, LEF32, LEF64, 'ulaw', 'alaw'

Core Audio includes a number of audio codecs that translate audio data to and from Linear PCM. Codecs for the following audio data type are available in OS X v10.4. Audio applications may install additional encoders and decoders.

Audio data typeEncode from linear PCM?Decode to linear PCM?

MPEG Layer 3 ('.mp3')NoYes

MACE 3:1 ('MAC3')YesYes

MACE 6:1 ('MAC6')YesYes

QDesign Music 2 ('QDM2')YesYes

QDesign ('QDMC')NoYes

Qualcomm PureVoice ('Qclp')YesYes

Qualcomm QCELP ('qclq')NoYes

AAC ('aac ')YesYes

Apple Lossless ('alac')YesYes

Apple GSM 10:1 ('agsm')NoYes

ALaw 2:1 'alaw')YesYes

Apple DRM Audio Decoder ('drms')NoYes

AC-3NoNo

DVI 4:1 ('dvi ')NoYes

Apple IMA 4:1 ('ima4')YesYes

LPC 23:1 ('lpc ')NoYes

Microsoft ADPCMNoYes

DVI ADPCMYesYes

GSM610NoYes

AMR Narrowband ('samr')YesYes

µLaw 2:1 ('ulaw')YesYes

1.3 总结:

android/ios都可以对mp3解码,但不能编码,编码依赖lame;

android/ios支持对aac进行编解码;

mp3,aac均是音乐编码器,android支持对amr窄带与宽带编解码,ios文档显示对窄带支持编解码,但有人说ios4.3.x版本之后不再支持AMR,剔除了AMR的硬解,如需使用依赖libopencore库;

结论:

h5 audio标签对mp3支持最好(audio标签除了firefox与opera都支持mp3,ogg,wav;flash播放器可以支持到mp3,aac,speex,nellymoser),考虑对纯web的兼容性,使用mp3;

android,ios硬件对aac支持最好,考虑硬编码的性能与效率,使用aac;

amr是语音编码器,考虑使用场景,推荐amr.

对比微信,微信短语音,6.0之前用的amr,6.0之后用的silk_v3.

2.音频基础概念

2.1声音三要素

声音的特性可由三个要素来描述,即响度、音调和音色。

响度:人耳对声音强弱的主观感觉称为响度。响度和声波振动的幅度有关。一般说来,声波振动幅度越大则响度也越大。当我们用较大的力量敲鼓时,鼓膜振动的幅度大,发出的声音响;轻轻敲鼓时,鼓膜振动的幅度小,发出的声音弱。音叉振动时发出的声波为单音,即只有一个频率成分。若设法将音叉的振动规律记录下来,可发现其振动波形为一正弦波。当用不同力量敲击某个音叉时,音叉发出的声波幅度不同,这意味着声音的响度不同。给出了两个声音波形,其幅度一大一小,幅度大的波形其声音响度大,幅度小的波形其声音响度小。另外,人们对响度的感觉还和声波的频率有关,同样强度的声波,如果其频率不同,人耳感觉到的响度也不同。

音调:人耳对声音高低的感觉称为音调。音调主要与声波的频率有关。声波的频率高,则音调也高。当我们分别敲击一个小鼓和一个大鼓时,会感觉它们所发出的声音不同。小鼓被敲击后振动频率快,发出的声音比较清脆,即音调较高;而大鼓被敲击后振动频率较慢,发出的声音比较低沉,即音调较低。如果分别敲击一个小音叉和一个大音叉时,同样会感觉到小音叉所发声音的音调较高,大音叉所发声音音调较低。如果设法把大、小音叉所发出的声波记录下来,可发现小音叉在单位时间内振动的次数多,即频率高,大音叉在单位时间内振动的次数少,即频率低。给出了两个频率不同的声音波形,从声音可听出,频率高的声音波形听起来音调较高,而频率低的声音波形听起来则音调较低。

音色:音色是人们区别具有同样响度、同样音调的两个声音之所以不同的特性,或者说是人耳对各种频率、各种强度的声波的综合反应。音色与声波的振动波形有关,或者说与声音的频谱结构有关。前面说过,音叉可产生一个单一频率的声波,其波形为正弦波。但实际上人们在自然界中听到的绝大部分声音都具有非常复杂的波形,这些波形由基波和多种谐波构成。谐波的多少和强弱构成了不同的音色。各种发声物体在发出同一音调声音时,其基波成分相同。但由于谐波的多少不同,并且各次谐波的幅度各异,因而产生了不同的音色。例如当我们听胡琴和扬琴等乐器同奏一个曲子时,虽然它们的音调相同,但我们却能把不同乐器的声音区别开来。这是因为,各种乐器的发音材料和结构不同,它们发出同一个音调的声音时,虽然基波相同,但谐波构成不同,因此产生的波形不同,从而造成音色不同。给出了小提琴和钢琴的波形和声音,这两个声音的响度和音调都是相同的,但听起来却不一样,这就是因为这两个声音的音色不同(波形不同)。

2.2采样率和采样大小

声音其实是一种能量波,因此也有频率和振幅的特征,频率对应于时间轴线,振幅对应于电平轴线。波是无限光滑的,弦线可以看成由无数点组成,由于存储空间是相对有限的,数字编码过程中,必须对弦线的点进行采样。采样的过程就是抽取某点的频率值,很显然,在一秒中内抽取的点越多,获取得频率信息更丰富,**为了复原波形,一次振动中,必须有2个点的采样**,人耳能够感觉到的最高频率为20kHz,因此要满足人耳的听觉要求,则需要至少每秒进行40k次采样,用40kHz表达,这个40kHz就是采样率。我们常见的CD,采样率为44.1kHz。光有频率信息是不够的,我们还必须获得该频率的能量值并量化,用于表示信号强度。量化电平数为2的整数次幂,我们常见的CD位16bit的采样大小,即2的16次方。采样大小相对采样率更难理解,因为要显得抽象点,举个简单例子:假设对一个波进行8次采样,采样点分别对应的能量值分别为A1-A8,但我们只使用2bit的采样大小,结果我们只能保留A1-A8中4个点的值而舍弃另外4个。如果我们进行3bit的采样大小,则刚好记录下8个点的所有信息。采样率和采样大小的值越大,记录的波形更接近原始信号。

2.3有损和无损

根据采样率和采样大小可以得知,相对自然界的信号,音频编码最多只能做到无限接近,至少目前的技术只能这样了,相对自然界的信号,任何数字音频编码方案都是有损的,因为无法完全还原。在计算机应用中,能够达到最高保真水平的就是PCM编码,被广泛用于素材保存及音乐欣赏,CD、DVD以及我们常见的WAV文件中均有应用。因此,PCM约定俗成了无损编码,因为PCM代表了数字音频中最佳的保真水准,并不意味着PCM就能够确保信号绝对保真,PCM也只能做到最大程度的无限接近。我们而习惯性的把MP3列入有损音频编码范畴,是相对PCM编码的。强调编码的相对性的有损和无损,是为了告诉大家,要做到真正的无损是困难的,就像用数字去表达圆周率,不管精度多高,也只是无限接近,而不是真正等于圆周率的值。

2.4频率与采样率的关系

采样率表示了每秒对原始信号采样的次数,我们常见到的音频文件采样率多为44.1KHz,这意味着什么呢?假设我们有2段正弦波信号,分别为20Hz和20KHz,长度均为一秒钟,以对应我们能听到的最低频和最高频,分别对这两段信号进行40KHz的采样,我们可以得到一个什么样的结果呢?结果是:20Hz的信号每次振动被采样了40K/20=2000次,而20K的信号每次振动只有2次采样。显然,在相同的采样率下,记录低频的信息远比高频的详细。这也是为什么有些音响发烧友指责CD有数码声不够真实的原因,CD的44.1KHz采样也无法保证高频信号被较好记录。要较好的记录高频信号,看来需要更高的采样率,于是有些朋友在捕捉CD音轨的时候使用48KHz的采样率,这是不可取的!这其实对音质没有任何好处,对抓轨软件来说,保持和CD提供的44.1KHz一样的采样率才是最佳音质的保证之一,而不是去提高它。较高的采样率只有相对模拟信号的时候才有用,如果被采样的信号是数字的,请不要去尝试提高采样率。

亨利·奈奎斯特(Harry Nyquist)采样定理:当对连续变化的信号波形进行采样时,若采样率fs高于该信号所含最高频率的两倍,那么可以由采样值通过插补技术正确的回复原信号中的波形,否则将会引起频谱混叠(Aliasing),产生混叠噪音(Aliasing Noise),而重叠的部分是不能恢复的.(同样适用于模拟视频信号的采样)

根据人声语音的特点,人类的听力感知范围是从20Hz到20kHz。这个频宽范围被划分成四个频宽类别:窄带、宽带、超宽带和全带。

窄带(narrowband)普通电话所覆盖的频宽,从300Hz到3.4kHz,对应采样率6.8kHz。普通电话的采样率是8kHz,对应频宽4kHz,对于人声语音是足够的。

宽带(wideband)从50Hz到7kH的频宽,对应采样率14khz,可以很好地捕捉和还原人声,然而对于音乐声还是不够的。这是在人声语音通话场景下的所谓高清语音。

超宽带(super-wideband)从50Hz到14kHz,对应采样率28kHz,基本可以覆盖人声和音乐声,对于非专业音乐人的用户来说,不管是人声通话还是音乐直播,这样的频宽都是足够的。

全带(fullband)从20Hz到20kHz,对应40kHz采样率,全面覆盖人类的听觉范围,能够满足音乐发烧友或者专业音乐人的需求。超过40Hz都可以称作全带语音。CD的采样率就是44.1kHz。

因此,窄带(narrowband)的音质是能满足人声录制回放的。

从四个角度衡量音频编码:

成本:开发成本,服务器流量成本

音质:

系统影响:对系统资源的暂用,软编解码器比硬编解码器占用更多cpu

兼容性:对移动端以及web端的兼容

适合产品场景的编码器具备以下四个特点

码率相对低,满足成本可控的要求,一般不要超过16kbps。一个sample用1bit就能编好,那么8kHz采样率(narrowband)对应8kbps的码率,16kHz采样率(wideband)对应16kbps的码率。码率的本质就是成本。

算法复杂度要比较低,对系统CPU、内存和电量消耗少,对系统影响要尽量低。

音质可以适当作出牺牲,以保障上面三个因素,8kHz采样率对人声场景是够用的,16kHz采样率可以提供高清语音。

兼顾兼容性

3.主流音频编码器

音频编码格式的比较: https://zh.wikipedia.org/wiki/%E9%9F%B3%E9%A2%91%E7%BC%96%E7%A0%81%E6%A0%BC%E5%BC%8F%E7%9A%84%E6%AF%94%E8%BE%83

下图列举一组主流的音频编解码器,展示了随着码率变化,音质相应变化的情况。这是基于编解码器听音测试的结果绘画出来的,对选取音频编解码器有参考意义。根据上面的分析并且参照下图,发现码率低于16kbps的低码率人声编解码器(speech codecs)包含:Opus(SILK),Speex,AMR-NB,AMR-WB,和iLBC。

下图是另外一组主流的音频编解码器,展示了随着码率的变化,算法延迟时间相应变化的情况。根据上面的分析并且参照下图,发现算法延迟时间低于60毫秒,码率低于16kbps的人声编解码器(speech codecs)包含:Opus(SILK)、Speex(NB,WB)、G.729、和G.729.1。

从图中我们可以获得如下几方面信息:

对于固定码率的编码标准:如G.711或者G.722,图中采用单点表示,说明这两个编码标准是固定码率编码标准。其他如Opus、Speex,它们的曲线是连续的,说明这类编码标准是可变码率的编码标准。

从频带方面看:G.711、G.722、AMR和iLBC等标准适用于narrowband(8khz采样率)和wideband(16khz采样率)范围,针对普通的语音通话场景。AAC和MP3适用于fullband(48khz采样率)范围,针对特殊的音乐场景。而Opus适用于整个频带,可以进行最大范围的动态调节,适用范围最广。

从标准的收费情况看:适用于互联网传输的iLBC、Speex和Opus都是免费且开源的;适用于音乐场景的MP3和AAC,需要license授权,而且不开源。

综合上面的两个图,我们可以大致总结,比较适合人声短语音的音频编解码器包含Opus(SILK)、Speex(NB,WB)、AMR-NB、AMR-WB、iLBC、G.729、和G.729.1。

码率采样率算法延迟

OPUS(SILK)6-12,7-25,

8-30,12-40kbps

8,12,

16,24kHz

25ms

Speex2.15–24.6 kbps (NB)

4–44.2 kbps (WB)

8, 16,

32, 48kHz

30 ms(NB)

34 ms (WB)

AMR-NB4.75, 5.15, 5.90,

6.70, 7.40, 7.95,

10.20, 12.20 kbps

8kHz25ms (20ms per frame

plus 5ms look-ahead,

20ms for 12.2 kbps)

AMR-WB6.60, 8.85, 12.65,14.25, 15.85, 18.25, 19.85, 23.05, 23.85 kbps16kHz25ms (20ms per frame

plus 5ms look-ahead)

iLBC13.33 kbps

15.20 kbps

8kHz25 ms

40 ms

G.7298kbps8kHz15 ms

G.729.18 kbps,

12–32 kbps

8kHz

16kHz

48.94ms

Codec20.7, 1.2, 1.3, 1.4,

1.6, 2.4, 3.2 kbps

8kHz20–40 ms

(额外增加的,超低码率)

短语音不同于实时语音,可以忽略延迟

上面都是为人声场景设计的低码率音频编解码器,具有码率低(16kbps以下),算法延迟低(大部分在40ms以下),和采样率在8kHz和16kHz之间的特点,都可供短语音编码方案选择。其中,有几个语音编解码器值得在这里稍作介绍:

Opus(SILK)

https://en.wikipedia.org/wiki/Opus_(audio_format)

完全开源而且免费,包含了SILK、CELT、以及两者的混合模式,是目前最为兼容并包的音频编解码器。在处理窄带和宽带人声语音(speech)的时候,采用SILK; 在处理超宽带和全带音乐声音(music)的时候,采用CELT。在人声和音乐声混合的场景中,甚至可以智能切换两个编解码器。WebRTC就采用了Opus作为语音编解码器。而SILK是Skype网络电话所用的语音编解码器。Opus真可谓是久经考验的名门精品。根据即构科技的测试结果,Opus虽然在音乐场景中表现并非首选,但是在人声场景中表现十分出色。

iLBC

完全开源而且免费的,由GIPS开发并被IETF标准化,曾经被QQ和Skype使用过,现在被WebRTC使用,是被世界顶级产品证明过的窄带实时语音编解码器。iLBC能够通过平滑降低语音质量的方式来处理IP网络丢包。由于iLBC的语音帧块之间是相互独立的,在丢帧出现的时候也不会导致错误蔓延,因此具有较强的抗丢包能力。在窄带应用环境中,iLBC具有延迟低,无断续或杂音的特点,通话效果可以和移动电话媲美。

Speex

免费的人声音频编解码器。因为Speex是为VoIP专门设计的,所以Speex对IP网络有很强的抗丢包能力。为了达到这个目的,Speex采用了CELP算法。市场上狼人杀产品的游戏实时语音技术,厂商自研的方案采用了Speex。

Codec2

开源并且专利免费,码率超低的人声语音编解码器。码率在0.7 kbps至3.2 kbps。Codec2填补了开源编码器在5 kbps码率以下的空白。

评估音频编码指标,除码率、采样率、和算法延迟以外,还要参考MOS、VBR/CBR、和基础算法等。其中,MOS (Mean Opinion Score)是语音编解码器的主观评估指标。MOS是一个广为接受的有统计意义的主观听音指标。上面音视频编解码器的列表没有把它包含进去,是因为同一个编解码器,在不同码率下,表现出来的MOS值是会变化的。对一个音频编解码器给出一个固定的MOS值,反而会起误导的作用。另外,虽然MOS值已经是主观的听觉测试评估结果,但是音频工程师在选用音频编解码器的时候,还要以自己亲身的听感作为最终的依据。

下图是Nokia在2011年的时候对Opus、AMR、和G.722.1C等音频编解码器在无噪音和有噪音的环境里做的MOS语音测试的结果。我们可以从语音测试的结果看出:

1)MOS值会随着码率变化。固定的MOS值并没有绝对的参考意义。

2)在低码率情况下,AMR-NB和AMR-WB都表现相对出色。

参考:

1.Getting Started with Audio & Video: https://developer.apple.com/library/content/referencelibrary/GettingStarted/GS_MusicAudio/_index.html

2.Opus ios: https://github.com/chrisballinger/Opus-iOS

3.android opus: https://gitlab.com/axet/android-opus

4.opus_android: https://github.com/louisyonge/opus_android

5.opuscodec: https://github.com/martoreto/opuscodec

6.与大家讨论如何用opencore amr在iOS上decode: https://blog.csdn.net/devday/article/details/6804553

7. ios支持 https://developer.apple.com/library/archive/documentation/MusicAudio/Conceptual/CoreAudioOverview/CoreAudioEssentials/CoreAudioEssentials.html#//apple_ref/doc/uid/TP40003577-CH10-SW13

热点内容
餐饮消毒液如何配置 发布:2025-01-18 19:11:01 浏览:590
入侵php 发布:2025-01-18 19:01:09 浏览:801
存储的下标范围 发布:2025-01-18 19:00:57 浏览:337
文件夹怎么打开 发布:2025-01-18 18:47:07 浏览:296
杉德卡卡号和密码看哪里 发布:2025-01-18 18:43:27 浏览:712
android返回退出 发布:2025-01-18 18:43:26 浏览:601
linux采集视频 发布:2025-01-18 18:38:38 浏览:638
差异度算法 发布:2025-01-18 18:34:27 浏览:698
电脑全套配置有哪些 发布:2025-01-18 18:32:39 浏览:145
新项目源码 发布:2025-01-18 18:14:48 浏览:517