2012-03-01 14 views
20

オーディオファイルから波形を表示するにはJavaScriptプログラムを作成するにはどうすればよいですか? Web AudioとCanvasを使いたいです。Webオーディオをビジュアル化して波形と対話する

私はこのコードを試してみました:

(new window.AudioContext).decodeAudioData(audioFile, function (data) { 
    var channel = data.getChannelData(0); 
    for (var i = 0; i < channel; i++) { 
     canvas.getContext('2d').fillRect(i, 1, 40 - channel[i], 40); 
    } 
}); 

をしかし、結果は、これまで私は(私は長方形で描いてるので、すなわち、画像が滑らかではない)何をしたいからです。波形を実装する方法の

Waveform example

任意のヒント:私は、この画像のように滑らかに見えるようにしたいですか?

+0

多分これは出発点です:http://www.storiesinflight.com/jsfft/visualizer/indexhtml – Mika

+0

@Mika、それは遠方のデモベルを鳴らします。 – katspaugh

+0

これはトピックです:http://softwarerecs.stackexchange.com/ – kenorb

答えて

9

あなたは興味があるかもしれませんAudioJedit。これはオープンソースプロジェクトhosted at GitHubです。これは、オーディオファイルをロードするための小さなサーバー側のnode.jsスクリプトを持っていますが、クライアント側のJavaScriptで実装されたオーディオとのやりとりはすべてあります。私はこれがあなたが探しているものに似ていると思う。

+0

Vadim、それは私が欲しかったものです。波形グラフィックスはSoundCloudからロードされますが、['RealtimeAnalyserNode'](https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification)で追加するのは簡単です。 html#dfn-getByteTimeDomainData)。どうもありがとう! – katspaugh

39

結局のところ自分のライブラリをロールアウトしました。wavesurfer.jsです。

PCMデータから波形を描き、それをクリックしてオーディオの領域を探します。この特定のケースでは(うまくいけば)あなたは私たちがIRCAMで何をしているかをチェックすることをお勧めします簡単な使用、アプリの波形の統合のために

Imgur

+0

ローカルオーディオファイル(サーバー上ではホストされていませんが、私のPCの別のディレクトリで利用可能)の波形をプロットするにはどうすればいいですか?あなたのjsで可能ですか? – madLokesh

+0

@madLokesh、はい、File API(http://dev.w3.org/2006/webapi/FileAPI/)を使ってファイルをプロットできます。 – katspaugh

+0

私はCordovaを使用していますので、ファイルにアクセスするにはCordovaのFile APIを使用する必要がありますが、どのようにオーディオファイルを渡す必要がありますか? base64でエンコードされたUR1または配列バッファ – madLokesh

0

はあなたのコードをレンダリングするすべてのオープンソースだとモジュール(および進行中の作業)を目的とし

それがために44100個のピクセルをレンダリングしますので、非常に非効率的ですオーディオの各秒。好ましくは、縮小されたデータセットで最大でビューポートの幅をレンダリングする必要があります。

波形をビューポートに収めるために必要なピクセル単位のサンプル範囲は、audioDurationSeconds * samplerate/viewPortWidthPxで計算できます。したがって、1000pxのビューポートと44100で2秒のオーディオファイルをサンプリングすると、ピクセルあたりのサンプル数=(2 * 44100)/ 1000 =〜88になります。 画面上の各ピクセルについて、そのサンプル範囲から最小値と最大値を取る場合は、このデータを使用して波形を描画します。

これを行うアルゴリズムの例ですが、仮想スクロールとズームを可能にするスクロール位置と同様に、ピクセルごとのサンプルを引数として与えることができます。あなたが代わりにlineToを使用する必要があり、それを滑らかにするために、そこにdrawメソッドは、あなたに似ている Drawing zoomable audio waveform timeline in Javascript

:それはあなたのパフォーマンスを微調整することができ、解像度パラメータを含んで、これはどのように多く、それが画素サンプル範囲ごとに取るべきサンプルを示していますこの差は実際には巨大ではありません。キャンバスに幅と高さの属性を設定するのを忘れるかもしれないと思います。 cssでこれを設定すると描画がぼやけますので、属性を設定する必要があります。

let drawWaveform = function(canvas, drawData, width, height) { 
    let ctx = canvas.getContext('2d'); 
    let drawHeight = height/2; 

    // clear canvas incase there is already something drawn 
    ctx.clearRect(0, 0, width, height); 

    ctx.beginPath(); 
    ctx.moveTo(0, drawHeight); 
    for(let i = 0; i < width; i++) { 
     // transform data points to pixel height and move to centre 
     let minPixel = drawData[i][0] * drawHeigth + drawHeight; 
     ctx.lineTo(i, minPixel); 
    } 
    ctx.lineTo(width, drawHeight); 
    ctx.moveTo(0, drawHeight); 
    for(let i = 0; i < width; i++) { 
     // transform data points to pixel height and move to centre 
     let maxPixel = drawData[i][1] * drawHeigth + drawHeight; 
     ctx.lineTo(i, maxPixel); 
    } 
    ctx.lineTo(width, drawHeight); 
    ctx.closePath(); 
    ctx.fill(); // can do ctx.stroke() for an outline of the waveform 
} 
関連する問題