2012-08-25 58 views
4

我有一個音頻發生器應用程序,可根據頻率滑塊值生成音調。這部分應用程序正常工作。我redering使用具有可變振盪模式的iOS音頻發生器

#import <AudioToolbox/AudioToolbox.h> 

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

{ 
// Fixed amplitude is good enough for our purposes 
const double amplitude = 0.25; 

// Get the tone parameters out of the view controller 
ToneGeneratorViewController *viewController = 
    (ToneGeneratorViewController *)inRefCon; 
double theta = viewController->theta; 
double theta_increment = 2.0 * M_PI * viewController->frequency/viewController- >sampleRate; 

// 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++) 
{ 
    buffer[frame] = sin(theta) * amplitude; 

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

// Store the theta back in the view controller 
viewController->theta = theta; 

return noErr; 
} 



- (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: %ld", err); 

// Set our tone rendering function on the unit 
AURenderCallbackStruct input; 
input.inputProc = RenderTone; 
input.inputProcRefCon = self; 
err = AudioUnitSetProperty(toneUnit, 
    kAudioUnitProperty_SetRenderCallback, 
    kAudioUnitScope_Input, 
    0, 
    &input, 
    sizeof(input)); 
NSAssert1(err == noErr, @"Error setting callback: %ld", 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 = sampleRate; 
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: %ld", err); 
} 

現在我需要修改像狗惠斯勒應用的應用模式的基調。任何人都可以告訴我,我需要做什麼來修改源代碼之後的波形?

在此先感謝

+1

你需要更清楚你想要達到的目標。查看各種Dog Whistler應用程序的網頁,它們支持各種功能。您試圖複製哪個特定的應用程序和哪些功能? – user1118321

回答

5

您可能需要爲每個特定的模式不同RenderTone實現。代碼中的實現產生一個沒有調製的採樣純正弦波。您可以生成各種模式,這取決於您的需求,您將實施什麼。

例如,生成較短或較長的嘟嘟聲會要求您在'for'循環中爲循環內的特定幀數的正弦曲線生成'沉默'(將0-s寫入緩衝區),然後生成然後再次靜音樣品...(這就像是斬波信號)

您還可以通過使用另一個正弦信號計算的因子對樣本值進行縮放來調製(顫音效果)較低的頻率)。

另一個例子是通過調製生成的樣本的頻率(顫音效果),也就是根據低頻信號調整變量theta_increment的值來產生「警笛」聲。或者,只需使用兩個不同的值就可以與上面的「嗶聲」效果交替使用。

希望,這有助於。