본문 바로가기

Software/iOS & Objective-C

iOS Audio Play

Mac OS 또는 iOS에서 Audio를 Play하는 방법은 여러가지가 있다.



방법에는 크게 두가지 방식으로 나뉘는데,

- Audio를 컨트롤 위해 추상화 작업이 완료된 API를 이용하는 방법(AVAudioPlayer, MPMediaPlayer) 

or

- Low Level에서 직접 오디오 Unit를 활용하는 방법(Audio Unit, AUGraph)이다.


문제 접근의 시작은 이러하였다.


AVAudioPlayer나 MPMediaPlayer 와 같은 추상화된 오디오 Class를 통해 Equalizer 기능을 제공하고 싶었다. 하지만 해당 API로는 Equalizer 기능을 수행할 수 없었다.

(여기서 말하는 Equalizer는 iOS Setting의 기본 eq 정보를 말합니다.)


자료정보를 찾아보다 알게된 사실인데, Apple이 상기 API를 이용하여 equalizer기능을 제공하지 않는 것은 해당 기능이 범용성에서 떨어지기 때문이라고 한다. 따라서 eq 설정을 하기 위해서는 AUGraph라는 Core Audio Framework의 low level API를 이용해야만 한다.


AVAudioPlayer, MPMediaPlayer API를 이용해서는 기본적인 Music Player Application을 제작하기에는 충분하다. Playback Control, 해당 Playback에 따른 Delegate function 제공, 여러모로 추상화 API를 이용하는 것이 바람직 하겠으나, 고수준의 media control를 위해서는 Low level API를 숙지하는 것이 불가피 하다.


Audio Unit은 low level의 API로 Mac OS X에서는 디바이스 드라이버 위에 존재하며, iOS의 경우 최하위 낮은 레벨의 API 이다. 이는 사용함에 있어 간단하지는 않으나, 상위 API에서 사용할 수 없는 기능이 수행 가능함을 의미 한다.


오디오 Unit은 일종의 Object로 오디오를 가지고 할 수 있는 작은 기능이라고 보면된다.

예를들어. 오디오 스트림을 만들고, 효과를 집어넣고(Equalizer), 입력장치(마이크)를 통해 오디오를 저장하고, 스피커를 통해 출력하는 기능을 수행한다. 각각의 오디오 유닛이 작은 기능들을 따로 수행한다. 이는 실제 존재하는 하드웨어와 비슷하게 볼 수 있는데 이를 소프트웨어 적으로 구현한 것이다.

전체적인 개념에 대해 이해해 보았다면 이제 Core Audio에 대하여 알아보도록 하자.



What is Core Audio?


Core Audio OS X iOS 집적된 통합 Audio 모듈이며, 이는 고성능 퍼포먼스를 가능케 하는 역할을 수행한다.

OS X에서, 대부분의 Core Audio 서비스는 그림 1-1과 같이 Hardware Abstracton Layer(HAL)위에 계층화 되어 있다. 오디오 신호는 HAL를 통해 하드웨어로 전달되어진다. 실시간 오디오 정보가 필요하다면, Core Audio Framework에서 오디오 하드웨어 서비스를 이용하여 HAL에 접근 가능하다. Core MIDI(Musical Instrument Digital Interface) Framework에서는 MIDI 데이터 및 장치 작업을 위한 유사한 인터페이스를 제공한다.


Figure 1-1 OS X Core Audio Architecture


Core Audio Application-level-Services는 Audio  Toolbox 와 Audio Unit framework에서 확인할 수 있다.

  • Audio Queue Services를 사용하여 오디오 녹음, 재생, 일시 중지, 반복 및 동기화 할 수 있다.

  • 오디오 파일, Converter 및 Codec 서비스를 사용하여 디스크에서 읽고 쓸 수 있으며, 오디오 데이터 Format을 변환 시킬 수 있다. OS X에서는 사용자 정의 Codec을 만들 수도 있다.

  • Audio Unit Services 와 Audio Processing Graph Services(Audio Unit으로 통합)를 이용하여 Application의 Audio 장지(오디오 플러그 인)를 호스팅한다.

  • Music Sequencing Services를 이용하여 MIDI 기반 컨트롤 및 음악 데이터를 재생한다.

  • 오디오 및 MIDI 동기화 및 Time Format 관리를 위해 Core Audio Clock Services를 사용한다.

  • System Sound Services를 사용하여 System 소리와 사용자 Application Interface 음향 효과를 재생한다.



iOS의 Core Audio는 베터리 기반 모바일 플랫폼에서 사용할 수 있는 컴퓨팅 리소스에 최적화 되어있다. 따라서 OS의해 매우 엄격하게 관리되어야하는 서비스, 특히 HAL 및 I/O Kit에 대한 API는 존재하지 않는다. 그러나 iOS에는 OS X에는 없는 추가 Services들이 있다. 예를들어 Audio Session Services를 이용하면 휴대 전화 및 iPod 기능을 하는 장치의 Context에서 Application에서 오디오 동작을 관리 할 수 있다. 그림 1-2는 iOS의 오디오 아키텍처에 대한 상위 레벨을 보여준다.


Figure 1-2 iOS Core Audio architecture



잠깐! Digital Audio 와 Linear PCM에 대하여...

대부분의 Core Audio 서비스는 가장 일반적인 비 압축 디지털 오디오 데이터 형식인 Linear pulse-code-modulated(linear PCM) 포멧을 사용하고 다루게된다. Digital Audio 녹음은 일정한 간격(샘플링 속도-Sampling rate)으로 아날로그(실제-Real) 오디오 신호의 크기를 측정하고 각 샘플을 숫자 값으로 변환하여 PCM 데이터를 만든다. 표준 CD(Compact Disc) 오디오는 44.1 kHz의 샘플링 속도를 사용하며 각 샘플을 설명하는 16비트 정수는 해상도 또는 비트 심도를 구성한다.

  • Sample은 단일 채널에 대한 단일 숫자 값이다.

  • Frame은 시간과 일치하는 샘플들의 집합이다. 예들들어, 스테레오 사운드 파일에는 프레임당 두 개의 샘플이 있는데 하나는 왼족 채널을 표현하며 다른 하나는 오른쪽 채널을 표현한다.

  • Packet은 하나 이상의 인접한 Frame의 집합이다. Linear PCM Audio에서 패킷은 항상 단일 Frame이다. 압축 형식에서는 일반적으로 더 많이 사용된다. 패킷은 주어진 오디오 형식에 대해 프레임의 가장 작은 집합을 정의한다.


Linear PCM Audio에서 샘플 값은 해당 신호가 나타내는 원래 신호의 진폭에 따라 선형 적으로 변한다. 예를들어, 표준 CD 오디오의 16비트 정수 샘플은 무음과 최대 레벨 사이에서 65,536개의 가능한 값을 허용한다. 하나의 디지털 값에서 다음 디지털 값가지의 진폭 차이는 항상 동일하다.

CoreAudioTypes.h 헤더 파일에 선언 된 Core Audio 데이터 구조는 모든 샘플 속도 및 비트 심도에서 Linear PCM을 설명할 수 있다. Audio Data Format은 해당 링크를 참조하기 바란다.

OS X에서 Core Audio는 오디오 데이터가 기본 엔디안 32비트 부동 소수점 Linear PCM 형식이어야 한다고 간주한다. 오디오 Converter 서비스를 사용하여 서로 다른 Linear PCM간 오디오 데이터를 변환할 수 있다. 또한 이러한 Converter를 사용하여 Linear PCM과 MP3 및 Apple Lossless와 같은 압축 오디오 형식간 변환도 가능하다. OS X의 Core Audio는 가장 일반적인 디지털 오디오 포맷을 변환하는 코덱을 제공한다.(MP3로 변환하기 위한 인코더는 제공하지 않는다.)

iOS는 정수 및 고정 소수점 오디오 데이터를 사용한다. 그 결과 오디오 처리시 계산이 빨라지고 베터리 소모가 줄어 든다. iOS는 Converter 오디오 장치를 제공하며 오디오 Converter services 인터페이스를 제공한다. iOS및 OS X용 소위 표준 오디오 데이터 형식에 대한 자세한 사항은 해당 링크를 확인하기 바란다.

iOS 그리고 OS X에서의 Core Audio는 iPhone 오디오 파일 형식 및 OS X에서 지원되는 오디오 파일 및 데이터 형식에 설명된 대로 오디오 데이터 저장 및 재생을 위한 가장 일반적인 파일 형식을 지원한다.


Audio Units

Audio Units은 Audio Data를 처리하기 위한 Software plug-in 이다. OS X에서는 하나의 Audio Unit을 통해 무제한 채널과 Application으로 동시에 사용할 수 있다.

iOS에서는 모바일 플랫폼에서 효율성과 성능을 위해 최적화 된 Audio Units Sets를 제공한다. iOS Application에서 사용하기 위한 Audio Unit을 개발할 수 있다. Custom Audio Unit 코드는 정적으로 application에 연결해야 하기 때문에, customized된 Audio Unit은 iOS의 다른 application에서 사용할 수 없다.

iOS에서 제공되는 Audio Unit은 User Interface가 없다. 주요 용도는 application에 지연 시간이 짧은 오디오를 제공하는 것이다. iPhone Audio Unit에 대한 자세한 내용은 Core Audio Plug-in : Audio Units and Codecs 링크를 참조하기 바란다.

Application에서 사용 가능하도록 Audio DSP 코드를 개발하는 경우, audio Unit을 통해야만 가능하다.



정확하게 Core Audio가 제공하는 audio type은 다음과 같다.


1. Generator Unit : 소스로 부터 오디오 스트림을 만든다.(FILE, 네트워크 스트림, 메모리의 Data)

2. Instrument Unit : 1번의 generator unit과 비슷하나, MIDI 데이터로 부터 만든다.

3. Mixer Unit : 여러 스트림을 받아서 하나 혹은 여러 스트림으로 합친다. 2차원(스테레오) 또는 3차원 사운드로 만들수 있다.

4. Effect Unit : 디지털 프로세싱을 수행하여 효과를 만든다. (에코, 음정 조절, 노이즈 필터링)

5. Converter Unit : 다른 종류의 PCM으로 변환하거나, 플레이 속도등을 조절 한다.

6. Output Unit : Input/Output 하드웨어 인터페이스.(이름이 Output Unit이라고 해서  Output만 관여한다고 생각하면 안된다. Input 역할도 수행한다.)


당연하게도 Audio Unit끼리 서로 관계가 있다.

(Generator Unit에서 만든 Audio Stream이 출력되기 위해서는 Output Unit으로 가야되는것은 당연한 것)

이러한 관계를 표현하기 위해서 AUGraph라는게 필요하다. 좀더 자세하게 살펴 보자면 AUGraph안의 AUNode가 이러한 관계를 표현해준다.

(마치 커널의 Process 관리 방식과 같이 Struct와 Linked List Node의 관계처럼 말이다.)



The Hardware Abstraction Layer


Core Audio는 하드웨어 추상화 계층(HAL)을 사용하여 Application이 하드웨어와 상호 작용할 수 있도록 일관되고 예측 가능한 인터페이스를 제공한다. 또한 HAL은 Application에 Timing Information을 제공하여 동기화를 단순화 하거나 대기 시간을 조정할 수 있다.

대부분의 경우 작성되어지는 코드가 HAL과 직접적으로 상호 작용하지 않는다. Apple은 OS X의 AUHAL Unit 및 iOS의 AURemoteIO 장치라는 특수 오디오 Unit을 제공하여 다른 오디오 Unit의 오디오를 하드웨어로 전달할 수 있다. 마찬가지로, 하드웨어에서 들어오는 입력은 AUHAL Unit(또는 iOS의 AURemoteIO Unit)를 통해 라우팅 되고 그림 1-4와 같이 오디오 Unit에서 사용할 수 있다.


Figure 1-4 Hardware input through the HAL the AUHAL unit



반응형

'Software > iOS & Objective-C' 카테고리의 다른 글

Audio Unit Hosting Fundamentals  (0) 2016.12.06
Audio Unit Hosting에 대하여...  (0) 2016.12.05
Concurrency Programming Guide 요약  (0) 2016.10.10
[iOS] App 내에서 언어 변경법  (0) 2016.03.02
클래스 기본 문법  (0) 2015.11.09