2010-11-28 5 views
7

iPhone/iPad에서 오디오 파일의 원시 데이터에 액세스하려고합니다. 나는 필요한 경로를 따라 가기 시작한 다음 코드를 가지고있다. 그러나 일단 AudioBuffer를 사용하면 무엇을 해야할지에 난처한 상황에 처하게됩니다.Core Audio AudioBuffer의 프레임 수를 확인하십시오.

AVAssetReader *assetReader = [AVAssetReader assetReaderWithAsset:urlAsset error:nil]; 
AVAssetReaderTrackOutput *assetReaderOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:[[urlAsset tracks] objectAtIndex:0] outputSettings:nil]; 
[assetReader addOutput:assetReaderOutput]; 
[assetReader startReading]; 

CMSampleBufferRef ref; 
NSArray *outputs = assetReader.outputs; 
AVAssetReaderOutput *output = [outputs objectAtIndex:0]; 
int y = 0; 
while (ref = [output copyNextSampleBuffer]) { 
    AudioBufferList audioBufferList; 
    CMBlockBufferRef blockBuffer; 
    CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(ref, NULL, &audioBufferList, sizeof(audioBufferList), NULL, NULL, 0, &blockBuffer); 
    for (y=0; y<audioBufferList.mNumberBuffers; y++) { 
     AudioBuffer audioBuffer = audioBufferList.mBuffers[y]; 
     SInt16 *frames = audioBuffer.mData; 
     for(int i = 0; i < 24000; i++) { // This sometimes crashes 
      Float32 currentFrame = frames[i]/32768.0f; 
     } 
    } 
} 

기본적으로 나는 각 버퍼는 내가 확실하게 그들로부터 데이터를 추출 할 수 없습니다 포함 프레임 수를 확인하는 방법을 모르겠어요. 필자는 원시 오디오 데이터 작업에 익숙하지 않으므로 AudioBuffer 구조체의 mData 속성을 가장 잘 읽는 방법에 대한 제안은 열려 있습니다. 나는 또한 과거에 무효 포인터로 많은 일을하지 않았으므로이 컨텍스트에서 도움이 될 것입니다!

+0

뛰어난 질문! 귀하의 질문은 내 비슷한 문제를 해결하는 데 도움이되었습니다. – user523234

+0

blockBuffer를 누출하고 있습니다 –

답변

13

audioBuffer.mDataByteSize는 버퍼 크기를 알려줍니다. 이거 아시나요? 그냥 AudioBuffer 구조체의 선언을 보지 못했을 때 말입니다. 헤더 파일과 문서를 항상 확인해야합니다.

mDataByteSize를 이해하려면 데이터 형식을 알아야합니다. 출력 값의 수는 mDataByteSize/sizeof (outputType)입니다. 그러나 형식에 대해 혼란스러워합니다. 어딘가에 지정해야합니다. 16 비트가 INT

SInt16 *frames = audioBuffer.mData

서명으로 우선 당신이 그것을 치료하면 24000 개 값은, 물론이 뜻이 있다고 가정 inbetween 당신은 32 비트 부동 소수점

Float32 currentFrame = frames[i]/32768.0f

로 취급 정확히 24000 16 비트 값이 없으면 충돌이 발생합니다. 또한 데이터를 '프레임'이라고 부르지 만 실제로 의미하는 것은 샘플입니다. 'currentFrame'이라고 부르는 각 값은 오디오의 한 샘플입니다. '프레임'은 일반적으로 .mData와 같은 샘플 블록을 나타냅니다.

데이터 형식이 32 비트 플로트라고 가정 할 때 (또한 유의할 점, 8 비트 정수 또는 32 비트 고정인지는 모르겠습니다. 내가 아는 누구나를 위해)

for(int y=0; y<audioBufferList.mNumberBuffers; y++) 
{ 
    AudioBuffer audioBuffer = audioBufferList.mBuffers[y]; 
    int bufferSize = audioBuffer.mDataByteSize/sizeof(Float32); 
    Float32 *frame = audioBuffer.mData; 
    for(int i=0; i<bufferSize; i++) { 
    Float32 currentSample = frame[i]; 
    } 
} 

참고 sizeof (Float32)는 항상 4 다. 그러나 나는 그것을 명백하게했다.

+0

audioBuffer.mDataByteSize/sizeof (Float32)는 제가 감사해야 할 부분이었습니다! – macinjosh

+0

AudioBuffer를 cmd를 클릭하면 xcode는 헤더 파일의 엄격한 선언으로 이동해야합니다. 당신이 다루고있는 것을 조사하는데 유용합니다. – hooleyhoop

+4

어긋남이지만 프레임의 Core Audio 정의는 모든 채널에서 하나의 샘플입니다. – sbooth

관련 문제