This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Cocoa | |
import AUFramework | |
class ViewController: NSViewController { | |
private var audioPlayer: AudioPlayer! | |
private var pluginVC: AudioUnitViewController! | |
@IBOutlet weak var auContainer: NSView! | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import CoreAudioKit | |
public class AudioUnitViewController: AUViewController, AUAudioUnitFactory { | |
public var audioUnit: VolumePluginAudioUnit? { | |
didSet { | |
DispatchQueue.main.async { | |
if self.isViewLoaded { | |
self.connectWithAU() | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <AVFoundation/AVFoundation.h> | |
struct Buffer { | |
AVAudioPCMBuffer *pcmBuffer = nullptr; | |
AudioBufferList* mutableAudioBufferList = nullptr; | |
AudioBufferList const* originalAudioBufferList = nullptr; | |
AUAudioFrameCount maxFrames = 0; | |
float volume = 1.0; | |
/* | |
prepareInputBufferList populates the mutableAudioBufferList with the data |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public func selectAudioUnitWithComponentDescription(_ componentDescription: AudioComponentDescription?, completionHandler: @escaping (() -> Void)) { | |
// Internal function to resume playing and call the completion handler. | |
func done() { | |
if isPlaying { | |
playerNode.play() | |
} | |
completionHandler() | |
} | |
let hardwareFormat = self.engine.outputNode.outputFormat(forBus: 0) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private func connectAudioUnitWithPlayer() { | |
var componentDescription = AudioComponentDescription() | |
componentDescription.componentType = kAudioUnitType_Effect | |
// used https://codebeautify.org/string-hex-converter to convert strings to fourCC hex | |
componentDescription.componentSubType = 0x44656d6f // "Demo" | |
componentDescription.componentManufacturer = 0x44656d6f // "Demo" | |
componentDescription.componentFlags = 0 | |
componentDescription.componentFlagsMask = 0 | |
AUAudioUnit.registerSubclass(VolumePluginAudioUnit.self, as: componentDescription, name: "demo: VolumePlugin", version: UInt32.max) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Define parameter addresses. | |
const AudioUnitParameterID myParam1 = 0; | |
@interface VolumePluginAudioUnit () | |
@property (nonatomic, readwrite) AUParameterTree *parameterTree; | |
@property AUAudioUnitBus *inputBus; | |
@property AUAudioUnitBus *outputBus; | |
@property AUAudioUnitBusArray *inputBusArray; | |
@property AUAudioUnitBusArray *outputBusArray; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- (instancetype)initWithComponentDescription:(AudioComponentDescription)componentDescription options:(AudioComponentInstantiationOptions)options error:(NSError **)outError { | |
self = [super initWithComponentDescription:componentDescription options:options error:outError]; | |
if (self == nil) { return nil; } | |
// initialize Buffer | |
_buffer = Buffer(); | |
_buffer.maxFrames = 0; | |
_buffer.pcmBuffer = nullptr; | |
_buffer.mutableAudioBufferList = nullptr; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- (BOOL)allocateRenderResourcesAndReturnError:(NSError **)outError { | |
if (![super allocateRenderResourcesAndReturnError:outError]) { | |
return NO; | |
} | |
// Validate that the bus formats are compatible. | |
if (self.outputBus.format.channelCount != _inputBus.format.channelCount) { | |
if (outError) { | |
*outError = [NSError errorWithDomain:NSOSStatusErrorDomain code:kAudioUnitErr_FailedInitialization userInfo:nil]; | |
NSLog(@"kAudioUnitErr_FailedInitialization at %d", __LINE__); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- (AUInternalRenderBlock)internalRenderBlock { | |
// Capture in locals to avoid ObjC member lookups. If "self" is captured in render, we're doing it wrong. See sample code. | |
__block Buffer* buffer = &_buffer; | |
return ^AUAudioUnitStatus(AudioUnitRenderActionFlags *actionFlags, const AudioTimeStamp *timestamp, AVAudioFrameCount frameCount, NSInteger outputBusNumber, AudioBufferList *outputData, const AURenderEvent *realtimeEventListHead, AURenderPullInputBlock pullInputBlock) { | |
// Do event handling and signal processing here. | |
AudioUnitRenderActionFlags pullFlags = 0; | |
buffer->prepareInputBufferList(); | |
AUAudioUnitStatus err = pullInputBlock(&pullFlags, timestamp, frameCount, 0, buffer->mutableAudioBufferList); | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import AVFoundation | |
class AudioPlayer: NSObject { | |
private let engine = AVAudioEngine() | |
private let playerNode = AVAudioPlayerNode() | |
private var file: AVAudioFile! | |
private var isPlaying = false | |
private let audioPlayerQueue = DispatchQueue(label: "AudioPlayerQueue") | |