首页 > 解决方案 > d3 - 无法绘制圆圈来表示音频剪辑的频率与时间的关系

问题描述

我对 d3 相当陌生,我正在从事一个项目,该项目涉及接收音频剪辑并在图表中绘制频率/音高与时间的关系。我想用圆圈表示数据点。

x 轴是时间,y 轴是给定时间 x 的音高。每个圆的半径将与给定时间 x 的剪辑体积有关。

我的第一个问题是 - 我如何反复提取这个音高数据?我如何找到要绘制的平均/代表性“音高”?据我了解,frequencyBinCount 为您提供了整个频率范围,并为每个频率提供了 0-255 的值。但我只需要“代表”频率。

我的第二个问题是 - 如果我想在播放剪辑时按顺序显示每个点,我将如何做到这一点?我如何每次循环?下面是我的代码 - 我知道可能存在明显的问题,但我刚刚开始使用 d3。基本代码是从此修改的。

伪代码:

1.导入音频分析仪

  1. 开始音频

  2. 每秒循环:- 获取当前正在播放的当前音频的音高和音量(current_time)。
    - 在 height=pitch, x_position = current_time 处绘制圆

  3. 音频结束后,停止绘图

<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>

标签: javascriptd3.jsdata-visualization

解决方案


推荐阅读