Я довольно новичок в d3, и я работаю над проектом, который включает в себя получение аудиоклипа и построение графика зависимости частоты / высоты звука от времени на графике. Я бы хотел представить точки данных кружками.
Ось X будет временем, а ось Y будет шагом в данное время х. Радиус каждого круга будет связан с объемом клипа в данный момент времени x.
Мой первый вопрос - как я могу вытащить эти данные высоты тона? И как мне найти среднюю / репрезентативную «подачу» для сюжета? Из того, что я понимаю, частота BinCount дает вам полный диапазон частот и дает значение от 0 до 255 для каждой частоты. Но мне просто нужна "репрезентативная" частота.
Мой второй вопрос: если бы я хотел отображать каждую точку последовательно во время воспроизведения клипа, как бы я это сделал? Как мне пройти через каждый раз? Ниже приведен мой код - я знаю, что, возможно, есть серьезные проблемы, но я только начинаю с d3. Базовый код был изменен с этого источника .
псевдокод:
1.Импортный аудиоанализатор
Начало аудио
Цикл для каждой секунды:
-Получить высоту и громкость текущего звука, который воспроизводится в данный момент времени (current_time).
-Кружка на высоте = высота тона, x_position = current_time
Когда аудио закончится, остановите рисование
<script>
var audioElement = document.getElementById('audioElement');
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var audioSrc = audioCtx.createMediaElementSource(audioElement);
var analyser = audioCtx.createAnalyser();
audioSrc.connect(analyser);
audioSrc.connect(audioCtx.destination);
var bufferSize = analyser.frequencyBinCount
var frequencyData = new Uint8Array(bufferSize);
analyser.getByteFrequencyData(frequencyData);
var timeDomainData = new Uint8Array(bufferSize);
analyser.getByteTimeDomainData(timeDomainData);
// return average frequency
var total = 0;
for(var i = 0; i < frequencyData.length; i++) {
total += frequencyData[i];
}
var avgfreq = total / frequencyData.length;
// return average amplitude
var total = 0;
for(var i = 0; i < timeDomainData.length; i++) {
total += Math.abs(timeDomainData[i] % 128);
}
var avgtd = total / timeDomainData.length;
var svgHeight = window.innerHeight - 100;
var svgWidth = window.innerWidth-10;
// var colorScale = d3.scaleLinear()
// .domain([0, 150])
// .range(["#2c7bb6","#d7191c"]);
var svg = d3.select('body').append('svg')
.attr('width', svgWidth)
.attr('height', svgHeight);
//how do I loop this while audio is playing so that it sequentially plots points?
var circle = svg.append('circle')
.attr('r', function() { return avgtd+2; })
.attr('cx', function() { return svgWidth/2; })
.attr('cy', function() { return svgHeight - avgfreq; })
.attr('fill', function() { return 'blue'; });
</script>