2011-08-03 37 views
10

Viết lại câu hỏi này để thành công hơn một chút.Ghi âm thanh vào đĩa từ thiết bị IO

Vấn đề của tôi là tôi không thể ghi thành công tệp âm thanh vào đĩa từ Thiết bị IO từ xa.

Các bước tôi đã thực hiện là

Mở tệp mp3 và trích xuất âm thanh của nó thành bộ đệm. Tôi thiết lập một asbd để sử dụng với biểu đồ của tôi dựa trên các thuộc tính của biểu đồ. Tôi thiết lập và chạy đồ thị của tôi lặp lại âm thanh và âm thanh được trích xuất thành công.

Điều tôi đang gặp khó khăn là lấy mẫu âm thanh từ cuộc gọi lại từ xa IO và ghi chúng vào tệp âm thanh trên đĩa mà tôi đang sử dụng ExtAudioFileWriteASync.

Tệp âm thanh không được viết và mang một số tính tương đồng có thể kiểm tra đối với bản gốc mp3 nhưng có vẻ rất bị méo.

Tôi không chắc chắn nếu vấn đề là

A) ExtAudioFileWriteAsync không thể viết các mẫu càng nhanh càng đơn vị io gọi lại cung cấp cho họ.

  • hoặc -

B) Tôi đã thiết lập các ASBD cho refeference extaudiofile sai. Tôi muốn bắt đầu bằng cách lưu một tập tin wav. Tôi không chắc chắn nếu tôi đã mô tả điều này đúng trong ASBD dưới đây.

Thứ hai, tôi không chắc chắn giá trị nào cần chuyển cho thuộc tính inChannelLayout khi tạo tệp âm thanh.

Và cuối cùng tôi rất không chắc chắn về những gì asbd sử dụng cho kExtAudioFileProperty_ClientDataFormat. Tôi đã sử dụng định dạng luồng âm thanh nổi nhưng nhìn kỹ hơn các tài liệu nói rằng đây phải là pcm. Đây có phải là định dạng giống như đầu ra cho remoteio không? Và nếu như vậy là tôi sai để thiết lập định dạng đầu ra của io từ xa để stereostreamformat?

Tôi nhận thấy có rất nhiều điều khủng khiếp trong câu hỏi này nhưng tôi có rất nhiều điều không chắc chắn mà tôi không thể tự mình làm rõ.

định dạng dòng thiết lập âm thanh stereo

- (void) setupStereoStreamFormat 
{ 

    size_t bytesPerSample = sizeof (AudioUnitSampleType); 
    stereoStreamFormat.mFormatID   = kAudioFormatLinearPCM; 
    stereoStreamFormat.mFormatFlags  = kAudioFormatFlagsAudioUnitCanonical; 
    stereoStreamFormat.mBytesPerPacket = bytesPerSample; 
    stereoStreamFormat.mFramesPerPacket = 1; 
    stereoStreamFormat.mBytesPerFrame  = bytesPerSample; 
    stereoStreamFormat.mChannelsPerFrame = 2;     // 2 indicates stereo 
    stereoStreamFormat.mBitsPerChannel = 8 * bytesPerSample; 
    stereoStreamFormat.mSampleRate  = engineDescribtion.samplerate; 

    NSLog (@"The stereo stereo format :"); 


} 

thiết lập remoteio gọi lại sử dụng định dạng dòng stereo

AudioUnitSetProperty(engineDescribtion.masterChannelMixerUnit, 
          kAudioUnitProperty_StreamFormat, 
          kAudioUnitScope_Output, 
          masterChannelMixerUnitloop, 
          &stereoStreamFormat, 
          sizeof(stereoStreamFormat)); 

     AudioUnitSetProperty(engineDescribtion.masterChannelMixerUnit, 
          kAudioUnitProperty_StreamFormat, 
          kAudioUnitScope_Input, 
          masterChannelMixerUnitloop, 
          &stereoStreamFormat, 
          sizeof(stereoStreamFormat)); 




static OSStatus masterChannelMixerUnitCallback(void *inRefCon, 
           AudioUnitRenderActionFlags *ioActionFlags, 
           const AudioTimeStamp *inTimeStamp, 
           UInt32 inBusNumber, 
           UInt32 inNumberFrames, 
           AudioBufferList *ioData) 

{ 

    // ref.equnit; 
    //AudioUnitRender(engineDescribtion.channelMixers[inBusNumber], ioActionFlags, inTimeStamp, 0, inNumberFrames, ioData); 
    Engine *engine= (Engine *) inRefCon; 
    AudioUnitRender(engineDescribtion.equnit, ioActionFlags, inTimeStamp, 0, inNumberFrames, ioData); 

    if(engine->isrecording) 
    { 
     ExtAudioFileWriteAsync(engine->recordingfileref, inNumberFrames, ioData); 

    } 


    return 0; 

} 

** thiết lập ghi âm **

-(void)startrecording 

{ 

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    destinationFilePath = [[NSString alloc] initWithFormat: @"%@/testrecording.wav", documentsDirectory]; 
    destinationURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)destinationFilePath, kCFURLPOSIXPathStyle, false); 

    OSStatus status; 

    // prepare a 16-bit int file format, sample channel count and sample rate 
    AudioStreamBasicDescription dstFormat; 
    dstFormat.mSampleRate=44100.0; 
    dstFormat.mFormatID=kAudioFormatLinearPCM; 
    dstFormat.mFormatFlags=kAudioFormatFlagsNativeEndian|kAudioFormatFlagIsSignedInteger|kAudioFormatFlagIsPacked; 
    dstFormat.mBytesPerPacket=4; 
    dstFormat.mBytesPerFrame=4; 
    dstFormat.mFramesPerPacket=1; 
    dstFormat.mChannelsPerFrame=2; 
    dstFormat.mBitsPerChannel=16; 
    dstFormat.mReserved=0; 

    // create the capture file 
    status= ExtAudioFileCreateWithURL(destinationURL, kAudioFileWAVEType, &dstFormat, NULL, kAudioFileFlags_EraseFile, &recordingfileref); 
    CheckError(status ,"couldnt create audio file"); 
     // set the capture file's client format to be the canonical format from the queue 
status=ExtAudioFileSetProperty(recordingfileref, kExtAudioFileProperty_ClientDataFormat, sizeof(AudioStreamBasicDescription), &stereoStreamFormat); 

    CheckError(status ,"couldnt set input format"); 

    ExtAudioFileSeek(recordingfileref, 0); 
isrecording=YES; 

    // [documentsDirectory release]; 


} 

chỉnh sửa 1

Tôi đang thực sự đâm trong bóng tối ở đây bây giờ nhưng tôi có cần sử dụng trình chuyển đổi âm thanh hay không kExtAudioFileProperty_ClientDataFormat sẽ xử lý điều đó?

chỉnh sửa 2

Im gắn 2 mẫu âm thanh. Đầu tiên là âm thanh gốc mà Im lặp và cố gắng sao chép. Thứ hai là âm thanh được ghi lại của vòng lặp đó. Hy vọng rằng nó có thể cung cấp cho ai đó một đầu mối như những gì đang xảy ra sai.

Original mp3

Problem recording of mp3

+0

Câu hỏi ngu ngốc, nhưng bạn có kiểm tra xem liệu 'sizeof (AudioUnitSampleType);' trả về cùng kích thước như bạn đang gán cho 'mBytesPerPacket'? –

+0

Tôi đã kiểm tra kỹ để chắc chắn. Cả hai đều có cùng kích thước. – dubbeat

+0

@dubbeat hv u đã thực hiện nó với ghi âm – Aadil

Trả lời

9

Sau một vài ngày kể từ khi nước mắt & tóc kéo tôi có một giải pháp.

Trong mã của tôi và trong các ví dụ khác tôi đã thấy extaudiofilewriteasync được gọi trong gọi lại cho đơn vị từ xa như vậy.

** remoteiounit callback **

static OSStatus masterChannelMixerUnitCallback(void *inRefCon, 
           AudioUnitRenderActionFlags *ioActionFlags, 
           const AudioTimeStamp *inTimeStamp, 
           UInt32 inBusNumber, 
           UInt32 inNumberFrames, 
           AudioBufferList *ioData) 

{ 


    AudioUnitRender(engineDescribtion.equnit, ioActionFlags, inTimeStamp, 0, inNumberFrames, ioData); 


    if(isrecording) 
    { 
     ExtAudioFileWriteAsync(engine->recordingfileref, inNumberFrames, ioData); 


    } 



    return 0; 

} 

Trong callback này tôi kéo dữ liệu âm thanh từ một đơn vị âm thanh mà áp dụng eqs và pha trộn âm thanh.

Tôi đã xóa cuộc gọi extaudiofilewriteasync khỏi cuộc gọi lại từ xa đến cuộc gọi lại khác mà remoteio kéo và tệp ghi thành công !!

* equnits hàm callback *

static OSStatus outputCallback(void *inRefCon, 
           AudioUnitRenderActionFlags *ioActionFlags, 
           const AudioTimeStamp *inTimeStamp, 
           UInt32 inBusNumber, 
           UInt32 inNumberFrames, 
           AudioBufferList *ioData) { 


    AudioUnitRender(engineDescribtion.masterChannelMixerUnit, ioActionFlags, inTimeStamp, 0, inNumberFrames, ioData); 

    //process audio here  

    Engine *engine= (Engine *) inRefCon; 


    OSStatus s; 

    if(engine->isrecording) 
    { 
     s=ExtAudioFileWriteAsync(engine->recordingfileref, inNumberFrames, ioData); 


    } 


    return noErr; 

} 

Trong sự quan tâm của sự hiểu biết đầy đủ tại sao giải pháp của tôi làm việc ai đó có thể giải thích cho tôi tại sao ghi dữ liệu vào tập tin từ bufferlist iodata của remoteio gây âm thanh méo mó nhưng viết dữ liệu thêm một bước xuống chuỗi kết quả trong âm thanh hoàn hảo?

+0

Bạn có thể giải thích giải pháp của mình không. Tôi đang đối mặt với cùng một vấn đề. Dữ liệu âm thanh được ghi vào tệp trong cuộc gọi lại bị méo. Chúng ta nên viết lại lời gọi nào? – Namratha

+0

Nó thực sự phụ thuộc vào AUGraph của bạn. Những gì tôi đã tìm thấy từ kinh nghiệm là cố gắng để ghi âm thanh vào đĩa từ callback đầu ra của remoteio (nút 0) thường không hoạt động. Thay vào đó hãy đặt nó trong một cuộc gọi lại đầu vào cho một số nút khác. Nếu bạn viết một câu hỏi đầy đủ hơn với mã nguồn, tôi có thể giúp bạn nhiều hơn. – dubbeat

Các vấn đề liên quan