Azure Cognitive Servislerin Speech Servisi İle Speech-To-Text Yapmak

Speech Servisi basitçe insan konuşması ile ilgilenmektedir. Speech To Text, Text-To-Speech gibi hizmetleri bulunmaktadır. Kullanması oldukça kolay olan servisler hem Speech Sdkları ile hem de Rest Api’si üzerinden kullanılabilmektedir.

Öncelikle Speech To Text’ten başlayalım ve istediğimiz mikrofon üzerinden aldığımız çıktıları paylaşalım.

Öncelikle .Net için ilgili SDK’yı indirmemiz gerekmektedir. Nuget üzerinden:

Install-Package Microsoft.CognitiveServices.Speech

Ardından Azure üzerinden Speech Service kaynağı oluşturup kullanmaya başlayabilirsiniz. Speech servisi oluşturduğunuzu varsayarak yazıya devam ediyorum.

Öncelikle oluşturduğunuz Subscription’ı SDK’mızda initiliaze etmemiz gerekmektedir:

var speechConfig = SpeechConfig.FromSubscription("your key1 or key2", "resourcelocation");

Ardından kullanmaya başlayabiliriz. Örnek olarak:

using var audioConfig = AudioConfig.FromMicrophoneInput("micropoheneid"); using var recognizer = new SpeechRecognizer(speechConfig, "tr-TR", audioConfig); while(true)
{
var result = await recognizer.RecognizeOnceAsync(); Console.Out.WriteLineAsync($"Offset={result.OffsetInTicks} Text={result.Text}"); }

Evet yukarıdaki konsol aplikasyonunun çıktısı aşağıdaki gibi olacaktır:

Yukarıdaki gibi kodlarda her bir konuşma bloğu için bir Sonuç oluşturmakta. Şöyle ki her sonuç oluşturduğunda bir boşluk yaşanmakta ve bu aradaki boşluğu dinleyememekte. Belirtilen dinleyememe durumunu çözmek için RecognizeConitinous metodunu kullanmamız gerekmektedir. Şöyle ki:

SynchronizedCollection<string> utterences = new SynchronizedCollection<string>(); await recognizer.StartContinuousRecognitionAsync(); 
recognizer.Recognized += (s, e) => { string resultAsText = e.Result.Text;
if (!isRecognitionCancelled)
{
utterences.Add(resultAsText); } Console.Out.WriteLineAsync($"Offset={e.Result.OffsetInTicks}
Text={e.Result.Text}");
if(resultAsText.ToLower().Contains("dikteyi kapat"))
{
recognizer.StopContinuousRecognitionAsync(); } };

Gördüğünüz gibi artık eventleri dinlemekteyiz. Herhangi bir dinleme boşluğu bulunmamakta, oluşan konuşma sonuçları sürekli olarak utterences collectionımıza eklenmekte. Evet belirtilen şekilde çok uzun süren bir konuşmayı dahi text’e çevirebiliriz.

Tam koda aşağıdaki linkten ulaşabilirsiniz.:

https://gist.github.com/anilkay/0f0dce5cd9b7237ab8983bed21b87be5

Evet şimdiye kadar hep mikrofondan okuduk ama gerçek hayatta mikrofondan çok hali hazırda kayıtlı olan dosyalardan birtakım sonuçlar çıkarmamız istenecektir. Bu gibi durum gibi durumlar için Wav dosyasından sentez yapma olasılığınızı kullanabiliriz. Elimizde büyük ihtimal mp3 formatında dosyalar olacaktır, Mp3 dosyalarını waw’a çevirmek için öncelikle ffmpeg ile aşağıdaki komutu kullanmamız gerekmektedir:

ffmpeg -i deneme.mp3 -acodec pcm_u8 -ar 22050 deneme.wav

Ardından ilgili dosyayı aynı mikrofondan dinlermiş gibi aynı kod ile kullanabilirsiniz:

using var audioConfig = AudioConfig.FromWavFileInput("path/to/deneme.wav");

Ardından yine aynı şekilde Continious ile okumakta ve çıktısını basabilmekteyiz:

Evet dosyadan okumayı da anlattığımıza göre sırada okunanları yazma kısmı var.

Okunanları dosyaya direkt olarak satır satır yazmaya tercihine gittim ben. Siz offsetleri ile beraber de yazabilirsiniz. Şöyleki SynchronizedCollection isimli sınıfı kullanıyorum ve sonrasında direkt olarak collectiondaki elemanları sırasıyla yazdırıyorum:

SynchronizedCollection<string> utterences = new SynchronizedCollection<string>(); recognizer.SessionStopped += (s, e) => 
{
Console.WriteLine("Dinleme Sonlandı.");
Random random = new Random(); if (utterences.Count > 0)
{
File.WriteAllLinesAsync("transcript" + random.Next(0, 1000) + ".txt", utterences); utterences.Clear(); } };

Not: RecognizeOnce’lı olan fonksiyonda herhangi bir Concurrency Safe Veri yapısı kullanmanız gerekmemektedir.

Okuduğunuz için teşekkürler :)

Originally published at http://anilkaynr.wordpress.com on October 24, 2021.

Computer Engineer,Sociologist, CSE Master Student