White Screen appears at launch when a sound file played SKAction - swift

I am trying to get a background sound file to play in the GameScene.swift file. But whenever I do and call the run.SKAction, the screen turns white and I hear a lot of static until it crashes. When I comment out the run.SKAction the game starts normally. Ive tried changing the formats of the file to WAV, MP3, AAC, CAF. But the same thing happens. I checked to see if I mispelled anything but I did not.
It gives me a message saying: "Message from debugger: Terminated due to memory issue"
IMPORTANT NOTE: the "waitForCompletion is set to TRUE it seems to work fine with a little static at the beginning of the soundtrack then it plays normally. but when "waitForCompletion" is set to FALSE I get the white screen. I Also Sometimes get a message saying:
SKAction: Error loading sound resource: "Entry.m4a"
I tried several different soundtrack files but it always happens.
Here is the beginning of the GameScene():
class GameScene: SKScene {
var SpaceShip2 = SKSpriteNode(imageNamed:"IntroSpaceShip")
var GameSceneSound = SKAction.playSoundFileNamed("BackgroundSound.wav", waitForCompletion: false)
}
Here is the function I used to call the sound:
func playsound(soundVariable: SKAction){
run(SKAction.repeatForever(soundVariable))
}
And here is when I call it:
override func didMove(to view: SKView) {
playsound(soundVariable: GameSceneSound)
}
Can someone please help me!
Thank you in advance!

Since waitForCompletion is set to false, the action is considered to be have been completed immediately when run. Since this is a repeatForever action, the next repetition of the action runs before the the first action of playing the sound has completed. The 2nd repetition runs, immediately causing the 3rd repetition, which causes the 4th one, etc. Eventually you fill up too much memory with all the SKActions and the app is terminated by iOS.
I would suggest having waitForCompletion set to true. That way the 2nd repetition of the action won't start until the 1st action has completed playing the sound.
Hope this helps!

Related

WKInterfaceInlineMovie Starts Playing Even if setAutoplays(_:) is Set to false

I have an WKInterfaceInlineMovie within an WKInterfaceController. The URL of the video is set at some point after the video file is downloaded. Playing works fine besides this problem which is a different story, I think.
Here's the problem. If I keep the screen open, lower my wrist and then raise it again, I can see the same screen and the video starts playing automatically.
It looks very weird and unexpected especially because I have some custom UI (video progress indicator, animated Play/Pause buttons) which is triggered when I manually start the video but it obviously doesn't react on this unwanted automatic video start. If I close the extension with the Crown button, next time I open the app, it again shows the screen with video and start playing automatically. I can even not using the extension for a while and receive a user notification later – while the custom notification UI is displayed, I can hear the video starts playing somewhere below for a short period of time.
When it happens I always receive two messages in console:
<<<< PlayerRemoteXPC >>>> remoteXPCPlaybackItem_NotificationFilter: [0x128b86e0] I/NQB.01 Received kFigPlaybackItemNotification_FirstVideoFrameEnqueued
<<<< PlayerRemoteXPC >>>> remoteXPCItem_handleFirstFrameNotificationLatch: [0x128b86e0] I/NQB.01 Posting kFigPlaybackItemNotification_FirstVideoFrameEnqueued
I have the Autoplay checkmark unchecked in storyboard. I also tried to set setAutoplays(_:) to false programmatically when the outlet is initialized, or later when a URL is set to the movie. All of this makes no difference.
The behavior is the same no matter was the video playing or not when the screen get deactivated. I tried to call pause() on willDisappear() and didDeactivate() – it also doesn't do any difference.
I even tried to call pause() on didAppear() and willActivate() – didn't help either. Curiously enough, these methods are not called when I lower the wrist and raise it again (however, willDisappear() and didDeactivate() are both called.) But perhaps, it's a different story, too.

AKMIDI - Different behaviour - virtual midi

I have the following situation: In my app I have created virtual MIDI ports, as explained in some examples on the Audiokit page.
I use midi in order to trigger AKMIDISampler and AKMIDISampler loads .aupresets for percusive instruments. I create the .aupresets in the AULAB so that the NOTE OFF should be ignored.
So the samples can fade out and will not be cut off when the next hit comes.
It works as expected with my MIDI Keyboard and some other hardware MIDI controller. MIDI NOTE OFF is ignored, previous sound can fade out and the sounds overlap fine. But when I load my App in AudioBus and trigger it over virtual MIDI with a Sequencer, every new sample always cuts off the previous one. That sounds very unnatural and should be changed.
Where is the difference between virtual MIDI and not virtual? What am I doing wrong and how to get the same behaviour on both levels? Any help is appreciated! Thank you!
//open midi ports
let midi = AudioKit.midi
midi.createVirtualPorts()
midi.openInput(name: "Session 1")
midi.addListener(self)
//Play Sampler
func receivedMIDINoteOn(noteNumber: MIDINoteNumber, velocity: MIDIVelocity, channel: MIDIChannel) {
do {
try self.myMIDISampler.play(noteNumber: myNote, velocity: velocity, channel: myMIDIChannel)
} catch {
AKLog("Can't play the file, error:\(error)")
}
}
It should have the same results on virtual midi and hardware midi commands.
In principle I think I need a way to ignore / filter midi note off at all levels.
That could also be a solution.
#user3491466,
Without seeing your entire Xcode project and the .aupreset that you've saved from AU Lab, could you try increasing the layer's Release Time in the parameters menu, so that the samples continue to play out and not get cut off?
Please let me know if this helps at all. Be sure to also check out the Audiobus SDK and associated classes that are in the AudioKit Synth One open source project. That way, you can see if there's anything that's set differently.
https://github.com/AudioKit/AudioKitSynthOne

How to start AVAudioPlayer without loading full buffer?

I want to use the AVAudioPlayer to play a previously recorded file. That recording works fine, and I saved the file to the temp directory.
The problem is, as soon as I setup the AVAudioPlayer, it starts buffering and will not start playing before fully buffering that recording. Now it may work fine with recordings of about 30 seconds, but I also want it to work with like 1 hour long recordings. I am talking about > 1 minute of waiting.
How do I force AVAudioPlayer to just begin playing with the current buffer?
Like I can tell AVPlayer with player.automaticallyWaitsToMinimizeStalling = false
because I don't expect there to be any stalling issue.
Or how do I get something like averagePower()->Float from AVPlayer?
I could not use AVPlayer because I need something like AVAudioPlayer's func averagePower(forChannel channelNumber: Int) -> Float to show a visualized presentation of the recording. If you know how to get to those averagePower values from AVPlayer, -Item, -Asset or -Track, that would be fine too, I could not find anything fitting.
I found that, if you use AVAudioPlayer but call player.play() on another thread, it is not waiting for the buffer and starts playing right away.
DispatchQueue.global(qos: .background).async {
self.player.play()
}
But this comes with some restrictions, because now I can't use player.play(at: TimeInverval) because that seems to interrupt building the buffer and then the file will not be played to its full duration. I worked around that by setting player.currentTime before player.play(), which does not to bother the buffer.

Swift game won't stay paused

I'm having difficulty pausing the game when I leave and switch back to it.
I'm trying to pause the SKSpriteNode called main, which contains all my sprites, when the view returns from the background. In-game, I can touch the pause button and the game pauses, and the resume button and it resumes.
This is my code:
func didBecomeActive() {
println("didBecomeActive")
main.paused = true
}
The first time this runs is when the app opens for the first time, and everything is paused as it should be. The second time, is when it returns from the background, and suddenly all the animations (SKActions, particles, etc.) start working.
I've confirmed that the method is running, and I've also tried setting main.paused to false and then true, and even self.paused to true. Nothing works.
I'm completely stumped. Anyone know what the issue is here?
Setting self.scene.paused = YES should fix this. I have tried it with a game I am developing and it works fine.
Just set self.scene.paused = YES when the game enters the background, then when it return to the foreground, it should stay paused till you resume it, i.e. set self.scene.paused = NO.

ios - AVAudioPlayer - audioPlayerDidFinishPlaying is sometimes called at random times in a clip

I have a ~30 minute mp3 file being played by an AVAudioPlayer. Sometimes, audioPlayerDidFinishPlaying:successfully is called (with the successfully flag set to TRUE), even when it is only 5 minutes into the clip. It happens infrequently, but it can happen at any position in the clip.
I've only noticed that it happens when the user is pressing a button on the user interface, or moving a slider. And the more quickly they press buttons on the user interface, the more likely it is to happen it seems.
Any ideas what could be causing this, or how to fix it?
MORE INFO:
Only 1 sound is played at a time. No sounds are played for button actions. The AVAudioPlayer is declared locally in my main ViewController. I've tested on an iPhone 3GS and an iPhone 4s. The problem happens very very rarely on the iPhone 4s. It's much more frequent on the 3GS.
OK, I had the same problem starting yesterday. Don't whether we were having the same problem but I will throw it here
In the slider ValueChanged event handler, I tried to update the view elements based on the new position of the slider. But within the updateViewMethod, I called another
slider.value = self.player.currentTime;
Removing that solved my problem.
So in short, your timer's callback should update the slider, but slider valuechanged handler should not redo the work.