Skip to content

Commit

Permalink
ios: Check the background state actively
Browse files Browse the repository at this point in the history
It looks like the notifications for background state might not be
sent on some environments (e.g., iPod touch).

Updates #93
  • Loading branch information
hajimehoshi committed Sep 15, 2020
1 parent ccbe804 commit 717e5f1
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 56 deletions.
38 changes: 2 additions & 36 deletions driver_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ package oto
// void oto_render(void* inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer);
//
// void oto_setNotificationHandler(AudioQueueRef audioQueue);
// bool oto_isBackground(void);
import "C"

import (
Expand Down Expand Up @@ -50,9 +51,6 @@ type driver struct {
paused bool
lastPauseTime time.Time

background bool
backgroundCond *sync.Cond

err error

chWrite chan []byte
Expand Down Expand Up @@ -138,7 +136,6 @@ func newDriver(sampleRate, channelNum, bitDepthInBytes, bufferSizeInBytes int) (
chWrite: make(chan []byte),
chWritten: make(chan int),
}
d.backgroundCond = sync.NewCond(&d.m)
runtime.SetFinalizer(d, (*driver).Close)
// Set the driver before setting the rendering callback.
setDriver(d)
Expand Down Expand Up @@ -257,7 +254,6 @@ func (d *driver) enqueueBuffer(buffer C.AudioQueueBufferRef) {

if osstatus := C.AudioQueueEnqueueBuffer(d.audioQueue, buffer, 0, nil); osstatus != C.noErr && d.err == nil {
d.err = fmt.Errorf("oto: AudioQueueEnqueueBuffer failed: %d", osstatus)
d.backgroundCond.Signal()
return
}
}
Expand All @@ -279,11 +275,7 @@ func (d *driver) resume(afterSleep bool) bool {
}
}

for d.background && d.err == nil {
// As backgroundCond shares the same mutex as d.m, Wait unlocks the mutex.
d.backgroundCond.Wait()
}
if d.err != nil {
if C.oto_isBackground() {
return false
}

Expand All @@ -304,7 +296,6 @@ func (d *driver) pause() {
}
if osstatus := C.AudioQueuePause(d.audioQueue); osstatus != C.noErr && d.err == nil {
d.err = fmt.Errorf("oto: AudioQueuePause failed: %d", osstatus)
d.backgroundCond.Signal()
return
}
d.paused = true
Expand All @@ -319,21 +310,6 @@ func (d *driver) setError(err error) {
return
}
theDriver.err = err
d.backgroundCond.Signal()
}

func (d *driver) setForeground() {
d.backgroundCond.L.Lock()
d.background = false
d.backgroundCond.Signal()
d.backgroundCond.L.Unlock()
}

func (d *driver) setBackground() {
d.backgroundCond.L.Lock()
d.background = true
d.backgroundCond.Signal()
d.backgroundCond.L.Unlock()
}

func setNotificationHandler(driver *driver) {
Expand All @@ -355,13 +331,3 @@ func oto_setErrorByNotification(s C.OSStatus, from *C.char) {
gofrom := C.GoString(from)
theDriver.setError(fmt.Errorf("oto: %s at notification failed: %d", gofrom, s))
}

//export oto_setForeground
func oto_setForeground() {
theDriver.setForeground()
}

//export oto_setBackground
func oto_setBackground() {
theDriver.setBackground()
}
39 changes: 19 additions & 20 deletions driver_ios.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ @interface OtoNotificationObserver : NSObject {
}

- (void)onAudioSessionInterruption:(NSNotification *)notification;
- (void)onApplicationDidEnterBackground:(NSNotification *)notification;
- (void)onApplicationWillEnterForeground:(NSNotification *)notification;

@end

Expand Down Expand Up @@ -58,14 +56,6 @@ - (void)onAudioSessionInterruption:(NSNotification *)notification {
}
}

- (void)onApplicationDidEnterBackground:(NSNotification *)notification {
oto_setBackground();
}

- (void)onApplicationWillEnterForeground:(NSNotification *)notification {
oto_setForeground();
}

@end

// oto_setNotificationHandler sets a handler for interruption events.
Expand All @@ -78,14 +68,23 @@ void oto_setNotificationHandler(AudioQueueRef audioQueue) {
selector:@selector(onAudioSessionInterruption:)
name:AVAudioSessionInterruptionNotification
object:session];
[[NSNotificationCenter defaultCenter]
addObserver:observer
selector:@selector(onApplicationDidEnterBackground:)
name:UIApplicationDidEnterBackgroundNotification
object:session];
[[NSNotificationCenter defaultCenter]
addObserver:observer
selector:@selector(onApplicationWillEnterForeground:)
name:UIApplicationWillEnterForegroundNotification
object:session];

// The notifications UIApplicationDidEnterBackgroundNotification and
// UIApplicationWillEnterForegroundNotification were not reliable: at least,
// they were not notified at iPod touch A2178.
//
// Instead, check the background state via UIApplication actively.
}

bool oto_isBackground(void) {
if ([NSThread isMainThread]) {
return [[UIApplication sharedApplication] applicationState] ==
UIApplicationStateBackground;
}

__block bool background = false;
dispatch_sync(dispatch_get_main_queue(), ^{
background = oto_isBackground();
});
return background;
}
5 changes: 5 additions & 0 deletions driver_macos.m
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,8 @@ void oto_setNotificationHandler(AudioQueueRef audioQueue) {
name:NSWorkspaceDidWakeNotification
object:NULL];
}

bool oto_isBackground(void) {
// TODO: Should this be implemented?
return false;
}

0 comments on commit 717e5f1

Please sign in to comment.