all. Thanks for the time any help is appreciated.
Here is my issue: I have written some code in "Windows Form VC++" that would take a text file perform a speech-To-Text on the file, using a flip of a Text-To-Speech algorithm. After the text is vocalized using MS "Speak" function it is then supposed to write to a textBox some header information and what was said. After that a count variable is updated and then another function is called that would synthesize another voice from a different direction.
The problem is that the first voice is synthesized correctly and at the right time, however before the header info and spoken words can be written into the textBox the second function is called and once it ends it fills the textBox with its information only. No information from the first is ever written into the textBox.
What could be causing this?? I tried delaying the call to the second function in several different ways with no success. I could sure use as much help as is out there. I both code snippets in this questions. Thank you in advance and I hope for assistance really really quick. Thanks again.
First code with call to second:
for(ClickCount_ATCText = 0; ClickCount_ATCText < FilesSelected_ATC_A; ClickCount_ATCText++)
{
SetChannelVolumeLevel(ATC_OverLord);
PlaySound(TEXT("c:\\SSL_Sound\\AC_AudioBackground.wav"), NULL, SND_FILENAME);
//GetWavFilePath(ATC_OverLord);
//if(ClickCount_ATCText > (FilesSelected_ATC_A - 1))
//{
//ClickCount_ATCText = 0;
//}// End DataLink if statement
SpeechSynthesizer^ Vocalize = gcnew SpeechSynthesizer(); //Create a voice synthesizer instance.
string TTS_TxtPath = ATC_TxtFiles[ClickCount_ATCText]; //The following two lines converts the standard string in to a system string for use in the StreamReader function.
String^ TTS_FilePath = gcnew String(TTS_TxtPath.c_str());
StreamReader^ FileRead = gcnew StreamReader(TTS_FilePath); //Get the text file from the path identified.
String^ AutoTTSFileRead = FileRead->ReadToEnd(); //Read the entire file and store the text characters in the string variable "AutoTTSFileRead".
Vocalize->Speak(AutoTTSFileRead); //Vocalize the text in the textbox.
//Sleep(3000); //Pause half a second before displaying the text. Not needed, but kept for reference.
//* The 6 lines code below provides a timestamp and formats the output of the data link message.
TextToSpeechTextbox->Text = " Data Link Message \r\n \r\n";
time(&WhatTimeIsIt);
String^ strNew = gcnew String(ctime(&WhatTimeIsIt));
TextToSpeechTextbox->Text = TextToSpeechTextbox->Text + "Timestamp: " + strNew + "\r\n";
TextToSpeechTextbox->Text = TextToSpeechTextbox->Text + "\r\n";
TextToSpeechTextbox->Text = TextToSpeechTextbox->Text + "Message: " + AutoTTSFileRead + "\r\n"; //Display the speech data in the text box.
ClickCount_ATCText++;
NE_STT_SLL_Function();
}//End for loop
**NE_STT_SLL_Function:**
void NE_STT_SLL_Function()
{
//Sleep(3000);
SetChannelVolumeLevel(North_East); //Set the volume level for this SSL and zero the rest.
PlaySound(TEXT("c:\\SSL_Sound\\AC_AudioBackground.wav"), NULL, SND_FILENAME); //Play a snippet of radio noise in the background before sythesizing
if(ClickCount_NorthEastText >= (FilesSelected_NE - 1))
{
ClickCount_NorthEastText = 0;
}// End DataLink if statement
SpeechSynthesizer^ Vocalize = gcnew SpeechSynthesizer(); //Create a voice synthesizer instance.
string TTS_TxtPath = NorthEast_TxtFiles[ClickCount_NorthEastText]; //The following two lines converts the standard string in to a system string for use in the StreamReader function.
String^ TTS_FilePath = gcnew String(TTS_TxtPath.c_str());
StreamReader^ FileRead = gcnew StreamReader(TTS_FilePath); //Get the text file from the path identified.
String^ AutoTTSFileRead = FileRead->ReadToEnd(); //Read the entire file and store the text characters in the string variable "AutoTTSFileRead".
Vocalize->Speak(AutoTTSFileRead); //Vocalize the text in the textbox.
//* The 6 lines code below provides a timestamp and formats the output of the data link message.
TextToSpeechTextbox->Text = " (NE) Sound Source Location Message \r\n \r\n";
time(&WhatTimeIsIt);
String^ strNew = gcnew String(ctime(&WhatTimeIsIt));
TextToSpeechTextbox->Text = TextToSpeechTextbox->Text + "Timestamp: " + strNew + "\r\n";
TextToSpeechTextbox->Text = TextToSpeechTextbox->Text + "\r\n";
TextToSpeechTextbox->Text = TextToSpeechTextbox->Text + "Message: " + AutoTTSFileRead + "\r\n"; //Display the speech data in the text box.
ClickCount_NorthEastText++; //Increment array index value.
return;
}//End NE STT SSL function
A windows Forms application is based on a message loop. If the messagge loop has no time to execute, then nothing will be displayed or refreshed. If you change a text in a for-loop, only the last one will be displayed. Also be aware, that the Text2Speach is normally asynchonus. So the function returns even if the text was not spoken. So please use the finished event to process with your actions... (SpeechSynthesizer::SpeakCompleted)
Also you should never use Sleep or other tight loops in a windows UI application. Please consider to use a timer (Windows::Forms::Timer) or consider to use event-based processing!
Related
I've been gathering information using api calls from my jira. Information gathered is saved in a body file and it has the following content:
No tickets:
{"startAt":0,"maxResults":50,"total":0,"issues":[]}{"startAt":0,"maxResults":50,"total":0,"issues":[]}
One Ticket:
{"expand":"names,schema","startAt":0,"maxResults":50,"total":1,"issues":[{"expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields","id":"456881","self":"https://myjira...com","key":"TICKET-1111","fields":{"summary":"[TICKET] New Test jira","created":"2018-12-17T01:47:09.000-0800"}}]}{"expand":"names,schema","startAt":0,"maxResults":50,"total":1,"issues":[{"expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields","id":"456881","self":"https://myjira...com","key":"TICKET-1111","fields":{"summary":"[TICKET] New Test jira","created":"2018-12-17T01:47:09.000-0800"}}]}
Two Tickets:
{expand:schema,names,startAt:0,maxResults:50,total:2,issues:[{expand:operations,versionedRepresentations,editmeta,changelog,renderedFields,id:456881,self:https://myjira...com,key:TICKET-1111,fields:{summary:[TICKET] New Test jira,created:2018-12-17T01:47:09.000-0800}},{expand:operations,versionedRepresentations,editmeta,changelog,renderedFields,id:320281,self:https://myjira...com,key:TICKET-2222,fields:{summary:[TICKET] Test jira,created:2016-03-18T07:58:52.000-0700}}]}{expand:schema,names,startAt:0,maxResults:50,total:2,issues:[{expand:operations,versionedRepresentations,editmeta,changelog,renderedFields,id:456881,self:https://myjira...com,key:TICKET-1111,fields:{summary:[TICKET] New Test jira,created:2018-12-17T01:47:09.000-0800}},{expand:operations,versionedRepresentations,editmeta,changelog,renderedFields,id:320281,self:https://myjira...com,key:TICKET-2222,fields:{summary:[TICKET] Test jira,created:2016-03-18T07:58:52.000-0700}}]}
etc..
Using this code I've been able to gather total open tickets:
std::ifstream t("BodyOpenIssues.out");
std::string BodyString((std::istreambuf_iterator<char>(t)),
std::istreambuf_iterator<char>());
// Removing Quotes
BodyString.erase(std::remove(BodyString.begin(), BodyString.end(), '"'), BodyString.end());
int Result = 0;
unsigned first = BodyString.find("total:");
unsigned last = BodyString.find(",issues");
std::string TotalOpenIssues = BodyString.substr(first + 6, last - (first + 6));
Result = std::stoi(TotalOpenIssues);
return Result;
Using a second function I'm trying to get the keys based on total open tickets.
if (GetOpenIssuesNumber() > 0)
{
std::ifstream t("BodyOpenIssues.out");
std::string BodyString((std::istreambuf_iterator<char>(t)),
std::istreambuf_iterator<char>());
// Removing Quotes
BodyString.erase(std::remove(BodyString.begin(), BodyString.end(), '"'), BodyString.end());
unsigned first = BodyString.find("key:TICKET-");
unsigned last = BodyString.find(",fields");
std::string TotalOpenIssues = BodyString.substr(first + 11, last - (first + 11));
String^ Result = gcnew String(TotalOpenIssues.c_str());
return "TICKET-" + Result;
}
else
{
return "No open issues found";
}
What I mean is:
If Total is 1 to search from the beginning and find the first key TICKET-1111.
If Total is 2 to search from the beginning and get the first key TICKET-1111 then to continue from there and to find the next key TICKET-2222.
And based on that total to find that many keys in that string.
I got lost from all the casting between the types as ifstream reads the file and I save the result in std::string. After the find I save the result in System::String to use it in my Label.. I've been researching and found out that I can use char array but I can't make it dynamic based on BodyString.length().
If more information is required please let me know.
Any suggestions are really appreciated! Thank you in advance!
I went for nlohmann json library. It has everything I need. Thank you Walnut!
These are formatted as JSON. You should use a JSON library for C++ and parse the files with that. Using search/replace is unnecessary complicated and you will likely run into corner cases you haven't considered sooner or later (do you really want the code to randomly miss tickets, etc.?). Also String^ is not C++. Are you writing C++/CLI instead of C++? If so, please tag c++-cli instead of c++. – walnut
I want to write a string to file, n number of times (n being the length of the string). With each insertion being on a new line.
For example, the string "antallabel" (with a length of 10), should be inserted into a file 10 times, with each insertion on its own line. Should I use an array, list or something else?
I'm really new to programming, so I hope this question makes sense.
Check if file exists, then generate 2 files:
if (File.Exists(fullPath)) {
File.Delete(fullPath);
File.WriteAllText(fullPath, totalv + ";" + laste + ";" + antallabels);
File.Create(filePath + #"\" + controlFile).Close();
}
else
{
File.WriteAllText(fullPath, totalv + ";" + laste);
File.Create(filePath + #"\" + controlFile).Close();
I do not think you need this code at all. The WriteAllText(...) function is explained here.
Creates a new file, write the contents to the file, and then closes the file. If the target file already exists, it is overwritten.
So if it not exist it will be created and if it exists it will be deleted and recreated with your content. Please consider also adding the programming language as tag.
for(int i = 0; i < inputVar.length; i++) {
//do sth. as many times as the string is long
File.AppendAllText(path, inputVar + System.Environment.NewLine);
}
I use AppDesigner inMATLAB to show photos with changed RGB. But there is the problem with character of the photo.
When I switch on my own fuction "changeRGB", finally "choosenImage" has 20bytes, class "char" and size(1x10). OK!
There is no problem in using the "function OpenButtonValueChanged". OK!
There is the problem with "function UploadButtonPushed". OK!
ABOUT THE PROBLEM:
When I click button which callback is "function UploadButtonPushed" I get the error:
"Error using imread>parse_inputs (line 502)
The file name or URL argument must be a character
vector or string scalar."
"Error in imread (line 342)
[source, fmt_s, extraArgs, was_cached_fmt_used] =
parse_inputs(cached_fmt, varargin{:});"
WHY?
Because in the "function UploadButtonPushed" my choosenImage has 1977624bytes, class "uint8" and size(681x968x3). So it's too bug for "imread".
WHAT I TRIED:
When in "function OpenButtonValueChanged" I convert a photo, adding "char": (myimage = char(app.clickedImage)); the class of the photo is changing from uint8 to char but the size.
When I use "num2cell", the claas of the photo is changing on "cell" but size and number of bytes are the same- so big. And I get the Error: "Error using imread>parse_inputs (line 502) The file name or URL argument must be a character vector or string scalar."
In my own function "changeRGB" I used "imread(image)" and here is the problem with the size of the photo. Do you know how to get the correct one?
%my own properties in AppDesigner- to use them in different functions
properties (Access = public)
clickedImage;
addR = 1;
addG = 1;
addB = 1;
end
%first function in AppDeesigner
function OpenButtonValueChanged(app, event)
value = app.OpenButton.Value;
[file, howManyFiles] = chooseImagesFromComputer; %myown function
%I load 3 images which are showed as miniatures
myFile1 = imread(file{1});
imshow(myFile1, 'Parent', app.UIAxes1_1);
myFile2 = imread(file{2});
imshow(myFile2, 'Parent', app.UIAxes1_2);
myFile3 = imread(file{3});
imshow(myFile3, 'Parent', app.UIAxes1_3);
%take values of changed RGB from the slider
app.addR = app.SliderR.Value
app.addG = app.SliderG.Value
app.addB = app.SliderB.Value
%work only on one image to change its colors. app.clickedImage, app.addR, app.addG, app.addB are properties at the beginning of the code
app.clickedImage = file{1};
app.clickedImage = changeRGB(app.clickedImage,app.addR,app.addG,app.addB); %changeRGB- my own function- here is the problem. I add it bottom
imshow(app.clickedImage,'Parent',app.UIAxesMain);
end
%second function in AppDesigner
%here is the button to upload color of the photo
function UploadButtonPushed(app, event)
myimage = app.clickedImage;
myimage = changeRGB(myimage,app.addR,app.addG,app.addB);
imshow(myimage);
end
%here is my own function in matlab, not in AppDesigner, which makes problem:
function [changedImage] = changeRGB(choosenImage, addR, addG, addB)
whos
loadedImage = imread(choosenImage);
R = loadedImage(:,:,1); %extract one of the color channels
G = loadedImage(:,:,2);
B = loadedImage(:,:,3);
RBG = cat(3,R,G,B);
R_adj2 = R + addR;
G_adj2 = G + addG;
B_adj2 = B + addB;
changedImage = cat(3,R_adj2,G_adj2,B_adj2);
end
First, you make unnecessary operations in changeRGB
function [changedImage] = changeRGB(choosenImage, addR, addG, addB)
loadedImage = imread(choosenImage);
loadedImage = bsxfun(#sum, loadedImage, reshape([addR, addG, addB], [1 1 3]);
end
Then this function return an array (the modified image) so in UploadButtonPushed(app, event) when you run myimage = app.clickedImage;, you are passing the modified array instead of the image path, that you set here app.clickedImage = changeRGB(app.clickedImage,app.addR,app.addG,app.addB);
So you have to change the design of your variables, because app.clickedImage is saving either the image path, or the image itself. Consider having 2 different variables.
A good advice also is to use matlab debugger which is really good help to find the source of this kind of problems.
So, I have a text file where the information are separated by the enter key (I don't know how to explain, I will paste the code and some stuff).
cha-cha
Fruzsina
Ede
salsa
Szilvia
Imre
Here's how the text file looks like, and I need to split it into three parts, the first being the type of the dance, and then dancer 1 and dancer 2.
using System;
using System.Collections.Generic;
using System.IO;
namespace tanciskola
{
struct tanc
{
public string tancnev;
public string tancos1;
public string tancos2;
}
class Program
{
static void Main(string[] args)
{
#region 1.feladat
StreamReader sr = new StreamReader("tancrend.txt");
tanc[] tanc = new tanc[140];
string[] elv;
int i = 0;
while (sr.Peek() != 0)
{
elv = sr.ReadLine().Split('I don't know what goes here');
tanc[i].tancnev = elv[0];
tanc[i].tancos1 = elv[1];
tanc[i].tancos2 = elv[2];
i++;
}
#endregion
Console.ReadKey();
}
}
}
Here is how I tried to solve it, although I don't really get how I should do it. The task is would be to display the first dance and the last dance, but for that I need to split it somehow.
As mentioned in my comments, you seem to have a text file where each item is on a new line, and a set of 3 lines constitutes a single 'record'. In that case, you can simply read all the lines of the file, and then create your records, like so:
var v = File.ReadLines("file path");
tancr[] tanc = new tancr[140];
for (int i = 0; i < v.Count(); i += 3)
{
tanc[i/3].tancnev= v.ElementAt(i);
tanc[i/3].tancos1 = v.ElementAt(i + 1);
tanc[i/3].tancos2 = v.ElementAt(i + 2);
}
Note: ReadLines() is better when the file size is large. If your file is small, you could use ReadAllLines() instead.
To split by the "enter character" you can use Environment.NewLine in .NET:
https://msdn.microsoft.com/en-us/library/system.environment.newline(v=vs.110).aspx
elv = sr.ReadAllText().Split(new string[] {Environment.NewLine}, StringSplitOptions.None);
This constant will contain the sequence that is specific to your OS (I'm guessing Windows).
You should be aware that the characters used for newlines is different for Windows vs. Linux/Unix. So in the rare event that someone edits your file on a different OS, you can run into problems.
On Windows, newline is a two character sequence: carriage-return + line-feed (ASCII 13 + 10). On Linux it is just line-feed. So if you wanted to be extra clever, you could first check for CRLF and if you only get one element back from Split() then try just LF.
I can send attachments that have non-ascii filenames in JavaMail but I am not able to download them. I am getting java.io.FileNotFoundException specifically for those attachments whose file names contain non-ascii characters.
FYI: I am using something like messageBodyPart.setFileName(MimeUtility.encodeText(filename[i])) to encode the text and MimeUtility.decodeText(bodyPart.getFileName()) to decode the non-ascii file names
Is there a workaround for this?
EDIT
#Bill, here is part of my code that reads attachments. I have also added the properties.setProperty("mail.mime.decodeparameters", "true") and properties.setProperty("mail.mime.decodefilename", "true") properties in my code.
if (message[a].getContent() instanceof MimeMultipart) {
Multipart multipart = (Multipart) message[a].getContent();
for (int i = 0; i < multipart.getCount(); i++) {
bodyPart = multipart.getBodyPart(i);
disposition = bodyPart.getDisposition();
if (disposition != null && (disposition.equals(BodyPart.ATTACHMENT) || (disposition.equals(BodyPart.INLINE)))) {
DataHandler handler = bodyPart.getDataHandler();
String path = bodyPart.getFileName();
String[] str = path.split("/");
String fileName = str[str.length - 1];
String filePath = ReadConfigPropertiesFile.getPropertyValue("server.buildpath");
System.out.println(fileName);
File tempDir = new File(filePath + user);
if (!tempDir.exists()) {
tempDir.mkdir();
}
File saveFile = new File(tempDir + "/" + fileName);
int count = 0;
while (saveFile.exists()) {
count++;
saveFile = new File(tempDir + "/" + count + "_" + fileName);
}
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(saveFile));
byte[] buff = new byte[2048];
InputStream is = bodyPart.getInputStream();
int ret = 0;
while ((ret = is.read(buff)) > 0) {
bos.write(buff, 0, ret);
}
bos.close();
is.close();
//System.out.println(bodyPart.getContentType());
}else {
//display body (message) of the attachment;
//System.out.println(bodyPart.getContent().toString());
}
}
}
The above code raises the FileNotFoundException exception at BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(saveFile)) line and this is getting raised for the attachments whose file names are non-ascii characters (something like ሰላም.pdf). Every thing else works fine.
This answer taken from comment of #semytech (OP). It was hard to find it there, so I will add it as answer for more visibility. It helped me with hebrew filenames.
MimeBodyPart attachment = new MimeBodyPart();
attachment.setFileName(MimeUtility.encodeText(filename, "UTF-8", null));
You should never need to do the encoding or decoding yourself.
There are two sets of properties you can set to tell JavaMail to do the encoding/decoding for you:
mail.mime.encodefilename/mail.mime.decodefilename
mail.mime.encodeparameters/mail.mime.decodeparameters
See the javadocs for the javax.mail.internet package for details.
The first set uses a non-standard encoding technique, similar to what you're doing yourself. This works fine with some older mailers that use this technique.
The second set uses a MIME standard encoding technique. This version works with most modern mailers.
None of this explains why you're getting FileNotFoundException, but then you didn't provide enough detail to know what you're doing when you get the exception.