Introduction
Azure AI Speech is a cloud-based service provided by Microsoft as part of its Azure Cognitive services. It enables developers to integrate speech processing capabilities into their applications, services, and devices. The Azure AI Speech service offers various speech capabilities including speech recognition, text-to-speech, speech translation, and speaker recognition.
In this post, we will see all the steps to record audio from microphone using an Angular 16 application as webm format and send it to a .NET 6 Web API. Backend API will convert webm to wav with the help of NAudio library and then using Azure AI Speech service, convert this wav audio file to plain text and return back to Angular app.
Here’s an overview of the key features of Azure AI Speech service:
1. Speech-to-Text (STT)
- Real-Time Speech Recognition: Converts spoken audio into text in real-time. Useful for applications like voice assistants, transcription services, and more.
- Batch Transcription: Allows for the processing of pre-recorded audio files in batch mode.
- Customization: Enables customization of the speech recognition models to better understand domain-specific terminology.
- Different Languages and Dialects: Supports a wide range of languages and dialects.
2. Text-to-Speech (TTS)
- Realistic Voices: Converts text into lifelike spoken audio in various languages.
- Custom Voice: Allows for the creation of a unique voice font for your brand.
- Style Control: Adjusts the speaking style of the voice to suit different scenarios or emotions.
3. Speech Translation
- Real-Time Translation: Supplies real-time translation of spoken language into another spoken language.
- Wide Range of Languages: Supports many languages and dialects.
4. Speaker Recognition
- Speaker Verification: Confirms whether a given piece of audio matches a specific speaker's voice.
- Speaker Identification: Shows who is speaking from a group of known speakers.
- Voice Enrollment: Process of registering a user's voice for later recognition.
5. Speech Analytics
- Sentiment Analysis: Analyzes spoken language to figure out the speaker's sentiment.
- Keyword Spotting: Shows specific words or phrases in spoken language.
Use Cases
- Voice Assistants and Bots: Enhance customer service with voice-enabled assistants.
- Transcription Services: Automatically transcribe audio from meetings, lectures, or interviews.
- Accessibility: Make applications more accessible with voice interfaces.
- Language Learning: Help in language learning with speech recognition and translation.
- Security: Use speaker recognition for biometric authentication.
Azure AI Speech continues to evolve, and Microsoft constantly adds new features and capabilities to improve the service and extend its functionality.
Create an Azure AI Speech in Azure portal
We can choose Azure AI services blade and select Speech service in Azure portal.

Please choose an existing resource group / create a new resource group. We can choose the Free F0 plan for testing purposes. Please note that, per subscription, only one free tier plan is available.

After creating the speech resource, we can go to the Keys and Endpoint tab and get the key. We will be using this key later in our .NET 6 Web API project.

Create .NET 6 Web API with Visual Studio 2022
We can create .NET 6 Web API with Visual Studio 2022.
Please add the NuGet libraries below into the project.
-
Microsoft.CognitiveServices.Speech
-
NAudio
When user gives an audio input from Angular, audio byte array will be passed to .NET Web API. By default, audio will be in webm format. We use NAudio library to convert webm to wav format. Because currently, Microsoft Cognitive Speech recognizes only wav files, not webm format.
We can create a Helper class now.
Helper.cs
using Microsoft.CognitiveServices.Speech.Audio;
using Microsoft.CognitiveServices.Speech;
using NAudio.Wave;
using System.Diagnostics;
namespace SpeechToText.NET6;
public static class Helper
{
private static readonly string subscriptionKey = "342fdfe6715d469f9b64359275fc97df";
private static readonly string serviceRegion = "eastus";
public static async Task<string> ConvertAudioToTextAsync(string audioFilePath, string lang)
{
var config = SpeechConfig.FromSubscription(subscriptionKey, serviceRegion);
var audioConfig = AudioConfig.FromWavFileInput(audioFilePath);
if (lang != null)
{
config.SpeechRecognitionLanguage = lang;
}
try
{
using var recognizer = new SpeechRecognizer(config, audioConfig);
var result = await recognizer.RecognizeOnceAsync();
if (result.Reason == ResultReason.RecognizedSpeech)
{
return result.Text;
}
else if (result.Reason == ResultReason.NoMatch)
{
return "No speech could be recognized.";
}
else if (result.Reason == ResultReason.Canceled)
{
var cancellation = CancellationDetails.FromResult(result);
return $"CANCELED: Reason={cancellation.Reason}";
// Handle cancellation reasons like CancellationReason.Error
}
else
{
return "Recognition failed.";
}
}
catch (Exception ex)
{
return ex.Message;
}
}
public static void ConvertWebmToWav(string webmInput, string wavOutput)
{
string rawOutput = "temp.raw";
// Step 1: Convert webm to raw PCM
var processStartInfo = new ProcessStartInfo
{
FileName = "ffmpeg",
Arguments = $"-i {webmInput} -f s16le -ac 2 -ar 44100 -y {rawOutput}",
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
};
using (var process = Process.Start(processStartInfo))
{
process.WaitForExit();
}
// Step 2: Convert raw PCM to wav using NAudio
var waveFormat = new WaveFormat(44100, 2);
using (var fileStream = File.OpenRead(rawOutput))
using (var reader = new RawSourceWaveStream(fileStream, waveFormat))
using (var writer = new WaveFileWriter(wavOutput, reader.WaveFormat))
{
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = reader.Read(buffer, 0, buffer.Length)) > 0)
{
writer.Write(buffer, 0, bytesRead);
}
}
// Cleanup
try
{
System.IO.File.Delete(rawOutput);
}
catch (Exception ex)
{
Console.WriteLine($"Failed to delete {rawOutput}. Reason: {ex.Message}");
}
}
}
We have added two static methods inside this class. ConvertWebmToWav and ConvertAudioToTextAsync.
Inside ConvertWebmToWav method, we are using NAduio library and ffmpeg.exe file to convert webm file to wav format.
FFmpeg is a powerful and versatile open-source software suitable for handling multimedia files and streams. It supplies a wide range of tools and libraries for converting audio and video formats, processing multimedia content, and streaming. FFmpeg is popular for its high performance, compatibility with many formats, and extensive feature set.
You can download FFmpeg.exe from the site below.
https://www.videohelp.com/software/ffmpeg
Inside ConvertAudioToTextAsync method, audio file path is passed to AudioConfig.FromWavFileInput method and covert audio to a text.
We need an OutputResult model for getting converted audio text and pass to Angular application.
OutputResult.cs
namespace SpeechToText.NET6;
public class OutputResult
{
public string? Result { get; set; }
}
Create an AudioController under the Controllers folder.
AudioController.cs
using Microsoft.AspNetCore.Mvc;
namespace SpeechToText.NET6.Controllers;
[Route("api/[controller]")]
[ApiController]
public class AudioController : ControllerBase
{
private readonly string _audioSavePath = Path.Combine(Directory.GetCurrentDirectory(), "AudioFiles");
[HttpPost("upload")]
public async Task<ActionResult<OutputResult>> Upload([FromQuery] string lang)
{
var audio = Request.Form.Files[0];
if (audio == null || audio.Length == 0)
return BadRequest("No audio file provided.");
var sourcefilePath = Path.Combine(_audioSavePath, audio.FileName);
var destFilePath = Path.Combine(_audioSavePath, "converted-audio" + ".wav");
if (!Directory.Exists(_audioSavePath))
{
Directory.CreateDirectory(_audioSavePath);
}
using (var stream = new FileStream(sourcefilePath, FileMode.Create))
{
audio.CopyTo(stream);
}
Helper.ConvertWebmToWav(sourcefilePath, destFilePath);
string text = await Helper.ConvertAudioToTextAsync(Path.Combine(_audioSavePath, destFilePath), lang);
OutputResult result = new()
{
Result = text
};
return result;
}
}






Dharminder SinghPosted Jun 26, 2024, 6:54 AM
Getting error An error occurred trying to start process 'ffmpeg' with working directory 'E:\Projects\Jr-18_Hub-Shared-API-Repo\Hub.Web.Api'. The system cannot find the file specified.