How to do syncronized playback using AVAudioPlayer API? - xamarin

There is an example here on using AVAudioPlayer. In the description it says it's able to:
Play multiple sounds at the same time with optional synchronization.
I don't see how to do that in the example.
Apple API that says the same thing:
Play multiple sounds simultaneously by synchronizing the playback of multiple players
https://developer.apple.com/documentation/avfaudio/avaudioplayer?language=objc
Example:
https://github.com/xamarin/docs-archive/tree/master/Recipes/ios/media/sound/avaudioplayer
Note: The repository is archived and does not allow adding issues.

Use the playAtTime() method on all the sounds you want and pass in the same date to all the sounds to play at the same time.
I read about the playAtTime() method and thought it was "play at this position in time of the sound" BECAUSE IT SAYS IT SAYS THE PARAMETER IS NAMED TIME NOT DATE:
but it actually takes a Date and that means play at a future date and time.
So if you were only looking at the auto complete API and it says playAtTime(time) you don't get the details you do when looking at the documentation. Seeing that there is another property on sound player that is currentTime that is a number and not a date.
Documentation:
Plays audio asynchronously, starting at a specified point in the audio
output device’s timeline.
func startSynchronizedPlayback() {
// Create a time offset relative to the current device time.
let timeOffset = playerOne.deviceCurrentTime + 0.01
// Start playback of both players at the same time.
playerOne.play(atTime: timeOffset)
playerTwo.play(atTime: timeOffset)
}

Related

using REST, how does one set the fan duration for a one-time action?

three fan-related variables are defined in https://developer.nest.com/documentation/api#has_fan
has_fan (r/o, boolean)
fan_timer_active (r/w, boolean)
fan_timer_timeout (r/o, iso8601)
i suspect that fan_timer_timeout should be read-write; however, when i PUT
{"fan_timer_active": true, "fan_timer_timeout": "2014-09-30T01:07:29Z"}
i get back
No write permission(s) for field(s): fan_timer_timeout
none of the examples (on the SDK site) actually change the fan, so no guidance there.
the "non-public API" from "the early days" would have you do this:
fan_timer_duration = seconds
fan_timer_timeout = time-since-epoch-in-seconds + seconds
fan_timer_timeout isn't documented on the SDK site; however, doing that yields
No write permission(s) for field(s): fan_timer_duration,fan_timer_timeout
could someone clue me in as to what i need to send to get the fan to spin for the next 15 minutes?
many thanks!
The user configures the fan time duration in the Nest app or on the device, the API only provides a way to trigger a fan event.
It seems that fan time duration is a global setting, and would affect turning on the fan manually at the thermostat, hence why it is read only in the API. (Avoids user confusion)

Glympse API - Prefil the Name of the Receivers in the Send Wizard

As there is a way to preset the Duration, Destination, Invitee Message, So Can we preset the Recipients of the Glympse too ?
One more thing I would like to ask is that I want to make Time Duration Wheel as Non Editable for that I am using following configuration:
final int WIZARD_FLAGS
= LC.SEND_WIZARD_INVITES_EDITABLE
| LC.SEND_WIZARD_MESSAGE_READONLY
| LC.SEND_WIZARD_DESTINATION_READONLY
| LC.SEND_WIZARD_TIME_READONLY;
// Launches the wizard which will send the Glympse
glympse.sendTicket(ticket, WIZARD_FLAGS);
But the Time Duration Field is still showing as EDITABLE, I just donot want to make it EDITABLE
Please tell me
The way to preset a recipient is to add an invite to the ticket before calling sendTicket like this:
_activeTicket = LiteFactory.createTicket(DURATION, MESSAGE, DESTINATION);
_activeTicket.addInvite(GC.INVITE_TYPE_SMS, "My friend", "555-555-5555");
// Launch the wizard with these pre-populated values and settings
GlympseLiteWrapper.instance().getGlympse().sendTicket(_activeTicket, 0);
As for setting the timer as read only, you have the correct flag set, but I see a bug that causes that flag to not work as intended. Currently the wheel can be edited even though it has no effect on the actual duration of the ticket (notice the time in the center goes up but the expire time above the wheel stays the same).
We'll make sure this is fixed in the next SDK release. For now even though it looks like the duration can be changed, the ticket that is sent will be the duration that you specify as a preset.

ScheduledAgent and GeoCoordinateWatcher - how to make them work?

I'm trying to get GPS position via GeoCoordinateWatcher running in ScheduledAgent. Unfortunately only location I get is some old one, recorded when application was running. How to get current (latest) location in ScheduledAgent?
I have come across the same problem. Unfortunaty, this is intended behaviour according to the WP7.1 APIs
According to the documentation, "This API, used for obtaining the geographic coordinates of the device, is supported for use in background agents, but it uses a cached location value instead of real-time data. The cached location value is updated by the device every 15 minutes."
http://msdn.microsoft.com/en-us/library/hh202962(v=VS.92).aspx
My 2 Centlys.
it is probably becoz the GeoCoordinateWatcher takes some time (2 seconds or so) to get the new coordinate values and to lock to GPS or Cellular Mast or Wifi or whatever. And it will give you the last recordered position in the meantime.
So, try to hook to the following events
watcher.StatusChanged += new EventHandler< GeoPositionStatusChangedEventArgs>(watcher_StatusChanged);
watcher.PositionChanged += new EventHandler< GeoPositionChangedEventArgs< GeoCoordinate>>(watcher_PositionChanged);
where watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
and call the NotifyComplete(); in your "watcher_PositionChanged" event handler.

Should I rely on the local phone's time for time sensitive app (Windows Phone 7)

I'm building an app where my users will post content. The exact time of the post is an important data point - I need to know exactly when the user hit the "Post" button. Once the post has been captured I'll upload that posting to my web server. My app should still work in offline mode, meaning when there is no internet connectivity the post will be saved locally and uploaded next time the network becomes available.
Question is, how can I guarantee that the time of the post is accurate? Should I rely on the phone's local time? Should I try to create some crazy code that regularly sync's the difference between my servers time and the devices time so I can always know the difference (if there is one). Are there better time management solutions that I'm not aware of?
Thanks,
UPDATE
Here's the server side code that I wrote to ensure that server and client times are perfectly matched. Hope it helps others...
/// <summary>
/// Calculates the actual time the client event occurred.
/// Takes in account that the event and the sending of the
/// event may have happened seprately.
/// </summary>
public static DateTime CalculateClientEventTime(
DateTime serverReceiveTime,
DateTime clientSendTime,
DateTime clientEventTime)
{
// first we need to sync the client and server time
// we also need to subtract any time zone offsets
// then we can subtract the actual time on de ice
DateTime serverReceiveUtc = serverReceiveTime.ToUniversalTime();
DateTime clientSendUtc = clientSendTime.ToUniversalTime();
DateTime clientEventUtc = clientEventTime.ToUniversalTime();
// note: all dates are in utc
// just need to subtract the client TimeSpan from the client Send
// then subtract that TimeSpan from the server utc time
TimeSpan diffBetweenClientEventAndClientSend = (clientSendUtc - clientEventUtc);
return serverReceiveUtc.Subtract(diffBetweenClientEventAndClientSend);
}
I suggest that you do the following:
In online mode: Take the time from your server when the user post their data.
In offline mode: Save the time from the phone. When going online, submit all saved data, and the current time of the phone. Calculate the difference between the phone and your server time to get the real time.
You cannot rely on the phone's time because user can change it and your app can run in diffrent time zones. Use always the sever time or you can get the phone time and calibrate your local timer to get the value of a lag.

Can i get a notification, when a new day begins?

In Cocoa, is there a notification i can register for, that informs me, when a new day begins - at 00h:00min:01s in the morning?
If it is for iPhone development, you can also listen for a UIApplicationSignificantTimeChangeNotification. It gets posted on more occasions than the arrival of midnight, but when you receive one, you can simply check if you are on or near midnight.
For Mac OS X, you would have to do what Tom Dalling suggests but you should also keep track of changes to the system clock yourself (in order to update your timer) as well as changes to the current time zone.
There's no notification that I know of. You can get a timer to fire whenever a new day begins like so:
[[NSTimer alloc] initWithFireDate:midnight
interval:60 * 60 * 24 //one day, in seconds
target:someObj
selector:#selector(someSelector)
userInfo:nil
repeats:YES];
The trick is getting an NSDate set to midnight. Check the Date and Time Programming Guide for how to do that with date components and the like.
EDIT: see this question for how to get the midnight NSDate.
As of iOS8, you can also directly listen to NSCalendarDayChangedNotification.
As mentioned by others, in iOS 8 you can use NSCalendarDayChangedNotification. In terms of how to do that, this post gives you more info.
Essentially NSCalendarDayChangedNotification requires that you go to your appDelegate file and insert the below code in app (adapted from guide for Swift 3):
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.dayChangedOperations(notif:)), name:NSNotification.Name.NSCalendarDayChanged, object:nil)
Where "ViewController" is the classname of one of my classes and "dayChangedOperations" is the name of the function that I want to run whenever the day changes.
Count Days Since Last Change
Note that all you get from this is an alert that the day changed. You are not given the number of days since the app last ran. So remember to save the date to a userDefault each time this function runs, so you can use it for comparison later.

Resources