I have two methods that record audio every 10 minutes, alternating each method, properly recorded during the first 6 or 7 hours, but then I generates large files to twice normal to hear hear bad but only happens with a method other Normal still recording. I use to record WaveInEnvent since the method is inside a thread, I think problem is in OnDataAvailable.
Here the code used:
wavein = new WaveInEvent();
wavein.Dispose();
wavein.DeviceNumber = 0;
wavein.NumberOfBuffers = 11;
wavein.BufferMilliseconds = 1000;
wavein.WaveFormat = new WaveFormat(8000, 16, 2);
wavein.DataAvailable += OnDataAvailable;
wavein.RecordingStopped += OnRecordingStopped;
writer = new WaveFileWriter(outfilename, wavein.WaveFormat);
bufferedWaveProvider = new BufferedWaveProvider(wavein.WaveFormat);
bufferedWaveProvider.DiscardOnBufferOverflow = true;
wavein.StartRecording();
private void OnDataAvailable(object sender, WaveInEventArgs e)
{
if (this.InvokeRequired)
{
//Debug.WriteLine("Data Available");
this.BeginInvoke(new EventHandler<WaveInEventArgs>(OnDataAvailable), sender, e);
}
else
{
if (writer != null)
{
try
{
for (int i = 0; i < e.BytesRecorded; i += 2)
{
short sample = (short)((e.Buffer[i + 1] << 8) | e.Buffer[i + 0]);
float sample32 = sample / 32768f;
writer.WriteByte(e.Buffer[i + 0]);
writer.WriteByte(e.Buffer[i + 1]);
}
}
catch (Exception ex)
{
// Log error
}
}
}
}
Related
I am creating a Javafx chat app which also allows for file transfer. My issue is I open a FileOutputStream for the received file within the below method. I can see my listener.statusTransferring() updating the UI only if I enable Platform.runLater. I think I now need to enable the same on the fos.write(b, 0, tmpTransferred) within the while loop but don't know how to do this. I have tried unsuccessfully wrapping the whole method within Platform runlater. Note: If I don't use platform runlater I don't get any errors however the UI does not update until the file transfer is complete eg listener.statusCompleted() is called;. The error I get now as a result of the fos being in Platform runlater. is below.. Line 185 is fos.write(b, 0, tmpTransferred); The other listener calls appear to work fine. Just not listener.statusTransferring(); or listener.transferUpdate(); which utilise the fos. Any help will be greatly appreciated. Also for your own sanity I am a self taught google programmer. Yep the worst kind I am sure. Thanks in advance.
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at net.thebowdens.net.FileReceiver.transfer(FileReceiver.java:185)
at net.thebowdens.net.DefaultMessageResponder.fileSend(DefaultMessageResponder.java:543)
public boolean transfer() {
listener.statusConnecting();
received = false;
cancel = false;
try {
if (sSock != null) {
sock = sSock.accept();
listener.statusTransferring();
Platform.runLater(() ->{
try {
fos = new FileOutputStream(file);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
is = sock.getInputStream();
final byte[] b = new byte[1024];
transferred = 0;
percent = 0;
int tmpTransferred = 0;
int tmpPercent = 0;
int transCounter = 0;
bCounter.prepare();
while (!cancel && (tmpTransferred = is.read(b)) != -1) {
fos.write(b, 0, tmpTransferred);
transferred += tmpTransferred;
percent = (int) ((transferred * 100) / size);
bCounter.addBytes(tmpTransferred);
transCounter++;
if (percent > tmpPercent || transCounter >= 250) {
transCounter = 0;
tmpPercent = percent;
listener.transferUpdate();
}
}
if (!cancel && transferred == size) {
received = true;
listener.statusCompleted();
}
else {
listener.statusFailed();
}
}
}
catch (final IOException e) {
LOG.log(Level.SEVERE, e.toString());
listener.statusFailed();
}
finally {
stopReceiver();
cleanupConnections();
}
return received;
}
Keep in mind that you should use Platform.runLater only for updating the UI, everything else should be outside it otherwhise the UI will become unresponsive.
I suggest you to to refactor your code according to this.
Well after much discussion over the correct language and other issues I solved my problem of the UI updating. I had two issues. My choice selector and Filechooser methods were not on the Javafx application thread (hope this is the right terminology) so I had to do the following:
private ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(new Runnable() {
#Override
public void run() {
Platform.runLater(() -> {
try {
receiveRequest(tmpUser, fileRes, user, fileName, size, fileHash);
} catch (IOException | ServerException | CommandException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
}
});
I then had to do the same within the Filechooser and file accept method for the transfer class UI to update
executorService.execute(new Runnable() {
#Override public void run() {
if (fileRes.transfer()) {
ui.showSystemMessage("Successfully received " + fileName +
" from " + user + ", and saved as " + fileRes.getFile().getName());
}
else {
ui.showSystemMessage("Failed to receive " + fileName + " from " + user);
fileRes.cancel();
}
}
});
}
my application is not responding when spamming a number generator button, I do not know what I am doing wrong.
Number is being added at least when bigger than 9999.
private void button17_Click_1(object sender, EventArgs e)
{
byte[] buffer = Guid.NewGuid().ToByteArray();
var FormNumber = BitConverter.ToUInt16(buffer, 0);
int IDNumber = FormNumber;
for (; ; )
{
if (IDNumber > 9999)
{
listBox1.Items.Add(FormNumber);
break;
}
else
{
//repeat
}
}
}
This is an example of the button which causes my whole program to stop responding, when button is being spammed, sometimes even after the first try it just stops,
Im using Visual Studio 2017, Winforms C#
Yeah because IDNumber maybe less than at 9999 at any time, you don't have any handle conditions if IDNumber is less
better do it this way
for (; ; )
{
byte[] buffer = Guid.NewGuid().ToByteArray();
var FormNumber = BitConverter.ToUInt16(buffer, 0);
int IDNumber = FormNumber;
if (IDNumber > 9999)
{
listBox1.Items.Add(FormNumber);
break;
}
else
{
//repeat
}
}
Actually I've added return
private void button17_Click_1(object sender, EventArgs e)
{
byte[] buffer = Guid.NewGuid().ToByteArray();
var FormNumber = BitConverter.ToUInt16(buffer, 0);
int IDNumber = FormNumber;
for (; ; )
{
if (IDNumber > 9999)
{
listBox1.Items.Add(FormNumber);
break;
}
else
{
//repeat
}
return;
}
}
and it works, looks like program wasn't able to exit the loop properly...
I want to create a simple news feed, I use web API to get the news updates, users can use combox select category (world news & sports news),and the news will be auto updated every 5 seconds, if I only select once, the news feed can auto updated and repeat, But if I change the selection, it start to show me both categories. here is my code
public async void NewsRepeat()
{
RootObject2 myNews = await NewsProxy.GetNews();
RootObject3 mySportNews = await sportsNewsProxy.GetSportNews();
if (newsTpye.SelectedIndex==0)
{
for ( k = 0; k <= 8; k++)
{
newsImage.Source = new BitmapImage(new Uri(myNews.articles[k].urlToImage, UriKind.Absolute));
showTime.Text = myNews.articles[k].publishedAt.ToString();
showDescription.Text = "(" + myNews.source + "): " + myNews.articles[k].description;
await Task.Delay(5000);
}
}
else if (newsTpye.SelectedIndex==1)
{
for (k = 0; k <= 8; k++)
{
newsImage.Source = new BitmapImage(new Uri(mySportNews.articles[k].urlToImage, UriKind.Absolute));
showTime.Text = mySportNews.articles[k].publishedAt;
showDescription.Text = "(" + mySportNews.source + "): " + mySportNews.articles[k].description;
await Task.Delay(5000);
}
}
NewsRepeat();
}
private void newsType_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
NewsRepeat();
}
Your code runs continuously / infinite loops. NewsRepeat never finishes - so when you change selection your now running two instances of NewsRepeat side by side. Change it again and you're running three, and so on.
On SelectionChanged you want to somehow stop the previous instance of NewsRepeat from running.
(Also, creating BitmapImages in the ViewModel is a bad idea generally - bind the directly in XAML to the URL property - Windows will carry out some performance and memory enhancements for you)
One possible solution is to use a CancellationTokenSource, which is a very simple object you can use to manually throw OperationCanceledException's when you deem it necessary (
frequently used as a pattern to cancel async Tasks). Keep it mind it does not work automatically - it's something you have to handle.
CancellationTokenSource cts = null;
public async void NewsRepeat()
{
cts?.Cancel();
try
{
var localCts = cts = new CancellationTokenSource();
RootObject2 myNews = await NewsProxy.GetNews();
RootObject3 mySportNews = await sportsNewsProxy.GetSportNews();
localCts.Token.ThrowIfCancellationRequested();
if (newsTpye.SelectedIndex == 0)
{
for (k = 0; k <= 8; k++)
{
newsImage.Source = new BitmapImage(new Uri(myNews.articles[k].urlToImage, UriKind.Absolute));
showTime.Text = myNews.articles[k].publishedAt.ToString();
showDescription.Text = "(" + myNews.source + "): " + myNews.articles[k].description;
await Task.Delay(5000);
localCts.Token.ThrowIfCancellationRequested();
}
}
else if (newsTpye.SelectedIndex == 1)
{
for (k = 0; k <= 8; k++)
{
newsImage.Source = new BitmapImage(new Uri(mySportNews.articles[k].urlToImage, UriKind.Absolute));
showTime.Text = mySportNews.articles[k].publishedAt;
showDescription.Text = "(" + mySportNews.source + "): " + mySportNews.articles[k].description;
await Task.Delay(5000);
localCts.Token.ThrowIfCancellationRequested();
}
}
NewsRepeat();
}
catch (OperationCanceledException)
{
// Swallow this exception only - this is probably
// the one we've thrown ourselves
}
}
private void newsType_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
NewsRepeat();
}
I have a method that adds a label with some text to an existing xaml StackLayout.
The method is called from a couple of places, an event fired by xaml ListView and an NFC tag read. In both scenarios, the method is hit in the code-behind.
The methods both call another method that creates the label and adds it on screen. The one that originates from the ListView event works fine but the one from the NFC tag does nothing. It passes over each row of code without causing an exception but does not add anything to the screen. I can see after this that the child count of the StackLayout is 1 and remains as 1 if you do it again.
The NFC method:
public async void HandleNFC(string convertedtag)
{
int result = 0;
try
{
var mp = (MainPage)App.Current.MainPage;
Label sl1 = mp.CurrentPage.FindByName<Label>("timeLabel");
}
catch (Exception e)
{ }
Label sl = timeLabel;
string time = sl.Text;
PeopleLocationsForUserRoot peoplelocationforuser = await WebDataAccess.GetPeopleLocationForUser(UserInfoRepository.GetUserName(), _locationID);
DateTime dt = Convert.ToDateTime(time);
long timeticks = (long)((dt.ToUniversalTime().Ticks - DatetimeMinTimeTicks) / 10000);
getServerTime();
string name = "";
try
{
foreach (var person in peoplelocationforuser.locationPeople)
{
if (person.TATokenValue == convertedtag)
{
var action = await DisplayActionSheet(person.FirstName + " " + person.LastName, "Cancel", null, "IN", "OUT");
string act = action;
string formattedact = act;
int swipedirection = 0;
name = person.FirstName + " " + person.LastName;
if (act == "IN")
{
formattedact = "in";
swipedirection = 1;
}
if (act == "OUT")
{
formattedact = "out";
swipedirection = 0;
}
if (act != "Cancel")
{
result = SwipeRepository.ClockUserInOut(person.EB_Counter, _locationID, swipedirection, dt, timeticks, 1, UserInfoRepository.GetLatt(), UserInfoRepository.GetLongi());
addToReadout(name, time, formattedact);
}
}
}
if (name == "")
{
await DisplayAlert("Tag Error", "Tag not recognised", "cancel");
}
}
catch (Exception ex)
{
ErrorRepository.InsertError(ex.ToString());
}
await WebDataAccess.SaveSwipesToCloud();
}
The 'addToReadOut' method that it calls:
public void addToReadout(string name, string time, string inout)
{
try
{
Label label1 = new Label { Text = name + " Successfully clocked " + inout + " # " + time, TextColor = Color.Black };
try
{
readOut.Children.Add(label1);
StackLayout sl = this.FindByName<StackLayout>("readOut");
sl.Children.Add(label1);
sl.Focus();
timeLabel.Text = "test";
}
catch (Exception e)
{ }
// StackLayout sl = mp.CurrentPage.FindByName<StackLayout>("readOut");
if (readOut.Children.Count() < 6)
{
readOut.Children.Add(label1);
readOut.Children.Count();
}
else
{
readOut.Children.RemoveAt(0);
readOut.Children.Add(label1);
readOut.Children.Count();
}
}
catch (Exception ex)
{
ErrorRepository.InsertError(ex.ToString());
}
}
You can see that I have also tried to modify the object called 'timelabel' but does also does not change on screen.
The must be something different happening following the NFC event which is causing an issue here but I can't find what's causing it.
You NFC event is firing on a background thread; your UI updates need to happen on the UI thread
Device.BeingInvokeOnMainThread( () => {
// UI Code goes here
});
For my school project i have to make a game where a cannon have to shoot a bullet to a airplane, the problem is, when we shoot we can see all the position (X . Y) of the bullet on console but the bullet doesn't update on the UI
Here's the Test code:
vel = Slider.getValue();
double angle = panelNero.getRotate();
boolean dead = false;
while (dead == false) {
double X = P.getLayoutX();
double Y = P.getLayoutY();
if (X > 1 && Y > 1 && X < MP.getWidth() && Y < MP.getHeight()) {
System.out.println("x: " + X + " y: " + Y + " maxX: " + MP.getWidth() + " maxY: " + MP.getHeight());
double x = P.getLayoutX();
double y = P.getLayoutY();
P.setLayoutX(x += (Math.cos(Math.toRadians(angle)) * vel));
P.setLayoutY(y += (Math.cos(Math.toRadians(angle)) * vel));
System.out.println("VIVO");
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException ex) {
Logger.getLogger(FileFXMLController.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
System.out.println("MORTO");
P.setLayoutX(pro.posX);
P.setLayoutY(pro.posY);
dead = true;
}
}
Please take a look at this post: Platform.runLater and Task in JavaFX
You can use Platform.runlater() to update your GUI from a non-GUI thread. In this case, your update request is put in a queue and handled by the GUI thread ASAP.
But since this is a more complex iteration, you can consider using a Task on a new Thread.
I suggest you to use something like this:
Task task = new Task<Void>() {
#Override
public Void call() throws Exception {
while (dead == false) {
Platform.runLater(new Runnable() {
#Override
public void run() {
P.setLayoutX(...);
P.setLayoutY(...);
}
});
Thread.sleep(500);
}
}
};
Thread th = new Thread(task);
th.start();