AVAssetReader를 통해 오디오 샘플을 어떻게 읽으십니까? AVAssetReader를 사용하여 복제 또는 믹싱 예제를 찾았지만 이러한 루프는 항상 AVAssetWriter 루프에 의해 제어됩니다. AVAssetReader를 만들고이를 통해 읽을 수 있으며 각 샘플을 가져 와서 각 오디오 샘플의 int32를 배열에 던져 넣을 수 있습니까?AVAssetReader를 통해 오디오 샘플 읽기
감사합니다.
AVAssetReader를 통해 오디오 샘플을 어떻게 읽으십니까? AVAssetReader를 사용하여 복제 또는 믹싱 예제를 찾았지만 이러한 루프는 항상 AVAssetWriter 루프에 의해 제어됩니다. AVAssetReader를 만들고이를 통해 읽을 수 있으며 각 샘플을 가져 와서 각 오디오 샘플의 int32를 배열에 던져 넣을 수 있습니까?AVAssetReader를 통해 오디오 샘플 읽기
감사합니다.
@ amrox의 답변을 확장하면 CMBlockBufferRef에서 AudioBufferList를 가져올 수 있습니다.
CMItemCount numSamplesInBuffer = CMSampleBufferGetNumSamples(buffer);
AudioBufferList audioBufferList;
CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(
buffer,
NULL,
&audioBufferList,
sizeof(audioBufferList),
NULL,
NULL,
kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment,
&buffer
);
for (int bufferCount=0; bufferCount < audioBufferList.mNumberBuffers; bufferCount++) {
SInt16* samples = (SInt16 *)audioBufferList.mBuffers[bufferCount].mData;
for (int i=0; i < numSamplesInBuffer; i++) {
// amplitude for the sample is samples[i], assuming you have linear pcm to start with
}
}
//Release the buffer when done with the samples
//(retained by CMSampleBufferGetAudioBufferListWithRetainedblockBuffer)
CFRelease(buffer);
AVAssetReader *reader = [[AVAssetReader alloc] initWithAsset:asset error:&error];
AVAssetTrack *track = [[asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
NSDictionary *settings = @{ AVFormatIDKey : [NSNumber numberWithInt:kAudioFormatLinearPCM] };
AVAssetReaderTrackOutput *readerOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:track
outputSettings:settings];
[reader addOutput:readerOutput];
[reader startReading];
CMSampleBufferRef sample = [readerOutput copyNextSampleBuffer];
while (sample)
{
sample = [readerOutput copyNextSampleBuffer];
if (! sample)
{
continue;
}
CMBlockBufferRef buffer = CMSampleBufferGetDataBuffer(sample);
size_t lengthAtOffset;
size_t totalLength;
char *data;
if (CMBlockBufferGetDataPointer(buffer, 0, &lengthAtOffset, &totalLength, &data) != noErr)
{
NSLog(@"error!");
break;
}
// do something with data...
CFRelease(sample);
}
감사합니다. @amrox. 이것은 약간을 돕는다. 그러나 출력을 추가하고 독서를 시작하는 것이 빠진 것 같습니다. 그냥 다음과 같이 추가 할 수 있습니다 : \t [reader addOutput : readerOutput]; \t [독자 시작 읽기]; readerOutput을 만든 후에는 맞습니까? 일단 추가하면 전체 오디오 파일을 읽지 않고 한두 번만 읽을 수 있습니다. 그게 어떻게 작동해야합니까? 그렇다면이 방법으로 개별 샘플에 어떤 영향을 미치는지 이해할 수 없습니다. 오디오 파일의 각 샘플은 비트 깊이와 샘플 속도로 정의 된 양과 범위와 함께 int입니다. 그 int들에 어떻게 접근 할 수 있습니까? 다시 한 번 감사드립니다. –
그들은 char * 데이터에 있습니다. 더 많은 제어가 필요하면 설정 사전에 더 많은 키를 설정하십시오 : AVNumberOfChannelsKey, AVLinearPCMBitDepthKey. 그리고 amrox에 현상금을 수여하는 것을 잊지 마십시오. –
여기에 나온 대답은 일반적인 것이 아닙니다. AudioBufferList
크기를 다르게 조정해야하는 경우 CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer
에 대한 호출이 실패 할 수 있습니다. 비 intererleaved 샘플을 예로 들면.
올바른 방법은 CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer
을 두 번 호출하는 것입니다. 첫 번째 호출은 AudioBufferList
에 필요한 크기를 쿼리하고 두 번째 호출은 실제로 AudioBufferList
을 채 웁니다. 당신은 오류 처리를 수행해야하고 또한 모든 프레임을 malloc을해서는 안 실제 예에서
size_t bufferSize = 0;
CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(
sampleBuffer,
&bufferSize,
NULL,
0,
NULL,
NULL,
0,
NULL
);
AudioBufferList *bufferList = malloc(bufferSize);
CMBlockBufferRef blockBuffer = NULL;
CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(
sampleBuffer,
NULL,
bufferList,
bufferSize,
NULL,
NULL,
kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment,
&blockBuffer
);
// handle audio here
free(bufferList);
CFRelease(blockBuffer);
는 대신
AudioBufferList
을 캐시합니다.
정말 고마워요! 그게 내가 놓친 부분 이었어. –
이 방법을 사용할 때 사운드가 고르지 않게됩니다. char *를 사용하는 @ amrox의 방법을 사용할 때'samples [i] * = 0.5; '와 같은 것을 수행하여 볼륨을 변경할 때 모든 것이 잘 작동합니다. – Dex
샘플을 가져 와서 다른 오디오 파일에 쓸 수 있습니까? 오디오 파일을 뒤집어 쓰려고합니다. 제발 [제 질문] (http://stackoverflow.com/questions/41310944/reverse-an-audio-file-swift-objective-c)을보십시오. 어떤 도움을 주시면 감사하겠습니다. –