我正在使用Apple的MixerHost类的修改版本,它在其回调中将音频分成两个流(这是为了使得到的音频可以是单声道或立体声)。结果显然是非交错流。我是Core Audio的新手,我需要一个交错的流,我想知道是否有人能指出我正确的方向来修改回调中的缓冲区以存储交错的立体声数据。
谢谢。
以下是其中一个回调:
static OSStatus inputRenderCallback (
void *inRefCon, // A pointer to a struct containing the complete audio data
// to play, as well as state information such as the
// first sample to play on this invocation of the callback.
AudioUnitRenderActionFlags *ioActionFlags, // Unused here. When generating audio, use ioActionFlags to indicate silence
// between sounds; for silence, also memset the ioData buffers to 0.
const AudioTimeStamp *inTimeStamp, // Unused here.
UInt32 inBusNumber, // The mixer unit input bus that is requesting some new
// frames of audio data to play.
UInt32 inNumberFrames, // The number of frames of audio to provide to the buffer(s)
// pointed to by the ioData parameter.
AudioBufferList *ioData // On output, the audio data to play. The callback's primary
// responsibility is to fill the buffer(s) in the
// AudioBufferList.
) {
soundStructPtr soundStructPointerArray = (soundStructPtr) inRefCon;
UInt32 frameTotalForSound = soundStructPointerArray[inBusNumber].frameCount;
BOOL isStereo = soundStructPointerArray[inBusNumber].isStereo;
// Declare variables to point to the audio buffers. Their data type must match the buffer data type.
AudioUnitSampleType *dataInLeft;
AudioUnitSampleType *dataInRight;
dataInLeft = soundStructPointerArray[inBusNumber].audioDataLeft;
if (isStereo) dataInRight = soundStructPointerArray[inBusNumber].audioDataRight;
// Establish pointers to the memory into which the audio from the buffers should go. This reflects
// the fact that each Multichannel Mixer unit input bus has two channels, as specified by this app's
// graphStreamFormat variable.
AudioUnitSampleType *outSamplesChannelLeft;
AudioUnitSampleType *outSamplesChannelRight;
outSamplesChannelLeft = (AudioUnitSampleType *) ioData->mBuffers[0].mData;
if (isStereo) outSamplesChannelRight = (AudioUnitSampleType *) ioData->mBuffers[1].mData;
// Get the sample number, as an index into the sound stored in memory,
// to start reading data from.
UInt32 sampleNumber = soundStructPointerArray[inBusNumber].sampleNumber;
// Fill the buffer or buffers pointed at by *ioData with the requested number of samples
// of audio from the sound stored in memory.
for (UInt32 frameNumber = 0; frameNumber < inNumberFrames; ++frameNumber) {
if (sampleNumber == frameTotalForSound) {
NSString *AudioFileDidFinishPlaying = @"AudioFileDidFinishPlaying";
[[NSNotificationCenter defaultCenter] postNotificationName: AudioFileDidFinishPlaying object: nil];
/*NSString *CloseExtAudioFile = @"CloseExtAudioFile";
[[NSNotificationCenter defaultCenter] postNotificationName: CloseExtAudioFile object: nil];*/
}
outSamplesChannelLeft[frameNumber] = dataInLeft[sampleNumber];
if (isStereo) outSamplesChannelRight[frameNumber] = dataInRight[sampleNumber];
sampleNumber++;
// After reaching the end of the sound stored in memory--that is, after
// (frameTotalForSound / inNumberFrames) invocations of this callback--loop back to the
// start of the sound so playback resumes from there.
//NSLog (@"Audio file finished; stopping audio playback.");
}
// Update the stored sample number so, the next time this callback is invoked, playback resumes
// at the correct spot.
soundStructPointerArray[inBusNumber].sampleNumber = sampleNumber;
return noErr;
}