2016-12-24 1 views
4

.m4a 오디오 파일을 뒤집어 내보낼 수있는 방법이 있습니까? 오디오 트랙 here을 뒤집을 해결책을 찾았지만 .caf 파일 형식에서만 작동하는 것 같습니다. 유일한 방법은 .caf를 사용하는 것입니다. .m4a 파일을 .caf 파일로 먼저 변환하는 방법이 있습니까?오디오 파일 반전하기 Swift/Objective-C

업데이트 : AVAssetReader 오디오 파일에서 오디오 샘플을 읽을 수 있습니다,하지만 난 어떻게 다시 역순으로 샘플을 작성하는 아무 생각이 없다는 것을 발견 another post에서 . 아래의 코드 스 니펫은 게시물의 답변입니다. 어떤 도움을 주시면 감사하겠습니다. 덕분에

+ (void) reverseAudioTrack: (AVAsset *)audioAsset outputURL: (NSURL *)outputURL { 
NSError *error; 

AVAssetReader* reader = [[AVAssetReader alloc] initWithAsset:audioAsset error:&error]; 
if (error) {NSLog(@"%@", error.localizedDescription);} 

AVAssetTrack* track = [[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; 

NSMutableDictionary* audioReadSettings = [NSMutableDictionary dictionary]; 
[audioReadSettings setValue:[NSNumber numberWithInt:kAudioFormatLinearPCM] 
        forKey:AVFormatIDKey]; 

AVAssetReaderTrackOutput* readerOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:track outputSettings:audioReadSettings]; 
[reader addOutput:readerOutput]; 
[reader startReading]; 

CMSampleBufferRef sample; //= [readerOutput copyNextSampleBuffer]; 
NSMutableArray *samples = [[NSMutableArray alloc] init]; 

// Get all samples 
while((sample = [readerOutput copyNextSampleBuffer])) { 
    [samples addObject:(__bridge id)sample]; 
    CFRelease(sample); 
} 

// Process samples in reverse 
AudioChannelLayout acl; 
bzero(&acl, sizeof(acl)); 
acl.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo; 

AVAssetWriter *writer = [[AVAssetWriter alloc] initWithURL:outputURL 
                fileType:AVFileTypeAppleM4A 
                 error:&error]; 
if (error) {NSLog(@"%@", error.localizedDescription);} 
NSDictionary *writerOutputSettings = [ NSDictionary dictionaryWithObjectsAndKeys: 
             [ NSNumber numberWithInt: kAudioFormatAppleLossless ], AVFormatIDKey, 
             [ NSNumber numberWithInt: 16 ], AVEncoderBitDepthHintKey, 
             [ NSNumber numberWithFloat: 44100.0 ], AVSampleRateKey, 
             [ NSNumber numberWithInt: 1 ], AVNumberOfChannelsKey, 
             [ NSData dataWithBytes: &acl length: sizeof(acl) ], AVChannelLayoutKey, nil ]; 

AVAssetWriterInput *audioWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:writerOutputSettings]; 

[writer addInput:audioWriterInput]; 
[writer startWriting]; 
[writer startSessionAtSourceTime:CMSampleBufferGetPresentationTimeStamp((__bridge CMSampleBufferRef)samples[0]) ]; 

// (1) Would it work if I loop in reverse here? 
for (NSInteger i = 0; i < samples.count; i++) { 
    CMBlockBufferRef buffer = CMSampleBufferGetDataBuffer((__bridge CMSampleBufferRef)samples[i]); 

    CMItemCount numSamplesInBuffer = CMSampleBufferGetNumSamples((__bridge CMSampleBufferRef)samples[i]); 
    AudioBufferList audioBufferList; 
    CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer((__bridge CMSampleBufferRef)samples[i], 
                  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 

      // (2) What should I be doing to write the samples into an audio file? 
     } 
    } 
    CFRelease(buffer); 
} 
+0

샘플을 '// 모든 샘플 가져 오기'에서 만든 후 되돌리려면 어떻게해야합니까? – Guig

+0

@Guig 그래, 문제는'// (2) 내가해야할 일은 ... '이다. 샘플을 하나의 오디오 파일에 쓰는 법을 모르겠다./ –

답변

1

예, 오디오 파일 중 하나가되는 아이폰 OS 지원이, 당신이 처리 할 수있는 방법, 수출이 있습니다.

그러나 대부분의 형식 (mp3은 이름이 불완전합니다)이 손실되고 압축되었습니다. 먼저 데이터의 압축을 풀고 변형을 적용한 다음 다시 압축해야합니다. 오디오 정보에 적용 할 대부분의 변형은 원시 PCM 수준에서 수행되어야합니다.

이 두 문장을 결합, 당신이 몇 패스 수행

  1. 임시 파일 (내용을 역) AIFF
  2. 과정
  3. 처럼 kAudioFormatLinearPCM 준수 오디오 파일을 원본 파일을 변환 임시 파일을 원래 형식으로 다시 변환하십시오.

압축 된 jpeg 이미지에 변형을 적용하는 것처럼 프로세스가 저하됩니다. 최종 오디오는 기껏해야 압축 과정을 한 번 더 거치게됩니다.

그래서이 접근법에 대한 실제 수학적 대답은 실제로 아니오입니다.


그냥 참조를 위해, 여기가 파일 헤더를 건너 뛰려면 더 세련미를 필요로 신속 3. 일부 스타터 코드입니다.

var outAudioFile:AudioFileID? 
var pcm = AudioStreamBasicDescription(mSampleRate: 44100.0, 
             mFormatID: kAudioFormatLinearPCM, 
             mFormatFlags: kAudioFormatFlagIsBigEndian | kAudioFormatFlagIsSignedInteger, 
             mBytesPerPacket: 2, 
             mFramesPerPacket: 1, 
             mBytesPerFrame: 2, 
             mChannelsPerFrame: 1, 
             mBitsPerChannel: 16, 
             mReserved: 0) 

var theErr = AudioFileCreateWithURL(destUrl as CFURL!, 
            kAudioFileAIFFType, 
            &pcm, 
            .eraseFile, 
            &outAudioFile) 
if noErr == theErr, let outAudioFile = outAudioFile { 
    var inAudioFile:AudioFileID? 
    theErr = AudioFileOpenURL(sourceUrl as! CFURL, .readPermission, 0, &inAudioFile) 

    if noErr == theErr, let inAudioFile = inAudioFile { 

     var fileDataSize:UInt64 = 0 
     var thePropertySize:UInt32 = UInt32(MemoryLayout<UInt64>.stride) 
     theErr = AudioFileGetProperty(inAudioFile, 
             kAudioFilePropertyAudioDataByteCount, 
             &thePropertySize, 
             &fileDataSize) 

     if(noErr == theErr) { 
      let dataSize:Int64 = Int64(fileDataSize) 
      let theData = UnsafeMutableRawPointer.allocate(bytes: Int(dataSize), 
                  alignedTo: MemoryLayout<UInt8>.alignment) 

      var readPoint:Int64 = Int64(dataSize) 
      var writePoint:Int64 = 0 

      while(readPoint > 0) 
      { 
       var bytesToRead = UInt32(2) 

       AudioFileReadBytes(inAudioFile, false, readPoint, &bytesToRead, theData) 
       AudioFileWriteBytes(outAudioFile, false, writePoint, &bytesToRead, theData) 

       writePoint += 2 
       readPoint -= 2 
      } 

      theData.deallocate(bytes: Int(dataSize), alignedTo: MemoryLayout<UInt8>.alignment) 

      AudioFileClose(inAudioFile); 
      AudioFileClose(outAudioFile); 
     } 
    } 
} 
+0

정말 감사합니다! 나는 꽤 오랫동안 이것에 집착 해왔다. .m4a에서 .aiff로 오디오 파일을 변환하려고했지만 어떤 이유로 작동하지 않습니다. 나는 [다른 질문] (http://stackoverflow.com/questions/41436229/converting-m4a-file-to-aiff-using-audioconverter-swift)에 물었다. 그걸 도와 줄 수 있니? –