Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>In <strong><em>initializaeOutputUnit</em></strong> you only created your audio file:</p> <pre><code>OSStatus setupErr = ExtAudioFileCreateWithURL(destinationURL, kAudioFileWAVEType, &amp;audioFormat, NULL, kAudioFileFlags_EraseFile, &amp;effectState.audioFileRef); </code></pre> <p>by passing <strong>0</strong> (frames) and <strong>NULL</strong> (audiobuffer) is just for init internal buffers: </p> <pre><code>setupErr = ExtAudioFileWriteAsync(effectState.audioFileRef, 0, NULL); </code></pre> <p>That's what's going wrong in <strong>recordingCallback</strong>:</p> <p>1) ioActionFlags are always 0 and inBusNumber are always 1, because thats how you setup your callback (kInputBus = 1):</p> <pre><code>if (*ioActionFlags == kAudioUnitRenderAction_PostRender&amp;&amp;inBusNumber==0) </code></pre> <p>so just remove the if statement.</p> <p>2) From <strong>AudioUnitRender</strong> you will receive <strong>-50 error</strong>, which is defined in CoreAudioTypes.h as an <strong>kAudio_ParamError</strong> error. This happens by bufferList is not defined and NULL!</p> <blockquote> <pre><code> OSStatus status; status = AudioUnitRender(THIS-&gt;mAudioUnit, ioActionFlags, inTimeStamp, kInputBus, inNumberFrames, &amp;bufferList); if (noErr != status) { printf("AudioUnitRender error: %ld", status); return noErr; } </code></pre> </blockquote> <p>You just need to define an valid AudioBuffer and pass it to AudioUnitRender, this is my working RenderCallback:</p> <blockquote> <pre><code> static OSStatus recordingCallback (void * inRefCon, AudioUnitRenderActionFlags * ioActionFlags, const AudioTimeStamp * inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList * ioData) { double timeInSeconds = inTimeStamp-&gt;mSampleTime / kSampleRate; printf("\n%fs inBusNumber: %lu inNumberFrames: %lu ", timeInSeconds, inBusNumber, inNumberFrames); //printAudioUnitRenderActionFlags(ioActionFlags); AudioBufferList bufferList; SInt16 samples[inNumberFrames]; // A large enough size to not have to worry about buffer overrun memset (&amp;samples, 0, sizeof (samples)); bufferList.mNumberBuffers = 1; bufferList.mBuffers[0].mData = samples; bufferList.mBuffers[0].mNumberChannels = 1; bufferList.mBuffers[0].mDataByteSize = inNumberFrames*sizeof(SInt16); ViewController* THIS = THIS = (__bridge ViewController *)inRefCon; OSStatus status; status = AudioUnitRender(THIS-&gt;mAudioUnit, ioActionFlags, inTimeStamp, kInputBus, inNumberFrames, &amp;bufferList); if (noErr != status) { printf("AudioUnitRender error: %ld", status); return noErr; } // Now, we have the samples we just read sitting in buffers in bufferList ExtAudioFileWriteAsync(THIS-&gt;mAudioFileRef, inNumberFrames, &amp;bufferList); return noErr; } </code></pre> </blockquote> <p>In <strong>stopRecord</strong> you should close the audio file with <strong>ExtAudioFileDispose</strong>:</p> <blockquote> <pre><code> - (void)stopRecording:(NSTimer*)theTimer { printf("\nstopRecording\n"); AudioOutputUnitStop(mAudioUnit); AudioUnitUninitialize(mAudioUnit); OSStatus status = ExtAudioFileDispose(mAudioFileRef); printf("OSStatus(ExtAudioFileDispose): %ld\n", status); } </code></pre> </blockquote> <p>Full source code: <a href="http://pastebin.com/92Fyjaye">http://pastebin.com/92Fyjaye</a></p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload