문제

압축 된 (MP3) 사운드를 취하고 PCM으로 저장하는 데 약간의 진전이 있습니다. 또한 동일한 프로세스 내에서 원본 파일을 2 초 길이의 청크로 나누고 싶었습니다. 나는 성공한 것 같지만 왜 그런지에 대해 조금 혼란스러워합니다.

오디오 블록을 읽고 파일을 작성하면 파일이 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);

내 질문은 다음과 같습니다 (관련 줄에 레이블을 붙이려고했습니다).

A : 버퍼에 오프셋을 찾을 수있는 더 좋은 방법이 있으므로 거기에 약간의 값이 잘못되어 있지 않습니까? 예를 들어, 프레임 번호에서 데이터 오프셋을 얻을 수있는 축복받은 방법이 있습니까?

B : excupilewrite가 압축에서 압축 압축으로 변환하는 경우, 내가 쓰고있는 데이터가 아직 압축 압축되지 않았으므로 (오른쪽?), 내가 처리 할 때 프레임 번호와 오프셋을 사용하는 것에 대해 걱정할 필요가 없습니다. 압축 데이터? 대신 파일을 먼저 PCM 파일 또는 메모리로 변환 한 다음 해당 PCM을 분할해야합니까?

감사!

-Mahboud

추신.

ClientFormat은 다음과 같이 정의됩니다.

        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
도움이 되었습니까?

해결책

조금 더 많은 코드를 보지 않고는 올바르게 대답하기가 어렵습니다. 그러나 ClientFormat이 인터리브 PCM 형식이라고 가정합니다.

b) excupilewrite는 압축에서 압축 압축으로의 전환을 수행하지 않습니다. MP3 소스 파일과 "표준"16 비트 44.1 khz pcm 클라이언트 형식을 가정하면 Excudiofileread에 대한 호출은 MP3 바이트에서 PCM 데이터로 변환됩니다. 이것은 Audiofile 및 AudioConverter API를 사용하여 후드 아래에서 수행됩니다.

a) 이것은 SRCBuffer가 어떻게 정의되는지 보지 않고 대답하기가 약간 어렵습니다 (INT16_T 배열을 가정합니다). PCM 데이터로 작업하는 경우하고있는 일은 괜찮아 보입니다. NewNumFrames * ClientFormat.MbyTesperFrame * ClientFormat.mchannelsperFrame을 사용할 수도 있지만 16 비트 PCM 데이터를 가정하면 MByTesperFrame == MByTesperPacket == 2를 사용할 수 있습니다. 그것은 사실이 아닌 것 같습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top