870920 Menu

JUCE音频之基—其他重要的底层核心

在对音频数据进行读写和处理时,还有一个底层环节非常重要:对不同音频格式的采样数据进行转换。通常,程序员无需动用这些底层的“低级类”。但是,如果把JUCE作为第三方库添加到已有的音视频项目中,或对第三方音视频库进行改写,或将第三方音视频库嵌入JUCE项目中,这些类的作用就至关重要,不可或缺。

实现这一功能依赖于下面几个类模板和嵌套类。

AudioData::Pointer <S, E, I, C>

AudioData::Pointer<S, E, I, C> 是AudioData类的嵌套类模板,该类相当于一个指针,指向特定编码格式的音频数据块,可读写该数据块中的音频采样。除此之外,还可将A格式的音频采样转换为B格式。本类需4个模板参数。这些模板参数的数据类型均是AudioData类的嵌套类,依次为:
 SampleFormat 本类所指向数据的采样格式
 Endianness 采样数据所使用的字节顺序,
 InterleavingType 通道之间是否采用交错类型
 Constness 本指针是否可操作常量数据

模板参数(AudioData的嵌套类)详解:

模板1参“采样格式”。AudioData中嵌套定义了JUCE音频的所有采样格式(即:编码方式),每个采样格式均为一个类。有如下6个嵌套类:
 AudioData::Uint8 无符号8位整型
 AudioData::Int8 有符号8位整型
 AudioData::Int16 有符号16位整型
 AudioData::Int24 有符号24位整型
 AudioData::Int32 有符号32位整型
 AudioData::Float32 32位浮点格式

模板2参“字节顺序”:有如下3个嵌套类:
 AudioData::BigEndian 大字节顺序
 AudioData::LittleEndian 小字节顺序
 AudioData::NativeEndian 本机CPU字节顺序

模板3参“交错类型”:有如下两个嵌套类:
 AudioData::NonInterleaved 无交错,采样字节连续存储
 AudioData::Interleaved 通道之间采用交错采样格式

模板4参“可否操作常量”:有如下两个嵌套类:
 AudioData::NonConst 表明AudioData::Pointer不可操作常量数据
 AudioData::Const 表明AudioData::Pointer可操作常量数据

以上嵌套类,无需也不能单独使用,它们专用于AudioData::Pointer的模板参数。即:仅供创建Pointer类对象时所用。这些嵌套类(包括Pointer)的类定义位于:
juce/modules/juce_audio_basics/buffers/juce_AudioDataConverters.h头文件中。

AudioData::Pointer的构造函数有两个版本,均为从适当格式的原始数据中创建本类对象(实为一种特殊的“指针”)。单参构造所创建的是无交错格式(此时模板3参必须指定为AudioData::NonInterleaved),双参构造所创建的是交错格式,此时构造2参需指定使用交错格式的通道数量:
 AudioData::Pointer (原始数据)
 AudioData::Pointer (原始数据, 交错通道的数量)

实例化AudioData::Pointer对象的示例代码(注意,下面的代码是一条语句。即:pointer对象的声明):

本类对象读写音频采样数据的示例代码:

AudioData::Pointer 类的静态函数:
 isFloatingPoint () 如果使用了浮点采样格式, 则返回true
 isBigEndian () 如果采样格式为Big-Endian, 则返回true
 getBytesPerSample () 返回每个采样的字节数, 忽略交错通道
 get32BitResolution () 使用32位整型格式时,返回此格式的精度

成员函数:
 拷构和“=”运算符
 getAsFloat () 将当前所指向的采样返回为浮点值
 setAsFloat () 将当前所指向的采样设置为浮点值
 getAsInt32 () 将当前所指向的采样返回为32位整型
 setAsInt32 () 将当前所指向的采样设置为32位整型
 operator++ () 本指针移动到下一个采样处
 operator– () 本指针移动到上一个采样处
 operator+= () 本指针移动到下n个采样处
 convertSamples () 复制并转换给出的采样数据
 clearSamples () 将一批采样值置零
 getNumInterleavedChannels () 返回此格式中交错通道的数量
 getNumBytesBetweenSamples () 返回每个采样之间的字节数,忽略交错通道
 getRawData () 返回本对象所持有的指向原始数据的指针

AudioData::Pointer所位于的juce_AudioDataConverters.h头文件中,还定义了另外两个重要的嵌套类,这两个类有继承关系:抽象基类为AudioData::Converter,用于转换两个不同格式的采样。其派生类为类模板AudioData::ConverterInstance <S, D>,两个模板参数代表要转换的采样的原格式与目标格式,即:将模板1参的采样格式转换为模板2参的采样格式。这两个模板参数的数据类型为AudioData::Pointer。也就是说:AudioData::ConverterInstance的模板参数为AudioData::Pointer类模板的模板参数实例化之后的具体类型。

AudioData::ConverterInstance <S, D> 的构造函数为:
AudioData::ConverterInstance (来源通道的数量, 目标通道的数量)
该类只有两个成员函数,而且是重载的同名函数,用于转换一个采样序列:
 convertSamples (目标数组, 来源数组, 要转换的采样数)
 convertSamples (目标数组, 目标通道, 来源数组, 来源通道, 要转换的采样数)