Pitch volume Detection in Speech Recognition – JavaScript

Web Speech API allows recording human voice and convert it to text or generate an audio file.


This can be used to enable the users to access the website hand free and give commands with voice.

Sometimes, requires to detect the user voice volume.

To do this I am using volume-meter.js library.

It returns pitch volume.

Use this value to draw graphical representation.


1. Download

  • Download volume-meter.js from GitHub and copy it in your project directory.
  • Also, download the jQuery library.

2. HTML

Create index.html file.

Created 2 buttons –

  1. To start voice recognition.
  2. To stop the voice recognition.

Display recording status in the <span id=‘status’> whether it is started or stopped.

Use <div id=‘voiceVolume’> to display the user voice pitch in the horizontal bar.

Display said words in the <textarea id='saidwords'>.

Included volume-meter.js and the jQuery library.

Completed Code

<style type="text/css">
.recorder{ border: 1px solid black; width: 320px; height: 100px; text-align: center; padding-top: 50px;
}
#saidwords{ width: 320px; height: 100px;
}
#volumeBar{ width:200px; height: 10px; border: 1px solid black; position: relative; margin: 0 auto;
}
#voiceVolume{ width: 0px; height: 10px; background: green;
}
</style> <div class='recorder'> <input type="button" id="but_start" value='Start Recording' onclick='startSpeech();'> <input type="button" id="but_stop" value='Stop Recording' onclick='stopSpeech();'> <br><br> <span id='status'>Recording not started.</span> <!-- Volume bar --> <div id='volumeBar'><div id='voiceVolume' ></div> </div> </div> <br>
Said Words -<br>
<textarea id='saidwords'></textarea> <!-- Script -->
<script type='text/javascript' src='jquery.min.js'></script>
<script type='text/javascript' src='volume-meter.js'></script>

3. Script

meter variable is used to create an instance of the volume meter.

Create an object of webkitSpeechRecognition() and to detect voice continuously set recognition.continuous = true.

recognition.onresult is called when service returns a result. Display said words in the <textarea id='saidwords'>.

Start Recording –

When Start Recording button gets clicked then call startSpeech() function from where display “Recording Started.” Message in the <span id=‘status’>, clear the <textarea>, and assign true to recordingStarted.

Call recognition.start() to enable voice detection.

Stop Recording –

When Stop Recording button gets clicked then call stopSpeech() function from where display “Recording Stopped.” Message in the <span id=‘status’>, and assign false to recordingStarted.

Call recognition.stop() to stop the voice detection.

Create voice pitch –

To detect stream define navigator.getuserMedia from where call startUserMedia() function.

In startUserMedia() function create an analyzer and connect the stream source.

Assign createAudioMeter(ctx) to meter and connect with streamNode.

Call drawLoop() function to create pitch volume meter.

Calculate width –

Get the voice pitch volume and set minimum_volume = 130. You can change the value if you want.

If recording started then find the percentage and assign in the width variable.

Update the <div id=‘voiceVolume’ > width.

Completed Code

var meter = null;
var WIDTH = 500;
var recordingStarted = false; // initialize SpeechRecognition object
let recognition = new webkitSpeechRecognition();
recognition.maxAlternatives = 1;
recognition.continuous = true; // Detect the said words
recognition.onresult = e => { var current = event.resultIndex; // Get a transcript of what was said. var transcript = event.results[current][0].transcript; // Add the current transcript with existing said values var noteContent = $('#saidwords').val(); noteContent += ' ' + transcript; $('#saidwords').val(noteContent); } // Stop recording
function stopSpeech(){ // Change status $('#status').text('Recording Stopped.'); recordingStarted = false; // Stop recognition recognition.stop();
} // Start recording
function startSpeech(){ try{ // calling it twice will throw.. $('#status').text('Recording Started.'); $('#saidwords').val(''); recordingStarted = true; // Start recognition recognition.start(); } catch(e){}
} navigator.getUserMedia({audio: true}, startUserMedia, function(e) { __log('No live audio input: ' + e);
}); function startUserMedia(stream) { const ctx = new AudioContext(); const analyser = ctx.createAnalyser(); const streamNode = ctx.createMediaStreamSource(stream); streamNode.connect(analyser); // Create a new volume meter and connect it. meter = createAudioMeter(ctx); streamNode.connect(meter); drawLoop(); } // Create pitch bar
function drawLoop( time ) { var pitchVolume = meter.volume*WIDTH*1.4; var width = 0; // Pitch detection minimum volume var minimum_volume = 130; // Get width if Recording started if(recordingStarted){ if(pitchVolume < minimum_volume){ width = 0; }else if(pitchVolume >= minimum_volume && pitchVolume < (minimum_volume+20) ){ width = 10; }else if(pitchVolume >= (minimum_volume+20) && pitchVolume < (minimum_volume+40)){ width = 20; }else if(pitchVolume >= (minimum_volume+40) && pitchVolume < (minimum_volume+60)){ width = 30; }else if(pitchVolume >= (minimum_volume+60) && pitchVolume < (minimum_volume+80)){ width = 40; }else if(pitchVolume >= (minimum_volume+80) && pitchVolume < (minimum_volume+100)){ width = 50; }else if(pitchVolume >= (minimum_volume+100) && pitchVolume < (minimum_volume+120)){ width = 60; }else if(pitchVolume >= (minimum_volume+120) && pitchVolume < (minimum_volume+140)){ width = 70; }else if(pitchVolume >= (minimum_volume+140) && pitchVolume < (minimum_volume+160)){ width = 80; }else if(pitchVolume >= (minimum_volume+160) && pitchVolume < (minimum_volume+180)){ width = 90; }else if(pitchVolume >= (minimum_volume+180)){ width = 100; } } // Update width document.getElementById('voiceVolume').style.width = width+'%'; rafID = window.requestAnimationFrame( drawLoop );
}

4. Conclusion

I displayed the pitch volume bar horizontally which you also display in vertically just need to update the CSS.

You can adjust the pitch detection value according to your requirement.

Related Posts