How to get NBest alternatives with azure speech-to-text - azure-speech

I want to get more than one alternative transcription for a single speech utterance using azure speech-to-text.
I have set the format=detailed argument, and the response does include a field called NBest. But that field only every contains one transcription.
Is there something else I need to set on the input side?
Thx.

I am joining the comment to ensure what mechanism you're using:
REST API for short audio or
Speech SDK
If you're using Speech CLI or would like to try it, then do this:
First set:
spx config recognize #default.output --set ##output.all.detailed
then:
spx recognize --file FILE --output all itn text --output all file type json
or
spx recognize --file FILE --output all lexical text --output all file type json

I believe you have defined everything that needs to be defined on the input side.
But with more information about the surrounding context, it would be easier to figure out how to answer precisely. For example, I'm not sure if it behaves the same in ContinuousRecognition mode or in RecognizeOnce mode.
In the following C# code, I do obtain results where NBest array contains 5 Results. Note, however, that in the code sample I found, and which you'll find below integrated with my own, the NBest property is defined as a List. I'm unsure if this, in the framework you're using, could be the source of your NBest object containing a single result.
SpeechConfig _speechConfig = SpeechConfig.FromSubscription(SUBSCRIPTION_KEY, SUBSCRIPTION_REGION);
_speechConfig.SpeechRecognitionLanguage = SPEECH_RECOGNITION_LANGUAGE;
_speechConfig.OutputFormat = OutputFormat.Detailed;
AudioConfig _audioConfig = AudioConfig.FromDefaultMicrophoneInput();
_recognizer = new SpeechRecognizer(_speechConfig, _audioConfig);
_recognizer.Recognized += (s, e) => OnRecognized(e);
private void OnRecognized(SpeechRecognitionEventArgs e)
{
if (e.Result.Reason == ResultReason.RecognizedSpeech)
{
SpeechRecognitionResult result = e.Result;
PropertyCollection propertyCollection = result.Properties;
string jsonResult = propertyCollection.GetProperty(PropertyId.SpeechServiceResponse_JsonResult);
var structuredResult = JsonConvert.DeserializeObject<Result>(jsonResult);
var bestResult = structuredResult?.NBest[0]; // <= pick your favorite NBest
// Do something with the bestResult of your choice
}
}
public class Word
{
public int Duration { get; set; }
public int Offset { get; set; }
public string word { get; set; }
}
public class NBest
{
public double Confidence { get; set; }
public string Display { get; set; }
public string ITN { get; set; }
public string Lexical { get; set; }
public string MaskedITN { get; set; }
public List<Word> Words { get; set; }
}
public class Result
{
public string DisplayText { get; set; }
public int Duration { get; set; }
public string Id { get; set; }
public List<NBest> NBest { get; set; }
public Int64 Offset { get; set; }
public string RecognitionStatus { get; set; }
}

Answer to this question (if using REST API) :
According to a Microsoft document, authored by a MS employee on 1 September 2021, if you are using the REST API, you can only get one alternate:
"The rest API returns only the best result. There has been no change in the behavior of this api for a long while."
See:
https://learn.microsoft.com/en-us/answers/questions/534368/azure-speech-to-text-how-to-receive-nbext-with-res.html
This is unusual because Microsoft's own documentation for the REST API for Short Audio shows a "sample return" containing two (2) alternates.

Related

How to manage DTO Implementaion for Rest-Api in .NET CORE? Alternatives?

I have a quite big query in my WebApi which filters data from different models to send them in a DTO Object to FrontEnd(Angular).
I think DTO could be the right approach because it isn't neccessary for the frontend to get all parameters from all models.
My problem consists in from mapping the DTO Object back to my WebApi Models.
I tried Automapper from NugetPackages but it didn't work. I also heard that AutoMapper isn't the right choice when projects are getting bigger and bigger.
Below is the Code for my DTO object, query and models:
public class ApplicationSettingsDto
{
public string KeyName { get; set; }
public string Wert { get; set; }
public string DefaultValue { get; set; }
public string Description { get; set; }
}
Models:
public partial class ApplicationSettings
{
public string KeyName { get; set; }
public string Wert { get; set; }
public int Typ { get; set; }
public string DisplayOrder { get; set; }
}
public partial class ApplicationSettingsDefaults
{
public Guid Id { get; set; }
public string KeyName { get; set; }
public string Value { get; set; }
public int ProduktOption { get; set; }
}
public partial class Text
{
public string KeyName { get; set; }
public string Sprache { get; set; }
public string Text1 { get; set; }
public DateTime LetzteAenderung { get; set; }
}
Query:
public IQueryable Description()
{
int produktOption = GetProduktOption();
var query = from appl in _repositoryContext.ApplicationSettings
from text in _repositoryContext.Text
from defaults in _repositoryContext.ApplicationSettingsDefaults
//filter DefaultValues
where appl.KeyName.Equals(defaults.KeyName) &&
(defaults.ProduktOption.Equals(produktOption) || defaults.ProduktOption.Equals(65535))
//Filter TextValues
where EF.Functions.Like(text.KeyName, "%" + appl.KeyName) ||
EF.Functions.Like(text.KeyName, "%" + appl.KeyName + "$Descr")
where EF.Functions.Like(text.Sprache, "de-DE")
select new ApplicationSettingsDto()
{
KeyName = appl.KeyName,
Wert = appl.Wert,
DefaultValue = defaults.Value,
Description = text.Text1
}
into output orderby output.KeyName select output;
return query;
}
So this question is not about an detailed implementation, it's only about recommendations for implementing DTO because mapping can be a pain in the *ss, like in my example.
I'm open to new ideas or patterns I don't know yet to try to manage problems like this.
Thanks in Advance ;)
This question is likely to be closed as you have working code, but my recommendation, after years of having tried AutoMapper, reflection based mappings, and hand-written mappings, that you should just stick with what is simplest and works.
You typically have to write the mapping logic for your DTOs once. The code you would write is legible and straightforward. When you move that to AutoMapper, you now end up having an often unrelated and less legible piece of code for something very, very simple.
In the event that you need the mapping logic in another function, extract it to a separate method. In the event that you need it in a separate class, promote that mapping function to a static method on your DTO.
Most of my mapping code looks like:
// Some controller code
da.GetStudents().Select(Map); // Map is the function below
In the controller, the following method is defined:
public StudentDto Map(Student student)
{
if (student == null) return null;
return new StudentDto
{
FirstName = student.FirstName,
...
};
}
Hope that helps.

Are there are any libraries that support user content localization in aspnetcore?

The are plenty of resources describing G11n an L10n in aspnetcore including the official docs.
But are there any libraries that simplify the implementation of a user content localization? An example could be a content of a blog post that may be translated into multiple languages. Such a library would use a specific table in SQL for storing/retrieving translation.
Here is the possible use case:
// this object contains content that user can add manually
public class BlogPost
{
// should be localised
public string Content { get; private set; }
}
It seems like we can add a collection of "string Content" in order to solve this issue:
public class LocalizableContent
{
public string CultureInfo { get; private set; }
public string Content { get; private set; }
}
public class BlogPost
{
public ICollection<LocalizableContent> Content { get; private set; }
}
Note: after making a bit of googling I found a related question (but it gives no answers):
Best Practices to localize entities with EF Code first | StackOverflow
Also, it doesn't seem like this library can help:
github.com/damienbod/AspNetCoreLocalization
Any suggestions?
I think you can implement your content localization library without the need to use third parties. Personaly I do something like below:
public class BlogPost {
public int Id { get; set; }
public ICollection<BloPostLocalized> Localizations { get; set; }
}
Create a localized class for BlogPost:
public class BlogPostLocalized {
public int Id { get; set; }
public BlogPostId { get; set; }
public BlogPost { get; set; }
public string Culture { get; set; }
public string Title { get; set; }
public string Content { get; set; }
}
Notice that the main BloPost has no Title nor Content fields, because we will have them defined in the BlogPostLocalized class for neutral and localized cultures.
So each blog post will have multiple localized versions that can be fetched simply from the db as a child of the main post.

Marten JasperFx - How to ignore property of class when document is generated

Its possible ignore class property when Marten store document on database?
Eg.:
public class Test
{
public int Id { get; set; }
public string Name { get; set; }
[Ignore this when create a document on DB]
public Date DateOfBirth { get; set; }
}
SOLVED
public class Test
{
public int Id { get; set; }
public string Name { get; set; }
[IgnoreDataMember]
public Date DateOfBirth { get; set; }
}
TL:DR
Marten just uses Newtonsoft.Json under the hood, so to ignore property, use Newtonsoft JsonIgnoreAttribute:
public class Account
{
public string FullName { get; set; }
public string EmailAddress { get; set; }
[JsonIgnore]
public string PasswordHash { get; set; }
}
Explanation
This seems to be question visible on top of google search so I'd like to add my 50 cents.
Since MartenDB use internally Newtonsoft.Json then all attributes from this lib should work fine. I don't know about Igor answer, couldn't confirm this anywhere in library so it seems to be outdated at the moment.
From docs:
An absolutely essential ingredient in Marten's persistence strategy is JSON serialization of the document objects. Marten aims to make the JSON serialization extensible and configurable through the native mechanisms in each JSON serialization library. For the purposes of having a smooth "getting started" story, Marten comes out of the box with support for a very basic usage of Newtonsoft.Json as the main JSON serializer.
About Newtonsoft.json in MartenDB
MartenDB isn't tied to Newtonsoft.json, you could always write own adapter for other library.
All you have to do is implement ISerializer interface:
public interface ISerializer
{
void ToJson(object document, TextWriter writer);
string ToJson(object document);
T FromJson<T>(TextReader reader);
object FromJson(Type type, TextReader reader);
string ToCleanJson(object document);
EnumStorage EnumStorage { get; }
Casing Casing { get; }
CollectionStorage CollectionStorage { get; }
NonPublicMembersStorage NonPublicMembersStorage { get; }
}
More detailed example: docs

How to create a LINQ to Entities query including both tag class name and text string

My ASP.NET MVC project has some
chapter class
and related
tag class
They have many to many relationship though one tag has multiple chapter and also one chapter has multiple tags on it.
My question is: I want to make a query by using tag.title within this structure but LINQ doesn't allow objects; it only gets variables like string, int ...etc.
I am feeling a little bit stupid but I can't figured it out this basic thing :( (May be I have to give a break to let it be clear in my mind)
My models are:
public partial class Chapter
{
public string Id { get; set; }
public string Subject { get; set; }
public string Content { get; set; }
public virtual ICollection<Tag> Tags { get; set; }
}
public partial class Tag
{
public int? TagId { get; set; }
public string Title { get; set; }
public int CallCount { get; set; }
public virtual ICollection<Chapter> Chapters { get; set; }
}
and also for db:
public class DataContext : DbContext
{
public DbSet<Chapter> Chapters { get; set; }
public DbSet<Tag> Tags { get; set; }
}
so here we go:
var tag = (from t in db.Tags where t.Title.Contains(search_word)).FirstOrDefault();
var chapters = (from c in db.Chapters where (m.Title.Contains(search_word) || m.Tags.Contains(tag)) select c).ToList();
As I explained above; it gives
"you should use string, guid, int... on queries"
error for this query. I think there is a logical failure I made but my brain stopped responding...
Briefly; I want to search by tag names and if you have another approach I will be pleased to listen it..
Any help will be highly appreciated.
Thanks!
You want:
var tag = (from t in db.Tags
where t.Title.Contains(search_word)
select t).FirstOrDefault();
var chapters = (from c in db.Chapters
where m.Title.Contains(search_word)
|| m.Tags.Any(t => t.TagId == tag.TagId)
select c).ToList();

Saving multiple objects

I have the following classes:
public class Test
{
public int Id { get; set; }
public string Title { get; set; }
public List<TestQuestion> Questions { get; set; }
}
public class TestQuestion
{
public int Id { get; set; }
public int TestId { get; set; }
public string Text { get; set; }
public List<TestQuestionAnswer> Answers { get; set; }
}
public class TestQuestionAnswer
{
public int Id { get; set; }
public int TestQuestionId { get; set; }
public string Text { get; set; }
public bool? IsCorrect { get; set; }
}
I'm having some problems with Save method in TestRepository.
Here's the logic:
If Test.Id > 0 then update Test, otherwise create a new one
If TestQuestion.Id > 0 and TestQuestion.Text = "" delete TestQuestion from database and all Answers for that object
If TestQuestion.Id == 0 then create a new row in database
If TestQuestion.Id > 0 and TestQuestion.Text != "" then update that row
If TestQuestionAnswer.Id > 0 and Text = "" then delete it from database, otherwise call create or update method.
I'm using Entity Framework Code First, but I'm willing to switch to classic ADO.NET if that would make this job much easier.
Any help would be greatly appreciated!
Given the apparent complexity of your update, it would probably make sense to move its logic to a stored procedure, and then map your updates to that stored procedure.
There are two ways you can make this simple and as you said, you would like to switch to classic ADO.NET,
Create a Stored Procedure and place all of these logic in there. This can be done in a single Transction.
Write the ADO.NET coding with related QUERY's.
I personally prefer first option since that will make use of the existing Entity Framework.
Let me know further direction and also may I know the issues while using Save method in TestRepository.