表題の件について質問です.
以前にqiitaで,このような記事を書かせていただき,https://qiita.com/ukeyshima/items/b1cb4291de9f1a065de5
webGLで音を作成し,webAudioAPIで音を流すプログラムを作成しました.
これはshadertoyなどでも使われている手法です.
しかし,僕のプログラムでは,必ず節目節目にブツッという音が入ってしまい,ずっと放置していた状態です.
正直音について詳しくなく,音の記述の方がおかしいのか,プログラムがおかしいのかがわかっていません.おそらく,setIntervalなどの問題だと思っていいて,https://www.html5rocks.com/ja/tutorials/audio/scheduling/
の記事などを参考にしようとは思っているのですが,イマイチピンとこずコードに起こせない状態です.
プログラムの構造などはqiitaの記事をみていただけるとわかると思います.もしどなたか同じようなコードを書いた方がいらっしゃれば解決策をご教授いただけると幸いです.よろしくお願いいたします.
javascript
1 2window.addEventListener("load", function () { 3 const c = document.createElement("canvas"); 4 let cw = window.innerWidth; 5 let ch = window.innerHeight; 6 c.width = cw; c.height = ch; 7 const gl = c.getContext("webgl2") || c.getContext("webgl") || c.getContext("experimental-webgl"); 8 const prg = create_program(create_shader("vs"), create_shader("fs")); 9 const uniLocation=new Array(); 10 uniLocation[0]=gl.getUniformLocation(prg,"iTime"); 11 let audioContext = new (window.AudioContext || window.webkitAudioContext)(); 12 let source = audioContext.createBufferSource(); 13 let sampleNum = 44100; 14 let time=0; 15 16 const play=()=>{ 17 gl.uniform1f(uniLocation[0],time); 18 const vTransformFeedback = gl.createBuffer(); 19 const transformFeedback = gl.createTransformFeedback(); 20 gl.bindBuffer(gl.ARRAY_BUFFER, vTransformFeedback); 21 gl.bufferData(gl.ARRAY_BUFFER, sampleNum * Float32Array.BYTES_PER_ELEMENT, gl.DYNAMIC_COPY); 22 gl.bindBuffer(gl.ARRAY_BUFFER, null); 23 gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedback); 24 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, vTransformFeedback); 25 gl.beginTransformFeedback(gl.POINTS); 26 gl.drawArrays(gl.POINTS, 0, sampleNum); 27 gl.endTransformFeedback(); 28 let arrBuffer = new Float32Array(sampleNum); 29 gl.getBufferSubData(gl.TRANSFORM_FEEDBACK_BUFFER, 0, arrBuffer); 30 console.log(arrBuffer); 31 let audioBuffer = audioContext.createBuffer(2, sampleNum, sampleNum); 32 for (let i = 0; i < 2; i++) { 33 let bufferring = audioBuffer.getChannelData(i); 34 bufferring.set(arrBuffer); 35 } 36 let source = audioContext.createBufferSource(); 37 source.buffer = audioBuffer; 38 source.connect(audioContext.destination); 39 //source.loop = true; 40 source.start(); 41 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null); 42 time++; 43 44 } 45 setInterval(play,1000); 46 47 48 function create_shader(id) { 49 let shader; 50 const scriptElement = document.getElementById(id); 51 if (!scriptElement) { return; } 52 switch (scriptElement.type) { 53 case "vertexShader.glsl": 54 shader = gl.createShader(gl.VERTEX_SHADER); 55 break; 56 case "fragmentShader.glsl": 57 shader = gl.createShader(gl.FRAGMENT_SHADER); 58 break; 59 default: 60 return; 61 } 62 gl.shaderSource(shader, scriptElement.text); 63 gl.compileShader(shader); 64 if (gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { 65 return shader; 66 } else { 67 alert(gl.getShaderInfoLog(shader)); 68 console.log(gl.getShaderInfoLog(shader)); 69 } 70 } 71 function create_program(vs, fs) { 72 const program = gl.createProgram(); 73 gl.attachShader(program, vs); 74 gl.attachShader(program, fs); 75 gl.transformFeedbackVaryings(program, ["sound"], gl.SEPARATE_ATTRIBS); 76 gl.linkProgram(program); 77 if (gl.getProgramParameter(program, gl.LINK_STATUS)) { 78 gl.useProgram(program); 79 return program; 80 } else { 81 return null; 82 } 83 } 84});
html
1<!DOCTYPE html> 2<html> 3<head> 4 <script src="main.js"></script> 5 <script id="vs" type="vertexShader.glsl">#version 300 es 6 precision highp float; 7 uniform float iTime; 8 out float sound; 9 void main(void){ 10 float time=float(gl_VertexID)/44100.0+iTime; 11 sound=sin(6.2831*440.0*time); 12 }</script> 13 <script id="fs" type="fragmentShader.glsl">#version 300 es 14 void main(void){}</script> 15</head> 16<body> 17 <canvas id="canvas"></canvas> 18</body> 19 20</html>
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/04/12 14:05
2018/04/13 16:02