WAVE TYPE (波形)

ピー音を再生する

まめちしき

虫除けアプリがうたう周波数:

蚊が嫌がる周波数 16KHz~18KHz、もしくは6000Hz~9000Hz

ネズミよけ 25kHz

若者にしか聞こえないモスキート音 17kHz~19kHz

※「虫よけには超音波が効く」という科学的根拠はない

view source

JavaScript

document.title = 'ピー音ノイズを再生する';

(function() {
    var fontColor = 'rgba(0, 0, 0, 1)';
    var waveColor = 'rgba(0, 0, 255, 0.8)';
    var gridColor = 'rgba(0, 0, 0, 0.1)';
    var font = '12px "Times New Roman"';
    var onDOMContentLoaded = function() {
 
        window.AudioContext = window.AudioContext || window.webkitAudioContext;
 
        try {
            // Create the instance of AudioContext
            var context = new AudioContext();
        } catch (error) {
            window.alert(error.message + ' : chrome.');
            return;
        }
 
        // Create the instance of OscillatorNode
        var oscillator = context.createOscillator();
 
        // Parameters for the instance of OscillatorNode
        var type      = oscillator.type;
        var frequency = oscillator.frequency.value;
        var detune    = oscillator.detune.value;
 
        // for legacy browsers
        context.createGain = context.createGain || context.createGainNode;
 
        // Create the instance of GainNode
        var gain = context.createGain();
 
        // Flag for starting or stopping sound
        var isStop = true;
 
        // for drawing sound wave
 
        // Create the instance of AnalyserNode
        var analyser = context.createAnalyser();
 
        var canvas = document.querySelector('canvas');
        var ctx = canvas.getContext('2d');
 
        var timerid  = null;
        var interval = document.getElementById('range-draw-interval').valueAsNumber;
 
        var drawWave = function() {
            var width  = canvas.width;
            var height = canvas.height;
 
            var paddingTop    = 20;
            var paddingBottom = 20;
            var paddingLeft   = 30;
            var paddingRight  = 30;
 
            var innerWidth  = width  - paddingLeft - paddingRight;
            var innerHeight = height - paddingTop  - paddingBottom;
            var innerBottom = height - paddingBottom;
 
            var middle = (innerHeight / 2) + paddingTop;
 
            // Sampling period
            var period = 1 / context.sampleRate;
 
            // This value is the number of samples during 5 msec
            var n5msec = Math.floor(5 * Math.pow(10, -3) * context.sampleRate);
 
            // Get data for drawing sound wave
            var times = new Uint8Array(analyser.fftSize);
            analyser.getByteTimeDomainData(times);
 
            // Clear previous data
            ctx.clearRect(0, 0, width, height);
 
            // Draw sound wave
            ctx.beginPath();
 
            for (var i = 0, len = times.length; i < len; i++) {
                var x = Math.floor((i / len) * innerWidth) + paddingLeft;
                var y = Math.floor((1 - (times[i] / 255)) * innerHeight) + paddingTop;
 
                if (i === 0) {
                    ctx.moveTo(x, y);
                } else {
                    ctx.lineTo(x, y);
                }
 
                // 5 msec ?
                if ((i % n5msec) === 0) {
                    var sec  = i * period;             // index -> time
                    var msec = sec * Math.pow(10, 3);  // sec -> msec
                    var text = Math.round(msec);// + ' msec';
                    // Draw grid (X)
                    ctx.fillStyle = gridColor;
                    ctx.fillRect(x, paddingTop, 1, innerHeight);
 
                    // Draw text (X)
                    ctx.fillStyle = fontColor;
                    ctx.font      = font;
                    ctx.fillText(text, (x - (ctx.measureText(text).width / 2)), (height - 3));
                }
            }
            var text = ' msec';
            ctx.fillText(text, (x), (height - 3));
            
 
            ctx.strokeStyle = waveColor;
            ctx.lineWidth   = 2;
            ctx.lineCap     = 'round';
            ctx.lineJoin    = 'miter';
            ctx.stroke();
 
            // Draw grid (Y)
            ctx.fillStyle = gridColor;
            ctx.fillRect(paddingLeft, paddingTop,  innerWidth, 1);
            ctx.fillRect(paddingLeft, middle,      innerWidth, 1);
            ctx.fillRect(paddingLeft, innerBottom, innerWidth, 1);
 
            // Draw text (Y)
            ctx.fillStyle = fontColor;
            ctx.font      = font;
            ctx.fillText(' 1.00', 3, paddingTop);
            ctx.fillText(' 0.00', 3, middle);
            ctx.fillText('-1.00', 3, innerBottom);
 
            timerid = window.setTimeout(drawWave, interval);
        };
 
        /*
         * Event Listener
         */
 
        // Start or Stop sound
        document.querySelector('button').addEventListener(EventWrapper.CLICK, function() {
            if (isStop) {
                // Create the instance of OscillatorNode
                oscillator = context.createOscillator();
 
                // for legacy browsers
                oscillator.start = oscillator.start || oscillator.noteOn;
                oscillator.stop  = oscillator.stop  || oscillator.noteOff;
 
                // OscillatorNode (Input) -> GainNode (Volume) -> AnalyserNode (Visualization) -> AudioDestinationNode (Output)
                oscillator.connect(gain)
                gain.connect(analyser);
                analyser.connect(context.destination);
 
                // Set parameters
                oscillator.type            = type;
                oscillator.frequency.value = frequency;
                oscillator.detune.value    = detune;
 
                // Start sound
                oscillator.start(0);
 
                // Start drawing sound wave
                drawWave();
 
                isStop = false;
                this.innerHTML = '■';
            } else {
                // Stop sound
                oscillator.stop(0);
 
                // Stop drawing sound wave
                if (timerid !== null) {
                    window.clearTimeout(timerid);
                    timerid = null;
                }
 
                isStop = true;
                this.innerHTML = '▶';
            }
        }, false);
 
        // Control Draw Interval
        document.getElementById('range-draw-interval').addEventListener('input', function() {
            interval = this.valueAsNumber;
            document.getElementById('output-draw-interval').textContent = this.value;
        }, false);
 
        // Control Volume
        document.getElementById('range-volume').addEventListener('input', function() {
            var min = gain.gain.minValue || 0;
            var max = gain.gain.maxValue || 1;
 
            if ((this.valueAsNumber >= min) && (this.valueAsNumber <= max)) {
                gain.gain.value = this.valueAsNumber;
                document.getElementById('output-volume').textContent = this.value;
            }
        }, false);
 
        // Select type
        document.getElementById('form-wave-type').addEventListener('change', function() {
            for (var i = 0, len = this.elements['radio-wave-type'].length; i < len; i++) {
                if (this.elements['radio-wave-type'][i].checked) {
                    oscillator.type = type = (typeof oscillator.type === 'string') ? this.elements['radio-wave-type'][i].value : i;
                    break;
                }
            }
        }, false);
 
        // Control frequency
        document.getElementById('range-frequency').addEventListener('input', function() {
            var min = oscillator.frequency.minValue || 0;
            var max = oscillator.frequency.maxValue || 100000;
 
            if ((this.valueAsNumber >= min) && (this.valueAsNumber <= max)) {
                oscillator.frequency.value = frequency = this.valueAsNumber;
                document.getElementById('output-frequency').textContent = this.value;
            }
        }, false);
 
        // Control detune
        document.getElementById('range-detune').addEventListener('input', function() {
            var min = oscillator.detune.minValue || -4800;
            var max = oscillator.detune.maxValue ||  4800;
 
            if ((this.valueAsNumber >= min) && (this.valueAsNumber <= max)) {
                oscillator.detune.value = detune = this.valueAsNumber;
                document.getElementById('output-detune').textContent = this.value;
            }
        }, false);
    };
 
    if ((document.readyState === 'interactive') || (document.readyState === 'complete')) {
        onDOMContentLoaded();
    } else {
        document.addEventListener('DOMContentLoaded', onDOMContentLoaded, true);
    }
 
})();






function EventWrapper(){
}
 
(function(){
    var click = '';
    var start = '';
    var move  = '';
    var end   = '';
 
    // Touch Panel ?
    if (/iPhone|iPad|iPod|Android/.test(navigator.userAgent)) {
        click = 'click';
        start = 'touchstart';
        move  = 'touchmove';
        end   = 'touchend';
    } else {
        click = 'click';
        start = 'mousedown';
        move  = 'mousemove';
        end   = 'mouseup';
    }
 
    EventWrapper.CLICK = click;
    EventWrapper.START = start;
    EventWrapper.MOVE  = move;
    EventWrapper.END   = end;
})();


//https://weblike-curtaincall.ssl-lolipop.jp/portfolio-web-sounder/webaudioapi-basic/demos/demo-16

CSS

#demo{
  display: grid;
  place-items: center;
}

canvas{
  display:block;
  margin:0 auto;
}
[name="form-wave-type"] label{
  display:block;
  height:32px;
  line-height:32px;
}

input[type="range"]{
  width:98%;
}

button{
  width:100%;
  min-width:80px;
  height:4em;
}

HTML

ページのソースを表示 : Ctrl+U , DevTools : F12

view-source:https://hi0a.com/demo/-js/js-audio-sign-wave-noize/

ABOUT

hi0a.com 「ひまアプリ」は無料で遊べるミニゲームや便利ツールを公開しています。

プログラミング言語の動作デモやWEBデザイン、ソースコード、フロントエンド等の開発者のための技術を公開しています。

必要な機能の関数をコピペ利用したり勉強に活用できます。

プログラムの動作サンプル結果は画面上部に出力表示されています。

環境:最新のブラウザ GoogleChrome / Windows / Android / iPhone 等の端末で動作確認しています。

画像素材や音素材は半分自作でフリー素材配布サイトも利用しています。LINK参照。

動く便利なものが好きなだけで技術自体に興味はないのでコードは汚いです。

途中放置や実験状態、仕様変更、API廃止等で動かないページもあります。