본문 바로가기
ios 뽀개기/objective-c

ios objective c 코어오디오 다루기 3 - AudioStreamBasicDescription 데이터 구조체

by 인생여희 2018. 11. 7.
반응형

ios objective c 코어오디오 다루기 3 - 데이터 구조체


코어오디오는 오디오 데이터 패킷을 스트림으로 본다. 

AudioStreamBasicDescription 구조체는 샘플율, 하나의 채널에 비트의 수, 프레임에 채널의 수등 데이터 구조를 묘사하는 메타데이터를 포함한다. 스트림의 ASBD에 관해 중요한점은 오디오 데이터 형식의 구현 세부사항이기 때문이다. 예로 파일이나 네트워크 스트림과 같은 어떤 소스에서 데이터를 읽을 때 코어 오디오의 여러 부분은 ASBD 값을 채운다. ASBD의 구조체 이름은 m으로 시작한다.


//

//  main.m

//

//

//  Created by MacBookPro on 06/11/2018.

//  Copyright © 2018 MacBookPro. All rights reserved.

//


#import <Foundation/Foundation.h>

#import <AudioToolbox/AudioToolbox.h>

int main(int argc, const char * argv[]) {

    

    //kAudioFileGlobalInfo_AvailableStreamDescriptionsForFormat의 속성을 사용하기 위해서 AudioFileTypeAndFormatID 구조체를

    //코어오디오에 전달해야 한다.

    AudioFileTypeAndFormatID fileTypeAndFormat;

    fileTypeAndFormat.mFileType = kAudioFileAIFFType;

    fileTypeAndFormat.mFormatID = kAudioFormatLinearPCM;

    //fileTypeAndFormat.mFileType = kAudioFileMP3Type;

    //fileTypeAndFormat.mFormatID = kAudioFormatMPEG4AAC; //aac 데이터를 mp3파일에 넣을 수 없다.

    

    //코어오디오 호출에서 결과 코드를 받기위한 변수

    OSStatus audioErr = noErr;

    //정보를 추출하기 전에 확인할 정보의 크기를 담을 변수 infoSize

    UInt32 infoSize = 0;

    

    //전역정보 속성을 얻는것은 속성의 크기를 미리 알아내고, UInt32 포인터에 저장하기 위함

    audioErr = AudioFileGetGlobalInfoSize(kAudioFileGlobalInfo_AvailableStreamDescriptionsForFormat,

                                          sizeof(fileTypeAndFormat),

                                          &fileTypeAndFormat,

                                          &infoSize);

    if(audioErr != noErr)

    {

       UInt32 err4cc = CFSwapInt32HostToBig(audioErr);

        NSLog(@"%4.4s", (char*)&err4cc);

    }

    

    

    assert(audioErr == noErr);      //aac 데이터를 mp3파일에 넣으면 fmt? 에러 발생

    

    //AudioFileGetGlobalInfoSize 호출은 실제로 전역 속성을 얻을 때 수신할 데이터의 양을 알려준다.

    //그 속성을 보관하기 위해서 메모리를 할당할 필요가 있다.

    AudioStreamBasicDescription *asbds = malloc(infoSize);

    

     //AudioFileTypeAndFormatID, 버퍼크기, 버퍼자체를 전달함.

    audioErr = AudioFileGetGlobalInfo(kAudioFileGlobalInfo_AvailableStreamDescriptionsForFormat,

                                      sizeof(fileTypeAndFormat),

                                      &fileTypeAndFormat,

                                      &infoSize,

                                      asbds);

    

    

    

    assert(audioErr == noErr);

    

    //속성 호출이 AudioStreamBasicDescription을 제공하고, 데이터의 크기를 asbd의 크기로 나눔으로써 배열의 길이를 가늠할 수 있다.

    int asbdCount = infoSize / sizeof(AudioStreamBasicDescription);

    for (int i = 0; i < asbdCount; i ++) {

        //네문자로된 코드 숫자형식을 읽기 가능한 네개의 문자로 변경하기 위함. 엔디언 교환으로 실행함

        UInt32 format4cc = CFSwapInt32HostToBig(asbds[i].mFormatID);

        //mFormatID의 엔디언 교환 표현을 보기 좋게 출력함.

        NSLog(@"%d : mFormatId : %4.4s, mFormatFlags : %d, mBitsPerChannel: %d",

              i,

              (char*)&format4cc,

              asbds[i].mFormatFlags,

              asbds[i].mBitsPerChannel);

    }

    

    free(asbds);

    

    return 0;

}




//1.결과

 //fileTypeAndFormat.mFileType = kAudioFileAIFFType;

//2018-11-06 21:57:17.243110+0900 3[932:67326] 0 : mFormatId : lpcm, mFormatFlags : 14, mBitsPerChannel: 8

//2018-11-06 21:57:17.243354+0900 3[932:67326] 1 : mFormatId : lpcm, mFormatFlags : 14, mBitsPerChannel: 16

//2018-11-06 21:57:17.243372+0900 3[932:67326] 2 : mFormatId : lpcm, mFormatFlags : 14, mBitsPerChannel: 24

//2018-11-06 21:57:17.243387+0900 3[932:67326] 3 : mFormatId : lpcm, mFormatFlags : 14, mBitsPerChannel: 32

/*

    aiff 가 pcm 형식에서 비트 깊이가 다른 형태만 지원함으로써 다양성이 부족함을 보여준다.

 

 

 2.변경

 아래코드로 변경했을때

 fileTypeAndFormat.mFileType = kAudioFileWAVEType;

 2018-11-06 22:13:11.776434+0900 3[981:92111] 0 : mFormatId : lpcm, mFormatFlags : 8, mBitsPerChannel: 8

 2018-11-06 22:13:11.777009+0900 3[981:92111] 1 : mFormatId : lpcm, mFormatFlags : 12, mBitsPerChannel: 16

 2018-11-06 22:13:11.777053+0900 3[981:92111] 2 : mFormatId : lpcm, mFormatFlags : 12, mBitsPerChannel: 24

 2018-11-06 22:13:11.777104+0900 3[981:92111] 3 : mFormatId : lpcm, mFormatFlags : 12, mBitsPerChannel: 32

 2018-11-06 22:13:11.777119+0900 3[981:92111] 4 : mFormatId : lpcm, mFormatFlags : 9, mBitsPerChannel: 32

 2018-11-06 22:13:11.777134+0900 3[981:92111] 5 : mFormatId : lpcm, mFormatFlags : 9, mBitsPerChannel: 64

 

 wav 파일이 다른 스타일의 pcm을 취함을 보여줌. wav파일은 항상 리틀엔디언 pcm으을 설정하고, 이는 형식이 정수 샘플에만 국한되지는 않는다.

 

 

 3.아래코드로 변경

 fileTypeAndFormat.mFileType = kAudioFileCAFType;

 2018-11-06 22:16:37.847672+0900 3[998:99577] 0 : mFormatId : lpcm, mFormatFlags : 14, mBitsPerChannel: 8

 2018-11-06 22:16:37.847877+0900 3[998:99577] 1 : mFormatId : lpcm, mFormatFlags : 14, mBitsPerChannel: 16

 2018-11-06 22:16:37.847899+0900 3[998:99577] 2 : mFormatId : lpcm, mFormatFlags : 14, mBitsPerChannel: 24

 2018-11-06 22:16:37.847929+0900 3[998:99577] 3 : mFormatId : lpcm, mFormatFlags : 14, mBitsPerChannel: 32

 2018-11-06 22:16:37.847950+0900 3[998:99577] 4 : mFormatId : lpcm, mFormatFlags : 11, mBitsPerChannel: 32

 2018-11-06 22:16:37.847977+0900 3[998:99577] 5 : mFormatId : lpcm, mFormatFlags : 11, mBitsPerChannel: 64

 2018-11-06 22:16:37.847998+0900 3[998:99577] 6 : mFormatId : lpcm, mFormatFlags : 12, mBitsPerChannel: 16

 2018-11-06 22:16:37.848017+0900 3[998:99577] 7 : mFormatId : lpcm, mFormatFlags : 12, mBitsPerChannel: 24

 2018-11-06 22:16:37.848036+0900 3[998:99577] 8 : mFormatId : lpcm, mFormatFlags : 12, mBitsPerChannel: 32

 2018-11-06 22:16:37.848055+0900 3[998:99577] 9 : mFormatId : lpcm, mFormatFlags : 9, mBitsPerChannel: 32

 2018-11-06 22:16:37.848073+0900 3[998:99577] 10 : mFormatId : lpcm, mFormatFlags : 9, mBitsPerChannel: 64

 caf는 여러가지 형식을 취하고, 정수와 부동소수점 샘플과 양과 음의 정수를 모두 사용한다.이는 aiff와 wav가 제공하는 하나를 제외한 모든 형식을 지원한다.

 

 

 4.아래코드로 변경

 fileTypeAndFormat.mFormatID = kAudioFormatMPEG4AAC;

 2018-11-06 22:20:17.493762+0900 3[1031:106537] 0 : mFormatId : aac , mFormatFlags : 0, mBitsPerChannel: 0

 aac가 caf 파일에 유요한 형태임을 알 수 있다.

 

 

 

 5.아래코드로 변경

 fileTypeAndFormat.mFileType = kAudioFileMP3Type;

 fileTypeAndFormat.mFormatID = kAudioFormatMPEG4AAC;

 오류발생 : fmt?

 aac데이터를 mp3 파일에 넣을 수 없다.(파일형식과 데이터 형식은 다르다.)

 */


반응형

댓글