개발/미디어개발

[iOS] AudioQueueInputCallback buffer 오디오 데이터 자르기

hagulu 하구루2017.02.25 16:45

AudioToolbox 에 AudioQueue 를 사용해서 레코딩을 하게 되는데,

AudioQueueInputCallback 를 통해서 인코딩된 음성 데이터를 얻어 올 수 있다.

이를 통해서 얻어온 오디오 데이터는 하나의 패킷이 아니라 여러 패킷이 하나로 뭉쳐있는 형태이다. 파일로 저장 할떄는 AudioFile.h 내의 메소드를 사용하면 큰 무리 없이 파일 저장이 가능하다.

하지만 데이터를 스트림 서버로 전달해야 하는 경우에는 달랐다.
일단 콜백을 통해서 전달되는 경우에는 데이터에 ADTS 데이터가 포함되어 있지 않다.
그 부분은 아래 포스팅 한 방식으로 어렵지 않게 추가가 가능하다.

하지만, 문제는 전달되는 데이터가 여러 패킷의 연속된 데이터라, 각 패킷마다 ADTS정보를
넣어 주어야 하는데 각 패킷의 자를 방법을 찾아야 했다.
콜백으로 전달된 데이터 중에 분명 해당 정보가 있을것이라 생각하고 파본 결과 역시나 존재하고 있었다.
void (*AudioQueueInputCallback)(
                 void *                  inUserData,
                 AudioQueueRef           inAQ,
                 AudioQueueBufferRef     inBuffer,
                 const AudioTimeStamp *  inStartTime,
                 UInt32                  inNumberPacketDescriptions,
                 const AudioStreamPacketDescription *inPacketDescs);
콜백의 원형은 위와 같다.
위 파라미터에서 inPacketDescs 이녀석을 주목하면 된다.

AudioStreamPacketDescription 구조체 타입이고 원형은 아래와 같다.
struct  AudioStreamPacketDescription
{
    SInt64  mStartOffset;
    UInt32  mVariableFramesInPacket;
    UInt32  mDataByteSize;
};
typedef struct AudioStreamPacketDescription AudioStreamPacketDescription;
보는것처럼 패킷의 offset과 size 정보가 들어 있다.
이를 통해서 packet을 나누어 주면 된다.
그리고 패킷은 inNumberPacketDescriptions개 이다.
inPacketDescs 은 보는것처럼 포인터로 배열 처럼 데이터가 저장되어 있다.

 inNumberPacketDescriptions 만큼 루프를 돌면서 inPacketDescs[1] 의 형태로 접근하면,
각각 패킷의 offset과 size정보를 얻어 올수 있게 된다.

이를 이용해서 각 패킷앞에 ADTS 데이터를 붙여주면 스트림으로 전달 가능한 완전한 오디오 데이터가 완성이 될수 있다.


신고

댓글

댓글쓰기 폼

개발/미디어개발

[미디어] ACC ADTS 생성하기

hagulu 하구루2017.02.25 16:44

AAC 는 최근 가장 많이 쓰이는 음성 코덱중에 하나이다.

아이폰과 아이팟에서 적극적으로 사용하면서 많이 확산된 코덱이다.
그와 관련 된 내용은 위키를 참조하기 바란다.

AAC 는 압축된 음성 데이터이고 이에 대응하는 헤더 정보가 ADTS이다.
ADTS를 들여다 보면 현재 압축되어 있는 음성정보에 대한 정보를 알수 있고,
디코더는 이 정보를 통해서 압축을 해제하여 PCM 데이터를 추출하게 된다.
그런데 가끔 AAC 를 다루다보면 압축된 데이터만 있고,  ADTS를 따로 추가해 줘야 하는 경우가 생긴다.

이런 상황에서 직접 ADTS를 생성하는 방법을 소개하려 한다.
일단 ADTS에 대한 정확한 정보는 아래 링크를 통해서 확인할수 있다.
링크를 보면 알수 있지만 총 7byte로 이루어 져있다.
(CRC를 포함한 9byte 형태도 있다.)

영어로 되어있고 복잡해 보이지만 여기서 주목해야할 데이터는 총 4가지이다.
2. Samplerate
3. Channels
4. 데이터 크기

1. MPEG-4 Audio Object Type 은 흔히 말하는 Audio Profile 이다.
아래 링크에 프로파일 인덱스가 있고 이 인덱스에서 1을 빼준값을 사용한다.
(*프로파일을 모를 때는 AAC LC (Low Complexity) 로 해보기 바란다. 최근에 가장 많이 쓰이는 프로파일이다) 

2. Samplerate도 인덱스로 입력이 되는데 해당 인덱스는 아래 링크를 확인하면 된다.

3. Channels 는 오디오의 채널을 그대로 입력하면 된다.
4. 데이터 크기는 헤더 크기 까지 포함한 전체 데이터 크기이다.

요 4가지만 입력해주면 헤더 정보는 완성된다.
다른부분은 적당한 기본값으로 채워 주면 된다.

아래와 같이 해당 변수에 적당한 값을 넣어주면 ADTS 데이터가 완성된다.

        Byte packet[7];
        // fill in ADTS data
        packet[0] = (Byte)0xFF;
        packet[1] = (Byte)0xF9;
        packet[2] = (Byte)(((audioProfile-1)<<6) + (sampleIndex<<2) +(channels>>2));
        packet[3] = (Byte)(((channels&0x3)<<6) + (dataLength>>11));
        packet[4] = (Byte)((dataLength&0x7FF) >> 3);
        packet[5] = (Byte)(((dataLength&0x7)<<5) + 0x1F);
        packet[6] = (Byte)0xFC;


이렇게 완성된 7byte를 AAC 데이터 앞에 붙여 주면 완성된다.


신고

댓글

댓글쓰기 폼

hagulu.com

.....

VISITED

Today : 103

Total : 119,814

Lately Comment