Skip to content

Commit

Permalink
darwin: Pause the audio when sleeping
Browse files Browse the repository at this point in the history
  • Loading branch information
hajimehoshi committed Jul 23, 2020
1 parent 38d9779 commit 98c7b3b
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 20 deletions.
16 changes: 16 additions & 0 deletions driver_darwin.go
Expand Up @@ -21,6 +21,8 @@ package oto
// #import <AudioToolbox/AudioToolbox.h>
//
// void oto_render(void* inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer);
//
// void oto_setNotificationHandler(AudioQueueRef audioQueue);
import "C"

import (
Expand Down Expand Up @@ -242,3 +244,17 @@ func (d *driver) Close() error {
setDriver(nil)
return nil
}

func setNotificationHandler(driver *driver) {
C.oto_setNotificationHandler(driver.audioQueue)
}

//export oto_setErrorByNotification
func oto_setErrorByNotification(s C.OSStatus, from *C.char) {
if theDriver.err != nil {
return
}

gofrom := C.GoString(from)
theDriver.err = fmt.Errorf("oto: %s at notification failed: %d", gofrom, s)
}
16 changes: 0 additions & 16 deletions driver_ios.go
Expand Up @@ -20,28 +20,12 @@ package oto
// #cgo LDFLAGS: -framework Foundation -framework AVFoundation
//
// #import <AudioToolbox/AudioToolbox.h>
//
// void oto_setNotificationHandler(AudioQueueRef audioQueue);
import "C"

import (
"fmt"
)

func setNotificationHandler(driver *driver) {
C.oto_setNotificationHandler(driver.audioQueue)
}

func componentSubType() C.OSType {
return C.kAudioUnitSubType_RemoteIO
}

//export oto_setErrorByNotification
func oto_setErrorByNotification(s C.OSStatus, from *C.char) {
if theDriver.err != nil {
return
}

gofrom := C.GoString(from)
theDriver.err = fmt.Errorf("oto: %s at notification failed: %d", gofrom, s)
}
6 changes: 2 additions & 4 deletions driver_macos.go
Expand Up @@ -17,13 +17,11 @@

package oto

// #cgo LDFLAGS: -framework AppKit
//
// #import <AudioToolbox/AudioToolbox.h>
import "C"

func setNotificationHandler(driver *driver) {
// Do nothing
}

func componentSubType() C.OSType {
return C.kAudioUnitSubType_DefaultOutput
}
63 changes: 63 additions & 0 deletions driver_macos.m
@@ -0,0 +1,63 @@
// Copyright 2020 The Oto Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// +build darwin,!ios,!js

#import <AppKit/AppKit.h>

#include "_cgo_export.h"

@interface OtoInterruptObserver : NSObject {
}

@property(nonatomic) AudioQueueRef audioQueue;

@end

@implementation OtoInterruptObserver {
AudioQueueRef _audioQueue;
}

- (void)receiveSleepNote:(NSNotification *)note {
OSStatus status = AudioQueuePause([self audioQueue]);
if (status != noErr) {
oto_setErrorByNotification(status, "AudioQueuePause");
}
}

- (void)receiveWakeNote:(NSNotification *)note {
OSStatus status = AudioQueueStart([self audioQueue], nil);
if (status != noErr) {
oto_setErrorByNotification(status, "AudioQueueStart");
}
}

@end

// oto_setNotificationHandler sets a handler for interruption events.
void oto_setNotificationHandler(AudioQueueRef audioQueue) {
OtoInterruptObserver *observer = [[OtoInterruptObserver alloc] init];
observer.audioQueue = audioQueue;

[[[NSWorkspace sharedWorkspace] notificationCenter]
addObserver:observer
selector:@selector(receiveSleepNote:)
name:NSWorkspaceWillSleepNotification
object:NULL];
[[[NSWorkspace sharedWorkspace] notificationCenter]
addObserver:observer
selector:@selector(receiveWakeNote:)
name:NSWorkspaceDidWakeNotification
object:NULL];
}

0 comments on commit 98c7b3b

Please sign in to comment.