[swift] AudioUnit의 오디오 출력

오디오를 다루는 데 사용되는 AudioUnit은 iOS나 macOS 애플리케이션에서 오디오 신호를 처리하고 출력하는 데 사용됩니다. 이 포스트에서는 AudioUnit을 사용하여 오디오를 출력하는 방법에 대해 알아보겠습니다.

AudioUnit 설정

먼저 AudioUnit을 초기화하고 설정해야 합니다. 다음 코드는 AudioComponentDescription을 사용하여 원하는 유형의 AudioUnit을 찾고 초기화하는 방법을 보여줍니다.

import AudioToolbox

var outputUnit: AudioUnit?

var outputComponentDescription = AudioComponentDescription(
    componentType: kAudioUnitType_Output,
    componentSubType: kAudioUnitSubType_DefaultOutput,
    componentManufacturer: kAudioUnitManufacturer_Apple,
    componentFlags: 0,
    componentFlagsMask: 0
)

let component = AudioComponentFindNext(nil, &outputComponentDescription)
AudioComponentInstanceNew(component!, &outputUnit)

포맷 설정

다음으로 출력할 오디오의 포맷을 설정해야 합니다. 이 예제에서는 AudioStreamBasicDescription을 사용하여 포맷을 설정하는 방법을 보여줍니다.

var streamFormat = AudioStreamBasicDescription(
    mSampleRate: 44100.0,
    mFormatID: kAudioFormatLinearPCM,
    mFramesPerPacket: 1,
    mChannelsPerFrame: 2,
    mBytesPerFrame: 4,
    mBytesPerPacket: 4,
    mBitsPerChannel: 16,
    mReserved: 0
)

AudioUnitSetProperty(outputUnit!,
                     kAudioUnitProperty_StreamFormat,
                     kAudioUnitScope_Input,
                     0,
                     &streamFormat,
                     UInt32(MemoryLayout<AudioStreamBasicDescription>.size))

콜백 함수 설정

마지막으로 출력할 오디오 데이터를 생성하는 콜백 함수를 설정해야 합니다. 아래 코드는 AURenderCallbackStruct를 사용하여 콜백 함수를 설정하는 방법을 보여줍니다.

func playbackCallback(
    inRefCon: UnsafeMutableRawPointer?,
    ioActionFlags: UnsafeMutablePointer<AudioUnitRenderActionFlags>,
    inTimeStamp:  UnsafePointer<AudioTimeStamp>,
    inBusNumber: UInt32,
    inNumberFrames: UInt32,
    ioData: UnsafeMutablePointer<AudioBufferList>?
) -> OSStatus {
    // 오디오 데이터 생성
    // ioData를 통해 출력할 오디오 데이터를 채워줌

    return noErr
}

var inputCallbackStruct = AURenderCallbackStruct(
    inputProc: playbackCallback,
    inputProcRefCon: nil
)

AudioUnitSetProperty(outputUnit!,
                     kAudioUnitProperty_SetRenderCallback,
                     kAudioUnitScope_Input,
                     0,
                     &inputCallbackStruct,
                     UInt32(MemoryLayout<AURenderCallbackStruct>.size))

재생 및 정리

이제 AudioUnit을 시작하고 오디오를 출력할 준비가 되었습니다.

AudioUnitInitialize(outputUnit!)
AudioOutputUnitStart(outputUnit!)

오디오 출력이 끝나면 다음 코드를 사용하여 정리할 수 있습니다.

AudioOutputUnitStop(outputUnit!)
AudioUnitUninitialize(outputUnit!)

위의 코드를 통해 AudioUnit을 사용하여 오디오를 출력하는 방법에 대해 간단히 알아보았습니다. 이제 여러분은 AudioUnit을 사용하여 iOS나 macOS 애플리케이션에서 오디오를 다루는 데 시작할 수 있을 것입니다.

참조: