如何修改此AudioUnit代码以使其具有立体声输出?

时间:2014-01-17 03:17:06

标签: ios core-audio audiounit audiotoolbox

我似乎无法在文档中找到我正在寻找的内容。这段代码效果很好,但我想要立体声输出。

- (void)createToneUnit
{
    // Configure the search parameters to find the default playback output unit
    // (called the kAudioUnitSubType_RemoteIO on iOS but
    // kAudioUnitSubType_DefaultOutput on Mac OS X)
    AudioComponentDescription defaultOutputDescription;
    defaultOutputDescription.componentType = kAudioUnitType_Output;
    defaultOutputDescription.componentSubType = kAudioUnitSubType_RemoteIO;
    defaultOutputDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
    defaultOutputDescription.componentFlags = 0;
    defaultOutputDescription.componentFlagsMask = 0;

    // Get the default playback output unit
    AudioComponent defaultOutput = AudioComponentFindNext(NULL, &defaultOutputDescription);
    NSAssert(defaultOutput, @"Can't find default output");

    // Create a new unit based on this that we'll use for output
    OSErr err = AudioComponentInstanceNew(defaultOutput, &_toneUnit);
    NSAssert1(_toneUnit, @"Error creating unit: %d", err);

    // Set our tone rendering function on the unit
    AURenderCallbackStruct input;
    input.inputProc = RenderTone;
    input.inputProcRefCon = (__bridge void*)self;
    err = AudioUnitSetProperty(_toneUnit,
                               kAudioUnitProperty_SetRenderCallback,
                               kAudioUnitScope_Input,
                               0,
                               &input,
                               sizeof(input));
    NSAssert1(err == noErr, @"Error setting callback: %d", err);

    // Set the format to 32 bit, single channel, floating point, linear PCM
    const int four_bytes_per_float = 4;
    const int eight_bits_per_byte = 8;
    AudioStreamBasicDescription streamFormat;
    streamFormat.mSampleRate = kSampleRate;
    streamFormat.mFormatID = kAudioFormatLinearPCM;
    streamFormat.mFormatFlags =
    kAudioFormatFlagsNativeFloatPacked | kAudioFormatFlagIsNonInterleaved;
    streamFormat.mBytesPerPacket = four_bytes_per_float;
    streamFormat.mFramesPerPacket = 1;
    streamFormat.mBytesPerFrame = four_bytes_per_float;
    streamFormat.mChannelsPerFrame = 1;
    streamFormat.mBitsPerChannel = four_bytes_per_float * eight_bits_per_byte;
    err = AudioUnitSetProperty (_toneUnit,
                                kAudioUnitProperty_StreamFormat,
                                kAudioUnitScope_Input,
                                0,
                                &streamFormat,
                                sizeof(AudioStreamBasicDescription));
    NSAssert1(err == noErr, @"Error setting stream format: %dd", err);
}

这是回调:

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



    // Get the tone parameters out of the view controller
    VWWSynthesizerC *synth = (__bridge VWWSynthesizerC *)inRefCon;
    double theta = synth.theta;
    double theta_increment = 2.0 * M_PI * synth.frequency / kSampleRate;




    // This is a mono tone generator so we only need the first buffer
    const int channel = 0;
    Float32 *buffer = (Float32 *)ioData->mBuffers[channel].mData;

    // Generate the samples
    for (UInt32 frame = 0; frame < inNumberFrames; frame++)
    {
        if(synth.muted){
            buffer[frame] = 0;
        }
        else{
            switch(synth.waveType){
                case VWWWaveTypeSine:{
                    buffer[frame] = sin(theta) * synth.amplitude;
                    break;
                }
                case VWWWaveTypeSquare:{
                    buffer[frame] = square(theta) * synth.amplitude;
                    break;
                }
                case VWWWaveTypeSawtooth:{
                    buffer[frame] = sawtooth(theta) * synth.amplitude;
                    break;
                }
                case VWWWaveTypeTriangle:{
                    buffer[frame] = triangle(theta) * synth.amplitude;
                    break;
                }
                default:
                    break;

            }
        }
        theta += theta_increment;
        if (theta > 2.0 * M_PI)
        {
            theta -= 2.0 * M_PI;
        }
    }

    synth.theta = theta;

    return noErr;
}

如果有不同或更好的方式来呈现此数据,我愿意接受建议。我正在渲染正弦波,方波,三角波,锯齿波......等等。

0 个答案:

没有答案