Jas*_*ske 9 javascript audio jquery html5
我正在开发一个动画徽标,将由零到十一的频谱分析仪显示出来.我正在寻找可以在各种浏览器上运行的东西,所以将它连接到HTML5音频元素可能不是一个选项,因为我发现只能在最新的WebKit和Firefox上工作的唯一库版本.到目前为止,我一直在玩一个间隔生成一个随机值.这是我目前陷入困境的一个例子(使用jQuery的animate函数()):
<div id='Logo'>
<div id='channelA' class='channel'></div>
<div id='channelB' class='channel'></div>
<div id='channelC' class='channel'></div>
<div id='channelD' class='channel'></div>
<div id='channelE' class='channel'></div>
<div id='channelF' class='channel'></div>
<div id='channelG' class='channel'></div>
</div>
<script>
setInterval(function () {
$('.channel').each(function () {
$(this).animate({
height: (Math.round(Math.random() * 185)) + 'px'
});
});
}, 100);
</script>
<style>
#Logo {
width: 245px;
height: 245px;
background: red;
}
div.channel {
float: left;
z-index: 9;
background: white;
}
#channelA {
width: 35px;
height: 45px;
}
#channelB {
width: 35px;
height: 85px;
}
#channelC {
width: 35px;
height: 85px;
}
#channelD {
width: 35px;
height: 50px;
}
#channelE {
width: 35px;
height: 150px;
}
#channelF {
width: 35px;
height: 30px;
}
#channelG {
width: 35px;
height: 85px;
}
</style>
Run Code Online (Sandbox Code Playgroud)
这看起来并不"正确".是否有能够生成"感觉"更像音频信号的数据的功能?我也对这个问题的其他方法感兴趣(也许我只需要在支持HTML5音频的浏览器中捕获频谱分析仪数据,然后在旧浏览器中"回放".)
这是我想要的样子的一个例子:

在JavaScript中搜索Bézier曲线的一些实现后,我开始混合生成的单曲来制作一些东西.虽然我未完成的工作,如果这给了其他人任何想法,这是一个演示.
小智 8
使频谱看起来真实(关键是否是虚拟数据)的关键是为频段提供回退机制.
仅当新值高于当前值时才设置波段.如果不是,则将当前值减小一个值(线性或对数).后退的速度也会影响感知.
由于频谱分析仪中的数据不代表实际波形,而是FFT(快速傅立叶变换)或每个频带的值,因此它可以与随机数据一起正常工作.你当然不会得到音乐的"节奏"指纹,但由于有后退,它在某种程度上仍然看起来很逼真(好像有人想听听噪音:-)).
以下是一个例子 -

演示:http:
//jsfiddle.net/AbdiasSoftware/VXxwt/
最初的HTML,一个简单的div:
<div id="logo"></div>
Run Code Online (Sandbox Code Playgroud)
初始CSS:
.band {
background-color: #3897e0;
border-radius:3px 3px 0 0;
}
Run Code Online (Sandbox Code Playgroud)
并且主要要求创建一个虚拟频谱:
makeSpectrum('logo', 300, 120, 7);
Run Code Online (Sandbox Code Playgroud)
完整代码:
/**
* Turn an element into a virtual spectrum,
* Ken Fyrstenberg Nilsen, Public domain.
*
* USAGE:
* makeSpectrum(id, width, height)
* makeSpectrum(id, width, height, bands)
* makeSpectrum(id, width, height, bands, volume)
*
* id id of the element to be converted into spectrum
* width width in pixels of spectrum
* height height in pixels of spectrum
* bands (optional) number of "bands"
* volume initial volume (0-1)
*
* METHODS:
*
* setVolume() returns current volume
* setVolume(vol) sets new volume (0-1 float)
*/
function makeSpectrum(id, width, height, bands, volume) {
bands = bands ? bands : 12;
volume = volume ? volume : 1;
if (bands < 1) bands = 1;
if (bands > 128) bands = 128;
// init parent element
var parent = document.getElementById(id),
bandElements = [];
if (typeof parent === 'undefined')
alert('Element ' +id + ' not found!');
parent.style.display = 'block';
parent.style.width = width + 'px';
parent.style.height = height + 'px';
parent.style.position = 'relative';
var bandValues = [],
oldBandValues = [],
bw = (((width)/ bands) |0),
me = this;
function calcBand(bandNum) {
var bv = bandValues[bandNum],
obv = oldBandValues[bandNum];
if (bv >= obv) obv = bv;
obv -= 0.1;
if (obv < 0 ) obv = 0;
obv *= volume;
oldBandValues[bandNum] = obv;
return obv;
}
function getFFT(band) {
band = band ? band : bandValues;
for(var i = 0; i < bands; i++) {
band[i] = Math.random();
}
}
function createBands() {
var i, html = '';
for(i = 0; i < bands; i++) {
h = 0
html += '<div id="' + id + '_band' + i + '" ';
html += 'style="display:block;position:absolute;';
html += 'left:' + ((i * bw + 1)|0);
html += 'px;top:' + ((height - height * h)|0);
html += 'px;width:' + (bw - 2);
html += 'px;height:' + ((height * h)|0);
html += 'px;" class="band"></div>';
}
parent.innerHTML = html;
for(i = 0; i < bands; i++) {
var el = document.getElementById(id + '_band' + i);
bandElements.push(el);
}
}
this.setVolume = function(vol) {
if (arguments.length === 0)
return volume;
if (vol < 0) vol = 0;
if (vol > 1) vol = 1;
volume = vol;
}
this.setVolume(volume);
this.createSnapshot = function() {
var h, y, el;
getFFT(bandValues);
for(var i = 0; i < bands; i++) {
h = calcBand(i);
el = bandElements[i].style;
el.top = ((height - height * h)|0) + 'px';
el.height = ((height * h)|0) + 'px';
}
parent.innerHTML = html;
}
//init bands
getFFT(oldBandValues);
createBands();
//GO
setInterval(me.createSnapshot, 100);
return this;
}
var sp = makeSpectrum('logo', 250, 100, null, 0);
var vol = 0;
function fadeIn() {
vol += 0.02;
sp.setVolume(vol);
if (vol < 1) setTimeout(fadeIn, 60);
}
fadeIn();
Run Code Online (Sandbox Code Playgroud)
代码没有优化,所以它在CPU上运行有点饿.它主要是为乐队生成html的方式.我会更喜欢做哪会工作更加高效canvas元素,但由于需要的浏览器支持多种我离开这个:-)
更新:
优化了循环设置高度和缓存元素的顶部.它还有一个方法setVolume()可以用来设置循环等的整体"音量".
使用淡入和新代码更新了示例(顶部的链接).
更新2:
在较低频率中添加了更多真实感,并通过基于内部时钟模拟BPM.我现在让时间影响三个第一个波段(如果波段数允许):
var d = (new Date()).getMilliseconds() % 10; //get milliseonds of second
band[0] = band[0] * 0.2 + (d / 10) * 0.8; //affect 1. band 80% + 20% random
band[1] = band[1] * 0.3 + (d / 10) * 0.7; //affect 2. band 70% + 30% random
band[2] = band[2] * 0.5 + (d / 10) * 0.5; //affect 3. band 50% + 50% random
Run Code Online (Sandbox Code Playgroud)
这可能是微妙的,但只是为了增加一点现实主义.
这里的样式版本具有静音功能:http:
//jsfiddle.net/AbdiasSoftware/hVkPN/
