2010-01-08 3 views
1

압축 된 (mp3) 사운드를 PCM으로 저장하는 중 일부 진전이 있습니다. 또한 원본 파일을 동일한 프로세스 내에서 2 초 길이의 청크로 분할하려고했습니다. 나는 성공한 것처럼 보이지만, 나는 왜 그렇게 혼란 스럽다.ExtAudioFileConvert questions

오디오 블록을 읽고 파일을 쓰는 동안 내 파일이 2 초 제한을 초과하게하는 청크를 작성할지 확인합니다. 그렇다면 필자는 2 초 동안 파일을 닫은 다음 새 파일을 열고 나머지를 새 파일에 쓰고 충분한 양의 데이터를 읽으 려합니다. 이런 식으로 뭔가 :

여기
framesInTimedSegment += numFrames; 
if ((framesInTimedSegment > (2.0 * sampleRate)) && (j < 5)) { 
    UInt32 newNumFrames = numFrames; 
    numFrames = framesInTimedSegment - (2.0 * sampleRate); 
    newNumFrames -= numFrames; 
// Question A 
    UInt32 segmentOffset = newNumFrames * numChannels * 2; 
    error = ExtAudioFileWrite(segmentFile, newNumFrames, &fillBufList); 
// Question B 
     // handle this error! We might have an interruption 
    if (segmentFile) ExtAudioFileDispose(segmentFile); 
    XThrowIfError(ExtAudioFileCreateWithURL(urlArray[++j], kAudioFileCAFType, &dstFormat, NULL, kAudioFileFlags_EraseFile, &breakoutFile), "ExtAudioFileCreateWithURL failed! - segmentFile"); 
    size = sizeof(clientFormat); 
    XThrowIfError(ExtAudioFileSetProperty(segmentFile, kExtAudioFileProperty_ClientDataFormat, size, &clientFormat), "couldn't set destination client format"); 
    fillBufList.mBuffers[0].mData = srcBuffer + segmentOffset; 
    fillBufList.mBuffers[0].mDataByteSize = numFrames * fillBufList.mBuffers[0].mNumberChannels * 2; 
    framesInTimedSegment = numFrames; 
} 
error = ExtAudioFileWrite(segmentFile, numFrames, &fillBufList); 

는 내 질문 (I는 해당 줄 레이블을 시도)됩니다

A : 내 버퍼에의 오프셋 (offset)를 찾을 수있는 더 나은 방법이 있나요를 그래서 나는 잘못하지 않습니다 거기에 어떤 가치를 하드 코드합니까? 예를 들어 프레임 번호에서 데이터 오프셋을 가져 오는 축복받은 방법이 있습니까?

B : ExtAudioFileWrite가 압축에서 압축 해제로 변환하는 경우, 필자가 작성한 데이터가 아직 압축 해제되지 않았기 때문에 (즉,?) 프레임 번호 및 오프셋으로 재생할 때 걱정할 필요가 없습니다. 압축 된 데이터를 다루고 있습니까? 대신 파일을 PCM 파일이나 메모리로 변환 한 다음 해당 PCM을 분할해야합니까?

감사합니다.

-mahboud

ps.

 clientFormat = dstFormat; 

및 dstFormat :

 dstFormat.mFormatID = outputFormat; 
     dstFormat.mChannelsPerFrame = srcFormat.NumberChannels(); 
     dstFormat.mBitsPerChannel = 16; 
     dstFormat.mBytesPerPacket = dstFormat.mBytesPerFrame = 2 * dstFormat.mChannelsPerFrame; 
     dstFormat.mFramesPerPacket = 1; 
     dstFormat.mFormatFlags = kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger; // little-endian 

답변

2

그것은 조금 더 코드를 보지 않고 제대로 대답하기는 어렵습니다 다음과 같이

clientFormat가 정의됩니다. 그러나 clientFormat이 인터리브 PCM 형식이라고 가정하면 :

B) ExtAudioFileWrite는 설정 한 클라이언트 형식에 따라 압축에서 압축 해제로 변환하지 않으며 ExtAudioFileRead는 수행하지 않습니다. MP3 소스 파일과 "표준"16 비트 44.1 KHz PCM 클라이언트 형식을 가정하면 ExtAudioFileRead를 호출하면 MP3 바이트가 PCM 데이터로 변환됩니다. 이것은 AudioFile 및 AudioConverter API를 사용하여 수행됩니다.

가) 이것은 srcBuffer가 정의 된 방법을 보지 않고도 대답하기가 어렵습니다 (int16_t 배열로 가정). PCM 데이터로 작업한다면, 당신이하는 일은 괜찮아 보입니다. 또한 newNumFrames * clientFormat.mBytesPerFrame * clientFormat.mChannelsPerFrame을 사용할 수도 있지만 16 비트 PCM 데이터를 가정하면 mBytesPerFrame == mBytesPerPacket == 2. 비 CBR 데이터로 작업하는 경우 패킷 설명에 신경 써야하지만 그럴 것 같지 않습니다.

+0

아주 좋은 답변 위의 코드는 Apple 샘플 인 "iPhoneExtAudiofileConvertTest"에서 ExtAudioFileConvert.cpp에 대한 유일한 변경 사항입니다. 아마도 익숙 할 것입니다. 이 권리가 있는지 알려주십시오 : MP3를 읽고 PCM을 쓰는 경우 ExtAudioFileRead에서 변환이 발생하고 있습니다. PCM을 읽고 MP3를 쓰고 있다면 ExtAudioFileWrite에서 변환이 일어나고 있습니다. 그 맞습니까? 원래 질문에 클라이언트 형식을 추가했습니다. – mahboudz

+0

맞습니다. ExtAudioFileRead는 파일의 네이티브 형식을 클라이언트 형식으로 변환하고 ExtAudioFileWrite는 클라이언트 형식에서 파일의 출력 형식으로 변환합니다. – sbooth

+0

나는 다른 질문을하는 것을 싫어하지만 Apple의 샘플에서는 ExtAudioRead에 대한 인터럽트가 ExtAudioRead가 아니라 걱정스러운 것으로 보입니다. 그게 맞습니까? CoreAudio 메일 링리스트에 게시해야 할 수도 있습니다. – mahboudz