Soundeffect not playing in background - windows-phone-8

I have an application that allows the user to take photos and save to isolated storage for upload to a server.
I am trying to play a shutter sound when the user clicks the software capture button provided. All documentation I can find indicates that soundeffect.play is asynchronous so the sound should keep playing in the background while logic continues, however in my case the sound either only partially plays or does not have time to play unless I put a breakpoint just after play() or add a Thread.Sleep(x) just after the call to play().
private void BtnCaptureClick(object Sender, RoutedEventArgs E)
{
if (_PhotoCamera != null)
{
PlayShutter();
_FileName = Guid.NewGuid().ToString(); //A breakpoint here will allow sound to play
_PhotoCamera.CaptureImage();
}
}
private void PlayShutter()
{
var Info = App.GetResourceStream(new Uri("Assets/camera.wav", UriKind.Relative));
try
{
_Effect = SoundEffect.FromStream((Info.Stream));
FrameworkDispatcher.Update();
using (_Effect)
{
if (_Effect.Play())
{
//Thread.Sleep(1000); //uncommenting this will allow sound to play if duration < 1000
}
}
}
catch (Exception Ex)
{
MessageBox.Show(Ex.Message);
}
}
I have tried using a soundeffectinstance explicitly, however behaviour does not change.
I have tried explicitly calling Play() asynchronously, no change in behaviour.
I have tried calling the following code asynchronously, no change in behaviour.
I have tried calling FrameworkDispatcher.Update frequently, no change in behaviour.
I have tried setting the .wav file in the project to “Resource” but this causes a nullreferenceexception when I call _Effect = SoundEffect.FromStream((Info.Stream)); because Info is null.(even with an absolute path)
This behaviour is present using both the emulator and an actual device via usb connection to pc to debug.
Can anybody help me resolve this frustrating issue please?

Answering my own issue now, it was the using block causing this behaviour, as the instance was being disposed. No idea why I was using that!

Related

LWJGL Game loop pauses whenever the GLFW window head is clicked

I have a very simple game loop.
public void gameLoop() {
long now;
long updateTime;
long wait;
final int TARGET_FPS = 60;
final long OPTIMAL_TIME = 1000000000 / TARGET_FPS;
while (!window.shouldClose()) {
now = System.nanoTime();
update();
render();
frame++;
updateTime = System.nanoTime() - now;
wait = (OPTIMAL_TIME - updateTime) / 1000000;
try {
Thread.sleep(wait);
} catch (Exception e) {
}
}
glfwTerminate();
}
Whenever I click the head of the window (the bar where the close and minimize buttons are), the loop for some reason pauses. The sounds in game continue to play (I use AL10), so this causes music and sounds to get out of sync with the game. I want to pause the window whenever this happens.
I but looking through the GLFW callbacks, there doesn't seem to be one which fixes this. The focus callback only works if I click outside of the window, and the windowPos callback only works whenever the window is moved, NOT when you simply click and hold the window head.
Is there a way to fix this problem.
This is actually expected behaviour on some platforms like Windows, where effectively glfwPollEvents will block inside of a Win32 API call for as long as you hold down the mouse button and/or potentially drag/move the window around.
In order to fix this, you should make your game loop independent of the window event processing loop, by using separate threads.
The main thread must be the one that is doing the window event processing (glfwPollEvents or glfwWaitEvents) to stay consistent with the requirements of some other platforms like macOS where this is a requirement, while another thread can do the game update and rendering.

MediaCapture and Window VisibilityChanged

[Question]
On Windows Phone 8.1, what exactly happens in between the time when the user leaves the app and the OnSuspended event fires? I'm having trouble with the ability to manage objects in that span, in particular MediaCpture object.
To better explain the problem, here is the scenario:
The user is on a page with a video preview being pumped to a CaptureElement
The user taps the Start button
The user taps Back button and returns to the page with a broken MediaCapture
With WinRT there isn't an ObscuredEvent and OnNavigatingFrom doesn’t fire unless you’re going to another page in the same Frame. After some investigation, I've found that the only event that fires is Window.Current.VisibilityChanged
I've gone ahead and hook it when the page is NavigatedTo and unhooked in OnNavigatedFrom (see ex2 below). Inside the event, I check for parameter that tells if the app is hiding or showing and dispose/initialize accordingly(see ex.1 below).
[Problem]
However, this only works with the debugger attached. If I do this without the debugger attached, it doesn't reinitialize and frequently crashes the camera and I have to literally reboot the device.
Code Example 1 (note: e.Visible == false is leaving the app and true when returning)
async void Current_VisibilityChanged(object sender, VisibilityChangedEventArgs e)
{
if (!e.Visible) //means leaving the app
{
await DisposeAll(); //cleans the MediaCapture and CaptureElement
}
else
{
if(mediaCaptureManager != null) await DisposeAll();
await Initialization(); //set up camera again
}
}
Example 2 (hooking into the event)
protected override void OnNavigatedTo(NavigationEventArgs e)
{
Window.Current.VisibilityChanged += Current_VisibilityChanged;
this.navigationHelper.OnNavigatedTo(e);
}
protected async override void OnNavigatedFrom(NavigationEventArgs e)
{
Window.Current.VisibilityChanged -= Current_VisibilityChanged;
this.navigationHelper.OnNavigatedFrom(e);
}
[Update: Resolution]
Instead of using VisibilityChanged, hook into Window.Current.Activated on the page's constructor. With the debugger completely detached, the Activated event will provide the WindowActivationState parameter in the WindowActivatedEventArgs. Like this:
private async void CurrentOnActivated(object sender, WindowActivatedEventArgs e)
{
if(e.WindowActivationState == CoreWindowActivationState.Deactivated)
{
//dispose MediaCapture here
}
else if(e.WindowActivationState == CoreWindowActivationState.CodeActivated || e.WindowActivationState == CoreWindowActivationState.PointerActivated)
{
//initialize MediaCapture here
}
}
See my answer in https://stackoverflow.com/a/28592882/3998132. Using Window.VisibilityChanged in conjunction with your Page\UserControl Loaded\Unloaded handler should solve your issue I believe.
Using Window.Activated is less desirable than Window.VisibilityChanged because Activated relates to being visible AND having focus where as VisibilityChanged only pertains to visibility. For showing a preview having focus is not applicable. Since Windows Store apps on Windows Phone can only have one Window showing there is no difference in using either however if your app becomes universal and runs on let's say on Windows 8+ Modern shell (which can show multiple Store apps with the Snap window feature) or Windows 10 desktop (which can support multiple Store apps showing at the same time) you will not want to stop preview when a user changes focus from your app but your app is still showing.
I'm not sure if it wouldn't be more suitable to use Suspending/Resuming events. Note only that in this case, you will have to debug it properly - it behaves little different while being run with/without debugger attached.
As for the code - hooking your event in OnNavigatedTo/OnNavigatedFrom is not a good idea - when the OS suspends the app and you are using SuspensionManager then OnNavigatedFrom will be called, but when you go back to your app (resume it), then OnNavigatedTo will not be called.
Using Window events may also work here, but why not subscribe it once, somewhere in constructor? - it's window-wide and hence in phone there is only one window, which stands for app, then subscribe once. In this case, you may add a line that recognizes the current page in window and if that page contains mediacapture then dispose (create similar). Then you can also dispose/initialize in navigation events in case user doesn't leave your app and just navigate.

Pause/Play functionality from one button?

Could someone tell me what I'm doing wrong here? I'm trying to use one icon in the Windows Phone Application Bar to enable a user to tap it to play and pause background audio that I've inserted as a MediaElement in the XAML. This is my code:
private void ApplicationBarIconButton_Click(object sender, EventArgs e)
{
if (PlayState.Playing == BackgroundAudioPlayer.Instance.PlayerState)
{
BackgroundAudioPlayer.Instance.Pause();
}
else if (PlayState.Paused == BackgroundAudioPlayer.Instance.PlayerState)
{
BackgroundAudioPlayer.Instance.Play();
}
It makes sense reading it through and does not throw up any errors when building, however when I tap it whilst testing on my device, the music does not pause and carries on playing (I've set AutoPlay = true to achieve this) Could someone tell me what I should do to enable one button to control play and pause functionality?
Also if I remove the "else if" and make the code into a simple "else" so it looks like this:
private void ApplicationBarIconButton_Click(object sender, EventArgs e)
{
if (PlayState.Playing == BackgroundAudioPlayer.Instance.PlayerState)
{
BackgroundAudioPlayer.Instance.Pause();
}
else
{
BackgroundAudioPlayer.Instance.Play();
}
}
it pauses, but does not resume to play!
Here is the step by step implementation to achieve play/pause functionality
click and get solution
"I've inserted as a MediaElement in the XAML."
If you are using a MediaElement, I think you are playing the audio in the foreground. Try closing out of your app after the audio starts. Does it keep playing? To pause and play a media element you can just use the play and pause methods on the media element.
nameOfMediaElement.Pause();
nameOfMediaElement.Play();
To use the event handlers that use the BackgroundAudioPlayer.Instance.PlayerState, you have to setup the initial audio playing back in the background. For this you need to start the audio playback via the BackgroundAudioPlayer.
http://msdn.microsoft.com/en-us/library/windowsphone/develop/microsoft.phone.backgroundaudio.backgroundaudioplayer(v=vs.105).aspx
Try this.
if(mediaelement.CurrentState == MediaElementState.Paused)
{
mediaelement.Play();
}
else
{
mediaelement.Pause();
}
Hope it works for you.

after setting the SetView my map does not change

I'm working on a windows store app and have the following code:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
myMap.SetView(_lastLocation, 10.0);
}
the problem is, when I start the app, I still see the default view and its not centered to the _lastLocation and also the zoom level is not set to 10.
when I debug it, _lastLocation is not null and the code in the OnNavigatedTo is reached.
Why I dont see it?
Try Loaded event of Page. It will solve the problem.

Windows Store app button respond to click but event is not fired successfully

I go this response in Certification report:
The app does not appear to fully support touch input. The various
tiles on the main screen respond to touch/clicks but do not launch an
action. Touch support in this app do not appear to work to our
reviewers. Please see:
http://msdn.microsoft.com/en-us/library/windows/apps/Hh761498.aspx for
some of the common interactions for keyboard, mouse and touch.
This has never been an issue while developing and testing on several desktop computers and Surface RT. Any ideas on what might be the cause, or how I might reproduce it? The actions mentioned are hooked up to event handlers in code behind and use the navigation model with view models as parameters. I can post an example if needed, but there is nothing special in that code. What could cause a event-bound button to appear to be pressed but not call the handler, on some environments?
Extracts from one of the main features that the testers mention as non-functional:
View:
<GridView ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
ItemClick="ItemView_ItemClick"..
Code behind:
void ItemView_ItemClick(object sender, ItemClickEventArgs e)
{
var foodItem = (FoodItemViewModel)e.ClickedItem;
var mainViewModel = (MainViewModel)this.DefaultViewModel["MainViewModel"];
mainViewModel.CurrentItem = foodItem;
this.Frame.Navigate(typeof(ItemDetailPageReadOnly), (MainViewModel)mainViewModel);
}
From ItemDetailPageReadOnly:
protected override void LoadState(Object navigationParameter,
Dictionary pageState)
{
if (pageState != null && pageState.ContainsKey("SelectedItem"))
{
navigationParameter = pageState["SelectedItem"];
}
var mainVm = (MainViewModel)navigationParameter;
this.DefaultViewModel["MainViewModel"] = mainVm;
this.DefaultViewModel["Item"] = mainVm.CurrentItem;
}
I would expect a NullPointerException if any of the parameters were null, not the described behavior from the testers.
you should use one of the higher level events unless you need to respond to a specific portion of the gesture. http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh994936.aspx