通过使用
SoundMixer.computeSpectrum()
方法,应用程序可以读取当前所播放的波形的原始声音数据。如果当前播放多个 SoundChannel 对象,
SoundMixer.computeSpectrum()
方法将显示混合在一起的每个 SoundChannel 对象的组合声音数据。
声音数据的返回方式
声音数据是作为 ByteArray 对象(包含 512 个 4 字节数组)返回的,其中的每个字节表示一个介于 -1 和 1 之间的浮点值。这些值表示所播放的声音波形中的点的波幅。这些值是分为两个组(每组包含 256 个值)提供的,第一个组用于左立体声声道,第二个组用于右立体声声道。
如果将
FFTMode
参数设置为
true
,
SoundMixer.computeSpectrum()
方法将返回频谱数据,而非波形数据。频谱显示按声音频率(从最低频率到最高频率)排列的波幅。可以使用快速傅立叶变换 (FFT) 将波形数据转换为频谱数据。生成的频谱值范围介于 0 和约 1.414(2 的平方根)之间。
下图比较了将
FFTMode
参数设置为
true
和
false
时从
computeSpectrum()
方法返回的数据。此图所用的声音在左声道中包含很大的低音;而在右声道中包含击鼓声。
computeSpectrum()
方法也可以返回已在较低比特率重新采样的数据。通常,这会产生更平滑的波形数据或频率数据,但会以牺牲细节为代价。
stretchFactor
参数控制
computeSpectrum()
方法数据的采样率。如果将
stretchFactor
参数设置为 0(默认值),则以采样率 44.1 kHz 采集声音数据样本。
stretchFactor
参数值每连续增加 1,采样率就减小一半,因此,值 1 指定采样率 22.05 kHz,值 2 指定采样率 11.025 kHz,依此类推。当使用较高的
stretchFactor
值时,
computeSpectrum()
方法仍会为每个立体声声道返回 256 个浮点值。
构建简单的声音可视化程序
以下示例使用
SoundMixer.computeSpectrum()
方法来显示定期绘制动画的声音波形图:
<html>
<title>Sound Spectrum</title>
<script src="AIRAliases.js" />
<script>
const PLOT_WIDTH = 600;
const CHANNEL_LENGTH = 256;
var snd = new air.Sound();
var req = new air.URLRequest("test.mp3");
var bytes = new air.ByteArray();
var divStyles = new Array;
/**
* Initializes the application. It draws 256 DIV elements to the document body,
* and sets up a divStyles array that contains references to the style objects of
* each DIV element. It then calls the playSound() function.
*/
function init()
{
var div;
for (i = 0; i < CHANNEL_LENGTH; i++)
{
div = document.createElement("div");
div.style.height = "1px";
div.style.width = "0px";
div.style.backgroundColor = "blue";
document.body.appendChild(div);
divStyles[i] = div.style;
}
playSound();
}
/**
* Plays a sound, and calls setInterval() to call the setMeter() function
* periodically, to display the sound spectrum data.
*/
function playSound()
{
if (snd.url != null)
{
snd.close();
}
snd.load(req);
var channel = snd.play();
timer = setInterval(setMeter, 100);
snd.addEventListener(air.Event.SOUND_COMPLETE, onPlaybackComplete);
}
/**
* Computes the width of each of the 256 colored DIV tags in the document,
* based on data returned by the call to SoundMixer.computeSpectrum(). The
* first 256 floating point numbers in the byte array represent the data from
* the left channel, and then next 256 floating point numbers represent the
* data from the right channel.
*/
function setMeter()
{
air.SoundMixer.computeSpectrum(bytes, false, 0);
var n;
for (var i = 0; i < CHANNEL_LENGTH; i++)
{
bytes.position = i * 4;
n = Math.abs(bytes.readFloat());
bytes.position = 256*4 + i * 4;
n += Math.abs(bytes.readFloat());
divStyles[i].width = n * PLOT_WIDTH;
}
}
/**
* When the sound is done playing, remove the intermediate process
* started by setInterval().
*/
function onPlaybackComplete(event)
{
clearInterval(interval);
}
</script>
<body onload="init()">
</body>
</html>
此示例首先加载并播放声音文件,然后使用
setInterval()
函数监视
SoundMixer.computeSpectrum()
方法,该方法将声音波形数据存储在
bytes
ByteArray 对象中。
声音波形是通过设置表示条形图的
div
元素的宽度进行绘制的。
|
|
|