Generate and Play PCM Sine Wave Data: Left Channel (261 Hz C + 330 Hz E), Right Channel (392 Hz G + 522 Hz C)
If you want to play PCM data in JavaScript but aren’t sure how to use AudioContext,
this article explains in detail how to generate and play sounds using createBuffer.
Please be careful with the volume when playing the sound.
It’s recommended to start with a low volume and gradually increase it.
Depending on your speakers, high‑frequency tones may not be audible.
Volume:
5
Play Sound Stop Sound
Source Code
<div style="display:flex;"><div>Volume:</div><div id="vol_label">5</div></div>
<input type="range" value="5" max="100" min="1" step="1" id="vol" style="max-width:100%;width:600px;"><br>
<a onclick="" style="cursor:pointer;" class="bt112 bt112r" id="play">Play Sound</a>
<a onclick="" style="cursor:pointer;" class="bt112 bt112b" id="stop">Stop Sound</a>
<br>
<script>
var audioCtx = null, source = null;
var vol = 5; // Volume
var samplingRate = 44100; // 44,100 PCM samples per second
window.addEventListener('DOMContentLoaded', function(){
// Change volume
document.getElementById('vol').addEventListener('input', function(){
document.getElementById('vol_label').innerHTML = document.getElementById('vol').value;
vol = document.getElementById('vol').value;
});
// Play sound
document.getElementById('play').addEventListener('click', function(){
if(audioCtx == null){
audioCtx = new (window.AudioContext || window.webkitAudioContext)();
//audioCtx.sampleRate = samplingRate;
}
// Create an empty 1‑second stereo buffer
var myArrayBuffer = audioCtx.createBuffer(
2, // Number of channels
samplingRate * 1, // 1 second
samplingRate // Sampling rate
);
// Set PCM data for channel 0 (left): combined 261 Hz and 330 Hz
let leftBuffer = myArrayBuffer.getChannelData(0);
for(let i = 0; i < leftBuffer.length; i++){
leftBuffer[i] =
Math.sin(Math.PI * 2 * i / samplingRate * 261) * vol / 100 +
Math.sin(Math.PI * 2 * i / samplingRate * 330) * vol / 100;
}
// Set PCM data for channel 1 (right): combined 392 Hz and 522 Hz
let rightBuffer = myArrayBuffer.getChannelData(1);
for(let i = 0; i < rightBuffer.length; i++){
rightBuffer[i] =
Math.sin(Math.PI * 2 * i / samplingRate * 392) * vol / 100 +
Math.sin(Math.PI * 2 * i / samplingRate * 522) * vol / 100;
}
// Get an AudioBufferSourceNode
source = audioCtx.createBufferSource();
// Assign the buffer to the AudioBufferSourceNode
source.buffer = myArrayBuffer;
// Connect the AudioBufferSourceNode to the output
source.connect(audioCtx.destination);
// Start playing the PCM data
source.start();
});
// Stop sound
document.getElementById('stop').addEventListener('click', function(){
source.stop();
});
});
</script>
